xref: /openbmc/qemu/target/mips/tcg/mxu_translate.c (revision ad75a51e)
1a2b0a27dSPhilippe Mathieu-Daudé /*
2a2b0a27dSPhilippe Mathieu-Daudé  *  Ingenic XBurst Media eXtension Unit (MXU) translation routines.
3a2b0a27dSPhilippe Mathieu-Daudé  *
4a2b0a27dSPhilippe Mathieu-Daudé  *  Copyright (c) 2004-2005 Jocelyn Mayer
5a2b0a27dSPhilippe Mathieu-Daudé  *  Copyright (c) 2006 Marius Groeger (FPU operations)
6a2b0a27dSPhilippe Mathieu-Daudé  *  Copyright (c) 2006 Thiemo Seufer (MIPS32R2 support)
7a2b0a27dSPhilippe Mathieu-Daudé  *  Copyright (c) 2009 CodeSourcery (MIPS16 and microMIPS support)
8a2b0a27dSPhilippe Mathieu-Daudé  *  Copyright (c) 2012 Jia Liu & Dongxue Zhang (MIPS ASE DSP support)
9a2b0a27dSPhilippe Mathieu-Daudé  *
10a2b0a27dSPhilippe Mathieu-Daudé  * SPDX-License-Identifier: LGPL-2.1-or-later
11a2b0a27dSPhilippe Mathieu-Daudé  *
12a2b0a27dSPhilippe Mathieu-Daudé  * Datasheet:
13a2b0a27dSPhilippe Mathieu-Daudé  *
14a2b0a27dSPhilippe Mathieu-Daudé  *   "XBurst® Instruction Set Architecture MIPS eXtension/enhanced Unit
15a2b0a27dSPhilippe Mathieu-Daudé  *   Programming Manual", Ingenic Semiconductor Co, Ltd., revision June 2, 2017
16a2b0a27dSPhilippe Mathieu-Daudé  */
17a2b0a27dSPhilippe Mathieu-Daudé 
18a2b0a27dSPhilippe Mathieu-Daudé #include "qemu/osdep.h"
19a2b0a27dSPhilippe Mathieu-Daudé #include "translate.h"
20a2b0a27dSPhilippe Mathieu-Daudé 
21a2b0a27dSPhilippe Mathieu-Daudé /*
22a2b0a27dSPhilippe Mathieu-Daudé  *
23a2b0a27dSPhilippe Mathieu-Daudé  *       AN OVERVIEW OF MXU EXTENSION INSTRUCTION SET
24a2b0a27dSPhilippe Mathieu-Daudé  *       ============================================
25a2b0a27dSPhilippe Mathieu-Daudé  *
26a2b0a27dSPhilippe Mathieu-Daudé  *
27a2b0a27dSPhilippe Mathieu-Daudé  * MXU (full name: MIPS eXtension/enhanced Unit) is a SIMD extension of MIPS32
28a2b0a27dSPhilippe Mathieu-Daudé  * instructions set. It is designed to fit the needs of signal, graphical and
29a2b0a27dSPhilippe Mathieu-Daudé  * video processing applications. MXU instruction set is used in Xburst family
30a2b0a27dSPhilippe Mathieu-Daudé  * of microprocessors by Ingenic.
31a2b0a27dSPhilippe Mathieu-Daudé  *
32a2b0a27dSPhilippe Mathieu-Daudé  * MXU unit contains 17 registers called X0-X16. X0 is always zero, and X16 is
33a2b0a27dSPhilippe Mathieu-Daudé  * the control register.
34a2b0a27dSPhilippe Mathieu-Daudé  *
35a2b0a27dSPhilippe Mathieu-Daudé  *
36a2b0a27dSPhilippe Mathieu-Daudé  *     The notation used in MXU assembler mnemonics
37a2b0a27dSPhilippe Mathieu-Daudé  *     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
38a2b0a27dSPhilippe Mathieu-Daudé  *
39a2b0a27dSPhilippe Mathieu-Daudé  *  Register operands:
40a2b0a27dSPhilippe Mathieu-Daudé  *
41a2b0a27dSPhilippe Mathieu-Daudé  *   XRa, XRb, XRc, XRd - MXU registers
42a2b0a27dSPhilippe Mathieu-Daudé  *   Rb, Rc, Rd, Rs, Rt - general purpose MIPS registers
43a2b0a27dSPhilippe Mathieu-Daudé  *
44a2b0a27dSPhilippe Mathieu-Daudé  *  Non-register operands:
45a2b0a27dSPhilippe Mathieu-Daudé  *
46a2b0a27dSPhilippe Mathieu-Daudé  *   aptn1 - 1-bit accumulate add/subtract pattern
47a2b0a27dSPhilippe Mathieu-Daudé  *   aptn2 - 2-bit accumulate add/subtract pattern
48a2b0a27dSPhilippe Mathieu-Daudé  *   eptn2 - 2-bit execute add/subtract pattern
49a2b0a27dSPhilippe Mathieu-Daudé  *   optn2 - 2-bit operand pattern
50a2b0a27dSPhilippe Mathieu-Daudé  *   optn3 - 3-bit operand pattern
51a2b0a27dSPhilippe Mathieu-Daudé  *   sft4  - 4-bit shift amount
52a2b0a27dSPhilippe Mathieu-Daudé  *   strd2 - 2-bit stride amount
53a2b0a27dSPhilippe Mathieu-Daudé  *
54a2b0a27dSPhilippe Mathieu-Daudé  *  Prefixes:
55a2b0a27dSPhilippe Mathieu-Daudé  *
56a2b0a27dSPhilippe Mathieu-Daudé  *   Level of parallelism:                Operand size:
57a2b0a27dSPhilippe Mathieu-Daudé  *    S - single operation at a time       32 - word
58a2b0a27dSPhilippe Mathieu-Daudé  *    D - two operations in parallel       16 - half word
59a2b0a27dSPhilippe Mathieu-Daudé  *    Q - four operations in parallel       8 - byte
60a2b0a27dSPhilippe Mathieu-Daudé  *
61a2b0a27dSPhilippe Mathieu-Daudé  *  Operations:
62a2b0a27dSPhilippe Mathieu-Daudé  *
63a2b0a27dSPhilippe Mathieu-Daudé  *   ADD   - Add or subtract
64a2b0a27dSPhilippe Mathieu-Daudé  *   ADDC  - Add with carry-in
65a2b0a27dSPhilippe Mathieu-Daudé  *   ACC   - Accumulate
66a2b0a27dSPhilippe Mathieu-Daudé  *   ASUM  - Sum together then accumulate (add or subtract)
67a2b0a27dSPhilippe Mathieu-Daudé  *   ASUMC - Sum together then accumulate (add or subtract) with carry-in
68a2b0a27dSPhilippe Mathieu-Daudé  *   AVG   - Average between 2 operands
69a2b0a27dSPhilippe Mathieu-Daudé  *   ABD   - Absolute difference
70a2b0a27dSPhilippe Mathieu-Daudé  *   ALN   - Align data
71a2b0a27dSPhilippe Mathieu-Daudé  *   AND   - Logical bitwise 'and' operation
72a2b0a27dSPhilippe Mathieu-Daudé  *   CPS   - Copy sign
73a2b0a27dSPhilippe Mathieu-Daudé  *   EXTR  - Extract bits
74a2b0a27dSPhilippe Mathieu-Daudé  *   I2M   - Move from GPR register to MXU register
75a2b0a27dSPhilippe Mathieu-Daudé  *   LDD   - Load data from memory to XRF
76a2b0a27dSPhilippe Mathieu-Daudé  *   LDI   - Load data from memory to XRF (and increase the address base)
77a2b0a27dSPhilippe Mathieu-Daudé  *   LUI   - Load unsigned immediate
78a2b0a27dSPhilippe Mathieu-Daudé  *   MUL   - Multiply
79a2b0a27dSPhilippe Mathieu-Daudé  *   MULU  - Unsigned multiply
80a2b0a27dSPhilippe Mathieu-Daudé  *   MADD  - 64-bit operand add 32x32 product
81a2b0a27dSPhilippe Mathieu-Daudé  *   MSUB  - 64-bit operand subtract 32x32 product
82a2b0a27dSPhilippe Mathieu-Daudé  *   MAC   - Multiply and accumulate (add or subtract)
83a2b0a27dSPhilippe Mathieu-Daudé  *   MAD   - Multiply and add or subtract
84a2b0a27dSPhilippe Mathieu-Daudé  *   MAX   - Maximum between 2 operands
85a2b0a27dSPhilippe Mathieu-Daudé  *   MIN   - Minimum between 2 operands
86a2b0a27dSPhilippe Mathieu-Daudé  *   M2I   - Move from MXU register to GPR register
87a2b0a27dSPhilippe Mathieu-Daudé  *   MOVZ  - Move if zero
88a2b0a27dSPhilippe Mathieu-Daudé  *   MOVN  - Move if non-zero
89a2b0a27dSPhilippe Mathieu-Daudé  *   NOR   - Logical bitwise 'nor' operation
90a2b0a27dSPhilippe Mathieu-Daudé  *   OR    - Logical bitwise 'or' operation
91a2b0a27dSPhilippe Mathieu-Daudé  *   STD   - Store data from XRF to memory
92a2b0a27dSPhilippe Mathieu-Daudé  *   SDI   - Store data from XRF to memory (and increase the address base)
93a2b0a27dSPhilippe Mathieu-Daudé  *   SLT   - Set of less than comparison
94a2b0a27dSPhilippe Mathieu-Daudé  *   SAD   - Sum of absolute differences
95a2b0a27dSPhilippe Mathieu-Daudé  *   SLL   - Logical shift left
96a2b0a27dSPhilippe Mathieu-Daudé  *   SLR   - Logical shift right
97a2b0a27dSPhilippe Mathieu-Daudé  *   SAR   - Arithmetic shift right
98a2b0a27dSPhilippe Mathieu-Daudé  *   SAT   - Saturation
99a2b0a27dSPhilippe Mathieu-Daudé  *   SFL   - Shuffle
100a2b0a27dSPhilippe Mathieu-Daudé  *   SCOP  - Calculate x’s scope (-1, means x<0; 0, means x==0; 1, means x>0)
101a2b0a27dSPhilippe Mathieu-Daudé  *   XOR   - Logical bitwise 'exclusive or' operation
102a2b0a27dSPhilippe Mathieu-Daudé  *
103a2b0a27dSPhilippe Mathieu-Daudé  *  Suffixes:
104a2b0a27dSPhilippe Mathieu-Daudé  *
105a2b0a27dSPhilippe Mathieu-Daudé  *   E - Expand results
106a2b0a27dSPhilippe Mathieu-Daudé  *   F - Fixed point multiplication
107a2b0a27dSPhilippe Mathieu-Daudé  *   L - Low part result
108a2b0a27dSPhilippe Mathieu-Daudé  *   R - Doing rounding
109a2b0a27dSPhilippe Mathieu-Daudé  *   V - Variable instead of immediate
110a2b0a27dSPhilippe Mathieu-Daudé  *   W - Combine above L and V
111a2b0a27dSPhilippe Mathieu-Daudé  *
112a2b0a27dSPhilippe Mathieu-Daudé  *
113a2b0a27dSPhilippe Mathieu-Daudé  *     The list of MXU instructions grouped by functionality
114a2b0a27dSPhilippe Mathieu-Daudé  *     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
115a2b0a27dSPhilippe Mathieu-Daudé  *
116a2b0a27dSPhilippe Mathieu-Daudé  * Load/Store instructions           Multiplication instructions
117a2b0a27dSPhilippe Mathieu-Daudé  * -----------------------           ---------------------------
118a2b0a27dSPhilippe Mathieu-Daudé  *
119a2b0a27dSPhilippe Mathieu-Daudé  *  S32LDD XRa, Rb, s12               S32MADD XRa, XRd, Rs, Rt
120a2b0a27dSPhilippe Mathieu-Daudé  *  S32STD XRa, Rb, s12               S32MADDU XRa, XRd, Rs, Rt
121a2b0a27dSPhilippe Mathieu-Daudé  *  S32LDDV XRa, Rb, rc, strd2        S32MSUB XRa, XRd, Rs, Rt
122a2b0a27dSPhilippe Mathieu-Daudé  *  S32STDV XRa, Rb, rc, strd2        S32MSUBU XRa, XRd, Rs, Rt
123a2b0a27dSPhilippe Mathieu-Daudé  *  S32LDI XRa, Rb, s12               S32MUL XRa, XRd, Rs, Rt
124a2b0a27dSPhilippe Mathieu-Daudé  *  S32SDI XRa, Rb, s12               S32MULU XRa, XRd, Rs, Rt
125a2b0a27dSPhilippe Mathieu-Daudé  *  S32LDIV XRa, Rb, rc, strd2        D16MUL XRa, XRb, XRc, XRd, optn2
126a2b0a27dSPhilippe Mathieu-Daudé  *  S32SDIV XRa, Rb, rc, strd2        D16MULE XRa, XRb, XRc, optn2
127a2b0a27dSPhilippe Mathieu-Daudé  *  S32LDDR XRa, Rb, s12              D16MULF XRa, XRb, XRc, optn2
128a2b0a27dSPhilippe Mathieu-Daudé  *  S32STDR XRa, Rb, s12              D16MAC XRa, XRb, XRc, XRd, aptn2, optn2
129a2b0a27dSPhilippe Mathieu-Daudé  *  S32LDDVR XRa, Rb, rc, strd2       D16MACE XRa, XRb, XRc, XRd, aptn2, optn2
130a2b0a27dSPhilippe Mathieu-Daudé  *  S32STDVR XRa, Rb, rc, strd2       D16MACF XRa, XRb, XRc, XRd, aptn2, optn2
131a2b0a27dSPhilippe Mathieu-Daudé  *  S32LDIR XRa, Rb, s12              D16MADL XRa, XRb, XRc, XRd, aptn2, optn2
132a2b0a27dSPhilippe Mathieu-Daudé  *  S32SDIR XRa, Rb, s12              S16MAD XRa, XRb, XRc, XRd, aptn1, optn2
133a2b0a27dSPhilippe Mathieu-Daudé  *  S32LDIVR XRa, Rb, rc, strd2       Q8MUL XRa, XRb, XRc, XRd
134a2b0a27dSPhilippe Mathieu-Daudé  *  S32SDIVR XRa, Rb, rc, strd2       Q8MULSU XRa, XRb, XRc, XRd
135a2b0a27dSPhilippe Mathieu-Daudé  *  S16LDD XRa, Rb, s10, eptn2        Q8MAC XRa, XRb, XRc, XRd, aptn2
136a2b0a27dSPhilippe Mathieu-Daudé  *  S16STD XRa, Rb, s10, eptn2        Q8MACSU XRa, XRb, XRc, XRd, aptn2
137a2b0a27dSPhilippe Mathieu-Daudé  *  S16LDI XRa, Rb, s10, eptn2        Q8MADL XRa, XRb, XRc, XRd, aptn2
138a2b0a27dSPhilippe Mathieu-Daudé  *  S16SDI XRa, Rb, s10, eptn2
139a2b0a27dSPhilippe Mathieu-Daudé  *  S8LDD XRa, Rb, s8, eptn3
140a2b0a27dSPhilippe Mathieu-Daudé  *  S8STD XRa, Rb, s8, eptn3         Addition and subtraction instructions
141a2b0a27dSPhilippe Mathieu-Daudé  *  S8LDI XRa, Rb, s8, eptn3         -------------------------------------
142a2b0a27dSPhilippe Mathieu-Daudé  *  S8SDI XRa, Rb, s8, eptn3
143a2b0a27dSPhilippe Mathieu-Daudé  *  LXW Rd, Rs, Rt, strd2             D32ADD XRa, XRb, XRc, XRd, eptn2
144a2b0a27dSPhilippe Mathieu-Daudé  *  LXH Rd, Rs, Rt, strd2             D32ADDC XRa, XRb, XRc, XRd
145a2b0a27dSPhilippe Mathieu-Daudé  *  LXHU Rd, Rs, Rt, strd2            D32ACC XRa, XRb, XRc, XRd, eptn2
146a2b0a27dSPhilippe Mathieu-Daudé  *  LXB Rd, Rs, Rt, strd2             D32ACCM XRa, XRb, XRc, XRd, eptn2
147a2b0a27dSPhilippe Mathieu-Daudé  *  LXBU Rd, Rs, Rt, strd2            D32ASUM XRa, XRb, XRc, XRd, eptn2
148a2b0a27dSPhilippe Mathieu-Daudé  *                                    S32CPS XRa, XRb, XRc
149a2b0a27dSPhilippe Mathieu-Daudé  *                                    Q16ADD XRa, XRb, XRc, XRd, eptn2, optn2
150a2b0a27dSPhilippe Mathieu-Daudé  * Comparison instructions            Q16ACC XRa, XRb, XRc, XRd, eptn2
151a2b0a27dSPhilippe Mathieu-Daudé  * -----------------------            Q16ACCM XRa, XRb, XRc, XRd, eptn2
152a2b0a27dSPhilippe Mathieu-Daudé  *                                    D16ASUM XRa, XRb, XRc, XRd, eptn2
153a2b0a27dSPhilippe Mathieu-Daudé  *  S32MAX XRa, XRb, XRc              D16CPS XRa, XRb,
154a2b0a27dSPhilippe Mathieu-Daudé  *  S32MIN XRa, XRb, XRc              D16AVG XRa, XRb, XRc
155a2b0a27dSPhilippe Mathieu-Daudé  *  S32SLT XRa, XRb, XRc              D16AVGR XRa, XRb, XRc
156a2b0a27dSPhilippe Mathieu-Daudé  *  S32MOVZ XRa, XRb, XRc             Q8ADD XRa, XRb, XRc, eptn2
157a2b0a27dSPhilippe Mathieu-Daudé  *  S32MOVN XRa, XRb, XRc             Q8ADDE XRa, XRb, XRc, XRd, eptn2
158a2b0a27dSPhilippe Mathieu-Daudé  *  D16MAX XRa, XRb, XRc              Q8ACCE XRa, XRb, XRc, XRd, eptn2
159a2b0a27dSPhilippe Mathieu-Daudé  *  D16MIN XRa, XRb, XRc              Q8ABD XRa, XRb, XRc
160a2b0a27dSPhilippe Mathieu-Daudé  *  D16SLT XRa, XRb, XRc              Q8SAD XRa, XRb, XRc, XRd
161a2b0a27dSPhilippe Mathieu-Daudé  *  D16MOVZ XRa, XRb, XRc             Q8AVG XRa, XRb, XRc
162a2b0a27dSPhilippe Mathieu-Daudé  *  D16MOVN XRa, XRb, XRc             Q8AVGR XRa, XRb, XRc
163a2b0a27dSPhilippe Mathieu-Daudé  *  Q8MAX XRa, XRb, XRc               D8SUM XRa, XRb, XRc, XRd
164a2b0a27dSPhilippe Mathieu-Daudé  *  Q8MIN XRa, XRb, XRc               D8SUMC XRa, XRb, XRc, XRd
165a2b0a27dSPhilippe Mathieu-Daudé  *  Q8SLT XRa, XRb, XRc
166a2b0a27dSPhilippe Mathieu-Daudé  *  Q8SLTU XRa, XRb, XRc
167a2b0a27dSPhilippe Mathieu-Daudé  *  Q8MOVZ XRa, XRb, XRc             Shift instructions
168a2b0a27dSPhilippe Mathieu-Daudé  *  Q8MOVN XRa, XRb, XRc             ------------------
169a2b0a27dSPhilippe Mathieu-Daudé  *
170a2b0a27dSPhilippe Mathieu-Daudé  *                                    D32SLL XRa, XRb, XRc, XRd, sft4
171a2b0a27dSPhilippe Mathieu-Daudé  * Bitwise instructions               D32SLR XRa, XRb, XRc, XRd, sft4
172a2b0a27dSPhilippe Mathieu-Daudé  * --------------------               D32SAR XRa, XRb, XRc, XRd, sft4
173a2b0a27dSPhilippe Mathieu-Daudé  *                                    D32SARL XRa, XRb, XRc, sft4
174a2b0a27dSPhilippe Mathieu-Daudé  *  S32NOR XRa, XRb, XRc              D32SLLV XRa, XRb, Rb
175a2b0a27dSPhilippe Mathieu-Daudé  *  S32AND XRa, XRb, XRc              D32SLRV XRa, XRb, Rb
176a2b0a27dSPhilippe Mathieu-Daudé  *  S32XOR XRa, XRb, XRc              D32SARV XRa, XRb, Rb
177a2b0a27dSPhilippe Mathieu-Daudé  *  S32OR XRa, XRb, XRc               D32SARW XRa, XRb, XRc, Rb
178a2b0a27dSPhilippe Mathieu-Daudé  *                                    Q16SLL XRa, XRb, XRc, XRd, sft4
179a2b0a27dSPhilippe Mathieu-Daudé  *                                    Q16SLR XRa, XRb, XRc, XRd, sft4
180a2b0a27dSPhilippe Mathieu-Daudé  * Miscellaneous instructions         Q16SAR XRa, XRb, XRc, XRd, sft4
181a2b0a27dSPhilippe Mathieu-Daudé  * -------------------------          Q16SLLV XRa, XRb, Rb
182a2b0a27dSPhilippe Mathieu-Daudé  *                                    Q16SLRV XRa, XRb, Rb
183a2b0a27dSPhilippe Mathieu-Daudé  *  S32SFL XRa, XRb, XRc, XRd, optn2  Q16SARV XRa, XRb, Rb
184a2b0a27dSPhilippe Mathieu-Daudé  *  S32ALN XRa, XRb, XRc, Rb
185a2b0a27dSPhilippe Mathieu-Daudé  *  S32ALNI XRa, XRb, XRc, s3
186a2b0a27dSPhilippe Mathieu-Daudé  *  S32LUI XRa, s8, optn3            Move instructions
187a2b0a27dSPhilippe Mathieu-Daudé  *  S32EXTR XRa, XRb, Rb, bits5      -----------------
188a2b0a27dSPhilippe Mathieu-Daudé  *  S32EXTRV XRa, XRb, Rs, Rt
189a2b0a27dSPhilippe Mathieu-Daudé  *  Q16SCOP XRa, XRb, XRc, XRd        S32M2I XRa, Rb
190a2b0a27dSPhilippe Mathieu-Daudé  *  Q16SAT XRa, XRb, XRc              S32I2M XRa, Rb
191a2b0a27dSPhilippe Mathieu-Daudé  *
192a2b0a27dSPhilippe Mathieu-Daudé  *
193a2b0a27dSPhilippe Mathieu-Daudé  *     The opcode organization of MXU instructions
194a2b0a27dSPhilippe Mathieu-Daudé  *     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
195a2b0a27dSPhilippe Mathieu-Daudé  *
196a2b0a27dSPhilippe Mathieu-Daudé  * The bits 31..26 of all MXU instructions are equal to 0x1C (also referred
197a2b0a27dSPhilippe Mathieu-Daudé  * as opcode SPECIAL2 in the base MIPS ISA). The organization and meaning of
198a2b0a27dSPhilippe Mathieu-Daudé  * other bits up to the instruction level is as follows:
199a2b0a27dSPhilippe Mathieu-Daudé  *
200a2b0a27dSPhilippe Mathieu-Daudé  *              bits
201a2b0a27dSPhilippe Mathieu-Daudé  *             05..00
202a2b0a27dSPhilippe Mathieu-Daudé  *
203a2b0a27dSPhilippe Mathieu-Daudé  *          ┌─ 000000 ─ OPC_MXU_S32MADD
204a2b0a27dSPhilippe Mathieu-Daudé  *          ├─ 000001 ─ OPC_MXU_S32MADDU
205a2b0a27dSPhilippe Mathieu-Daudé  *          ├─ 000010 ─ <not assigned>   (non-MXU OPC_MUL)
206a2b0a27dSPhilippe Mathieu-Daudé  *          │
207a2b0a27dSPhilippe Mathieu-Daudé  *          │                               20..18
208a2b0a27dSPhilippe Mathieu-Daudé  *          ├─ 000011 ─ OPC_MXU__POOL00 ─┬─ 000 ─ OPC_MXU_S32MAX
209a2b0a27dSPhilippe Mathieu-Daudé  *          │                            ├─ 001 ─ OPC_MXU_S32MIN
210a2b0a27dSPhilippe Mathieu-Daudé  *          │                            ├─ 010 ─ OPC_MXU_D16MAX
211a2b0a27dSPhilippe Mathieu-Daudé  *          │                            ├─ 011 ─ OPC_MXU_D16MIN
212a2b0a27dSPhilippe Mathieu-Daudé  *          │                            ├─ 100 ─ OPC_MXU_Q8MAX
213a2b0a27dSPhilippe Mathieu-Daudé  *          │                            ├─ 101 ─ OPC_MXU_Q8MIN
214a2b0a27dSPhilippe Mathieu-Daudé  *          │                            ├─ 110 ─ OPC_MXU_Q8SLT
215a2b0a27dSPhilippe Mathieu-Daudé  *          │                            └─ 111 ─ OPC_MXU_Q8SLTU
216a2b0a27dSPhilippe Mathieu-Daudé  *          ├─ 000100 ─ OPC_MXU_S32MSUB
217a2b0a27dSPhilippe Mathieu-Daudé  *          ├─ 000101 ─ OPC_MXU_S32MSUBU    20..18
218a2b0a27dSPhilippe Mathieu-Daudé  *          ├─ 000110 ─ OPC_MXU__POOL01 ─┬─ 000 ─ OPC_MXU_S32SLT
219a2b0a27dSPhilippe Mathieu-Daudé  *          │                            ├─ 001 ─ OPC_MXU_D16SLT
220a2b0a27dSPhilippe Mathieu-Daudé  *          │                            ├─ 010 ─ OPC_MXU_D16AVG
221a2b0a27dSPhilippe Mathieu-Daudé  *          │                            ├─ 011 ─ OPC_MXU_D16AVGR
222a2b0a27dSPhilippe Mathieu-Daudé  *          │                            ├─ 100 ─ OPC_MXU_Q8AVG
223a2b0a27dSPhilippe Mathieu-Daudé  *          │                            ├─ 101 ─ OPC_MXU_Q8AVGR
224a2b0a27dSPhilippe Mathieu-Daudé  *          │                            └─ 111 ─ OPC_MXU_Q8ADD
225a2b0a27dSPhilippe Mathieu-Daudé  *          │
226a2b0a27dSPhilippe Mathieu-Daudé  *          │                               20..18
227a2b0a27dSPhilippe Mathieu-Daudé  *          ├─ 000111 ─ OPC_MXU__POOL02 ─┬─ 000 ─ OPC_MXU_S32CPS
228a2b0a27dSPhilippe Mathieu-Daudé  *          │                            ├─ 010 ─ OPC_MXU_D16CPS
229a2b0a27dSPhilippe Mathieu-Daudé  *          │                            ├─ 100 ─ OPC_MXU_Q8ABD
230a2b0a27dSPhilippe Mathieu-Daudé  *          │                            └─ 110 ─ OPC_MXU_Q16SAT
231a2b0a27dSPhilippe Mathieu-Daudé  *          ├─ 001000 ─ OPC_MXU_D16MUL
232a2b0a27dSPhilippe Mathieu-Daudé  *          │                               25..24
233a2b0a27dSPhilippe Mathieu-Daudé  *          ├─ 001001 ─ OPC_MXU__POOL03 ─┬─ 00 ─ OPC_MXU_D16MULF
234a2b0a27dSPhilippe Mathieu-Daudé  *          │                            └─ 01 ─ OPC_MXU_D16MULE
235a2b0a27dSPhilippe Mathieu-Daudé  *          ├─ 001010 ─ OPC_MXU_D16MAC
236a2b0a27dSPhilippe Mathieu-Daudé  *          ├─ 001011 ─ OPC_MXU_D16MACF
237a2b0a27dSPhilippe Mathieu-Daudé  *          ├─ 001100 ─ OPC_MXU_D16MADL
238a2b0a27dSPhilippe Mathieu-Daudé  *          ├─ 001101 ─ OPC_MXU_S16MAD
239a2b0a27dSPhilippe Mathieu-Daudé  *          ├─ 001110 ─ OPC_MXU_Q16ADD
24059db9465SSiarhei Volkau  *          ├─ 001111 ─ OPC_MXU_D16MACE     20 (13..10 don't care)
241a2b0a27dSPhilippe Mathieu-Daudé  *          │                            ┌─ 0 ─ OPC_MXU_S32LDD
242a2b0a27dSPhilippe Mathieu-Daudé  *          ├─ 010000 ─ OPC_MXU__POOL04 ─┴─ 1 ─ OPC_MXU_S32LDDR
243a2b0a27dSPhilippe Mathieu-Daudé  *          │
24459db9465SSiarhei Volkau  *          │                               20 (13..10 don't care)
245a2b0a27dSPhilippe Mathieu-Daudé  *          ├─ 010001 ─ OPC_MXU__POOL05 ─┬─ 0 ─ OPC_MXU_S32STD
246a2b0a27dSPhilippe Mathieu-Daudé  *          │                            └─ 1 ─ OPC_MXU_S32STDR
247a2b0a27dSPhilippe Mathieu-Daudé  *          │
248a2b0a27dSPhilippe Mathieu-Daudé  *          │                               13..10
249a2b0a27dSPhilippe Mathieu-Daudé  *          ├─ 010010 ─ OPC_MXU__POOL06 ─┬─ 0000 ─ OPC_MXU_S32LDDV
250a2b0a27dSPhilippe Mathieu-Daudé  *          │                            └─ 0001 ─ OPC_MXU_S32LDDVR
251a2b0a27dSPhilippe Mathieu-Daudé  *          │
252a2b0a27dSPhilippe Mathieu-Daudé  *          │                               13..10
253a2b0a27dSPhilippe Mathieu-Daudé  *          ├─ 010011 ─ OPC_MXU__POOL07 ─┬─ 0000 ─ OPC_MXU_S32STDV
254a2b0a27dSPhilippe Mathieu-Daudé  *          │                            └─ 0001 ─ OPC_MXU_S32STDVR
255a2b0a27dSPhilippe Mathieu-Daudé  *          │
25659db9465SSiarhei Volkau  *          │                               20 (13..10 don't care)
257a2b0a27dSPhilippe Mathieu-Daudé  *          ├─ 010100 ─ OPC_MXU__POOL08 ─┬─ 0 ─ OPC_MXU_S32LDI
258a2b0a27dSPhilippe Mathieu-Daudé  *          │                            └─ 1 ─ OPC_MXU_S32LDIR
259a2b0a27dSPhilippe Mathieu-Daudé  *          │
26059db9465SSiarhei Volkau  *          │                               20 (13..10 don't care)
261a2b0a27dSPhilippe Mathieu-Daudé  *          ├─ 010101 ─ OPC_MXU__POOL09 ─┬─ 0 ─ OPC_MXU_S32SDI
262a2b0a27dSPhilippe Mathieu-Daudé  *          │                            └─ 1 ─ OPC_MXU_S32SDIR
263a2b0a27dSPhilippe Mathieu-Daudé  *          │
264a2b0a27dSPhilippe Mathieu-Daudé  *          │                               13..10
265a2b0a27dSPhilippe Mathieu-Daudé  *          ├─ 010110 ─ OPC_MXU__POOL10 ─┬─ 0000 ─ OPC_MXU_S32LDIV
266a2b0a27dSPhilippe Mathieu-Daudé  *          │                            └─ 0001 ─ OPC_MXU_S32LDIVR
267a2b0a27dSPhilippe Mathieu-Daudé  *          │
268a2b0a27dSPhilippe Mathieu-Daudé  *          │                               13..10
269a2b0a27dSPhilippe Mathieu-Daudé  *          ├─ 010111 ─ OPC_MXU__POOL11 ─┬─ 0000 ─ OPC_MXU_S32SDIV
270a2b0a27dSPhilippe Mathieu-Daudé  *          │                            └─ 0001 ─ OPC_MXU_S32SDIVR
271513cfdaeSSiarhei Volkau  *          ├─ 011000 ─ OPC_MXU_D32ADD  (catches D32ADDC too)
272a2b0a27dSPhilippe Mathieu-Daudé  *          │                               23..22
273a2b0a27dSPhilippe Mathieu-Daudé  *   MXU    ├─ 011001 ─ OPC_MXU__POOL12 ─┬─ 00 ─ OPC_MXU_D32ACC
274a2b0a27dSPhilippe Mathieu-Daudé  * opcodes ─┤                            ├─ 01 ─ OPC_MXU_D32ACCM
275a2b0a27dSPhilippe Mathieu-Daudé  *          │                            └─ 10 ─ OPC_MXU_D32ASUM
276a2b0a27dSPhilippe Mathieu-Daudé  *          ├─ 011010 ─ <not assigned>
277a2b0a27dSPhilippe Mathieu-Daudé  *          │                               23..22
278a2b0a27dSPhilippe Mathieu-Daudé  *          ├─ 011011 ─ OPC_MXU__POOL13 ─┬─ 00 ─ OPC_MXU_Q16ACC
279a2b0a27dSPhilippe Mathieu-Daudé  *          │                            ├─ 01 ─ OPC_MXU_Q16ACCM
2806191a807SSiarhei Volkau  *          │                            └─ 10 ─ OPC_MXU_D16ASUM
281a2b0a27dSPhilippe Mathieu-Daudé  *          │
282a2b0a27dSPhilippe Mathieu-Daudé  *          │                               23..22
283a2b0a27dSPhilippe Mathieu-Daudé  *          ├─ 011100 ─ OPC_MXU__POOL14 ─┬─ 00 ─ OPC_MXU_Q8ADDE
284a2b0a27dSPhilippe Mathieu-Daudé  *          │                            ├─ 01 ─ OPC_MXU_D8SUM
285a2b0a27dSPhilippe Mathieu-Daudé  *          ├─ 011101 ─ OPC_MXU_Q8ACCE   └─ 10 ─ OPC_MXU_D8SUMC
286a2b0a27dSPhilippe Mathieu-Daudé  *          ├─ 011110 ─ <not assigned>
287a2b0a27dSPhilippe Mathieu-Daudé  *          ├─ 011111 ─ <not assigned>
288a2b0a27dSPhilippe Mathieu-Daudé  *          ├─ 100000 ─ <not assigned>   (overlaps with CLZ)
289a2b0a27dSPhilippe Mathieu-Daudé  *          ├─ 100001 ─ <not assigned>   (overlaps with CLO)
290a2b0a27dSPhilippe Mathieu-Daudé  *          ├─ 100010 ─ OPC_MXU_S8LDD
291a2b0a27dSPhilippe Mathieu-Daudé  *          ├─ 100011 ─ OPC_MXU_S8STD       15..14
292a2b0a27dSPhilippe Mathieu-Daudé  *          ├─ 100100 ─ OPC_MXU_S8LDI    ┌─ 00 ─ OPC_MXU_S32MUL
29329059e72SSiarhei Volkau  *          ├─ 100101 ─ OPC_MXU_S8SDI    ├─ 01 ─ OPC_MXU_S32MULU
29429059e72SSiarhei Volkau  *          │                            ├─ 10 ─ OPC_MXU_S32EXTR
29529059e72SSiarhei Volkau  *          ├─ 100110 ─ OPC_MXU__POOL15 ─┴─ 11 ─ OPC_MXU_S32EXTRV
296a2b0a27dSPhilippe Mathieu-Daudé  *          │
297a2b0a27dSPhilippe Mathieu-Daudé  *          │                               20..18
298a2b0a27dSPhilippe Mathieu-Daudé  *          ├─ 100111 ─ OPC_MXU__POOL16 ─┬─ 000 ─ OPC_MXU_D32SARW
299a2b0a27dSPhilippe Mathieu-Daudé  *          │                            ├─ 001 ─ OPC_MXU_S32ALN
300a2b0a27dSPhilippe Mathieu-Daudé  *          │                            ├─ 010 ─ OPC_MXU_S32ALNI
301a2b0a27dSPhilippe Mathieu-Daudé  *          │                            ├─ 011 ─ OPC_MXU_S32LUI
302a2b0a27dSPhilippe Mathieu-Daudé  *          │                            ├─ 100 ─ OPC_MXU_S32NOR
303a2b0a27dSPhilippe Mathieu-Daudé  *          │                            ├─ 101 ─ OPC_MXU_S32AND
304a2b0a27dSPhilippe Mathieu-Daudé  *          │                            ├─ 110 ─ OPC_MXU_S32OR
305a2b0a27dSPhilippe Mathieu-Daudé  *          │                            └─ 111 ─ OPC_MXU_S32XOR
306a2b0a27dSPhilippe Mathieu-Daudé  *          │
30773c260c1SSiarhei Volkau  *          │                               8..6
308a2b0a27dSPhilippe Mathieu-Daudé  *          ├─ 101000 ─ OPC_MXU__POOL17 ─┬─ 000 ─ OPC_MXU_LXB
309a2b0a27dSPhilippe Mathieu-Daudé  *          │                            ├─ 001 ─ OPC_MXU_LXH
310a2b0a27dSPhilippe Mathieu-Daudé  *          ├─ 101001 ─ <not assigned>   ├─ 011 ─ OPC_MXU_LXW
311a2b0a27dSPhilippe Mathieu-Daudé  *          ├─ 101010 ─ OPC_MXU_S16LDD   ├─ 100 ─ OPC_MXU_LXBU
312a2b0a27dSPhilippe Mathieu-Daudé  *          ├─ 101011 ─ OPC_MXU_S16STD   └─ 101 ─ OPC_MXU_LXHU
313a2b0a27dSPhilippe Mathieu-Daudé  *          ├─ 101100 ─ OPC_MXU_S16LDI
314a2b0a27dSPhilippe Mathieu-Daudé  *          ├─ 101101 ─ OPC_MXU_S16SDI
315a2b0a27dSPhilippe Mathieu-Daudé  *          ├─ 101110 ─ OPC_MXU_S32M2I
316a2b0a27dSPhilippe Mathieu-Daudé  *          ├─ 101111 ─ OPC_MXU_S32I2M
317a2b0a27dSPhilippe Mathieu-Daudé  *          ├─ 110000 ─ OPC_MXU_D32SLL
318a2b0a27dSPhilippe Mathieu-Daudé  *          ├─ 110001 ─ OPC_MXU_D32SLR      20..18
319a2b0a27dSPhilippe Mathieu-Daudé  *          ├─ 110010 ─ OPC_MXU_D32SARL  ┌─ 000 ─ OPC_MXU_D32SLLV
320a2b0a27dSPhilippe Mathieu-Daudé  *          ├─ 110011 ─ OPC_MXU_D32SAR   ├─ 001 ─ OPC_MXU_D32SLRV
32107c92895SSiarhei Volkau  *          ├─ 110100 ─ OPC_MXU_Q16SLL   ├─ 011 ─ OPC_MXU_D32SARV
32207c92895SSiarhei Volkau  *          ├─ 110101 ─ OPC_MXU_Q16SLR   ├─ 100 ─ OPC_MXU_Q16SLLV
32307c92895SSiarhei Volkau  *          │                            ├─ 101 ─ OPC_MXU_Q16SLRV
32407c92895SSiarhei Volkau  *          ├─ 110110 ─ OPC_MXU__POOL18 ─┴─ 111 ─ OPC_MXU_Q16SARV
325a2b0a27dSPhilippe Mathieu-Daudé  *          │
326a2b0a27dSPhilippe Mathieu-Daudé  *          ├─ 110111 ─ OPC_MXU_Q16SAR
327a2b0a27dSPhilippe Mathieu-Daudé  *          │                               23..22
328a2b0a27dSPhilippe Mathieu-Daudé  *          ├─ 111000 ─ OPC_MXU__POOL19 ─┬─ 00 ─ OPC_MXU_Q8MUL
3297bb1206aSSiarhei Volkau  *          │                            └─ 10 ─ OPC_MXU_Q8MULSU
330a2b0a27dSPhilippe Mathieu-Daudé  *          │
331a2b0a27dSPhilippe Mathieu-Daudé  *          │                               20..18
332a2b0a27dSPhilippe Mathieu-Daudé  *          ├─ 111001 ─ OPC_MXU__POOL20 ─┬─ 000 ─ OPC_MXU_Q8MOVZ
333a2b0a27dSPhilippe Mathieu-Daudé  *          │                            ├─ 001 ─ OPC_MXU_Q8MOVN
334a2b0a27dSPhilippe Mathieu-Daudé  *          │                            ├─ 010 ─ OPC_MXU_D16MOVZ
335a2b0a27dSPhilippe Mathieu-Daudé  *          │                            ├─ 011 ─ OPC_MXU_D16MOVN
336a2b0a27dSPhilippe Mathieu-Daudé  *          │                            ├─ 100 ─ OPC_MXU_S32MOVZ
337a2b0a27dSPhilippe Mathieu-Daudé  *          │                            └─ 101 ─ OPC_MXU_S32MOVN
338a2b0a27dSPhilippe Mathieu-Daudé  *          │
339a2b0a27dSPhilippe Mathieu-Daudé  *          │                               23..22
340a2b0a27dSPhilippe Mathieu-Daudé  *          ├─ 111010 ─ OPC_MXU__POOL21 ─┬─ 00 ─ OPC_MXU_Q8MAC
341a2b0a27dSPhilippe Mathieu-Daudé  *          │                            └─ 10 ─ OPC_MXU_Q8MACSU
342a2b0a27dSPhilippe Mathieu-Daudé  *          ├─ 111011 ─ OPC_MXU_Q16SCOP
343a2b0a27dSPhilippe Mathieu-Daudé  *          ├─ 111100 ─ OPC_MXU_Q8MADL
344a2b0a27dSPhilippe Mathieu-Daudé  *          ├─ 111101 ─ OPC_MXU_S32SFL
345a2b0a27dSPhilippe Mathieu-Daudé  *          ├─ 111110 ─ OPC_MXU_Q8SAD
346a2b0a27dSPhilippe Mathieu-Daudé  *          └─ 111111 ─ <not assigned>   (overlaps with SDBBP)
347a2b0a27dSPhilippe Mathieu-Daudé  *
348a2b0a27dSPhilippe Mathieu-Daudé  *
349a2b0a27dSPhilippe Mathieu-Daudé  * Compiled after:
350a2b0a27dSPhilippe Mathieu-Daudé  *
351a2b0a27dSPhilippe Mathieu-Daudé  *   "XBurst® Instruction Set Architecture MIPS eXtension/enhanced Unit
352a2b0a27dSPhilippe Mathieu-Daudé  *   Programming Manual", Ingenic Semiconductor Co, Ltd., revision June 2, 2017
353a2b0a27dSPhilippe Mathieu-Daudé  */
354a2b0a27dSPhilippe Mathieu-Daudé 
355a2b0a27dSPhilippe Mathieu-Daudé enum {
356199fc7d2SSiarhei Volkau     OPC_MXU_S32MADD  = 0x00,
357199fc7d2SSiarhei Volkau     OPC_MXU_S32MADDU = 0x01,
358a2b0a27dSPhilippe Mathieu-Daudé     OPC_MXU__POOL00  = 0x03,
359199fc7d2SSiarhei Volkau     OPC_MXU_S32MSUB  = 0x04,
360199fc7d2SSiarhei Volkau     OPC_MXU_S32MSUBU = 0x05,
361ff7936f0SSiarhei Volkau     OPC_MXU__POOL01  = 0x06,
362f1e6547cSSiarhei Volkau     OPC_MXU__POOL02  = 0x07,
363a2b0a27dSPhilippe Mathieu-Daudé     OPC_MXU_D16MUL   = 0x08,
36427dc0e28SSiarhei Volkau     OPC_MXU__POOL03  = 0x09,
365a2b0a27dSPhilippe Mathieu-Daudé     OPC_MXU_D16MAC   = 0x0A,
3662ebc66e4SSiarhei Volkau     OPC_MXU_D16MACF  = 0x0B,
36715830fa2SSiarhei Volkau     OPC_MXU_D16MADL  = 0x0C,
368e722e680SSiarhei Volkau     OPC_MXU_S16MAD   = 0x0D,
369a9bfd80bSSiarhei Volkau     OPC_MXU_Q16ADD   = 0x0E,
3702ebc66e4SSiarhei Volkau     OPC_MXU_D16MACE  = 0x0F,
371a2b0a27dSPhilippe Mathieu-Daudé     OPC_MXU__POOL04  = 0x10,
37259db9465SSiarhei Volkau     OPC_MXU__POOL05  = 0x11,
37359db9465SSiarhei Volkau     OPC_MXU__POOL06  = 0x12,
37459db9465SSiarhei Volkau     OPC_MXU__POOL07  = 0x13,
37559db9465SSiarhei Volkau     OPC_MXU__POOL08  = 0x14,
37659db9465SSiarhei Volkau     OPC_MXU__POOL09  = 0x15,
37759db9465SSiarhei Volkau     OPC_MXU__POOL10  = 0x16,
37859db9465SSiarhei Volkau     OPC_MXU__POOL11  = 0x17,
3799e51e0cdSSiarhei Volkau     OPC_MXU_D32ADD   = 0x18,
38098db7a58SSiarhei Volkau     OPC_MXU__POOL12  = 0x19,
3816191a807SSiarhei Volkau     OPC_MXU__POOL13  = 0x1B,
382eb79951aSSiarhei Volkau     OPC_MXU__POOL14  = 0x1C,
383eb79951aSSiarhei Volkau     OPC_MXU_Q8ACCE   = 0x1D,
384a2b0a27dSPhilippe Mathieu-Daudé     OPC_MXU_S8LDD    = 0x22,
3853f0e94c1SSiarhei Volkau     OPC_MXU_S8STD    = 0x23,
3863f0e94c1SSiarhei Volkau     OPC_MXU_S8LDI    = 0x24,
3873f0e94c1SSiarhei Volkau     OPC_MXU_S8SDI    = 0x25,
38829059e72SSiarhei Volkau     OPC_MXU__POOL15  = 0x26,
389a2b0a27dSPhilippe Mathieu-Daudé     OPC_MXU__POOL16  = 0x27,
39073c260c1SSiarhei Volkau     OPC_MXU__POOL17  = 0x28,
391968045b6SSiarhei Volkau     OPC_MXU_S16LDD   = 0x2A,
392968045b6SSiarhei Volkau     OPC_MXU_S16STD   = 0x2B,
393968045b6SSiarhei Volkau     OPC_MXU_S16LDI   = 0x2C,
394968045b6SSiarhei Volkau     OPC_MXU_S16SDI   = 0x2D,
395a2b0a27dSPhilippe Mathieu-Daudé     OPC_MXU_S32M2I   = 0x2E,
396a2b0a27dSPhilippe Mathieu-Daudé     OPC_MXU_S32I2M   = 0x2F,
397f1fb1038SSiarhei Volkau     OPC_MXU_D32SLL   = 0x30,
398f1fb1038SSiarhei Volkau     OPC_MXU_D32SLR   = 0x31,
399f900da76SSiarhei Volkau     OPC_MXU_D32SARL  = 0x32,
400f1fb1038SSiarhei Volkau     OPC_MXU_D32SAR   = 0x33,
40152fe25d4SSiarhei Volkau     OPC_MXU_Q16SLL   = 0x34,
40252fe25d4SSiarhei Volkau     OPC_MXU_Q16SLR   = 0x35,
40307c92895SSiarhei Volkau     OPC_MXU__POOL18  = 0x36,
40452fe25d4SSiarhei Volkau     OPC_MXU_Q16SAR   = 0x37,
405a2b0a27dSPhilippe Mathieu-Daudé     OPC_MXU__POOL19  = 0x38,
406d1b6ded4SSiarhei Volkau     OPC_MXU__POOL20  = 0x39,
4077bb1206aSSiarhei Volkau     OPC_MXU__POOL21  = 0x3A,
40868a48804SSiarhei Volkau     OPC_MXU_Q16SCOP  = 0x3B,
409b72e2b3aSSiarhei Volkau     OPC_MXU_Q8MADL   = 0x3C,
4104b9680d3SSiarhei Volkau     OPC_MXU_S32SFL   = 0x3D,
4118aedfb64SSiarhei Volkau     OPC_MXU_Q8SAD    = 0x3E,
412a2b0a27dSPhilippe Mathieu-Daudé };
413a2b0a27dSPhilippe Mathieu-Daudé 
414a2b0a27dSPhilippe Mathieu-Daudé 
415a2b0a27dSPhilippe Mathieu-Daudé /*
416a2b0a27dSPhilippe Mathieu-Daudé  * MXU pool 00
417a2b0a27dSPhilippe Mathieu-Daudé  */
418a2b0a27dSPhilippe Mathieu-Daudé enum {
419a2b0a27dSPhilippe Mathieu-Daudé     OPC_MXU_S32MAX   = 0x00,
420a2b0a27dSPhilippe Mathieu-Daudé     OPC_MXU_S32MIN   = 0x01,
421a2b0a27dSPhilippe Mathieu-Daudé     OPC_MXU_D16MAX   = 0x02,
422a2b0a27dSPhilippe Mathieu-Daudé     OPC_MXU_D16MIN   = 0x03,
423a2b0a27dSPhilippe Mathieu-Daudé     OPC_MXU_Q8MAX    = 0x04,
424a2b0a27dSPhilippe Mathieu-Daudé     OPC_MXU_Q8MIN    = 0x05,
4254051f035SSiarhei Volkau     OPC_MXU_Q8SLT    = 0x06,
4264051f035SSiarhei Volkau     OPC_MXU_Q8SLTU   = 0x07,
427a2b0a27dSPhilippe Mathieu-Daudé };
428a2b0a27dSPhilippe Mathieu-Daudé 
429a2b0a27dSPhilippe Mathieu-Daudé /*
430ff7936f0SSiarhei Volkau  * MXU pool 01
431ff7936f0SSiarhei Volkau  */
432ff7936f0SSiarhei Volkau enum {
433ff7936f0SSiarhei Volkau     OPC_MXU_S32SLT   = 0x00,
434ff7936f0SSiarhei Volkau     OPC_MXU_D16SLT   = 0x01,
435ff7936f0SSiarhei Volkau     OPC_MXU_D16AVG   = 0x02,
436ff7936f0SSiarhei Volkau     OPC_MXU_D16AVGR  = 0x03,
437ff7936f0SSiarhei Volkau     OPC_MXU_Q8AVG    = 0x04,
438ff7936f0SSiarhei Volkau     OPC_MXU_Q8AVGR   = 0x05,
439bf1df65fSSiarhei Volkau     OPC_MXU_Q8ADD    = 0x07,
440ff7936f0SSiarhei Volkau };
441ff7936f0SSiarhei Volkau 
442ff7936f0SSiarhei Volkau /*
443f1e6547cSSiarhei Volkau  * MXU pool 02
444f1e6547cSSiarhei Volkau  */
445f1e6547cSSiarhei Volkau enum {
446f1e6547cSSiarhei Volkau     OPC_MXU_S32CPS   = 0x00,
447f1e6547cSSiarhei Volkau     OPC_MXU_D16CPS   = 0x02,
448f1e6547cSSiarhei Volkau     OPC_MXU_Q8ABD    = 0x04,
449f1e6547cSSiarhei Volkau     OPC_MXU_Q16SAT   = 0x06,
450f1e6547cSSiarhei Volkau };
451f1e6547cSSiarhei Volkau 
452f1e6547cSSiarhei Volkau /*
45327dc0e28SSiarhei Volkau  * MXU pool 03
45427dc0e28SSiarhei Volkau  */
45527dc0e28SSiarhei Volkau enum {
45627dc0e28SSiarhei Volkau     OPC_MXU_D16MULF  = 0x00,
45727dc0e28SSiarhei Volkau     OPC_MXU_D16MULE  = 0x01,
45827dc0e28SSiarhei Volkau };
45927dc0e28SSiarhei Volkau 
46027dc0e28SSiarhei Volkau /*
46159db9465SSiarhei Volkau  * MXU pool 04 05 06 07 08 09 10 11
462a2b0a27dSPhilippe Mathieu-Daudé  */
463a2b0a27dSPhilippe Mathieu-Daudé enum {
46459db9465SSiarhei Volkau     OPC_MXU_S32LDST  = 0x00,
46559db9465SSiarhei Volkau     OPC_MXU_S32LDSTR = 0x01,
466a2b0a27dSPhilippe Mathieu-Daudé };
467a2b0a27dSPhilippe Mathieu-Daudé 
468a2b0a27dSPhilippe Mathieu-Daudé /*
46998db7a58SSiarhei Volkau  * MXU pool 12
47098db7a58SSiarhei Volkau  */
47198db7a58SSiarhei Volkau enum {
47298db7a58SSiarhei Volkau     OPC_MXU_D32ACC    = 0x00,
47398db7a58SSiarhei Volkau     OPC_MXU_D32ACCM   = 0x01,
47498db7a58SSiarhei Volkau     OPC_MXU_D32ASUM   = 0x02,
47598db7a58SSiarhei Volkau };
47698db7a58SSiarhei Volkau 
47798db7a58SSiarhei Volkau /*
4786191a807SSiarhei Volkau  * MXU pool 13
4796191a807SSiarhei Volkau  */
4806191a807SSiarhei Volkau enum {
4816191a807SSiarhei Volkau     OPC_MXU_Q16ACC    = 0x00,
4826191a807SSiarhei Volkau     OPC_MXU_Q16ACCM   = 0x01,
4836191a807SSiarhei Volkau     OPC_MXU_D16ASUM   = 0x02,
4846191a807SSiarhei Volkau };
4856191a807SSiarhei Volkau 
4866191a807SSiarhei Volkau /*
487eb79951aSSiarhei Volkau  * MXU pool 14
488eb79951aSSiarhei Volkau  */
489eb79951aSSiarhei Volkau enum {
490eb79951aSSiarhei Volkau     OPC_MXU_Q8ADDE    = 0x00,
491eb79951aSSiarhei Volkau     OPC_MXU_D8SUM     = 0x01,
492eb79951aSSiarhei Volkau     OPC_MXU_D8SUMC    = 0x02,
493eb79951aSSiarhei Volkau };
494eb79951aSSiarhei Volkau 
495eb79951aSSiarhei Volkau /*
49629059e72SSiarhei Volkau  * MXU pool 15
49729059e72SSiarhei Volkau  */
49829059e72SSiarhei Volkau enum {
49929059e72SSiarhei Volkau     OPC_MXU_S32MUL    = 0x00,
50029059e72SSiarhei Volkau     OPC_MXU_S32MULU   = 0x01,
50129059e72SSiarhei Volkau     OPC_MXU_S32EXTR   = 0x02,
50229059e72SSiarhei Volkau     OPC_MXU_S32EXTRV  = 0x03,
50329059e72SSiarhei Volkau };
50429059e72SSiarhei Volkau 
50529059e72SSiarhei Volkau /*
506a2b0a27dSPhilippe Mathieu-Daudé  * MXU pool 16
507a2b0a27dSPhilippe Mathieu-Daudé  */
508a2b0a27dSPhilippe Mathieu-Daudé enum {
509f900da76SSiarhei Volkau     OPC_MXU_D32SARW  = 0x00,
51059259634SSiarhei Volkau     OPC_MXU_S32ALN   = 0x01,
511a2b0a27dSPhilippe Mathieu-Daudé     OPC_MXU_S32ALNI  = 0x02,
51259259634SSiarhei Volkau     OPC_MXU_S32LUI   = 0x03,
513a2b0a27dSPhilippe Mathieu-Daudé     OPC_MXU_S32NOR   = 0x04,
514a2b0a27dSPhilippe Mathieu-Daudé     OPC_MXU_S32AND   = 0x05,
515a2b0a27dSPhilippe Mathieu-Daudé     OPC_MXU_S32OR    = 0x06,
516a2b0a27dSPhilippe Mathieu-Daudé     OPC_MXU_S32XOR   = 0x07,
517a2b0a27dSPhilippe Mathieu-Daudé };
518a2b0a27dSPhilippe Mathieu-Daudé 
519a2b0a27dSPhilippe Mathieu-Daudé /*
52073c260c1SSiarhei Volkau  * MXU pool 17
52173c260c1SSiarhei Volkau  */
52273c260c1SSiarhei Volkau enum {
52373c260c1SSiarhei Volkau     OPC_MXU_LXB      = 0x00,
52473c260c1SSiarhei Volkau     OPC_MXU_LXH      = 0x01,
52573c260c1SSiarhei Volkau     OPC_MXU_LXW      = 0x03,
52673c260c1SSiarhei Volkau     OPC_MXU_LXBU     = 0x04,
52773c260c1SSiarhei Volkau     OPC_MXU_LXHU     = 0x05,
52873c260c1SSiarhei Volkau };
52973c260c1SSiarhei Volkau 
53073c260c1SSiarhei Volkau /*
53107c92895SSiarhei Volkau  * MXU pool 18
53207c92895SSiarhei Volkau  */
53307c92895SSiarhei Volkau enum {
53407c92895SSiarhei Volkau     OPC_MXU_D32SLLV  = 0x00,
53507c92895SSiarhei Volkau     OPC_MXU_D32SLRV  = 0x01,
53607c92895SSiarhei Volkau     OPC_MXU_D32SARV  = 0x03,
53707c92895SSiarhei Volkau     OPC_MXU_Q16SLLV  = 0x04,
53807c92895SSiarhei Volkau     OPC_MXU_Q16SLRV  = 0x05,
53907c92895SSiarhei Volkau     OPC_MXU_Q16SARV  = 0x07,
54007c92895SSiarhei Volkau };
54107c92895SSiarhei Volkau 
54207c92895SSiarhei Volkau /*
543a2b0a27dSPhilippe Mathieu-Daudé  * MXU pool 19
544a2b0a27dSPhilippe Mathieu-Daudé  */
545a2b0a27dSPhilippe Mathieu-Daudé enum {
546a2b0a27dSPhilippe Mathieu-Daudé     OPC_MXU_Q8MUL    = 0x00,
5477bb1206aSSiarhei Volkau     OPC_MXU_Q8MULSU  = 0x02,
548a2b0a27dSPhilippe Mathieu-Daudé };
549a2b0a27dSPhilippe Mathieu-Daudé 
550d1b6ded4SSiarhei Volkau /*
551d1b6ded4SSiarhei Volkau  * MXU pool 20
552d1b6ded4SSiarhei Volkau  */
553d1b6ded4SSiarhei Volkau enum {
554d1b6ded4SSiarhei Volkau     OPC_MXU_Q8MOVZ   = 0x00,
555d1b6ded4SSiarhei Volkau     OPC_MXU_Q8MOVN   = 0x01,
556d1b6ded4SSiarhei Volkau     OPC_MXU_D16MOVZ  = 0x02,
557d1b6ded4SSiarhei Volkau     OPC_MXU_D16MOVN  = 0x03,
558d1b6ded4SSiarhei Volkau     OPC_MXU_S32MOVZ  = 0x04,
559d1b6ded4SSiarhei Volkau     OPC_MXU_S32MOVN  = 0x05,
560d1b6ded4SSiarhei Volkau };
561d1b6ded4SSiarhei Volkau 
5627bb1206aSSiarhei Volkau /*
5637bb1206aSSiarhei Volkau  * MXU pool 21
5647bb1206aSSiarhei Volkau  */
5657bb1206aSSiarhei Volkau enum {
5667bb1206aSSiarhei Volkau     OPC_MXU_Q8MAC    = 0x00,
5677bb1206aSSiarhei Volkau     OPC_MXU_Q8MACSU  = 0x02,
5687bb1206aSSiarhei Volkau };
5697bb1206aSSiarhei Volkau 
5707bb1206aSSiarhei Volkau 
571a2b0a27dSPhilippe Mathieu-Daudé /* MXU accumulate add/subtract 1-bit pattern 'aptn1' */
572a2b0a27dSPhilippe Mathieu-Daudé #define MXU_APTN1_A    0
573a2b0a27dSPhilippe Mathieu-Daudé #define MXU_APTN1_S    1
574a2b0a27dSPhilippe Mathieu-Daudé 
575a2b0a27dSPhilippe Mathieu-Daudé /* MXU accumulate add/subtract 2-bit pattern 'aptn2' */
576a2b0a27dSPhilippe Mathieu-Daudé #define MXU_APTN2_AA    0
577a2b0a27dSPhilippe Mathieu-Daudé #define MXU_APTN2_AS    1
578a2b0a27dSPhilippe Mathieu-Daudé #define MXU_APTN2_SA    2
579a2b0a27dSPhilippe Mathieu-Daudé #define MXU_APTN2_SS    3
580a2b0a27dSPhilippe Mathieu-Daudé 
581a2b0a27dSPhilippe Mathieu-Daudé /* MXU execute add/subtract 2-bit pattern 'eptn2' */
582a2b0a27dSPhilippe Mathieu-Daudé #define MXU_EPTN2_AA    0
583a2b0a27dSPhilippe Mathieu-Daudé #define MXU_EPTN2_AS    1
584a2b0a27dSPhilippe Mathieu-Daudé #define MXU_EPTN2_SA    2
585a2b0a27dSPhilippe Mathieu-Daudé #define MXU_EPTN2_SS    3
586a2b0a27dSPhilippe Mathieu-Daudé 
587a2b0a27dSPhilippe Mathieu-Daudé /* MXU operand getting pattern 'optn2' */
588a2b0a27dSPhilippe Mathieu-Daudé #define MXU_OPTN2_PTN0  0
589a2b0a27dSPhilippe Mathieu-Daudé #define MXU_OPTN2_PTN1  1
590a2b0a27dSPhilippe Mathieu-Daudé #define MXU_OPTN2_PTN2  2
591a2b0a27dSPhilippe Mathieu-Daudé #define MXU_OPTN2_PTN3  3
592a2b0a27dSPhilippe Mathieu-Daudé /* alternative naming scheme for 'optn2' */
593a2b0a27dSPhilippe Mathieu-Daudé #define MXU_OPTN2_WW    0
594a2b0a27dSPhilippe Mathieu-Daudé #define MXU_OPTN2_LW    1
595a2b0a27dSPhilippe Mathieu-Daudé #define MXU_OPTN2_HW    2
596a2b0a27dSPhilippe Mathieu-Daudé #define MXU_OPTN2_XW    3
597a2b0a27dSPhilippe Mathieu-Daudé 
598a2b0a27dSPhilippe Mathieu-Daudé /* MXU operand getting pattern 'optn3' */
599a2b0a27dSPhilippe Mathieu-Daudé #define MXU_OPTN3_PTN0  0
600a2b0a27dSPhilippe Mathieu-Daudé #define MXU_OPTN3_PTN1  1
601a2b0a27dSPhilippe Mathieu-Daudé #define MXU_OPTN3_PTN2  2
602a2b0a27dSPhilippe Mathieu-Daudé #define MXU_OPTN3_PTN3  3
603a2b0a27dSPhilippe Mathieu-Daudé #define MXU_OPTN3_PTN4  4
604a2b0a27dSPhilippe Mathieu-Daudé #define MXU_OPTN3_PTN5  5
605a2b0a27dSPhilippe Mathieu-Daudé #define MXU_OPTN3_PTN6  6
606a2b0a27dSPhilippe Mathieu-Daudé #define MXU_OPTN3_PTN7  7
607a2b0a27dSPhilippe Mathieu-Daudé 
608a2b0a27dSPhilippe Mathieu-Daudé /* MXU registers */
609a2b0a27dSPhilippe Mathieu-Daudé static TCGv mxu_gpr[NUMBER_OF_MXU_REGISTERS - 1];
610a2b0a27dSPhilippe Mathieu-Daudé static TCGv mxu_CR;
611a2b0a27dSPhilippe Mathieu-Daudé 
612d4eda549SPhilippe Mathieu-Daudé static const char mxuregnames[NUMBER_OF_MXU_REGISTERS][4] = {
613a2b0a27dSPhilippe Mathieu-Daudé     "XR1",  "XR2",  "XR3",  "XR4",  "XR5",  "XR6",  "XR7",  "XR8",
61406106772SPhilippe Mathieu-Daudé     "XR9",  "XR10", "XR11", "XR12", "XR13", "XR14", "XR15", "XCR",
615a2b0a27dSPhilippe Mathieu-Daudé };
616a2b0a27dSPhilippe Mathieu-Daudé 
mxu_translate_init(void)617a2b0a27dSPhilippe Mathieu-Daudé void mxu_translate_init(void)
618a2b0a27dSPhilippe Mathieu-Daudé {
619a2b0a27dSPhilippe Mathieu-Daudé     for (unsigned i = 0; i < NUMBER_OF_MXU_REGISTERS - 1; i++) {
620*ad75a51eSRichard Henderson         mxu_gpr[i] = tcg_global_mem_new(tcg_env,
621a2b0a27dSPhilippe Mathieu-Daudé                                         offsetof(CPUMIPSState, active_tc.mxu_gpr[i]),
622a2b0a27dSPhilippe Mathieu-Daudé                                         mxuregnames[i]);
623a2b0a27dSPhilippe Mathieu-Daudé     }
624a2b0a27dSPhilippe Mathieu-Daudé 
625*ad75a51eSRichard Henderson     mxu_CR = tcg_global_mem_new(tcg_env,
626a2b0a27dSPhilippe Mathieu-Daudé                                 offsetof(CPUMIPSState, active_tc.mxu_cr),
627a2b0a27dSPhilippe Mathieu-Daudé                                 mxuregnames[NUMBER_OF_MXU_REGISTERS - 1]);
628a2b0a27dSPhilippe Mathieu-Daudé }
629a2b0a27dSPhilippe Mathieu-Daudé 
630a2b0a27dSPhilippe Mathieu-Daudé /* MXU General purpose registers moves. */
gen_load_mxu_gpr(TCGv t,unsigned int reg)631a2b0a27dSPhilippe Mathieu-Daudé static inline void gen_load_mxu_gpr(TCGv t, unsigned int reg)
632a2b0a27dSPhilippe Mathieu-Daudé {
633a2b0a27dSPhilippe Mathieu-Daudé     if (reg == 0) {
634a2b0a27dSPhilippe Mathieu-Daudé         tcg_gen_movi_tl(t, 0);
635a2b0a27dSPhilippe Mathieu-Daudé     } else if (reg <= 15) {
636a2b0a27dSPhilippe Mathieu-Daudé         tcg_gen_mov_tl(t, mxu_gpr[reg - 1]);
637a2b0a27dSPhilippe Mathieu-Daudé     }
638a2b0a27dSPhilippe Mathieu-Daudé }
639a2b0a27dSPhilippe Mathieu-Daudé 
gen_store_mxu_gpr(TCGv t,unsigned int reg)640a2b0a27dSPhilippe Mathieu-Daudé static inline void gen_store_mxu_gpr(TCGv t, unsigned int reg)
641a2b0a27dSPhilippe Mathieu-Daudé {
642a2b0a27dSPhilippe Mathieu-Daudé     if (reg > 0 && reg <= 15) {
643a2b0a27dSPhilippe Mathieu-Daudé         tcg_gen_mov_tl(mxu_gpr[reg - 1], t);
644a2b0a27dSPhilippe Mathieu-Daudé     }
645a2b0a27dSPhilippe Mathieu-Daudé }
646a2b0a27dSPhilippe Mathieu-Daudé 
gen_extract_mxu_gpr(TCGv t,unsigned int reg,unsigned int ofs,unsigned int len)647fb51df0cSPhilippe Mathieu-Daudé static inline void gen_extract_mxu_gpr(TCGv t, unsigned int reg,
648fb51df0cSPhilippe Mathieu-Daudé                                        unsigned int ofs, unsigned int len)
649fb51df0cSPhilippe Mathieu-Daudé {
650fb51df0cSPhilippe Mathieu-Daudé     if (reg == 0) {
651fb51df0cSPhilippe Mathieu-Daudé         tcg_gen_movi_tl(t, 0);
652fb51df0cSPhilippe Mathieu-Daudé     } else if (reg <= 15) {
653fb51df0cSPhilippe Mathieu-Daudé         tcg_gen_extract_tl(t, mxu_gpr[reg - 1], ofs, len);
654fb51df0cSPhilippe Mathieu-Daudé     }
655fb51df0cSPhilippe Mathieu-Daudé }
656fb51df0cSPhilippe Mathieu-Daudé 
657a2b0a27dSPhilippe Mathieu-Daudé /* MXU control register moves. */
gen_load_mxu_cr(TCGv t)658a2b0a27dSPhilippe Mathieu-Daudé static inline void gen_load_mxu_cr(TCGv t)
659a2b0a27dSPhilippe Mathieu-Daudé {
660a2b0a27dSPhilippe Mathieu-Daudé     tcg_gen_mov_tl(t, mxu_CR);
661a2b0a27dSPhilippe Mathieu-Daudé }
662a2b0a27dSPhilippe Mathieu-Daudé 
gen_store_mxu_cr(TCGv t)663a2b0a27dSPhilippe Mathieu-Daudé static inline void gen_store_mxu_cr(TCGv t)
664a2b0a27dSPhilippe Mathieu-Daudé {
665a2b0a27dSPhilippe Mathieu-Daudé     /* TODO: Add handling of RW rules for MXU_CR. */
666a2b0a27dSPhilippe Mathieu-Daudé     tcg_gen_mov_tl(mxu_CR, t);
667a2b0a27dSPhilippe Mathieu-Daudé }
668a2b0a27dSPhilippe Mathieu-Daudé 
669a2b0a27dSPhilippe Mathieu-Daudé /*
670a2b0a27dSPhilippe Mathieu-Daudé  * S32I2M XRa, rb - Register move from GRF to XRF
671a2b0a27dSPhilippe Mathieu-Daudé  */
gen_mxu_s32i2m(DisasContext * ctx)672a2b0a27dSPhilippe Mathieu-Daudé static void gen_mxu_s32i2m(DisasContext *ctx)
673a2b0a27dSPhilippe Mathieu-Daudé {
674a2b0a27dSPhilippe Mathieu-Daudé     TCGv t0;
675a2b0a27dSPhilippe Mathieu-Daudé     uint32_t XRa, Rb;
676a2b0a27dSPhilippe Mathieu-Daudé 
677a2b0a27dSPhilippe Mathieu-Daudé     t0 = tcg_temp_new();
678a2b0a27dSPhilippe Mathieu-Daudé 
679a2b0a27dSPhilippe Mathieu-Daudé     XRa = extract32(ctx->opcode, 6, 5);
680a2b0a27dSPhilippe Mathieu-Daudé     Rb = extract32(ctx->opcode, 16, 5);
681a2b0a27dSPhilippe Mathieu-Daudé 
682a2b0a27dSPhilippe Mathieu-Daudé     gen_load_gpr(t0, Rb);
683a2b0a27dSPhilippe Mathieu-Daudé     if (XRa <= 15) {
684a2b0a27dSPhilippe Mathieu-Daudé         gen_store_mxu_gpr(t0, XRa);
685a2b0a27dSPhilippe Mathieu-Daudé     } else if (XRa == 16) {
686a2b0a27dSPhilippe Mathieu-Daudé         gen_store_mxu_cr(t0);
687a2b0a27dSPhilippe Mathieu-Daudé     }
688a2b0a27dSPhilippe Mathieu-Daudé }
689a2b0a27dSPhilippe Mathieu-Daudé 
690a2b0a27dSPhilippe Mathieu-Daudé /*
691a2b0a27dSPhilippe Mathieu-Daudé  * S32M2I XRa, rb - Register move from XRF to GRF
692a2b0a27dSPhilippe Mathieu-Daudé  */
gen_mxu_s32m2i(DisasContext * ctx)693a2b0a27dSPhilippe Mathieu-Daudé static void gen_mxu_s32m2i(DisasContext *ctx)
694a2b0a27dSPhilippe Mathieu-Daudé {
695a2b0a27dSPhilippe Mathieu-Daudé     TCGv t0;
696a2b0a27dSPhilippe Mathieu-Daudé     uint32_t XRa, Rb;
697a2b0a27dSPhilippe Mathieu-Daudé 
698a2b0a27dSPhilippe Mathieu-Daudé     t0 = tcg_temp_new();
699a2b0a27dSPhilippe Mathieu-Daudé 
700a2b0a27dSPhilippe Mathieu-Daudé     XRa = extract32(ctx->opcode, 6, 5);
701a2b0a27dSPhilippe Mathieu-Daudé     Rb = extract32(ctx->opcode, 16, 5);
702a2b0a27dSPhilippe Mathieu-Daudé 
703a2b0a27dSPhilippe Mathieu-Daudé     if (XRa <= 15) {
704a2b0a27dSPhilippe Mathieu-Daudé         gen_load_mxu_gpr(t0, XRa);
705a2b0a27dSPhilippe Mathieu-Daudé     } else if (XRa == 16) {
706a2b0a27dSPhilippe Mathieu-Daudé         gen_load_mxu_cr(t0);
707a2b0a27dSPhilippe Mathieu-Daudé     }
708a2b0a27dSPhilippe Mathieu-Daudé 
709a2b0a27dSPhilippe Mathieu-Daudé     gen_store_gpr(t0, Rb);
710a2b0a27dSPhilippe Mathieu-Daudé }
711a2b0a27dSPhilippe Mathieu-Daudé 
712a2b0a27dSPhilippe Mathieu-Daudé /*
713a2b0a27dSPhilippe Mathieu-Daudé  * S8LDD XRa, Rb, s8, optn3 - Load a byte from memory to XRF
7143f0e94c1SSiarhei Volkau  *
7153f0e94c1SSiarhei Volkau  * S8LDI XRa, Rb, s8, optn3 - Load a byte from memory to XRF,
7163f0e94c1SSiarhei Volkau  * post modify address register
717a2b0a27dSPhilippe Mathieu-Daudé  */
gen_mxu_s8ldd(DisasContext * ctx,bool postmodify)7183f0e94c1SSiarhei Volkau static void gen_mxu_s8ldd(DisasContext *ctx, bool postmodify)
719a2b0a27dSPhilippe Mathieu-Daudé {
720a2b0a27dSPhilippe Mathieu-Daudé     TCGv t0, t1;
721a2b0a27dSPhilippe Mathieu-Daudé     uint32_t XRa, Rb, s8, optn3;
722a2b0a27dSPhilippe Mathieu-Daudé 
723a2b0a27dSPhilippe Mathieu-Daudé     t0 = tcg_temp_new();
724a2b0a27dSPhilippe Mathieu-Daudé     t1 = tcg_temp_new();
725a2b0a27dSPhilippe Mathieu-Daudé 
726a2b0a27dSPhilippe Mathieu-Daudé     XRa = extract32(ctx->opcode, 6, 4);
727a2b0a27dSPhilippe Mathieu-Daudé     s8 = extract32(ctx->opcode, 10, 8);
728a2b0a27dSPhilippe Mathieu-Daudé     optn3 = extract32(ctx->opcode, 18, 3);
729a2b0a27dSPhilippe Mathieu-Daudé     Rb = extract32(ctx->opcode, 21, 5);
730a2b0a27dSPhilippe Mathieu-Daudé 
731a2b0a27dSPhilippe Mathieu-Daudé     gen_load_gpr(t0, Rb);
732a2b0a27dSPhilippe Mathieu-Daudé     tcg_gen_addi_tl(t0, t0, (int8_t)s8);
7333f0e94c1SSiarhei Volkau     if (postmodify) {
7343f0e94c1SSiarhei Volkau         gen_store_gpr(t0, Rb);
7353f0e94c1SSiarhei Volkau     }
736a2b0a27dSPhilippe Mathieu-Daudé 
737a2b0a27dSPhilippe Mathieu-Daudé     switch (optn3) {
738a2b0a27dSPhilippe Mathieu-Daudé     /* XRa[7:0] = tmp8 */
739a2b0a27dSPhilippe Mathieu-Daudé     case MXU_OPTN3_PTN0:
740a2b0a27dSPhilippe Mathieu-Daudé         tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
741a2b0a27dSPhilippe Mathieu-Daudé         gen_load_mxu_gpr(t0, XRa);
742a2b0a27dSPhilippe Mathieu-Daudé         tcg_gen_deposit_tl(t0, t0, t1, 0, 8);
743a2b0a27dSPhilippe Mathieu-Daudé         break;
744a2b0a27dSPhilippe Mathieu-Daudé     /* XRa[15:8] = tmp8 */
745a2b0a27dSPhilippe Mathieu-Daudé     case MXU_OPTN3_PTN1:
746a2b0a27dSPhilippe Mathieu-Daudé         tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
747a2b0a27dSPhilippe Mathieu-Daudé         gen_load_mxu_gpr(t0, XRa);
748a2b0a27dSPhilippe Mathieu-Daudé         tcg_gen_deposit_tl(t0, t0, t1, 8, 8);
749a2b0a27dSPhilippe Mathieu-Daudé         break;
750a2b0a27dSPhilippe Mathieu-Daudé     /* XRa[23:16] = tmp8 */
751a2b0a27dSPhilippe Mathieu-Daudé     case MXU_OPTN3_PTN2:
752a2b0a27dSPhilippe Mathieu-Daudé         tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
753a2b0a27dSPhilippe Mathieu-Daudé         gen_load_mxu_gpr(t0, XRa);
754a2b0a27dSPhilippe Mathieu-Daudé         tcg_gen_deposit_tl(t0, t0, t1, 16, 8);
755a2b0a27dSPhilippe Mathieu-Daudé         break;
756a2b0a27dSPhilippe Mathieu-Daudé     /* XRa[31:24] = tmp8 */
757a2b0a27dSPhilippe Mathieu-Daudé     case MXU_OPTN3_PTN3:
758a2b0a27dSPhilippe Mathieu-Daudé         tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
759a2b0a27dSPhilippe Mathieu-Daudé         gen_load_mxu_gpr(t0, XRa);
760a2b0a27dSPhilippe Mathieu-Daudé         tcg_gen_deposit_tl(t0, t0, t1, 24, 8);
761a2b0a27dSPhilippe Mathieu-Daudé         break;
762a2b0a27dSPhilippe Mathieu-Daudé     /* XRa = {8'b0, tmp8, 8'b0, tmp8} */
763a2b0a27dSPhilippe Mathieu-Daudé     case MXU_OPTN3_PTN4:
764a2b0a27dSPhilippe Mathieu-Daudé         tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
765a2b0a27dSPhilippe Mathieu-Daudé         tcg_gen_deposit_tl(t0, t1, t1, 16, 16);
766a2b0a27dSPhilippe Mathieu-Daudé         break;
767a2b0a27dSPhilippe Mathieu-Daudé     /* XRa = {tmp8, 8'b0, tmp8, 8'b0} */
768a2b0a27dSPhilippe Mathieu-Daudé     case MXU_OPTN3_PTN5:
769a2b0a27dSPhilippe Mathieu-Daudé         tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
770a2b0a27dSPhilippe Mathieu-Daudé         tcg_gen_shli_tl(t1, t1, 8);
771a2b0a27dSPhilippe Mathieu-Daudé         tcg_gen_deposit_tl(t0, t1, t1, 16, 16);
772a2b0a27dSPhilippe Mathieu-Daudé         break;
773a2b0a27dSPhilippe Mathieu-Daudé     /* XRa = {{8{sign of tmp8}}, tmp8, {8{sign of tmp8}}, tmp8} */
774a2b0a27dSPhilippe Mathieu-Daudé     case MXU_OPTN3_PTN6:
775a2b0a27dSPhilippe Mathieu-Daudé         tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_SB);
776a2b0a27dSPhilippe Mathieu-Daudé         tcg_gen_mov_tl(t0, t1);
777a2b0a27dSPhilippe Mathieu-Daudé         tcg_gen_andi_tl(t0, t0, 0xFF00FFFF);
778a2b0a27dSPhilippe Mathieu-Daudé         tcg_gen_shli_tl(t1, t1, 16);
779a2b0a27dSPhilippe Mathieu-Daudé         tcg_gen_or_tl(t0, t0, t1);
780a2b0a27dSPhilippe Mathieu-Daudé         break;
781a2b0a27dSPhilippe Mathieu-Daudé     /* XRa = {tmp8, tmp8, tmp8, tmp8} */
782a2b0a27dSPhilippe Mathieu-Daudé     case MXU_OPTN3_PTN7:
783a2b0a27dSPhilippe Mathieu-Daudé         tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
784a2b0a27dSPhilippe Mathieu-Daudé         tcg_gen_deposit_tl(t1, t1, t1, 8, 8);
785a2b0a27dSPhilippe Mathieu-Daudé         tcg_gen_deposit_tl(t0, t1, t1, 16, 16);
786a2b0a27dSPhilippe Mathieu-Daudé         break;
787a2b0a27dSPhilippe Mathieu-Daudé     }
788a2b0a27dSPhilippe Mathieu-Daudé 
789a2b0a27dSPhilippe Mathieu-Daudé     gen_store_mxu_gpr(t0, XRa);
790a2b0a27dSPhilippe Mathieu-Daudé }
791a2b0a27dSPhilippe Mathieu-Daudé 
792a2b0a27dSPhilippe Mathieu-Daudé /*
7933f0e94c1SSiarhei Volkau  * S8STD XRa, Rb, s8, optn3 - Store a byte from XRF to memory
7943f0e94c1SSiarhei Volkau  *
7953f0e94c1SSiarhei Volkau  * S8SDI XRa, Rb, s8, optn3 - Store a byte from XRF to memory,
7963f0e94c1SSiarhei Volkau  * post modify address register
7973f0e94c1SSiarhei Volkau  */
gen_mxu_s8std(DisasContext * ctx,bool postmodify)7983f0e94c1SSiarhei Volkau static void gen_mxu_s8std(DisasContext *ctx, bool postmodify)
7993f0e94c1SSiarhei Volkau {
8003f0e94c1SSiarhei Volkau     TCGv t0, t1;
8013f0e94c1SSiarhei Volkau     uint32_t XRa, Rb, s8, optn3;
8023f0e94c1SSiarhei Volkau 
8033f0e94c1SSiarhei Volkau     t0 = tcg_temp_new();
8043f0e94c1SSiarhei Volkau     t1 = tcg_temp_new();
8053f0e94c1SSiarhei Volkau 
8063f0e94c1SSiarhei Volkau     XRa = extract32(ctx->opcode, 6, 4);
8073f0e94c1SSiarhei Volkau     s8 = extract32(ctx->opcode, 10, 8);
8083f0e94c1SSiarhei Volkau     optn3 = extract32(ctx->opcode, 18, 3);
8093f0e94c1SSiarhei Volkau     Rb = extract32(ctx->opcode, 21, 5);
8103f0e94c1SSiarhei Volkau 
8113f0e94c1SSiarhei Volkau     if (optn3 > 3) {
8123f0e94c1SSiarhei Volkau         /* reserved, do nothing */
8133f0e94c1SSiarhei Volkau         return;
8143f0e94c1SSiarhei Volkau     }
8153f0e94c1SSiarhei Volkau 
8163f0e94c1SSiarhei Volkau     gen_load_gpr(t0, Rb);
8173f0e94c1SSiarhei Volkau     tcg_gen_addi_tl(t0, t0, (int8_t)s8);
8183f0e94c1SSiarhei Volkau     if (postmodify) {
8193f0e94c1SSiarhei Volkau         gen_store_gpr(t0, Rb);
8203f0e94c1SSiarhei Volkau     }
8213f0e94c1SSiarhei Volkau     gen_load_mxu_gpr(t1, XRa);
8223f0e94c1SSiarhei Volkau 
8233f0e94c1SSiarhei Volkau     switch (optn3) {
8243f0e94c1SSiarhei Volkau     /* XRa[7:0] => tmp8 */
8253f0e94c1SSiarhei Volkau     case MXU_OPTN3_PTN0:
8263f0e94c1SSiarhei Volkau         tcg_gen_extract_tl(t1, t1, 0, 8);
8273f0e94c1SSiarhei Volkau         break;
8283f0e94c1SSiarhei Volkau     /* XRa[15:8] => tmp8 */
8293f0e94c1SSiarhei Volkau     case MXU_OPTN3_PTN1:
8303f0e94c1SSiarhei Volkau         tcg_gen_extract_tl(t1, t1, 8, 8);
8313f0e94c1SSiarhei Volkau         break;
8323f0e94c1SSiarhei Volkau     /* XRa[23:16] => tmp8 */
8333f0e94c1SSiarhei Volkau     case MXU_OPTN3_PTN2:
8343f0e94c1SSiarhei Volkau         tcg_gen_extract_tl(t1, t1, 16, 8);
8353f0e94c1SSiarhei Volkau         break;
8363f0e94c1SSiarhei Volkau     /* XRa[31:24] => tmp8 */
8373f0e94c1SSiarhei Volkau     case MXU_OPTN3_PTN3:
8383f0e94c1SSiarhei Volkau         tcg_gen_extract_tl(t1, t1, 24, 8);
8393f0e94c1SSiarhei Volkau         break;
8403f0e94c1SSiarhei Volkau     }
8413f0e94c1SSiarhei Volkau 
8423f0e94c1SSiarhei Volkau     tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_UB);
8433f0e94c1SSiarhei Volkau }
844968045b6SSiarhei Volkau 
845968045b6SSiarhei Volkau /*
846968045b6SSiarhei Volkau  * S16LDD XRa, Rb, s10, optn2 - Load a halfword from memory to XRF
847968045b6SSiarhei Volkau  *
848968045b6SSiarhei Volkau  * S16LDI XRa, Rb, s10, optn2 - Load a halfword from memory to XRF,
849968045b6SSiarhei Volkau  * post modify address register
850968045b6SSiarhei Volkau  */
gen_mxu_s16ldd(DisasContext * ctx,bool postmodify)851968045b6SSiarhei Volkau static void gen_mxu_s16ldd(DisasContext *ctx, bool postmodify)
852968045b6SSiarhei Volkau {
853968045b6SSiarhei Volkau     TCGv t0, t1;
854968045b6SSiarhei Volkau     uint32_t XRa, Rb, optn2;
855968045b6SSiarhei Volkau     int32_t s10;
856968045b6SSiarhei Volkau 
857968045b6SSiarhei Volkau     t0 = tcg_temp_new();
858968045b6SSiarhei Volkau     t1 = tcg_temp_new();
859968045b6SSiarhei Volkau 
860968045b6SSiarhei Volkau     XRa   = extract32(ctx->opcode,   6, 4);
861968045b6SSiarhei Volkau     s10   = sextract32(ctx->opcode, 10, 9) * 2;
862968045b6SSiarhei Volkau     optn2 = extract32(ctx->opcode,  19, 2);
863968045b6SSiarhei Volkau     Rb    = extract32(ctx->opcode,  21, 5);
864968045b6SSiarhei Volkau 
865968045b6SSiarhei Volkau     gen_load_gpr(t0, Rb);
866968045b6SSiarhei Volkau     tcg_gen_addi_tl(t0, t0, s10);
867968045b6SSiarhei Volkau     if (postmodify) {
868968045b6SSiarhei Volkau         gen_store_gpr(t0, Rb);
869968045b6SSiarhei Volkau     }
870968045b6SSiarhei Volkau 
871968045b6SSiarhei Volkau     switch (optn2) {
872968045b6SSiarhei Volkau     /* XRa[15:0] = tmp16 */
873968045b6SSiarhei Volkau     case MXU_OPTN2_PTN0:
874968045b6SSiarhei Volkau         tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UW);
875968045b6SSiarhei Volkau         gen_load_mxu_gpr(t0, XRa);
876968045b6SSiarhei Volkau         tcg_gen_deposit_tl(t0, t0, t1, 0, 16);
877968045b6SSiarhei Volkau         break;
878968045b6SSiarhei Volkau     /* XRa[31:16] = tmp16 */
879968045b6SSiarhei Volkau     case MXU_OPTN2_PTN1:
880968045b6SSiarhei Volkau         tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UW);
881968045b6SSiarhei Volkau         gen_load_mxu_gpr(t0, XRa);
882968045b6SSiarhei Volkau         tcg_gen_deposit_tl(t0, t0, t1, 16, 16);
883968045b6SSiarhei Volkau         break;
884968045b6SSiarhei Volkau     /* XRa = sign_extend(tmp16) */
885968045b6SSiarhei Volkau     case MXU_OPTN2_PTN2:
886968045b6SSiarhei Volkau         tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_SW);
887968045b6SSiarhei Volkau         break;
888968045b6SSiarhei Volkau     /* XRa = {tmp16, tmp16} */
889968045b6SSiarhei Volkau     case MXU_OPTN2_PTN3:
890968045b6SSiarhei Volkau         tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UW);
891968045b6SSiarhei Volkau         tcg_gen_deposit_tl(t0, t1, t1,  0, 16);
892968045b6SSiarhei Volkau         tcg_gen_deposit_tl(t0, t1, t1, 16, 16);
893968045b6SSiarhei Volkau         break;
894968045b6SSiarhei Volkau     }
895968045b6SSiarhei Volkau 
896968045b6SSiarhei Volkau     gen_store_mxu_gpr(t0, XRa);
897968045b6SSiarhei Volkau }
898968045b6SSiarhei Volkau 
899968045b6SSiarhei Volkau /*
900968045b6SSiarhei Volkau  * S16STD XRa, Rb, s8, optn2 - Store a byte from XRF to memory
901968045b6SSiarhei Volkau  *
902968045b6SSiarhei Volkau  * S16SDI XRa, Rb, s8, optn2 - Store a byte from XRF to memory,
903968045b6SSiarhei Volkau  * post modify address register
904968045b6SSiarhei Volkau  */
gen_mxu_s16std(DisasContext * ctx,bool postmodify)905968045b6SSiarhei Volkau static void gen_mxu_s16std(DisasContext *ctx, bool postmodify)
906968045b6SSiarhei Volkau {
907968045b6SSiarhei Volkau     TCGv t0, t1;
908968045b6SSiarhei Volkau     uint32_t XRa, Rb, optn2;
909968045b6SSiarhei Volkau     int32_t s10;
910968045b6SSiarhei Volkau 
911968045b6SSiarhei Volkau     t0 = tcg_temp_new();
912968045b6SSiarhei Volkau     t1 = tcg_temp_new();
913968045b6SSiarhei Volkau 
914968045b6SSiarhei Volkau     XRa = extract32(ctx->opcode, 6, 4);
915968045b6SSiarhei Volkau     s10 = sextract32(ctx->opcode, 10, 9) * 2;
916968045b6SSiarhei Volkau     optn2 = extract32(ctx->opcode, 19, 2);
917968045b6SSiarhei Volkau     Rb = extract32(ctx->opcode, 21, 5);
918968045b6SSiarhei Volkau 
919968045b6SSiarhei Volkau     if (optn2 > 1) {
920968045b6SSiarhei Volkau         /* reserved, do nothing */
921968045b6SSiarhei Volkau         return;
922968045b6SSiarhei Volkau     }
923968045b6SSiarhei Volkau 
924968045b6SSiarhei Volkau     gen_load_gpr(t0, Rb);
925968045b6SSiarhei Volkau     tcg_gen_addi_tl(t0, t0, s10);
926968045b6SSiarhei Volkau     if (postmodify) {
927968045b6SSiarhei Volkau         gen_store_gpr(t0, Rb);
928968045b6SSiarhei Volkau     }
929968045b6SSiarhei Volkau     gen_load_mxu_gpr(t1, XRa);
930968045b6SSiarhei Volkau 
931968045b6SSiarhei Volkau     switch (optn2) {
932968045b6SSiarhei Volkau     /* XRa[15:0] => tmp16 */
933968045b6SSiarhei Volkau     case MXU_OPTN2_PTN0:
934968045b6SSiarhei Volkau         tcg_gen_extract_tl(t1, t1, 0, 16);
935968045b6SSiarhei Volkau         break;
936968045b6SSiarhei Volkau     /* XRa[31:16] => tmp16 */
937968045b6SSiarhei Volkau     case MXU_OPTN2_PTN1:
938968045b6SSiarhei Volkau         tcg_gen_extract_tl(t1, t1, 16, 16);
939968045b6SSiarhei Volkau         break;
940968045b6SSiarhei Volkau     }
941968045b6SSiarhei Volkau 
942968045b6SSiarhei Volkau     tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_UW);
943968045b6SSiarhei Volkau }
944968045b6SSiarhei Volkau 
9453f0e94c1SSiarhei Volkau /*
94629059e72SSiarhei Volkau  * S32MUL  XRa, XRd, rs, rt - Signed 32x32=>64 bit multiplication
94729059e72SSiarhei Volkau  * of GPR's and stores result into pair of MXU registers.
94829059e72SSiarhei Volkau  * It strains HI and LO registers.
94929059e72SSiarhei Volkau  *
95029059e72SSiarhei Volkau  * S32MULU XRa, XRd, rs, rt - Unsigned 32x32=>64 bit multiplication
95129059e72SSiarhei Volkau  * of GPR's and stores result into pair of MXU registers.
95229059e72SSiarhei Volkau  * It strains HI and LO registers.
95329059e72SSiarhei Volkau  */
gen_mxu_s32mul(DisasContext * ctx,bool mulu)95429059e72SSiarhei Volkau static void gen_mxu_s32mul(DisasContext *ctx, bool mulu)
95529059e72SSiarhei Volkau {
95629059e72SSiarhei Volkau     TCGv t0, t1;
95729059e72SSiarhei Volkau     uint32_t XRa, XRd, rs, rt;
95829059e72SSiarhei Volkau 
95929059e72SSiarhei Volkau     t0 = tcg_temp_new();
96029059e72SSiarhei Volkau     t1 = tcg_temp_new();
96129059e72SSiarhei Volkau 
96229059e72SSiarhei Volkau     XRa = extract32(ctx->opcode,  6, 4);
96329059e72SSiarhei Volkau     XRd = extract32(ctx->opcode, 10, 4);
96429059e72SSiarhei Volkau     rs  = extract32(ctx->opcode, 16, 5);
96529059e72SSiarhei Volkau     rt  = extract32(ctx->opcode, 21, 5);
96629059e72SSiarhei Volkau 
96729059e72SSiarhei Volkau     if (unlikely(rs == 0 || rt == 0)) {
96829059e72SSiarhei Volkau         tcg_gen_movi_tl(t0, 0);
96929059e72SSiarhei Volkau         tcg_gen_movi_tl(t1, 0);
97029059e72SSiarhei Volkau     } else {
97129059e72SSiarhei Volkau         gen_load_gpr(t0, rs);
97229059e72SSiarhei Volkau         gen_load_gpr(t1, rt);
97329059e72SSiarhei Volkau 
97429059e72SSiarhei Volkau         if (mulu) {
97529059e72SSiarhei Volkau             tcg_gen_mulu2_tl(t0, t1, t0, t1);
97629059e72SSiarhei Volkau         } else {
97729059e72SSiarhei Volkau             tcg_gen_muls2_tl(t0, t1, t0, t1);
97829059e72SSiarhei Volkau         }
97929059e72SSiarhei Volkau     }
98029059e72SSiarhei Volkau     tcg_gen_mov_tl(cpu_HI[0], t1);
98129059e72SSiarhei Volkau     tcg_gen_mov_tl(cpu_LO[0], t0);
98229059e72SSiarhei Volkau     gen_store_mxu_gpr(t1, XRa);
98329059e72SSiarhei Volkau     gen_store_mxu_gpr(t0, XRd);
98429059e72SSiarhei Volkau }
98529059e72SSiarhei Volkau 
98629059e72SSiarhei Volkau /*
987a2b0a27dSPhilippe Mathieu-Daudé  * D16MUL  XRa, XRb, XRc, XRd, optn2 - Signed 16 bit pattern multiplication
98827dc0e28SSiarhei Volkau  * D16MULF XRa, XRb, XRc, optn2 - Signed Q15 fraction pattern multiplication
98927dc0e28SSiarhei Volkau  *   with rounding and packing result
99027dc0e28SSiarhei Volkau  * D16MULE XRa, XRb, XRc, XRd, optn2 - Signed Q15 fraction pattern
99127dc0e28SSiarhei Volkau  *   multiplication with rounding
992a2b0a27dSPhilippe Mathieu-Daudé  */
gen_mxu_d16mul(DisasContext * ctx,bool fractional,bool packed_result)99327dc0e28SSiarhei Volkau static void gen_mxu_d16mul(DisasContext *ctx, bool fractional,
99427dc0e28SSiarhei Volkau                            bool packed_result)
995a2b0a27dSPhilippe Mathieu-Daudé {
996a2b0a27dSPhilippe Mathieu-Daudé     TCGv t0, t1, t2, t3;
997a2b0a27dSPhilippe Mathieu-Daudé     uint32_t XRa, XRb, XRc, XRd, optn2;
998a2b0a27dSPhilippe Mathieu-Daudé 
999a2b0a27dSPhilippe Mathieu-Daudé     t0 = tcg_temp_new();
1000a2b0a27dSPhilippe Mathieu-Daudé     t1 = tcg_temp_new();
1001a2b0a27dSPhilippe Mathieu-Daudé     t2 = tcg_temp_new();
1002a2b0a27dSPhilippe Mathieu-Daudé     t3 = tcg_temp_new();
1003a2b0a27dSPhilippe Mathieu-Daudé 
1004a2b0a27dSPhilippe Mathieu-Daudé     XRa = extract32(ctx->opcode, 6, 4);
1005a2b0a27dSPhilippe Mathieu-Daudé     XRb = extract32(ctx->opcode, 10, 4);
1006a2b0a27dSPhilippe Mathieu-Daudé     XRc = extract32(ctx->opcode, 14, 4);
1007a2b0a27dSPhilippe Mathieu-Daudé     XRd = extract32(ctx->opcode, 18, 4);
1008a2b0a27dSPhilippe Mathieu-Daudé     optn2 = extract32(ctx->opcode, 22, 2);
1009a2b0a27dSPhilippe Mathieu-Daudé 
101027dc0e28SSiarhei Volkau     /*
101127dc0e28SSiarhei Volkau      * TODO: XRd field isn't used for D16MULF
101227dc0e28SSiarhei Volkau      * There's no knowledge how this field affect
101327dc0e28SSiarhei Volkau      * instruction decoding/behavior
101427dc0e28SSiarhei Volkau      */
101527dc0e28SSiarhei Volkau 
1016a2b0a27dSPhilippe Mathieu-Daudé     gen_load_mxu_gpr(t1, XRb);
1017a2b0a27dSPhilippe Mathieu-Daudé     tcg_gen_sextract_tl(t0, t1, 0, 16);
1018a2b0a27dSPhilippe Mathieu-Daudé     tcg_gen_sextract_tl(t1, t1, 16, 16);
1019a2b0a27dSPhilippe Mathieu-Daudé     gen_load_mxu_gpr(t3, XRc);
1020a2b0a27dSPhilippe Mathieu-Daudé     tcg_gen_sextract_tl(t2, t3, 0, 16);
1021a2b0a27dSPhilippe Mathieu-Daudé     tcg_gen_sextract_tl(t3, t3, 16, 16);
1022a2b0a27dSPhilippe Mathieu-Daudé 
1023a2b0a27dSPhilippe Mathieu-Daudé     switch (optn2) {
1024a2b0a27dSPhilippe Mathieu-Daudé     case MXU_OPTN2_WW: /* XRB.H*XRC.H == lop, XRB.L*XRC.L == rop */
1025a2b0a27dSPhilippe Mathieu-Daudé         tcg_gen_mul_tl(t3, t1, t3);
1026a2b0a27dSPhilippe Mathieu-Daudé         tcg_gen_mul_tl(t2, t0, t2);
1027a2b0a27dSPhilippe Mathieu-Daudé         break;
1028a2b0a27dSPhilippe Mathieu-Daudé     case MXU_OPTN2_LW: /* XRB.L*XRC.H == lop, XRB.L*XRC.L == rop */
1029a2b0a27dSPhilippe Mathieu-Daudé         tcg_gen_mul_tl(t3, t0, t3);
1030a2b0a27dSPhilippe Mathieu-Daudé         tcg_gen_mul_tl(t2, t0, t2);
1031a2b0a27dSPhilippe Mathieu-Daudé         break;
1032a2b0a27dSPhilippe Mathieu-Daudé     case MXU_OPTN2_HW: /* XRB.H*XRC.H == lop, XRB.H*XRC.L == rop */
1033a2b0a27dSPhilippe Mathieu-Daudé         tcg_gen_mul_tl(t3, t1, t3);
1034a2b0a27dSPhilippe Mathieu-Daudé         tcg_gen_mul_tl(t2, t1, t2);
1035a2b0a27dSPhilippe Mathieu-Daudé         break;
1036a2b0a27dSPhilippe Mathieu-Daudé     case MXU_OPTN2_XW: /* XRB.L*XRC.H == lop, XRB.H*XRC.L == rop */
1037a2b0a27dSPhilippe Mathieu-Daudé         tcg_gen_mul_tl(t3, t0, t3);
1038a2b0a27dSPhilippe Mathieu-Daudé         tcg_gen_mul_tl(t2, t1, t2);
1039a2b0a27dSPhilippe Mathieu-Daudé         break;
1040a2b0a27dSPhilippe Mathieu-Daudé     }
104127dc0e28SSiarhei Volkau     if (fractional) {
104227dc0e28SSiarhei Volkau         TCGLabel *l_done = gen_new_label();
104327dc0e28SSiarhei Volkau         TCGv rounding = tcg_temp_new();
104427dc0e28SSiarhei Volkau 
104527dc0e28SSiarhei Volkau         tcg_gen_shli_tl(t3, t3, 1);
104627dc0e28SSiarhei Volkau         tcg_gen_shli_tl(t2, t2, 1);
104727dc0e28SSiarhei Volkau         tcg_gen_andi_tl(rounding, mxu_CR, 0x2);
104827dc0e28SSiarhei Volkau         tcg_gen_brcondi_tl(TCG_COND_EQ, rounding, 0, l_done);
104927dc0e28SSiarhei Volkau         if (packed_result) {
105027dc0e28SSiarhei Volkau             TCGLabel *l_apply_bias_l = gen_new_label();
105127dc0e28SSiarhei Volkau             TCGLabel *l_apply_bias_r = gen_new_label();
105227dc0e28SSiarhei Volkau             TCGLabel *l_half_done = gen_new_label();
105327dc0e28SSiarhei Volkau             TCGv bias = tcg_temp_new();
105427dc0e28SSiarhei Volkau 
105527dc0e28SSiarhei Volkau             /*
105627dc0e28SSiarhei Volkau              * D16MULF supports unbiased rounding aka "bankers rounding",
105727dc0e28SSiarhei Volkau              * "round to even", "convergent rounding"
105827dc0e28SSiarhei Volkau              */
105927dc0e28SSiarhei Volkau             tcg_gen_andi_tl(bias, mxu_CR, 0x4);
106027dc0e28SSiarhei Volkau             tcg_gen_brcondi_tl(TCG_COND_NE, bias, 0, l_apply_bias_l);
106127dc0e28SSiarhei Volkau             tcg_gen_andi_tl(t0, t3, 0x1ffff);
106227dc0e28SSiarhei Volkau             tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0x8000, l_half_done);
106327dc0e28SSiarhei Volkau             gen_set_label(l_apply_bias_l);
106427dc0e28SSiarhei Volkau             tcg_gen_addi_tl(t3, t3, 0x8000);
106527dc0e28SSiarhei Volkau             gen_set_label(l_half_done);
106627dc0e28SSiarhei Volkau             tcg_gen_brcondi_tl(TCG_COND_NE, bias, 0, l_apply_bias_r);
106727dc0e28SSiarhei Volkau             tcg_gen_andi_tl(t0, t2, 0x1ffff);
106827dc0e28SSiarhei Volkau             tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0x8000, l_done);
106927dc0e28SSiarhei Volkau             gen_set_label(l_apply_bias_r);
107027dc0e28SSiarhei Volkau             tcg_gen_addi_tl(t2, t2, 0x8000);
107127dc0e28SSiarhei Volkau         } else {
107227dc0e28SSiarhei Volkau             /* D16MULE doesn't support unbiased rounding */
107327dc0e28SSiarhei Volkau             tcg_gen_addi_tl(t3, t3, 0x8000);
107427dc0e28SSiarhei Volkau             tcg_gen_addi_tl(t2, t2, 0x8000);
107527dc0e28SSiarhei Volkau         }
107627dc0e28SSiarhei Volkau         gen_set_label(l_done);
107727dc0e28SSiarhei Volkau     }
107827dc0e28SSiarhei Volkau     if (!packed_result) {
1079a2b0a27dSPhilippe Mathieu-Daudé         gen_store_mxu_gpr(t3, XRa);
1080a2b0a27dSPhilippe Mathieu-Daudé         gen_store_mxu_gpr(t2, XRd);
108127dc0e28SSiarhei Volkau     } else {
108227dc0e28SSiarhei Volkau         tcg_gen_andi_tl(t3, t3, 0xffff0000);
108327dc0e28SSiarhei Volkau         tcg_gen_shri_tl(t2, t2, 16);
108427dc0e28SSiarhei Volkau         tcg_gen_or_tl(t3, t3, t2);
108527dc0e28SSiarhei Volkau         gen_store_mxu_gpr(t3, XRa);
108627dc0e28SSiarhei Volkau     }
1087a2b0a27dSPhilippe Mathieu-Daudé }
1088a2b0a27dSPhilippe Mathieu-Daudé 
1089a2b0a27dSPhilippe Mathieu-Daudé /*
10902ebc66e4SSiarhei Volkau  * D16MAC XRa, XRb, XRc, XRd, aptn2, optn2
10912ebc66e4SSiarhei Volkau  *   Signed 16 bit pattern multiply and accumulate
10922ebc66e4SSiarhei Volkau  * D16MACF XRa, XRb, XRc, aptn2, optn2
10932ebc66e4SSiarhei Volkau  *   Signed Q15 fraction pattern multiply accumulate and pack
10942ebc66e4SSiarhei Volkau  * D16MACE XRa, XRb, XRc, XRd, aptn2, optn2
10952ebc66e4SSiarhei Volkau  *   Signed Q15 fraction pattern multiply and accumulate
1096a2b0a27dSPhilippe Mathieu-Daudé  */
gen_mxu_d16mac(DisasContext * ctx,bool fractional,bool packed_result)10972ebc66e4SSiarhei Volkau static void gen_mxu_d16mac(DisasContext *ctx, bool fractional,
10982ebc66e4SSiarhei Volkau                            bool packed_result)
1099a2b0a27dSPhilippe Mathieu-Daudé {
1100a2b0a27dSPhilippe Mathieu-Daudé     TCGv t0, t1, t2, t3;
1101a2b0a27dSPhilippe Mathieu-Daudé     uint32_t XRa, XRb, XRc, XRd, optn2, aptn2;
1102a2b0a27dSPhilippe Mathieu-Daudé 
1103a2b0a27dSPhilippe Mathieu-Daudé     t0 = tcg_temp_new();
1104a2b0a27dSPhilippe Mathieu-Daudé     t1 = tcg_temp_new();
1105a2b0a27dSPhilippe Mathieu-Daudé     t2 = tcg_temp_new();
1106a2b0a27dSPhilippe Mathieu-Daudé     t3 = tcg_temp_new();
1107a2b0a27dSPhilippe Mathieu-Daudé 
1108a2b0a27dSPhilippe Mathieu-Daudé     XRa = extract32(ctx->opcode, 6, 4);
1109a2b0a27dSPhilippe Mathieu-Daudé     XRb = extract32(ctx->opcode, 10, 4);
1110a2b0a27dSPhilippe Mathieu-Daudé     XRc = extract32(ctx->opcode, 14, 4);
1111a2b0a27dSPhilippe Mathieu-Daudé     XRd = extract32(ctx->opcode, 18, 4);
1112a2b0a27dSPhilippe Mathieu-Daudé     optn2 = extract32(ctx->opcode, 22, 2);
1113a2b0a27dSPhilippe Mathieu-Daudé     aptn2 = extract32(ctx->opcode, 24, 2);
1114a2b0a27dSPhilippe Mathieu-Daudé 
1115a2b0a27dSPhilippe Mathieu-Daudé     gen_load_mxu_gpr(t1, XRb);
1116a2b0a27dSPhilippe Mathieu-Daudé     tcg_gen_sextract_tl(t0, t1, 0, 16);
1117a2b0a27dSPhilippe Mathieu-Daudé     tcg_gen_sextract_tl(t1, t1, 16, 16);
1118a2b0a27dSPhilippe Mathieu-Daudé 
1119a2b0a27dSPhilippe Mathieu-Daudé     gen_load_mxu_gpr(t3, XRc);
1120a2b0a27dSPhilippe Mathieu-Daudé     tcg_gen_sextract_tl(t2, t3, 0, 16);
1121a2b0a27dSPhilippe Mathieu-Daudé     tcg_gen_sextract_tl(t3, t3, 16, 16);
1122a2b0a27dSPhilippe Mathieu-Daudé 
1123a2b0a27dSPhilippe Mathieu-Daudé     switch (optn2) {
1124a2b0a27dSPhilippe Mathieu-Daudé     case MXU_OPTN2_WW: /* XRB.H*XRC.H == lop, XRB.L*XRC.L == rop */
1125a2b0a27dSPhilippe Mathieu-Daudé         tcg_gen_mul_tl(t3, t1, t3);
1126a2b0a27dSPhilippe Mathieu-Daudé         tcg_gen_mul_tl(t2, t0, t2);
1127a2b0a27dSPhilippe Mathieu-Daudé         break;
1128a2b0a27dSPhilippe Mathieu-Daudé     case MXU_OPTN2_LW: /* XRB.L*XRC.H == lop, XRB.L*XRC.L == rop */
1129a2b0a27dSPhilippe Mathieu-Daudé         tcg_gen_mul_tl(t3, t0, t3);
1130a2b0a27dSPhilippe Mathieu-Daudé         tcg_gen_mul_tl(t2, t0, t2);
1131a2b0a27dSPhilippe Mathieu-Daudé         break;
1132a2b0a27dSPhilippe Mathieu-Daudé     case MXU_OPTN2_HW: /* XRB.H*XRC.H == lop, XRB.H*XRC.L == rop */
1133a2b0a27dSPhilippe Mathieu-Daudé         tcg_gen_mul_tl(t3, t1, t3);
1134a2b0a27dSPhilippe Mathieu-Daudé         tcg_gen_mul_tl(t2, t1, t2);
1135a2b0a27dSPhilippe Mathieu-Daudé         break;
1136a2b0a27dSPhilippe Mathieu-Daudé     case MXU_OPTN2_XW: /* XRB.L*XRC.H == lop, XRB.H*XRC.L == rop */
1137a2b0a27dSPhilippe Mathieu-Daudé         tcg_gen_mul_tl(t3, t0, t3);
1138a2b0a27dSPhilippe Mathieu-Daudé         tcg_gen_mul_tl(t2, t1, t2);
1139a2b0a27dSPhilippe Mathieu-Daudé         break;
1140a2b0a27dSPhilippe Mathieu-Daudé     }
11412ebc66e4SSiarhei Volkau 
11422ebc66e4SSiarhei Volkau     if (fractional) {
11432ebc66e4SSiarhei Volkau         tcg_gen_shli_tl(t3, t3, 1);
11442ebc66e4SSiarhei Volkau         tcg_gen_shli_tl(t2, t2, 1);
11452ebc66e4SSiarhei Volkau     }
1146a2b0a27dSPhilippe Mathieu-Daudé     gen_load_mxu_gpr(t0, XRa);
1147a2b0a27dSPhilippe Mathieu-Daudé     gen_load_mxu_gpr(t1, XRd);
1148a2b0a27dSPhilippe Mathieu-Daudé 
1149a2b0a27dSPhilippe Mathieu-Daudé     switch (aptn2) {
1150a2b0a27dSPhilippe Mathieu-Daudé     case MXU_APTN2_AA:
1151a2b0a27dSPhilippe Mathieu-Daudé         tcg_gen_add_tl(t3, t0, t3);
1152a2b0a27dSPhilippe Mathieu-Daudé         tcg_gen_add_tl(t2, t1, t2);
1153a2b0a27dSPhilippe Mathieu-Daudé         break;
1154a2b0a27dSPhilippe Mathieu-Daudé     case MXU_APTN2_AS:
1155a2b0a27dSPhilippe Mathieu-Daudé         tcg_gen_add_tl(t3, t0, t3);
1156a2b0a27dSPhilippe Mathieu-Daudé         tcg_gen_sub_tl(t2, t1, t2);
1157a2b0a27dSPhilippe Mathieu-Daudé         break;
1158a2b0a27dSPhilippe Mathieu-Daudé     case MXU_APTN2_SA:
1159a2b0a27dSPhilippe Mathieu-Daudé         tcg_gen_sub_tl(t3, t0, t3);
1160a2b0a27dSPhilippe Mathieu-Daudé         tcg_gen_add_tl(t2, t1, t2);
1161a2b0a27dSPhilippe Mathieu-Daudé         break;
1162a2b0a27dSPhilippe Mathieu-Daudé     case MXU_APTN2_SS:
1163a2b0a27dSPhilippe Mathieu-Daudé         tcg_gen_sub_tl(t3, t0, t3);
1164a2b0a27dSPhilippe Mathieu-Daudé         tcg_gen_sub_tl(t2, t1, t2);
1165a2b0a27dSPhilippe Mathieu-Daudé         break;
1166a2b0a27dSPhilippe Mathieu-Daudé     }
11672ebc66e4SSiarhei Volkau 
11682ebc66e4SSiarhei Volkau     if (fractional) {
11692ebc66e4SSiarhei Volkau         TCGLabel *l_done = gen_new_label();
11702ebc66e4SSiarhei Volkau         TCGv rounding = tcg_temp_new();
11712ebc66e4SSiarhei Volkau 
11722ebc66e4SSiarhei Volkau         tcg_gen_andi_tl(rounding, mxu_CR, 0x2);
11732ebc66e4SSiarhei Volkau         tcg_gen_brcondi_tl(TCG_COND_EQ, rounding, 0, l_done);
11742ebc66e4SSiarhei Volkau         if (packed_result) {
11752ebc66e4SSiarhei Volkau             TCGLabel *l_apply_bias_l = gen_new_label();
11762ebc66e4SSiarhei Volkau             TCGLabel *l_apply_bias_r = gen_new_label();
11772ebc66e4SSiarhei Volkau             TCGLabel *l_half_done = gen_new_label();
11782ebc66e4SSiarhei Volkau             TCGv bias = tcg_temp_new();
11792ebc66e4SSiarhei Volkau 
11802ebc66e4SSiarhei Volkau             /*
11812ebc66e4SSiarhei Volkau              * D16MACF supports unbiased rounding aka "bankers rounding",
11822ebc66e4SSiarhei Volkau              * "round to even", "convergent rounding"
11832ebc66e4SSiarhei Volkau              */
11842ebc66e4SSiarhei Volkau             tcg_gen_andi_tl(bias, mxu_CR, 0x4);
11852ebc66e4SSiarhei Volkau             tcg_gen_brcondi_tl(TCG_COND_NE, bias, 0, l_apply_bias_l);
11862ebc66e4SSiarhei Volkau             tcg_gen_andi_tl(t0, t3, 0x1ffff);
11872ebc66e4SSiarhei Volkau             tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0x8000, l_half_done);
11882ebc66e4SSiarhei Volkau             gen_set_label(l_apply_bias_l);
11892ebc66e4SSiarhei Volkau             tcg_gen_addi_tl(t3, t3, 0x8000);
11902ebc66e4SSiarhei Volkau             gen_set_label(l_half_done);
11912ebc66e4SSiarhei Volkau             tcg_gen_brcondi_tl(TCG_COND_NE, bias, 0, l_apply_bias_r);
11922ebc66e4SSiarhei Volkau             tcg_gen_andi_tl(t0, t2, 0x1ffff);
11932ebc66e4SSiarhei Volkau             tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0x8000, l_done);
11942ebc66e4SSiarhei Volkau             gen_set_label(l_apply_bias_r);
11952ebc66e4SSiarhei Volkau             tcg_gen_addi_tl(t2, t2, 0x8000);
11962ebc66e4SSiarhei Volkau         } else {
11972ebc66e4SSiarhei Volkau             /* D16MACE doesn't support unbiased rounding */
11982ebc66e4SSiarhei Volkau             tcg_gen_addi_tl(t3, t3, 0x8000);
11992ebc66e4SSiarhei Volkau             tcg_gen_addi_tl(t2, t2, 0x8000);
12002ebc66e4SSiarhei Volkau         }
12012ebc66e4SSiarhei Volkau         gen_set_label(l_done);
12022ebc66e4SSiarhei Volkau     }
12032ebc66e4SSiarhei Volkau 
12042ebc66e4SSiarhei Volkau     if (!packed_result) {
1205a2b0a27dSPhilippe Mathieu-Daudé         gen_store_mxu_gpr(t3, XRa);
1206a2b0a27dSPhilippe Mathieu-Daudé         gen_store_mxu_gpr(t2, XRd);
12072ebc66e4SSiarhei Volkau     } else {
12082ebc66e4SSiarhei Volkau         tcg_gen_andi_tl(t3, t3, 0xffff0000);
12092ebc66e4SSiarhei Volkau         tcg_gen_shri_tl(t2, t2, 16);
12102ebc66e4SSiarhei Volkau         tcg_gen_or_tl(t3, t3, t2);
12112ebc66e4SSiarhei Volkau         gen_store_mxu_gpr(t3, XRa);
12122ebc66e4SSiarhei Volkau     }
1213a2b0a27dSPhilippe Mathieu-Daudé }
1214a2b0a27dSPhilippe Mathieu-Daudé 
1215a2b0a27dSPhilippe Mathieu-Daudé /*
121615830fa2SSiarhei Volkau  * D16MADL XRa, XRb, XRc, XRd, aptn2, optn2 - Double packed
121715830fa2SSiarhei Volkau  * unsigned 16 bit pattern multiply and add/subtract.
121815830fa2SSiarhei Volkau  */
gen_mxu_d16madl(DisasContext * ctx)121915830fa2SSiarhei Volkau static void gen_mxu_d16madl(DisasContext *ctx)
122015830fa2SSiarhei Volkau {
122115830fa2SSiarhei Volkau     TCGv t0, t1, t2, t3;
122215830fa2SSiarhei Volkau     uint32_t XRa, XRb, XRc, XRd, optn2, aptn2;
122315830fa2SSiarhei Volkau 
122415830fa2SSiarhei Volkau     t0 = tcg_temp_new();
122515830fa2SSiarhei Volkau     t1 = tcg_temp_new();
122615830fa2SSiarhei Volkau     t2 = tcg_temp_new();
122715830fa2SSiarhei Volkau     t3 = tcg_temp_new();
122815830fa2SSiarhei Volkau 
122915830fa2SSiarhei Volkau     XRa = extract32(ctx->opcode, 6, 4);
123015830fa2SSiarhei Volkau     XRb = extract32(ctx->opcode, 10, 4);
123115830fa2SSiarhei Volkau     XRc = extract32(ctx->opcode, 14, 4);
123215830fa2SSiarhei Volkau     XRd = extract32(ctx->opcode, 18, 4);
123315830fa2SSiarhei Volkau     optn2 = extract32(ctx->opcode, 22, 2);
123415830fa2SSiarhei Volkau     aptn2 = extract32(ctx->opcode, 24, 2);
123515830fa2SSiarhei Volkau 
123615830fa2SSiarhei Volkau     gen_load_mxu_gpr(t1, XRb);
123715830fa2SSiarhei Volkau     tcg_gen_sextract_tl(t0, t1,  0, 16);
123815830fa2SSiarhei Volkau     tcg_gen_sextract_tl(t1, t1, 16, 16);
123915830fa2SSiarhei Volkau 
124015830fa2SSiarhei Volkau     gen_load_mxu_gpr(t3, XRc);
124115830fa2SSiarhei Volkau     tcg_gen_sextract_tl(t2, t3,  0, 16);
124215830fa2SSiarhei Volkau     tcg_gen_sextract_tl(t3, t3, 16, 16);
124315830fa2SSiarhei Volkau 
124415830fa2SSiarhei Volkau     switch (optn2) {
124515830fa2SSiarhei Volkau     case MXU_OPTN2_WW: /* XRB.H*XRC.H == lop, XRB.L*XRC.L == rop */
124615830fa2SSiarhei Volkau         tcg_gen_mul_tl(t3, t1, t3);
124715830fa2SSiarhei Volkau         tcg_gen_mul_tl(t2, t0, t2);
124815830fa2SSiarhei Volkau         break;
124915830fa2SSiarhei Volkau     case MXU_OPTN2_LW: /* XRB.L*XRC.H == lop, XRB.L*XRC.L == rop */
125015830fa2SSiarhei Volkau         tcg_gen_mul_tl(t3, t0, t3);
125115830fa2SSiarhei Volkau         tcg_gen_mul_tl(t2, t0, t2);
125215830fa2SSiarhei Volkau         break;
125315830fa2SSiarhei Volkau     case MXU_OPTN2_HW: /* XRB.H*XRC.H == lop, XRB.H*XRC.L == rop */
125415830fa2SSiarhei Volkau         tcg_gen_mul_tl(t3, t1, t3);
125515830fa2SSiarhei Volkau         tcg_gen_mul_tl(t2, t1, t2);
125615830fa2SSiarhei Volkau         break;
125715830fa2SSiarhei Volkau     case MXU_OPTN2_XW: /* XRB.L*XRC.H == lop, XRB.H*XRC.L == rop */
125815830fa2SSiarhei Volkau         tcg_gen_mul_tl(t3, t0, t3);
125915830fa2SSiarhei Volkau         tcg_gen_mul_tl(t2, t1, t2);
126015830fa2SSiarhei Volkau         break;
126115830fa2SSiarhei Volkau     }
126215830fa2SSiarhei Volkau     tcg_gen_extract_tl(t2, t2, 0, 16);
126315830fa2SSiarhei Volkau     tcg_gen_extract_tl(t3, t3, 0, 16);
126415830fa2SSiarhei Volkau 
126515830fa2SSiarhei Volkau     gen_load_mxu_gpr(t1, XRa);
126615830fa2SSiarhei Volkau     tcg_gen_extract_tl(t0, t1,  0, 16);
126715830fa2SSiarhei Volkau     tcg_gen_extract_tl(t1, t1, 16, 16);
126815830fa2SSiarhei Volkau 
126915830fa2SSiarhei Volkau     switch (aptn2) {
127015830fa2SSiarhei Volkau     case MXU_APTN2_AA:
127115830fa2SSiarhei Volkau         tcg_gen_add_tl(t3, t1, t3);
127215830fa2SSiarhei Volkau         tcg_gen_add_tl(t2, t0, t2);
127315830fa2SSiarhei Volkau         break;
127415830fa2SSiarhei Volkau     case MXU_APTN2_AS:
127515830fa2SSiarhei Volkau         tcg_gen_add_tl(t3, t1, t3);
127615830fa2SSiarhei Volkau         tcg_gen_sub_tl(t2, t0, t2);
127715830fa2SSiarhei Volkau         break;
127815830fa2SSiarhei Volkau     case MXU_APTN2_SA:
127915830fa2SSiarhei Volkau         tcg_gen_sub_tl(t3, t1, t3);
128015830fa2SSiarhei Volkau         tcg_gen_add_tl(t2, t0, t2);
128115830fa2SSiarhei Volkau         break;
128215830fa2SSiarhei Volkau     case MXU_APTN2_SS:
128315830fa2SSiarhei Volkau         tcg_gen_sub_tl(t3, t1, t3);
128415830fa2SSiarhei Volkau         tcg_gen_sub_tl(t2, t0, t2);
128515830fa2SSiarhei Volkau         break;
128615830fa2SSiarhei Volkau     }
128715830fa2SSiarhei Volkau 
128815830fa2SSiarhei Volkau     tcg_gen_andi_tl(t2, t2, 0xffff);
128915830fa2SSiarhei Volkau     tcg_gen_shli_tl(t3, t3, 16);
129015830fa2SSiarhei Volkau     tcg_gen_or_tl(mxu_gpr[XRd - 1], t3, t2);
129115830fa2SSiarhei Volkau }
129215830fa2SSiarhei Volkau 
129315830fa2SSiarhei Volkau /*
1294e722e680SSiarhei Volkau  * S16MAD XRa, XRb, XRc, XRd, aptn2, optn2 - Single packed
1295e722e680SSiarhei Volkau  * signed 16 bit pattern multiply and 32-bit add/subtract.
1296e722e680SSiarhei Volkau  */
gen_mxu_s16mad(DisasContext * ctx)1297e722e680SSiarhei Volkau static void gen_mxu_s16mad(DisasContext *ctx)
1298e722e680SSiarhei Volkau {
1299e722e680SSiarhei Volkau     TCGv t0, t1;
1300e722e680SSiarhei Volkau     uint32_t XRa, XRb, XRc, XRd, optn2, aptn1, pad;
1301e722e680SSiarhei Volkau 
1302e722e680SSiarhei Volkau     t0 = tcg_temp_new();
1303e722e680SSiarhei Volkau     t1 = tcg_temp_new();
1304e722e680SSiarhei Volkau 
1305e722e680SSiarhei Volkau     XRa = extract32(ctx->opcode, 6, 4);
1306e722e680SSiarhei Volkau     XRb = extract32(ctx->opcode, 10, 4);
1307e722e680SSiarhei Volkau     XRc = extract32(ctx->opcode, 14, 4);
1308e722e680SSiarhei Volkau     XRd = extract32(ctx->opcode, 18, 4);
1309e722e680SSiarhei Volkau     optn2 = extract32(ctx->opcode, 22, 2);
1310e722e680SSiarhei Volkau     aptn1 = extract32(ctx->opcode, 24, 1);
1311e722e680SSiarhei Volkau     pad = extract32(ctx->opcode, 25, 1);
1312e722e680SSiarhei Volkau 
1313e722e680SSiarhei Volkau     if (pad) {
1314e722e680SSiarhei Volkau         /* FIXME check if it influence the result */
1315e722e680SSiarhei Volkau     }
1316e722e680SSiarhei Volkau 
1317e722e680SSiarhei Volkau     gen_load_mxu_gpr(t0, XRb);
1318e722e680SSiarhei Volkau     gen_load_mxu_gpr(t1, XRc);
1319e722e680SSiarhei Volkau 
1320e722e680SSiarhei Volkau     switch (optn2) {
1321e722e680SSiarhei Volkau     case MXU_OPTN2_WW: /* XRB.H*XRC.H */
1322e722e680SSiarhei Volkau         tcg_gen_sextract_tl(t0, t0, 16, 16);
1323e722e680SSiarhei Volkau         tcg_gen_sextract_tl(t1, t1, 16, 16);
1324e722e680SSiarhei Volkau         break;
1325e722e680SSiarhei Volkau     case MXU_OPTN2_LW: /* XRB.L*XRC.L */
1326e722e680SSiarhei Volkau         tcg_gen_sextract_tl(t0, t0,  0, 16);
1327e722e680SSiarhei Volkau         tcg_gen_sextract_tl(t1, t1,  0, 16);
1328e722e680SSiarhei Volkau         break;
1329e722e680SSiarhei Volkau     case MXU_OPTN2_HW: /* XRB.H*XRC.L */
1330e722e680SSiarhei Volkau         tcg_gen_sextract_tl(t0, t0, 16, 16);
1331e722e680SSiarhei Volkau         tcg_gen_sextract_tl(t1, t1,  0, 16);
1332e722e680SSiarhei Volkau         break;
1333e722e680SSiarhei Volkau     case MXU_OPTN2_XW: /* XRB.L*XRC.H */
1334e722e680SSiarhei Volkau         tcg_gen_sextract_tl(t0, t0,  0, 16);
1335e722e680SSiarhei Volkau         tcg_gen_sextract_tl(t1, t1, 16, 16);
1336e722e680SSiarhei Volkau         break;
1337e722e680SSiarhei Volkau     }
1338e722e680SSiarhei Volkau     tcg_gen_mul_tl(t0, t0, t1);
1339e722e680SSiarhei Volkau 
1340e722e680SSiarhei Volkau     gen_load_mxu_gpr(t1, XRa);
1341e722e680SSiarhei Volkau 
1342e722e680SSiarhei Volkau     switch (aptn1) {
1343e722e680SSiarhei Volkau     case MXU_APTN1_A:
1344e722e680SSiarhei Volkau         tcg_gen_add_tl(t1, t1, t0);
1345e722e680SSiarhei Volkau         break;
1346e722e680SSiarhei Volkau     case MXU_APTN1_S:
1347e722e680SSiarhei Volkau         tcg_gen_sub_tl(t1, t1, t0);
1348e722e680SSiarhei Volkau         break;
1349e722e680SSiarhei Volkau     }
1350e722e680SSiarhei Volkau 
1351e722e680SSiarhei Volkau     gen_store_mxu_gpr(t1, XRd);
1352e722e680SSiarhei Volkau }
1353e722e680SSiarhei Volkau 
1354e722e680SSiarhei Volkau /*
13557bb1206aSSiarhei Volkau  * Q8MUL   XRa, XRb, XRc, XRd - Parallel quad unsigned 8 bit multiply
13567bb1206aSSiarhei Volkau  * Q8MULSU XRa, XRb, XRc, XRd - Parallel quad signed 8 bit multiply
13577bb1206aSSiarhei Volkau  * Q8MAC   XRa, XRb, XRc, XRd - Parallel quad unsigned 8 bit multiply
13587bb1206aSSiarhei Volkau  *   and accumulate
13597bb1206aSSiarhei Volkau  * Q8MACSU XRa, XRb, XRc, XRd - Parallel quad signed 8 bit multiply
13607bb1206aSSiarhei Volkau  *   and accumulate
1361a2b0a27dSPhilippe Mathieu-Daudé  */
gen_mxu_q8mul_mac(DisasContext * ctx,bool su,bool mac)13627bb1206aSSiarhei Volkau static void gen_mxu_q8mul_mac(DisasContext *ctx, bool su, bool mac)
1363a2b0a27dSPhilippe Mathieu-Daudé {
1364a2b0a27dSPhilippe Mathieu-Daudé     TCGv t0, t1, t2, t3, t4, t5, t6, t7;
13657bb1206aSSiarhei Volkau     uint32_t XRa, XRb, XRc, XRd, aptn2;
1366a2b0a27dSPhilippe Mathieu-Daudé 
1367a2b0a27dSPhilippe Mathieu-Daudé     t0 = tcg_temp_new();
1368a2b0a27dSPhilippe Mathieu-Daudé     t1 = tcg_temp_new();
1369a2b0a27dSPhilippe Mathieu-Daudé     t2 = tcg_temp_new();
1370a2b0a27dSPhilippe Mathieu-Daudé     t3 = tcg_temp_new();
1371a2b0a27dSPhilippe Mathieu-Daudé     t4 = tcg_temp_new();
1372a2b0a27dSPhilippe Mathieu-Daudé     t5 = tcg_temp_new();
1373a2b0a27dSPhilippe Mathieu-Daudé     t6 = tcg_temp_new();
1374a2b0a27dSPhilippe Mathieu-Daudé     t7 = tcg_temp_new();
1375a2b0a27dSPhilippe Mathieu-Daudé 
1376a2b0a27dSPhilippe Mathieu-Daudé     XRa = extract32(ctx->opcode, 6, 4);
1377a2b0a27dSPhilippe Mathieu-Daudé     XRb = extract32(ctx->opcode, 10, 4);
1378a2b0a27dSPhilippe Mathieu-Daudé     XRc = extract32(ctx->opcode, 14, 4);
1379a2b0a27dSPhilippe Mathieu-Daudé     XRd = extract32(ctx->opcode, 18, 4);
13807bb1206aSSiarhei Volkau     aptn2 = extract32(ctx->opcode, 24, 2);
1381a2b0a27dSPhilippe Mathieu-Daudé 
1382a2b0a27dSPhilippe Mathieu-Daudé     gen_load_mxu_gpr(t3, XRb);
1383a2b0a27dSPhilippe Mathieu-Daudé     gen_load_mxu_gpr(t7, XRc);
1384a2b0a27dSPhilippe Mathieu-Daudé 
13857bb1206aSSiarhei Volkau     if (su) {
13867bb1206aSSiarhei Volkau         /* Q8MULSU / Q8MACSU */
13877bb1206aSSiarhei Volkau         tcg_gen_sextract_tl(t0, t3,  0, 8);
13887bb1206aSSiarhei Volkau         tcg_gen_sextract_tl(t1, t3,  8, 8);
13897bb1206aSSiarhei Volkau         tcg_gen_sextract_tl(t2, t3, 16, 8);
13907bb1206aSSiarhei Volkau         tcg_gen_sextract_tl(t3, t3, 24, 8);
1391a2b0a27dSPhilippe Mathieu-Daudé     } else {
13927bb1206aSSiarhei Volkau         /* Q8MUL / Q8MAC */
13937bb1206aSSiarhei Volkau         tcg_gen_extract_tl(t0, t3,  0, 8);
13947bb1206aSSiarhei Volkau         tcg_gen_extract_tl(t1, t3,  8, 8);
13957bb1206aSSiarhei Volkau         tcg_gen_extract_tl(t2, t3, 16, 8);
13967bb1206aSSiarhei Volkau         tcg_gen_extract_tl(t3, t3, 24, 8);
1397a2b0a27dSPhilippe Mathieu-Daudé     }
1398a2b0a27dSPhilippe Mathieu-Daudé 
13997bb1206aSSiarhei Volkau     tcg_gen_extract_tl(t4, t7,  0, 8);
14007bb1206aSSiarhei Volkau     tcg_gen_extract_tl(t5, t7,  8, 8);
14017bb1206aSSiarhei Volkau     tcg_gen_extract_tl(t6, t7, 16, 8);
14027bb1206aSSiarhei Volkau     tcg_gen_extract_tl(t7, t7, 24, 8);
1403a2b0a27dSPhilippe Mathieu-Daudé 
1404a2b0a27dSPhilippe Mathieu-Daudé     tcg_gen_mul_tl(t0, t0, t4);
1405a2b0a27dSPhilippe Mathieu-Daudé     tcg_gen_mul_tl(t1, t1, t5);
1406a2b0a27dSPhilippe Mathieu-Daudé     tcg_gen_mul_tl(t2, t2, t6);
1407a2b0a27dSPhilippe Mathieu-Daudé     tcg_gen_mul_tl(t3, t3, t7);
1408a2b0a27dSPhilippe Mathieu-Daudé 
14097bb1206aSSiarhei Volkau     if (mac) {
14107bb1206aSSiarhei Volkau         gen_load_mxu_gpr(t4, XRd);
14117bb1206aSSiarhei Volkau         gen_load_mxu_gpr(t5, XRa);
14127bb1206aSSiarhei Volkau         tcg_gen_extract_tl(t6, t4,  0, 16);
14137bb1206aSSiarhei Volkau         tcg_gen_extract_tl(t7, t4, 16, 16);
14147bb1206aSSiarhei Volkau         if (aptn2 & 1) {
14157bb1206aSSiarhei Volkau             tcg_gen_sub_tl(t0, t6, t0);
14167bb1206aSSiarhei Volkau             tcg_gen_sub_tl(t1, t7, t1);
14177bb1206aSSiarhei Volkau         } else {
14187bb1206aSSiarhei Volkau             tcg_gen_add_tl(t0, t6, t0);
14197bb1206aSSiarhei Volkau             tcg_gen_add_tl(t1, t7, t1);
14207bb1206aSSiarhei Volkau         }
14217bb1206aSSiarhei Volkau         tcg_gen_extract_tl(t6, t5,  0, 16);
14227bb1206aSSiarhei Volkau         tcg_gen_extract_tl(t7, t5, 16, 16);
14237bb1206aSSiarhei Volkau         if (aptn2 & 2) {
14247bb1206aSSiarhei Volkau             tcg_gen_sub_tl(t2, t6, t2);
14257bb1206aSSiarhei Volkau             tcg_gen_sub_tl(t3, t7, t3);
14267bb1206aSSiarhei Volkau         } else {
14277bb1206aSSiarhei Volkau             tcg_gen_add_tl(t2, t6, t2);
14287bb1206aSSiarhei Volkau             tcg_gen_add_tl(t3, t7, t3);
14297bb1206aSSiarhei Volkau         }
14307bb1206aSSiarhei Volkau     }
1431a2b0a27dSPhilippe Mathieu-Daudé 
14327bb1206aSSiarhei Volkau     tcg_gen_deposit_tl(t0, t0, t1, 16, 16);
14337bb1206aSSiarhei Volkau     tcg_gen_deposit_tl(t1, t2, t3, 16, 16);
1434a2b0a27dSPhilippe Mathieu-Daudé 
1435a2b0a27dSPhilippe Mathieu-Daudé     gen_store_mxu_gpr(t0, XRd);
1436a2b0a27dSPhilippe Mathieu-Daudé     gen_store_mxu_gpr(t1, XRa);
1437a2b0a27dSPhilippe Mathieu-Daudé }
1438a2b0a27dSPhilippe Mathieu-Daudé 
1439a2b0a27dSPhilippe Mathieu-Daudé /*
1440b72e2b3aSSiarhei Volkau  * Q8MADL  XRd, XRa, XRb, XRc
1441b72e2b3aSSiarhei Volkau  *   Parallel quad unsigned 8 bit multiply and accumulate.
1442b72e2b3aSSiarhei Volkau  *   e.g. XRd[0..3] = XRa[0..3] + XRb[0..3] * XRc[0..3]
1443b72e2b3aSSiarhei Volkau  */
gen_mxu_q8madl(DisasContext * ctx)1444b72e2b3aSSiarhei Volkau static void gen_mxu_q8madl(DisasContext *ctx)
1445b72e2b3aSSiarhei Volkau {
1446b72e2b3aSSiarhei Volkau     TCGv t0, t1, t2, t3, t4, t5, t6, t7;
1447b72e2b3aSSiarhei Volkau     uint32_t XRa, XRb, XRc, XRd, aptn2;
1448b72e2b3aSSiarhei Volkau 
1449b72e2b3aSSiarhei Volkau     t0 = tcg_temp_new();
1450b72e2b3aSSiarhei Volkau     t1 = tcg_temp_new();
1451b72e2b3aSSiarhei Volkau     t2 = tcg_temp_new();
1452b72e2b3aSSiarhei Volkau     t3 = tcg_temp_new();
1453b72e2b3aSSiarhei Volkau     t4 = tcg_temp_new();
1454b72e2b3aSSiarhei Volkau     t5 = tcg_temp_new();
1455b72e2b3aSSiarhei Volkau     t6 = tcg_temp_new();
1456b72e2b3aSSiarhei Volkau     t7 = tcg_temp_new();
1457b72e2b3aSSiarhei Volkau 
1458b72e2b3aSSiarhei Volkau     XRa = extract32(ctx->opcode, 6, 4);
1459b72e2b3aSSiarhei Volkau     XRb = extract32(ctx->opcode, 10, 4);
1460b72e2b3aSSiarhei Volkau     XRc = extract32(ctx->opcode, 14, 4);
1461b72e2b3aSSiarhei Volkau     XRd = extract32(ctx->opcode, 18, 4);
1462b72e2b3aSSiarhei Volkau     aptn2 = extract32(ctx->opcode, 24, 2);
1463b72e2b3aSSiarhei Volkau 
1464b72e2b3aSSiarhei Volkau     gen_load_mxu_gpr(t3, XRb);
1465b72e2b3aSSiarhei Volkau     gen_load_mxu_gpr(t7, XRc);
1466b72e2b3aSSiarhei Volkau 
1467b72e2b3aSSiarhei Volkau     tcg_gen_extract_tl(t0, t3,  0, 8);
1468b72e2b3aSSiarhei Volkau     tcg_gen_extract_tl(t1, t3,  8, 8);
1469b72e2b3aSSiarhei Volkau     tcg_gen_extract_tl(t2, t3, 16, 8);
1470b72e2b3aSSiarhei Volkau     tcg_gen_extract_tl(t3, t3, 24, 8);
1471b72e2b3aSSiarhei Volkau 
1472b72e2b3aSSiarhei Volkau     tcg_gen_extract_tl(t4, t7,  0, 8);
1473b72e2b3aSSiarhei Volkau     tcg_gen_extract_tl(t5, t7,  8, 8);
1474b72e2b3aSSiarhei Volkau     tcg_gen_extract_tl(t6, t7, 16, 8);
1475b72e2b3aSSiarhei Volkau     tcg_gen_extract_tl(t7, t7, 24, 8);
1476b72e2b3aSSiarhei Volkau 
1477b72e2b3aSSiarhei Volkau     tcg_gen_mul_tl(t0, t0, t4);
1478b72e2b3aSSiarhei Volkau     tcg_gen_mul_tl(t1, t1, t5);
1479b72e2b3aSSiarhei Volkau     tcg_gen_mul_tl(t2, t2, t6);
1480b72e2b3aSSiarhei Volkau     tcg_gen_mul_tl(t3, t3, t7);
1481b72e2b3aSSiarhei Volkau 
1482b72e2b3aSSiarhei Volkau     gen_load_mxu_gpr(t4, XRa);
1483b72e2b3aSSiarhei Volkau     tcg_gen_extract_tl(t6, t4, 0, 8);
1484b72e2b3aSSiarhei Volkau     tcg_gen_extract_tl(t7, t4, 8, 8);
1485b72e2b3aSSiarhei Volkau     if (aptn2 & 1) {
1486b72e2b3aSSiarhei Volkau         tcg_gen_sub_tl(t0, t6, t0);
1487b72e2b3aSSiarhei Volkau         tcg_gen_sub_tl(t1, t7, t1);
1488b72e2b3aSSiarhei Volkau     } else {
1489b72e2b3aSSiarhei Volkau         tcg_gen_add_tl(t0, t6, t0);
1490b72e2b3aSSiarhei Volkau         tcg_gen_add_tl(t1, t7, t1);
1491b72e2b3aSSiarhei Volkau     }
1492b72e2b3aSSiarhei Volkau     tcg_gen_extract_tl(t6, t4, 16, 8);
1493b72e2b3aSSiarhei Volkau     tcg_gen_extract_tl(t7, t4, 24, 8);
1494b72e2b3aSSiarhei Volkau     if (aptn2 & 2) {
1495b72e2b3aSSiarhei Volkau         tcg_gen_sub_tl(t2, t6, t2);
1496b72e2b3aSSiarhei Volkau         tcg_gen_sub_tl(t3, t7, t3);
1497b72e2b3aSSiarhei Volkau     } else {
1498b72e2b3aSSiarhei Volkau         tcg_gen_add_tl(t2, t6, t2);
1499b72e2b3aSSiarhei Volkau         tcg_gen_add_tl(t3, t7, t3);
1500b72e2b3aSSiarhei Volkau     }
1501b72e2b3aSSiarhei Volkau 
1502b72e2b3aSSiarhei Volkau     tcg_gen_andi_tl(t5, t0, 0xff);
1503b72e2b3aSSiarhei Volkau     tcg_gen_deposit_tl(t5, t5, t1,  8, 8);
1504b72e2b3aSSiarhei Volkau     tcg_gen_deposit_tl(t5, t5, t2, 16, 8);
1505b72e2b3aSSiarhei Volkau     tcg_gen_deposit_tl(t5, t5, t3, 24, 8);
1506b72e2b3aSSiarhei Volkau 
1507b72e2b3aSSiarhei Volkau     gen_store_mxu_gpr(t5, XRd);
1508b72e2b3aSSiarhei Volkau }
1509b72e2b3aSSiarhei Volkau 
1510b72e2b3aSSiarhei Volkau /*
1511a2b0a27dSPhilippe Mathieu-Daudé  * S32LDD  XRa, Rb, S12 - Load a word from memory to XRF
151259db9465SSiarhei Volkau  * S32LDDR XRa, Rb, S12 - Load a word from memory to XRF
151359db9465SSiarhei Volkau  *   in reversed byte seq.
151459db9465SSiarhei Volkau  * S32LDI  XRa, Rb, S12 - Load a word from memory to XRF,
151559db9465SSiarhei Volkau  *   post modify base address GPR.
151659db9465SSiarhei Volkau  * S32LDIR XRa, Rb, S12 - Load a word from memory to XRF,
151759db9465SSiarhei Volkau  *   post modify base address GPR and load in reversed byte seq.
1518a2b0a27dSPhilippe Mathieu-Daudé  */
gen_mxu_s32ldxx(DisasContext * ctx,bool reversed,bool postinc)151959db9465SSiarhei Volkau static void gen_mxu_s32ldxx(DisasContext *ctx, bool reversed, bool postinc)
1520a2b0a27dSPhilippe Mathieu-Daudé {
1521a2b0a27dSPhilippe Mathieu-Daudé     TCGv t0, t1;
152259db9465SSiarhei Volkau     uint32_t XRa, Rb, s12;
1523a2b0a27dSPhilippe Mathieu-Daudé 
1524a2b0a27dSPhilippe Mathieu-Daudé     t0 = tcg_temp_new();
1525a2b0a27dSPhilippe Mathieu-Daudé     t1 = tcg_temp_new();
1526a2b0a27dSPhilippe Mathieu-Daudé 
1527a2b0a27dSPhilippe Mathieu-Daudé     XRa = extract32(ctx->opcode, 6, 4);
152859db9465SSiarhei Volkau     s12 = sextract32(ctx->opcode, 10, 10);
1529a2b0a27dSPhilippe Mathieu-Daudé     Rb = extract32(ctx->opcode, 21, 5);
1530a2b0a27dSPhilippe Mathieu-Daudé 
1531a2b0a27dSPhilippe Mathieu-Daudé     gen_load_gpr(t0, Rb);
153259db9465SSiarhei Volkau     tcg_gen_movi_tl(t1, s12 * 4);
153359db9465SSiarhei Volkau     tcg_gen_add_tl(t0, t0, t1);
1534a2b0a27dSPhilippe Mathieu-Daudé 
153559db9465SSiarhei Volkau     tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx,
153659db9465SSiarhei Volkau                        (MO_TESL ^ (reversed ? MO_BSWAP : 0)) |
153759db9465SSiarhei Volkau                         ctx->default_tcg_memop_mask);
153859db9465SSiarhei Volkau     gen_store_mxu_gpr(t1, XRa);
153959db9465SSiarhei Volkau 
154059db9465SSiarhei Volkau     if (postinc) {
154159db9465SSiarhei Volkau         gen_store_gpr(t0, Rb);
1542a2b0a27dSPhilippe Mathieu-Daudé     }
154359db9465SSiarhei Volkau }
154459db9465SSiarhei Volkau 
154559db9465SSiarhei Volkau /*
154659db9465SSiarhei Volkau  * S32STD  XRa, Rb, S12 - Store a word from XRF to memory
154759db9465SSiarhei Volkau  * S32STDR XRa, Rb, S12 - Store a word from XRF to memory
154859db9465SSiarhei Volkau  *   in reversed byte seq.
154959db9465SSiarhei Volkau  * S32SDI  XRa, Rb, S12 - Store a word from XRF to memory,
155059db9465SSiarhei Volkau  *   post modify base address GPR.
155159db9465SSiarhei Volkau  * S32SDIR XRa, Rb, S12 - Store a word from XRF to memory,
155259db9465SSiarhei Volkau  *   post modify base address GPR and store in reversed byte seq.
155359db9465SSiarhei Volkau  */
gen_mxu_s32stxx(DisasContext * ctx,bool reversed,bool postinc)155459db9465SSiarhei Volkau static void gen_mxu_s32stxx(DisasContext *ctx, bool reversed, bool postinc)
155559db9465SSiarhei Volkau {
155659db9465SSiarhei Volkau     TCGv t0, t1;
155759db9465SSiarhei Volkau     uint32_t XRa, Rb, s12;
155859db9465SSiarhei Volkau 
155959db9465SSiarhei Volkau     t0 = tcg_temp_new();
156059db9465SSiarhei Volkau     t1 = tcg_temp_new();
156159db9465SSiarhei Volkau 
156259db9465SSiarhei Volkau     XRa = extract32(ctx->opcode, 6, 4);
156359db9465SSiarhei Volkau     s12 = sextract32(ctx->opcode, 10, 10);
156459db9465SSiarhei Volkau     Rb = extract32(ctx->opcode, 21, 5);
156559db9465SSiarhei Volkau 
156659db9465SSiarhei Volkau     gen_load_gpr(t0, Rb);
156759db9465SSiarhei Volkau     tcg_gen_movi_tl(t1, s12 * 4);
156859db9465SSiarhei Volkau     tcg_gen_add_tl(t0, t0, t1);
156959db9465SSiarhei Volkau 
157059db9465SSiarhei Volkau     gen_load_mxu_gpr(t1, XRa);
157159db9465SSiarhei Volkau     tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx,
157259db9465SSiarhei Volkau                        (MO_TESL ^ (reversed ? MO_BSWAP : 0)) |
15730d5bede4SRichard Henderson                         ctx->default_tcg_memop_mask);
1574a2b0a27dSPhilippe Mathieu-Daudé 
157559db9465SSiarhei Volkau     if (postinc) {
157659db9465SSiarhei Volkau         gen_store_gpr(t0, Rb);
157759db9465SSiarhei Volkau     }
1578a2b0a27dSPhilippe Mathieu-Daudé }
1579a2b0a27dSPhilippe Mathieu-Daudé 
158059db9465SSiarhei Volkau /*
158159db9465SSiarhei Volkau  * S32LDDV  XRa, Rb, Rc, STRD2 - Load a word from memory to XRF
158259db9465SSiarhei Volkau  * S32LDDVR XRa, Rb, Rc, STRD2 - Load a word from memory to XRF
158359db9465SSiarhei Volkau  *   in reversed byte seq.
158459db9465SSiarhei Volkau  * S32LDIV  XRa, Rb, Rc, STRD2 - Load a word from memory to XRF,
158559db9465SSiarhei Volkau  *   post modify base address GPR.
158659db9465SSiarhei Volkau  * S32LDIVR XRa, Rb, Rc, STRD2 - Load a word from memory to XRF,
158759db9465SSiarhei Volkau  *   post modify base address GPR and load in reversed byte seq.
158859db9465SSiarhei Volkau  */
gen_mxu_s32ldxvx(DisasContext * ctx,bool reversed,bool postinc,uint32_t strd2)158959db9465SSiarhei Volkau static void gen_mxu_s32ldxvx(DisasContext *ctx, bool reversed,
159059db9465SSiarhei Volkau                              bool postinc, uint32_t strd2)
159159db9465SSiarhei Volkau {
159259db9465SSiarhei Volkau     TCGv t0, t1;
159359db9465SSiarhei Volkau     uint32_t XRa, Rb, Rc;
159459db9465SSiarhei Volkau 
159559db9465SSiarhei Volkau     t0 = tcg_temp_new();
159659db9465SSiarhei Volkau     t1 = tcg_temp_new();
159759db9465SSiarhei Volkau 
159859db9465SSiarhei Volkau     XRa = extract32(ctx->opcode, 6, 4);
159959db9465SSiarhei Volkau     Rc = extract32(ctx->opcode, 16, 5);
160059db9465SSiarhei Volkau     Rb = extract32(ctx->opcode, 21, 5);
160159db9465SSiarhei Volkau 
160259db9465SSiarhei Volkau     gen_load_gpr(t0, Rb);
160359db9465SSiarhei Volkau     gen_load_gpr(t1, Rc);
160459db9465SSiarhei Volkau     tcg_gen_shli_tl(t1, t1, strd2);
160559db9465SSiarhei Volkau     tcg_gen_add_tl(t0, t0, t1);
160659db9465SSiarhei Volkau 
160759db9465SSiarhei Volkau     tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx,
160859db9465SSiarhei Volkau                        (MO_TESL ^ (reversed ? MO_BSWAP : 0)) |
160959db9465SSiarhei Volkau                         ctx->default_tcg_memop_mask);
161059db9465SSiarhei Volkau     gen_store_mxu_gpr(t1, XRa);
161159db9465SSiarhei Volkau 
161259db9465SSiarhei Volkau     if (postinc) {
161359db9465SSiarhei Volkau         gen_store_gpr(t0, Rb);
161459db9465SSiarhei Volkau     }
161559db9465SSiarhei Volkau }
161659db9465SSiarhei Volkau 
161759db9465SSiarhei Volkau /*
161873c260c1SSiarhei Volkau  * LXW  Ra, Rb, Rc, STRD2 - Load a word from memory to GPR
161973c260c1SSiarhei Volkau  * LXB  Ra, Rb, Rc, STRD2 - Load a byte from memory to GPR,
162073c260c1SSiarhei Volkau  *   sign extending to GPR size.
162173c260c1SSiarhei Volkau  * LXH  Ra, Rb, Rc, STRD2 - Load a byte from memory to GPR,
162273c260c1SSiarhei Volkau  *   sign extending to GPR size.
162373c260c1SSiarhei Volkau  * LXBU Ra, Rb, Rc, STRD2 - Load a halfword from memory to GPR,
162473c260c1SSiarhei Volkau  *   zero extending to GPR size.
162573c260c1SSiarhei Volkau  * LXHU Ra, Rb, Rc, STRD2 - Load a halfword from memory to GPR,
162673c260c1SSiarhei Volkau  *   zero extending to GPR size.
162773c260c1SSiarhei Volkau  */
gen_mxu_lxx(DisasContext * ctx,uint32_t strd2,MemOp mop)162873c260c1SSiarhei Volkau static void gen_mxu_lxx(DisasContext *ctx, uint32_t strd2, MemOp mop)
162973c260c1SSiarhei Volkau {
163073c260c1SSiarhei Volkau     TCGv t0, t1;
163173c260c1SSiarhei Volkau     uint32_t Ra, Rb, Rc;
163273c260c1SSiarhei Volkau 
163373c260c1SSiarhei Volkau     t0 = tcg_temp_new();
163473c260c1SSiarhei Volkau     t1 = tcg_temp_new();
163573c260c1SSiarhei Volkau 
163673c260c1SSiarhei Volkau     Ra = extract32(ctx->opcode, 11, 5);
163773c260c1SSiarhei Volkau     Rc = extract32(ctx->opcode, 16, 5);
163873c260c1SSiarhei Volkau     Rb = extract32(ctx->opcode, 21, 5);
163973c260c1SSiarhei Volkau 
164073c260c1SSiarhei Volkau     gen_load_gpr(t0, Rb);
164173c260c1SSiarhei Volkau     gen_load_gpr(t1, Rc);
164273c260c1SSiarhei Volkau     tcg_gen_shli_tl(t1, t1, strd2);
164373c260c1SSiarhei Volkau     tcg_gen_add_tl(t0, t0, t1);
164473c260c1SSiarhei Volkau 
164573c260c1SSiarhei Volkau     tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, mop | ctx->default_tcg_memop_mask);
164673c260c1SSiarhei Volkau     gen_store_gpr(t1, Ra);
164773c260c1SSiarhei Volkau }
164873c260c1SSiarhei Volkau 
164973c260c1SSiarhei Volkau /*
165059db9465SSiarhei Volkau  * S32STDV  XRa, Rb, Rc, STRD2 - Load a word from memory to XRF
165159db9465SSiarhei Volkau  * S32STDVR XRa, Rb, Rc, STRD2 - Load a word from memory to XRF
165259db9465SSiarhei Volkau  *   in reversed byte seq.
165359db9465SSiarhei Volkau  * S32SDIV  XRa, Rb, Rc, STRD2 - Load a word from memory to XRF,
165459db9465SSiarhei Volkau  *   post modify base address GPR.
165559db9465SSiarhei Volkau  * S32SDIVR XRa, Rb, Rc, STRD2 - Load a word from memory to XRF,
165659db9465SSiarhei Volkau  *   post modify base address GPR and store in reversed byte seq.
165759db9465SSiarhei Volkau  */
gen_mxu_s32stxvx(DisasContext * ctx,bool reversed,bool postinc,uint32_t strd2)165859db9465SSiarhei Volkau static void gen_mxu_s32stxvx(DisasContext *ctx, bool reversed,
165959db9465SSiarhei Volkau                              bool postinc, uint32_t strd2)
166059db9465SSiarhei Volkau {
166159db9465SSiarhei Volkau     TCGv t0, t1;
166259db9465SSiarhei Volkau     uint32_t XRa, Rb, Rc;
166359db9465SSiarhei Volkau 
166459db9465SSiarhei Volkau     t0 = tcg_temp_new();
166559db9465SSiarhei Volkau     t1 = tcg_temp_new();
166659db9465SSiarhei Volkau 
166759db9465SSiarhei Volkau     XRa = extract32(ctx->opcode, 6, 4);
166859db9465SSiarhei Volkau     Rc = extract32(ctx->opcode, 16, 5);
166959db9465SSiarhei Volkau     Rb = extract32(ctx->opcode, 21, 5);
167059db9465SSiarhei Volkau 
167159db9465SSiarhei Volkau     gen_load_gpr(t0, Rb);
167259db9465SSiarhei Volkau     gen_load_gpr(t1, Rc);
167359db9465SSiarhei Volkau     tcg_gen_shli_tl(t1, t1, strd2);
167459db9465SSiarhei Volkau     tcg_gen_add_tl(t0, t0, t1);
167559db9465SSiarhei Volkau 
167659db9465SSiarhei Volkau     gen_load_mxu_gpr(t1, XRa);
167759db9465SSiarhei Volkau     tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx,
167859db9465SSiarhei Volkau                        (MO_TESL ^ (reversed ? MO_BSWAP : 0)) |
167959db9465SSiarhei Volkau                         ctx->default_tcg_memop_mask);
168059db9465SSiarhei Volkau 
168159db9465SSiarhei Volkau     if (postinc) {
168259db9465SSiarhei Volkau         gen_store_gpr(t0, Rb);
168359db9465SSiarhei Volkau     }
168459db9465SSiarhei Volkau }
1685a2b0a27dSPhilippe Mathieu-Daudé 
1686a2b0a27dSPhilippe Mathieu-Daudé /*
1687a2b0a27dSPhilippe Mathieu-Daudé  *                 MXU instruction category: logic
1688a2b0a27dSPhilippe Mathieu-Daudé  *                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1689a2b0a27dSPhilippe Mathieu-Daudé  *
1690a2b0a27dSPhilippe Mathieu-Daudé  *               S32NOR    S32AND    S32OR    S32XOR
1691a2b0a27dSPhilippe Mathieu-Daudé  */
1692a2b0a27dSPhilippe Mathieu-Daudé 
1693a2b0a27dSPhilippe Mathieu-Daudé /*
1694a2b0a27dSPhilippe Mathieu-Daudé  *  S32NOR XRa, XRb, XRc
1695a2b0a27dSPhilippe Mathieu-Daudé  *    Update XRa with the result of logical bitwise 'nor' operation
1696a2b0a27dSPhilippe Mathieu-Daudé  *    applied to the content of XRb and XRc.
1697a2b0a27dSPhilippe Mathieu-Daudé  */
gen_mxu_S32NOR(DisasContext * ctx)1698a2b0a27dSPhilippe Mathieu-Daudé static void gen_mxu_S32NOR(DisasContext *ctx)
1699a2b0a27dSPhilippe Mathieu-Daudé {
1700a2b0a27dSPhilippe Mathieu-Daudé     uint32_t pad, XRc, XRb, XRa;
1701a2b0a27dSPhilippe Mathieu-Daudé 
1702a2b0a27dSPhilippe Mathieu-Daudé     pad = extract32(ctx->opcode, 21, 5);
1703a2b0a27dSPhilippe Mathieu-Daudé     XRc = extract32(ctx->opcode, 14, 4);
1704a2b0a27dSPhilippe Mathieu-Daudé     XRb = extract32(ctx->opcode, 10, 4);
1705a2b0a27dSPhilippe Mathieu-Daudé     XRa = extract32(ctx->opcode,  6, 4);
1706a2b0a27dSPhilippe Mathieu-Daudé 
1707a2b0a27dSPhilippe Mathieu-Daudé     if (unlikely(pad != 0)) {
1708a2b0a27dSPhilippe Mathieu-Daudé         /* opcode padding incorrect -> do nothing */
1709a2b0a27dSPhilippe Mathieu-Daudé     } else if (unlikely(XRa == 0)) {
1710a2b0a27dSPhilippe Mathieu-Daudé         /* destination is zero register -> do nothing */
1711a2b0a27dSPhilippe Mathieu-Daudé     } else if (unlikely((XRb == 0) && (XRc == 0))) {
1712a2b0a27dSPhilippe Mathieu-Daudé         /* both operands zero registers -> just set destination to all 1s */
1713a2b0a27dSPhilippe Mathieu-Daudé         tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0xFFFFFFFF);
1714a2b0a27dSPhilippe Mathieu-Daudé     } else if (unlikely(XRb == 0)) {
1715a2b0a27dSPhilippe Mathieu-Daudé         /* XRb zero register -> just set destination to the negation of XRc */
1716a2b0a27dSPhilippe Mathieu-Daudé         tcg_gen_not_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]);
1717a2b0a27dSPhilippe Mathieu-Daudé     } else if (unlikely(XRc == 0)) {
1718a2b0a27dSPhilippe Mathieu-Daudé         /* XRa zero register -> just set destination to the negation of XRb */
1719a2b0a27dSPhilippe Mathieu-Daudé         tcg_gen_not_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
1720a2b0a27dSPhilippe Mathieu-Daudé     } else if (unlikely(XRb == XRc)) {
1721a2b0a27dSPhilippe Mathieu-Daudé         /* both operands same -> just set destination to the negation of XRb */
1722a2b0a27dSPhilippe Mathieu-Daudé         tcg_gen_not_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
1723a2b0a27dSPhilippe Mathieu-Daudé     } else {
1724a2b0a27dSPhilippe Mathieu-Daudé         /* the most general case */
1725a2b0a27dSPhilippe Mathieu-Daudé         tcg_gen_nor_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], mxu_gpr[XRc - 1]);
1726a2b0a27dSPhilippe Mathieu-Daudé     }
1727a2b0a27dSPhilippe Mathieu-Daudé }
1728a2b0a27dSPhilippe Mathieu-Daudé 
1729a2b0a27dSPhilippe Mathieu-Daudé /*
1730a2b0a27dSPhilippe Mathieu-Daudé  *  S32AND XRa, XRb, XRc
1731a2b0a27dSPhilippe Mathieu-Daudé  *    Update XRa with the result of logical bitwise 'and' operation
1732a2b0a27dSPhilippe Mathieu-Daudé  *    applied to the content of XRb and XRc.
1733a2b0a27dSPhilippe Mathieu-Daudé  */
gen_mxu_S32AND(DisasContext * ctx)1734a2b0a27dSPhilippe Mathieu-Daudé static void gen_mxu_S32AND(DisasContext *ctx)
1735a2b0a27dSPhilippe Mathieu-Daudé {
1736a2b0a27dSPhilippe Mathieu-Daudé     uint32_t pad, XRc, XRb, XRa;
1737a2b0a27dSPhilippe Mathieu-Daudé 
1738a2b0a27dSPhilippe Mathieu-Daudé     pad = extract32(ctx->opcode, 21, 5);
1739a2b0a27dSPhilippe Mathieu-Daudé     XRc = extract32(ctx->opcode, 14, 4);
1740a2b0a27dSPhilippe Mathieu-Daudé     XRb = extract32(ctx->opcode, 10, 4);
1741a2b0a27dSPhilippe Mathieu-Daudé     XRa = extract32(ctx->opcode,  6, 4);
1742a2b0a27dSPhilippe Mathieu-Daudé 
1743a2b0a27dSPhilippe Mathieu-Daudé     if (unlikely(pad != 0)) {
1744a2b0a27dSPhilippe Mathieu-Daudé         /* opcode padding incorrect -> do nothing */
1745a2b0a27dSPhilippe Mathieu-Daudé     } else if (unlikely(XRa == 0)) {
1746a2b0a27dSPhilippe Mathieu-Daudé         /* destination is zero register -> do nothing */
1747a2b0a27dSPhilippe Mathieu-Daudé     } else if (unlikely((XRb == 0) || (XRc == 0))) {
1748a2b0a27dSPhilippe Mathieu-Daudé         /* one of operands zero register -> just set destination to all 0s */
1749a2b0a27dSPhilippe Mathieu-Daudé         tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
1750a2b0a27dSPhilippe Mathieu-Daudé     } else if (unlikely(XRb == XRc)) {
1751a2b0a27dSPhilippe Mathieu-Daudé         /* both operands same -> just set destination to one of them */
1752a2b0a27dSPhilippe Mathieu-Daudé         tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
1753a2b0a27dSPhilippe Mathieu-Daudé     } else {
1754a2b0a27dSPhilippe Mathieu-Daudé         /* the most general case */
1755a2b0a27dSPhilippe Mathieu-Daudé         tcg_gen_and_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], mxu_gpr[XRc - 1]);
1756a2b0a27dSPhilippe Mathieu-Daudé     }
1757a2b0a27dSPhilippe Mathieu-Daudé }
1758a2b0a27dSPhilippe Mathieu-Daudé 
1759a2b0a27dSPhilippe Mathieu-Daudé /*
1760a2b0a27dSPhilippe Mathieu-Daudé  *  S32OR XRa, XRb, XRc
1761a2b0a27dSPhilippe Mathieu-Daudé  *    Update XRa with the result of logical bitwise 'or' operation
1762a2b0a27dSPhilippe Mathieu-Daudé  *    applied to the content of XRb and XRc.
1763a2b0a27dSPhilippe Mathieu-Daudé  */
gen_mxu_S32OR(DisasContext * ctx)1764a2b0a27dSPhilippe Mathieu-Daudé static void gen_mxu_S32OR(DisasContext *ctx)
1765a2b0a27dSPhilippe Mathieu-Daudé {
1766a2b0a27dSPhilippe Mathieu-Daudé     uint32_t pad, XRc, XRb, XRa;
1767a2b0a27dSPhilippe Mathieu-Daudé 
1768a2b0a27dSPhilippe Mathieu-Daudé     pad = extract32(ctx->opcode, 21, 5);
1769a2b0a27dSPhilippe Mathieu-Daudé     XRc = extract32(ctx->opcode, 14, 4);
1770a2b0a27dSPhilippe Mathieu-Daudé     XRb = extract32(ctx->opcode, 10, 4);
1771a2b0a27dSPhilippe Mathieu-Daudé     XRa = extract32(ctx->opcode,  6, 4);
1772a2b0a27dSPhilippe Mathieu-Daudé 
1773a2b0a27dSPhilippe Mathieu-Daudé     if (unlikely(pad != 0)) {
1774a2b0a27dSPhilippe Mathieu-Daudé         /* opcode padding incorrect -> do nothing */
1775a2b0a27dSPhilippe Mathieu-Daudé     } else if (unlikely(XRa == 0)) {
1776a2b0a27dSPhilippe Mathieu-Daudé         /* destination is zero register -> do nothing */
1777a2b0a27dSPhilippe Mathieu-Daudé     } else if (unlikely((XRb == 0) && (XRc == 0))) {
1778a2b0a27dSPhilippe Mathieu-Daudé         /* both operands zero registers -> just set destination to all 0s */
1779a2b0a27dSPhilippe Mathieu-Daudé         tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
1780a2b0a27dSPhilippe Mathieu-Daudé     } else if (unlikely(XRb == 0)) {
1781a2b0a27dSPhilippe Mathieu-Daudé         /* XRb zero register -> just set destination to the content of XRc */
1782a2b0a27dSPhilippe Mathieu-Daudé         tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]);
1783a2b0a27dSPhilippe Mathieu-Daudé     } else if (unlikely(XRc == 0)) {
1784a2b0a27dSPhilippe Mathieu-Daudé         /* XRc zero register -> just set destination to the content of XRb */
1785a2b0a27dSPhilippe Mathieu-Daudé         tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
1786a2b0a27dSPhilippe Mathieu-Daudé     } else if (unlikely(XRb == XRc)) {
1787a2b0a27dSPhilippe Mathieu-Daudé         /* both operands same -> just set destination to one of them */
1788a2b0a27dSPhilippe Mathieu-Daudé         tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
1789a2b0a27dSPhilippe Mathieu-Daudé     } else {
1790a2b0a27dSPhilippe Mathieu-Daudé         /* the most general case */
1791a2b0a27dSPhilippe Mathieu-Daudé         tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], mxu_gpr[XRc - 1]);
1792a2b0a27dSPhilippe Mathieu-Daudé     }
1793a2b0a27dSPhilippe Mathieu-Daudé }
1794a2b0a27dSPhilippe Mathieu-Daudé 
1795a2b0a27dSPhilippe Mathieu-Daudé /*
1796a2b0a27dSPhilippe Mathieu-Daudé  *  S32XOR XRa, XRb, XRc
1797a2b0a27dSPhilippe Mathieu-Daudé  *    Update XRa with the result of logical bitwise 'xor' operation
1798a2b0a27dSPhilippe Mathieu-Daudé  *    applied to the content of XRb and XRc.
1799a2b0a27dSPhilippe Mathieu-Daudé  */
gen_mxu_S32XOR(DisasContext * ctx)1800a2b0a27dSPhilippe Mathieu-Daudé static void gen_mxu_S32XOR(DisasContext *ctx)
1801a2b0a27dSPhilippe Mathieu-Daudé {
1802a2b0a27dSPhilippe Mathieu-Daudé     uint32_t pad, XRc, XRb, XRa;
1803a2b0a27dSPhilippe Mathieu-Daudé 
1804a2b0a27dSPhilippe Mathieu-Daudé     pad = extract32(ctx->opcode, 21, 5);
1805a2b0a27dSPhilippe Mathieu-Daudé     XRc = extract32(ctx->opcode, 14, 4);
1806a2b0a27dSPhilippe Mathieu-Daudé     XRb = extract32(ctx->opcode, 10, 4);
1807a2b0a27dSPhilippe Mathieu-Daudé     XRa = extract32(ctx->opcode,  6, 4);
1808a2b0a27dSPhilippe Mathieu-Daudé 
1809a2b0a27dSPhilippe Mathieu-Daudé     if (unlikely(pad != 0)) {
1810a2b0a27dSPhilippe Mathieu-Daudé         /* opcode padding incorrect -> do nothing */
1811a2b0a27dSPhilippe Mathieu-Daudé     } else if (unlikely(XRa == 0)) {
1812a2b0a27dSPhilippe Mathieu-Daudé         /* destination is zero register -> do nothing */
1813a2b0a27dSPhilippe Mathieu-Daudé     } else if (unlikely((XRb == 0) && (XRc == 0))) {
1814a2b0a27dSPhilippe Mathieu-Daudé         /* both operands zero registers -> just set destination to all 0s */
1815a2b0a27dSPhilippe Mathieu-Daudé         tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
1816a2b0a27dSPhilippe Mathieu-Daudé     } else if (unlikely(XRb == 0)) {
1817a2b0a27dSPhilippe Mathieu-Daudé         /* XRb zero register -> just set destination to the content of XRc */
1818a2b0a27dSPhilippe Mathieu-Daudé         tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]);
1819a2b0a27dSPhilippe Mathieu-Daudé     } else if (unlikely(XRc == 0)) {
1820a2b0a27dSPhilippe Mathieu-Daudé         /* XRc zero register -> just set destination to the content of XRb */
1821a2b0a27dSPhilippe Mathieu-Daudé         tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
1822a2b0a27dSPhilippe Mathieu-Daudé     } else if (unlikely(XRb == XRc)) {
1823a2b0a27dSPhilippe Mathieu-Daudé         /* both operands same -> just set destination to all 0s */
1824a2b0a27dSPhilippe Mathieu-Daudé         tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
1825a2b0a27dSPhilippe Mathieu-Daudé     } else {
1826a2b0a27dSPhilippe Mathieu-Daudé         /* the most general case */
1827a2b0a27dSPhilippe Mathieu-Daudé         tcg_gen_xor_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], mxu_gpr[XRc - 1]);
1828a2b0a27dSPhilippe Mathieu-Daudé     }
1829a2b0a27dSPhilippe Mathieu-Daudé }
1830a2b0a27dSPhilippe Mathieu-Daudé 
1831f900da76SSiarhei Volkau /*
1832f900da76SSiarhei Volkau  *                 MXU instruction category: shift
1833f900da76SSiarhei Volkau  *                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1834f900da76SSiarhei Volkau  *
1835f900da76SSiarhei Volkau  *               D32SLL    D32SLR    D32SAR    D32SARL
1836f900da76SSiarhei Volkau  *               D32SLLV   D32SLRV   D32SARV   D32SARW
1837f900da76SSiarhei Volkau  *               Q16SLL    Q16SLR    Q16SAR
1838f900da76SSiarhei Volkau  *               Q16SLLV   Q16SLRV   Q16SARV
1839f900da76SSiarhei Volkau  */
1840f900da76SSiarhei Volkau 
1841f900da76SSiarhei Volkau /*
1842f1fb1038SSiarhei Volkau  *  D32SLL XRa, XRd, XRb, XRc, SFT4
1843f1fb1038SSiarhei Volkau  *    Dual 32-bit shift left from XRb and XRc to SFT4
1844f1fb1038SSiarhei Volkau  *    bits (0..15). Store to XRa and XRd respectively.
1845f1fb1038SSiarhei Volkau  *  D32SLR XRa, XRd, XRb, XRc, SFT4
1846f1fb1038SSiarhei Volkau  *    Dual 32-bit shift logic right from XRb and XRc
1847f1fb1038SSiarhei Volkau  *    to SFT4 bits (0..15). Store to XRa and XRd respectively.
1848f1fb1038SSiarhei Volkau  *  D32SAR XRa, XRd, XRb, XRc, SFT4
1849f1fb1038SSiarhei Volkau  *    Dual 32-bit shift arithmetic right from XRb and XRc
1850f1fb1038SSiarhei Volkau  *    to SFT4 bits (0..15). Store to XRa and XRd respectively.
1851f1fb1038SSiarhei Volkau  */
gen_mxu_d32sxx(DisasContext * ctx,bool right,bool arithmetic)1852f1fb1038SSiarhei Volkau static void gen_mxu_d32sxx(DisasContext *ctx, bool right, bool arithmetic)
1853f1fb1038SSiarhei Volkau {
1854f1fb1038SSiarhei Volkau     uint32_t XRa, XRb, XRc, XRd, sft4;
1855f1fb1038SSiarhei Volkau 
1856f1fb1038SSiarhei Volkau     XRa  = extract32(ctx->opcode,  6, 4);
1857f1fb1038SSiarhei Volkau     XRb  = extract32(ctx->opcode, 10, 4);
1858f1fb1038SSiarhei Volkau     XRc  = extract32(ctx->opcode, 14, 4);
1859f1fb1038SSiarhei Volkau     XRd  = extract32(ctx->opcode, 18, 4);
1860f1fb1038SSiarhei Volkau     sft4 = extract32(ctx->opcode, 22, 4);
1861f1fb1038SSiarhei Volkau 
1862f1fb1038SSiarhei Volkau     TCGv t0 = tcg_temp_new();
1863f1fb1038SSiarhei Volkau     TCGv t1 = tcg_temp_new();
1864f1fb1038SSiarhei Volkau 
1865f1fb1038SSiarhei Volkau     gen_load_mxu_gpr(t0, XRb);
1866f1fb1038SSiarhei Volkau     gen_load_mxu_gpr(t1, XRc);
1867f1fb1038SSiarhei Volkau 
1868f1fb1038SSiarhei Volkau     if (right) {
1869f1fb1038SSiarhei Volkau         if (arithmetic) {
1870f1fb1038SSiarhei Volkau             tcg_gen_sari_tl(t0, t0, sft4);
1871f1fb1038SSiarhei Volkau             tcg_gen_sari_tl(t1, t1, sft4);
1872f1fb1038SSiarhei Volkau         } else {
1873f1fb1038SSiarhei Volkau             tcg_gen_shri_tl(t0, t0, sft4);
1874f1fb1038SSiarhei Volkau             tcg_gen_shri_tl(t1, t1, sft4);
1875f1fb1038SSiarhei Volkau         }
1876f1fb1038SSiarhei Volkau     } else {
1877f1fb1038SSiarhei Volkau         tcg_gen_shli_tl(t0, t0, sft4);
1878f1fb1038SSiarhei Volkau         tcg_gen_shli_tl(t1, t1, sft4);
1879f1fb1038SSiarhei Volkau     }
1880f1fb1038SSiarhei Volkau     gen_store_mxu_gpr(t0, XRa);
1881f1fb1038SSiarhei Volkau     gen_store_mxu_gpr(t1, XRd);
1882f1fb1038SSiarhei Volkau }
1883f1fb1038SSiarhei Volkau 
1884f1fb1038SSiarhei Volkau /*
188507c92895SSiarhei Volkau  *  D32SLLV XRa, XRd, rs
188607c92895SSiarhei Volkau  *    Dual 32-bit shift left from XRa and XRd to rs[3:0]
188707c92895SSiarhei Volkau  *    bits. Store back to XRa and XRd respectively.
188807c92895SSiarhei Volkau  *  D32SLRV XRa, XRd, rs
188907c92895SSiarhei Volkau  *    Dual 32-bit shift logic right from XRa and XRd to rs[3:0]
189007c92895SSiarhei Volkau  *    bits. Store back to XRa and XRd respectively.
189107c92895SSiarhei Volkau  *  D32SARV XRa, XRd, rs
189207c92895SSiarhei Volkau  *    Dual 32-bit shift arithmetic right from XRa and XRd to rs[3:0]
189307c92895SSiarhei Volkau  *    bits. Store back to XRa and XRd respectively.
189407c92895SSiarhei Volkau  */
gen_mxu_d32sxxv(DisasContext * ctx,bool right,bool arithmetic)189507c92895SSiarhei Volkau static void gen_mxu_d32sxxv(DisasContext *ctx, bool right, bool arithmetic)
189607c92895SSiarhei Volkau {
189707c92895SSiarhei Volkau     uint32_t XRa, XRd, rs;
189807c92895SSiarhei Volkau 
189907c92895SSiarhei Volkau     XRa = extract32(ctx->opcode, 10, 4);
190007c92895SSiarhei Volkau     XRd = extract32(ctx->opcode, 14, 4);
190107c92895SSiarhei Volkau     rs  = extract32(ctx->opcode, 21, 5);
190207c92895SSiarhei Volkau 
190307c92895SSiarhei Volkau     TCGv t0 = tcg_temp_new();
190407c92895SSiarhei Volkau     TCGv t1 = tcg_temp_new();
190507c92895SSiarhei Volkau     TCGv t2 = tcg_temp_new();
190607c92895SSiarhei Volkau 
190707c92895SSiarhei Volkau     gen_load_mxu_gpr(t0, XRa);
190807c92895SSiarhei Volkau     gen_load_mxu_gpr(t1, XRd);
190907c92895SSiarhei Volkau     gen_load_gpr(t2, rs);
191007c92895SSiarhei Volkau     tcg_gen_andi_tl(t2, t2, 0x0f);
191107c92895SSiarhei Volkau 
191207c92895SSiarhei Volkau     if (right) {
191307c92895SSiarhei Volkau         if (arithmetic) {
191407c92895SSiarhei Volkau             tcg_gen_sar_tl(t0, t0, t2);
191507c92895SSiarhei Volkau             tcg_gen_sar_tl(t1, t1, t2);
191607c92895SSiarhei Volkau         } else {
191707c92895SSiarhei Volkau             tcg_gen_shr_tl(t0, t0, t2);
191807c92895SSiarhei Volkau             tcg_gen_shr_tl(t1, t1, t2);
191907c92895SSiarhei Volkau         }
192007c92895SSiarhei Volkau     } else {
192107c92895SSiarhei Volkau         tcg_gen_shl_tl(t0, t0, t2);
192207c92895SSiarhei Volkau         tcg_gen_shl_tl(t1, t1, t2);
192307c92895SSiarhei Volkau     }
192407c92895SSiarhei Volkau     gen_store_mxu_gpr(t0, XRa);
192507c92895SSiarhei Volkau     gen_store_mxu_gpr(t1, XRd);
192607c92895SSiarhei Volkau }
192707c92895SSiarhei Volkau 
192807c92895SSiarhei Volkau /*
1929f900da76SSiarhei Volkau  *  D32SARL XRa, XRb, XRc, SFT4
1930f900da76SSiarhei Volkau  *    Dual shift arithmetic right 32-bit integers in XRb and XRc
1931f900da76SSiarhei Volkau  *    to SFT4 bits (0..15). Pack 16 LSBs of each into XRa.
1932f900da76SSiarhei Volkau  *
1933f900da76SSiarhei Volkau  *  D32SARW XRa, XRb, XRc, rb
1934f900da76SSiarhei Volkau  *    Dual shift arithmetic right 32-bit integers in XRb and XRc
1935f900da76SSiarhei Volkau  *    to rb[3:0] bits. Pack 16 LSBs of each into XRa.
1936f900da76SSiarhei Volkau  */
gen_mxu_d32sarl(DisasContext * ctx,bool sarw)1937f900da76SSiarhei Volkau static void gen_mxu_d32sarl(DisasContext *ctx, bool sarw)
1938f900da76SSiarhei Volkau {
1939f900da76SSiarhei Volkau     uint32_t XRa, XRb, XRc, rb;
1940f900da76SSiarhei Volkau 
1941f900da76SSiarhei Volkau     XRa = extract32(ctx->opcode,  6, 4);
1942f900da76SSiarhei Volkau     XRb = extract32(ctx->opcode, 10, 4);
1943f900da76SSiarhei Volkau     XRc = extract32(ctx->opcode, 14, 4);
1944f900da76SSiarhei Volkau     rb  = extract32(ctx->opcode, 21, 5);
1945f900da76SSiarhei Volkau 
1946f900da76SSiarhei Volkau     if (unlikely(XRa == 0)) {
1947f900da76SSiarhei Volkau         /* destination is zero register -> do nothing */
1948f900da76SSiarhei Volkau     } else {
1949f900da76SSiarhei Volkau         TCGv t0 = tcg_temp_new();
1950f900da76SSiarhei Volkau         TCGv t1 = tcg_temp_new();
1951f900da76SSiarhei Volkau         TCGv t2 = tcg_temp_new();
1952f900da76SSiarhei Volkau 
1953f900da76SSiarhei Volkau         if (!sarw) {
1954f900da76SSiarhei Volkau             /* Make SFT4 from rb field */
1955f900da76SSiarhei Volkau             tcg_gen_movi_tl(t2, rb >> 1);
1956f900da76SSiarhei Volkau         } else {
1957f900da76SSiarhei Volkau             gen_load_gpr(t2, rb);
1958f900da76SSiarhei Volkau             tcg_gen_andi_tl(t2, t2, 0x0f);
1959f900da76SSiarhei Volkau         }
1960f900da76SSiarhei Volkau         gen_load_mxu_gpr(t0, XRb);
1961f900da76SSiarhei Volkau         gen_load_mxu_gpr(t1, XRc);
1962f900da76SSiarhei Volkau         tcg_gen_sar_tl(t0, t0, t2);
1963f900da76SSiarhei Volkau         tcg_gen_sar_tl(t1, t1, t2);
1964f900da76SSiarhei Volkau         tcg_gen_extract_tl(t2, t1, 0, 16);
1965f900da76SSiarhei Volkau         tcg_gen_deposit_tl(t2, t2, t0, 16, 16);
1966f900da76SSiarhei Volkau         gen_store_mxu_gpr(t2, XRa);
1967f900da76SSiarhei Volkau     }
1968f900da76SSiarhei Volkau }
1969a2b0a27dSPhilippe Mathieu-Daudé 
1970a2b0a27dSPhilippe Mathieu-Daudé /*
197152fe25d4SSiarhei Volkau  *  Q16SLL XRa, XRd, XRb, XRc, SFT4
197252fe25d4SSiarhei Volkau  *    Quad 16-bit shift left from XRb and XRc to SFT4
197352fe25d4SSiarhei Volkau  *    bits (0..15). Store to XRa and XRd respectively.
197452fe25d4SSiarhei Volkau  *  Q16SLR XRa, XRd, XRb, XRc, SFT4
197552fe25d4SSiarhei Volkau  *    Quad 16-bit shift logic right from XRb and XRc
197652fe25d4SSiarhei Volkau  *    to SFT4 bits (0..15). Store to XRa and XRd respectively.
197752fe25d4SSiarhei Volkau  *  Q16SAR XRa, XRd, XRb, XRc, SFT4
197852fe25d4SSiarhei Volkau  *    Quad 16-bit shift arithmetic right from XRb and XRc
197952fe25d4SSiarhei Volkau  *    to SFT4 bits (0..15). Store to XRa and XRd respectively.
198052fe25d4SSiarhei Volkau  */
gen_mxu_q16sxx(DisasContext * ctx,bool right,bool arithmetic)198152fe25d4SSiarhei Volkau static void gen_mxu_q16sxx(DisasContext *ctx, bool right, bool arithmetic)
198252fe25d4SSiarhei Volkau {
198352fe25d4SSiarhei Volkau     uint32_t XRa, XRb, XRc, XRd, sft4;
198452fe25d4SSiarhei Volkau 
198552fe25d4SSiarhei Volkau     XRa  = extract32(ctx->opcode,  6, 4);
198652fe25d4SSiarhei Volkau     XRb  = extract32(ctx->opcode, 10, 4);
198752fe25d4SSiarhei Volkau     XRc  = extract32(ctx->opcode, 14, 4);
198852fe25d4SSiarhei Volkau     XRd  = extract32(ctx->opcode, 18, 4);
198952fe25d4SSiarhei Volkau     sft4 = extract32(ctx->opcode, 22, 4);
199052fe25d4SSiarhei Volkau 
199152fe25d4SSiarhei Volkau     TCGv t0 = tcg_temp_new();
199252fe25d4SSiarhei Volkau     TCGv t1 = tcg_temp_new();
199352fe25d4SSiarhei Volkau     TCGv t2 = tcg_temp_new();
199452fe25d4SSiarhei Volkau     TCGv t3 = tcg_temp_new();
199552fe25d4SSiarhei Volkau 
199652fe25d4SSiarhei Volkau     gen_load_mxu_gpr(t0, XRb);
199752fe25d4SSiarhei Volkau     gen_load_mxu_gpr(t2, XRc);
199852fe25d4SSiarhei Volkau 
199952fe25d4SSiarhei Volkau     if (arithmetic) {
200052fe25d4SSiarhei Volkau         tcg_gen_sextract_tl(t1, t0, 16, 16);
200152fe25d4SSiarhei Volkau         tcg_gen_sextract_tl(t0, t0,  0, 16);
200252fe25d4SSiarhei Volkau         tcg_gen_sextract_tl(t3, t2, 16, 16);
200352fe25d4SSiarhei Volkau         tcg_gen_sextract_tl(t2, t2,  0, 16);
200452fe25d4SSiarhei Volkau     } else {
200552fe25d4SSiarhei Volkau         tcg_gen_extract_tl(t1, t0, 16, 16);
200652fe25d4SSiarhei Volkau         tcg_gen_extract_tl(t0, t0,  0, 16);
200752fe25d4SSiarhei Volkau         tcg_gen_extract_tl(t3, t2, 16, 16);
200852fe25d4SSiarhei Volkau         tcg_gen_extract_tl(t2, t2,  0, 16);
200952fe25d4SSiarhei Volkau     }
201052fe25d4SSiarhei Volkau 
201152fe25d4SSiarhei Volkau     if (right) {
201252fe25d4SSiarhei Volkau         if (arithmetic) {
201352fe25d4SSiarhei Volkau             tcg_gen_sari_tl(t0, t0, sft4);
201452fe25d4SSiarhei Volkau             tcg_gen_sari_tl(t1, t1, sft4);
201552fe25d4SSiarhei Volkau             tcg_gen_sari_tl(t2, t2, sft4);
201652fe25d4SSiarhei Volkau             tcg_gen_sari_tl(t3, t3, sft4);
201752fe25d4SSiarhei Volkau         } else {
201852fe25d4SSiarhei Volkau             tcg_gen_shri_tl(t0, t0, sft4);
201952fe25d4SSiarhei Volkau             tcg_gen_shri_tl(t1, t1, sft4);
202052fe25d4SSiarhei Volkau             tcg_gen_shri_tl(t2, t2, sft4);
202152fe25d4SSiarhei Volkau             tcg_gen_shri_tl(t3, t3, sft4);
202252fe25d4SSiarhei Volkau         }
202352fe25d4SSiarhei Volkau     } else {
202452fe25d4SSiarhei Volkau         tcg_gen_shli_tl(t0, t0, sft4);
202552fe25d4SSiarhei Volkau         tcg_gen_shli_tl(t1, t1, sft4);
202652fe25d4SSiarhei Volkau         tcg_gen_shli_tl(t2, t2, sft4);
202752fe25d4SSiarhei Volkau         tcg_gen_shli_tl(t3, t3, sft4);
202852fe25d4SSiarhei Volkau     }
202952fe25d4SSiarhei Volkau     tcg_gen_deposit_tl(t0, t0, t1, 16, 16);
203052fe25d4SSiarhei Volkau     tcg_gen_deposit_tl(t2, t2, t3, 16, 16);
203152fe25d4SSiarhei Volkau 
203252fe25d4SSiarhei Volkau     gen_store_mxu_gpr(t0, XRa);
203352fe25d4SSiarhei Volkau     gen_store_mxu_gpr(t2, XRd);
203452fe25d4SSiarhei Volkau }
203552fe25d4SSiarhei Volkau 
203652fe25d4SSiarhei Volkau /*
203707c92895SSiarhei Volkau  *  Q16SLLV XRa, XRd, rs
203807c92895SSiarhei Volkau  *    Quad 16-bit shift left from XRa and XRd to rs[3:0]
203907c92895SSiarhei Volkau  *    bits. Store to XRa and XRd respectively.
204007c92895SSiarhei Volkau  *  Q16SLRV XRa, XRd, rs
204107c92895SSiarhei Volkau  *    Quad 16-bit shift logic right from XRa and XRd to rs[3:0]
204207c92895SSiarhei Volkau  *    bits. Store to XRa and XRd respectively.
204307c92895SSiarhei Volkau  *  Q16SARV XRa, XRd, rs
204407c92895SSiarhei Volkau  *    Quad 16-bit shift arithmetic right from XRa and XRd to rs[3:0]
204507c92895SSiarhei Volkau  *    bits. Store to XRa and XRd respectively.
204607c92895SSiarhei Volkau  */
gen_mxu_q16sxxv(DisasContext * ctx,bool right,bool arithmetic)204707c92895SSiarhei Volkau static void gen_mxu_q16sxxv(DisasContext *ctx, bool right, bool arithmetic)
204807c92895SSiarhei Volkau {
204907c92895SSiarhei Volkau     uint32_t XRa, XRd, rs;
205007c92895SSiarhei Volkau 
205107c92895SSiarhei Volkau     XRa = extract32(ctx->opcode, 10, 4);
205207c92895SSiarhei Volkau     XRd = extract32(ctx->opcode, 14, 4);
205307c92895SSiarhei Volkau     rs  = extract32(ctx->opcode, 21, 5);
205407c92895SSiarhei Volkau 
205507c92895SSiarhei Volkau     TCGv t0 = tcg_temp_new();
205607c92895SSiarhei Volkau     TCGv t1 = tcg_temp_new();
205707c92895SSiarhei Volkau     TCGv t2 = tcg_temp_new();
205807c92895SSiarhei Volkau     TCGv t3 = tcg_temp_new();
205907c92895SSiarhei Volkau     TCGv t5 = tcg_temp_new();
206007c92895SSiarhei Volkau 
206107c92895SSiarhei Volkau     gen_load_mxu_gpr(t0, XRa);
206207c92895SSiarhei Volkau     gen_load_mxu_gpr(t2, XRd);
206307c92895SSiarhei Volkau     gen_load_gpr(t5, rs);
206407c92895SSiarhei Volkau     tcg_gen_andi_tl(t5, t5, 0x0f);
206507c92895SSiarhei Volkau 
206607c92895SSiarhei Volkau 
206707c92895SSiarhei Volkau     if (arithmetic) {
206807c92895SSiarhei Volkau         tcg_gen_sextract_tl(t1, t0, 16, 16);
206907c92895SSiarhei Volkau         tcg_gen_sextract_tl(t0, t0,  0, 16);
207007c92895SSiarhei Volkau         tcg_gen_sextract_tl(t3, t2, 16, 16);
207107c92895SSiarhei Volkau         tcg_gen_sextract_tl(t2, t2,  0, 16);
207207c92895SSiarhei Volkau     } else {
207307c92895SSiarhei Volkau         tcg_gen_extract_tl(t1, t0, 16, 16);
207407c92895SSiarhei Volkau         tcg_gen_extract_tl(t0, t0,  0, 16);
207507c92895SSiarhei Volkau         tcg_gen_extract_tl(t3, t2, 16, 16);
207607c92895SSiarhei Volkau         tcg_gen_extract_tl(t2, t2,  0, 16);
207707c92895SSiarhei Volkau     }
207807c92895SSiarhei Volkau 
207907c92895SSiarhei Volkau     if (right) {
208007c92895SSiarhei Volkau         if (arithmetic) {
208107c92895SSiarhei Volkau             tcg_gen_sar_tl(t0, t0, t5);
208207c92895SSiarhei Volkau             tcg_gen_sar_tl(t1, t1, t5);
208307c92895SSiarhei Volkau             tcg_gen_sar_tl(t2, t2, t5);
208407c92895SSiarhei Volkau             tcg_gen_sar_tl(t3, t3, t5);
208507c92895SSiarhei Volkau         } else {
208607c92895SSiarhei Volkau             tcg_gen_shr_tl(t0, t0, t5);
208707c92895SSiarhei Volkau             tcg_gen_shr_tl(t1, t1, t5);
208807c92895SSiarhei Volkau             tcg_gen_shr_tl(t2, t2, t5);
208907c92895SSiarhei Volkau             tcg_gen_shr_tl(t3, t3, t5);
209007c92895SSiarhei Volkau         }
209107c92895SSiarhei Volkau     } else {
209207c92895SSiarhei Volkau         tcg_gen_shl_tl(t0, t0, t5);
209307c92895SSiarhei Volkau         tcg_gen_shl_tl(t1, t1, t5);
209407c92895SSiarhei Volkau         tcg_gen_shl_tl(t2, t2, t5);
209507c92895SSiarhei Volkau         tcg_gen_shl_tl(t3, t3, t5);
209607c92895SSiarhei Volkau     }
209707c92895SSiarhei Volkau     tcg_gen_deposit_tl(t0, t0, t1, 16, 16);
209807c92895SSiarhei Volkau     tcg_gen_deposit_tl(t2, t2, t3, 16, 16);
209907c92895SSiarhei Volkau 
210007c92895SSiarhei Volkau     gen_store_mxu_gpr(t0, XRa);
210107c92895SSiarhei Volkau     gen_store_mxu_gpr(t2, XRd);
210207c92895SSiarhei Volkau }
210307c92895SSiarhei Volkau 
210407c92895SSiarhei Volkau /*
2105ff7936f0SSiarhei Volkau  *                   MXU instruction category max/min/avg
2106a2b0a27dSPhilippe Mathieu-Daudé  *                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2107a2b0a27dSPhilippe Mathieu-Daudé  *
2108a2b0a27dSPhilippe Mathieu-Daudé  *                     S32MAX     D16MAX     Q8MAX
2109a2b0a27dSPhilippe Mathieu-Daudé  *                     S32MIN     D16MIN     Q8MIN
2110ff7936f0SSiarhei Volkau  *                     S32SLT     D16SLT     Q8SLT
2111ff7936f0SSiarhei Volkau  *                                           Q8SLTU
2112ff7936f0SSiarhei Volkau  *                                D16AVG     Q8AVG
2113ff7936f0SSiarhei Volkau  *                                D16AVGR    Q8AVGR
2114d1b6ded4SSiarhei Volkau  *                     S32MOVZ    D16MOVZ    Q8MOVZ
2115d1b6ded4SSiarhei Volkau  *                     S32MOVN    D16MOVN    Q8MOVN
2116a2b0a27dSPhilippe Mathieu-Daudé  */
2117a2b0a27dSPhilippe Mathieu-Daudé 
2118a2b0a27dSPhilippe Mathieu-Daudé /*
2119a2b0a27dSPhilippe Mathieu-Daudé  *  S32MAX XRa, XRb, XRc
2120a2b0a27dSPhilippe Mathieu-Daudé  *    Update XRa with the maximum of signed 32-bit integers contained
2121a2b0a27dSPhilippe Mathieu-Daudé  *    in XRb and XRc.
2122a2b0a27dSPhilippe Mathieu-Daudé  *
2123a2b0a27dSPhilippe Mathieu-Daudé  *  S32MIN XRa, XRb, XRc
2124a2b0a27dSPhilippe Mathieu-Daudé  *    Update XRa with the minimum of signed 32-bit integers contained
2125a2b0a27dSPhilippe Mathieu-Daudé  *    in XRb and XRc.
2126a2b0a27dSPhilippe Mathieu-Daudé  */
gen_mxu_S32MAX_S32MIN(DisasContext * ctx)2127a2b0a27dSPhilippe Mathieu-Daudé static void gen_mxu_S32MAX_S32MIN(DisasContext *ctx)
2128a2b0a27dSPhilippe Mathieu-Daudé {
2129a2b0a27dSPhilippe Mathieu-Daudé     uint32_t pad, opc, XRc, XRb, XRa;
2130a2b0a27dSPhilippe Mathieu-Daudé 
2131a2b0a27dSPhilippe Mathieu-Daudé     pad = extract32(ctx->opcode, 21, 5);
2132a2b0a27dSPhilippe Mathieu-Daudé     opc = extract32(ctx->opcode, 18, 3);
2133a2b0a27dSPhilippe Mathieu-Daudé     XRc = extract32(ctx->opcode, 14, 4);
2134a2b0a27dSPhilippe Mathieu-Daudé     XRb = extract32(ctx->opcode, 10, 4);
2135a2b0a27dSPhilippe Mathieu-Daudé     XRa = extract32(ctx->opcode,  6, 4);
2136a2b0a27dSPhilippe Mathieu-Daudé 
2137a2b0a27dSPhilippe Mathieu-Daudé     if (unlikely(pad != 0)) {
2138a2b0a27dSPhilippe Mathieu-Daudé         /* opcode padding incorrect -> do nothing */
2139a2b0a27dSPhilippe Mathieu-Daudé     } else if (unlikely(XRa == 0)) {
2140a2b0a27dSPhilippe Mathieu-Daudé         /* destination is zero register -> do nothing */
2141a2b0a27dSPhilippe Mathieu-Daudé     } else if (unlikely((XRb == 0) && (XRc == 0))) {
2142a2b0a27dSPhilippe Mathieu-Daudé         /* both operands zero registers -> just set destination to zero */
2143a2b0a27dSPhilippe Mathieu-Daudé         tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
2144a2b0a27dSPhilippe Mathieu-Daudé     } else if (unlikely((XRb == 0) || (XRc == 0))) {
2145a2b0a27dSPhilippe Mathieu-Daudé         /* exactly one operand is zero register - find which one is not...*/
2146a2b0a27dSPhilippe Mathieu-Daudé         uint32_t XRx = XRb ? XRb : XRc;
2147a2b0a27dSPhilippe Mathieu-Daudé         /* ...and do max/min operation with one operand 0 */
2148a2b0a27dSPhilippe Mathieu-Daudé         if (opc == OPC_MXU_S32MAX) {
2149a2b0a27dSPhilippe Mathieu-Daudé             tcg_gen_smax_i32(mxu_gpr[XRa - 1], mxu_gpr[XRx - 1], 0);
2150a2b0a27dSPhilippe Mathieu-Daudé         } else {
2151a2b0a27dSPhilippe Mathieu-Daudé             tcg_gen_smin_i32(mxu_gpr[XRa - 1], mxu_gpr[XRx - 1], 0);
2152a2b0a27dSPhilippe Mathieu-Daudé         }
2153a2b0a27dSPhilippe Mathieu-Daudé     } else if (unlikely(XRb == XRc)) {
2154a2b0a27dSPhilippe Mathieu-Daudé         /* both operands same -> just set destination to one of them */
2155a2b0a27dSPhilippe Mathieu-Daudé         tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
2156a2b0a27dSPhilippe Mathieu-Daudé     } else {
2157a2b0a27dSPhilippe Mathieu-Daudé         /* the most general case */
2158a2b0a27dSPhilippe Mathieu-Daudé         if (opc == OPC_MXU_S32MAX) {
2159a2b0a27dSPhilippe Mathieu-Daudé             tcg_gen_smax_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1],
2160a2b0a27dSPhilippe Mathieu-Daudé                                                mxu_gpr[XRc - 1]);
2161a2b0a27dSPhilippe Mathieu-Daudé         } else {
2162a2b0a27dSPhilippe Mathieu-Daudé             tcg_gen_smin_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1],
2163a2b0a27dSPhilippe Mathieu-Daudé                                                mxu_gpr[XRc - 1]);
2164a2b0a27dSPhilippe Mathieu-Daudé         }
2165a2b0a27dSPhilippe Mathieu-Daudé     }
2166a2b0a27dSPhilippe Mathieu-Daudé }
2167a2b0a27dSPhilippe Mathieu-Daudé 
2168a2b0a27dSPhilippe Mathieu-Daudé /*
2169a2b0a27dSPhilippe Mathieu-Daudé  *  D16MAX
2170a2b0a27dSPhilippe Mathieu-Daudé  *    Update XRa with the 16-bit-wise maximums of signed integers
2171a2b0a27dSPhilippe Mathieu-Daudé  *    contained in XRb and XRc.
2172a2b0a27dSPhilippe Mathieu-Daudé  *
2173a2b0a27dSPhilippe Mathieu-Daudé  *  D16MIN
2174a2b0a27dSPhilippe Mathieu-Daudé  *    Update XRa with the 16-bit-wise minimums of signed integers
2175a2b0a27dSPhilippe Mathieu-Daudé  *    contained in XRb and XRc.
2176a2b0a27dSPhilippe Mathieu-Daudé  */
gen_mxu_D16MAX_D16MIN(DisasContext * ctx)2177a2b0a27dSPhilippe Mathieu-Daudé static void gen_mxu_D16MAX_D16MIN(DisasContext *ctx)
2178a2b0a27dSPhilippe Mathieu-Daudé {
2179a2b0a27dSPhilippe Mathieu-Daudé     uint32_t pad, opc, XRc, XRb, XRa;
2180a2b0a27dSPhilippe Mathieu-Daudé 
2181a2b0a27dSPhilippe Mathieu-Daudé     pad = extract32(ctx->opcode, 21, 5);
2182a2b0a27dSPhilippe Mathieu-Daudé     opc = extract32(ctx->opcode, 18, 3);
2183a2b0a27dSPhilippe Mathieu-Daudé     XRc = extract32(ctx->opcode, 14, 4);
2184a2b0a27dSPhilippe Mathieu-Daudé     XRb = extract32(ctx->opcode, 10, 4);
2185a2b0a27dSPhilippe Mathieu-Daudé     XRa = extract32(ctx->opcode,  6, 4);
2186a2b0a27dSPhilippe Mathieu-Daudé 
2187a2b0a27dSPhilippe Mathieu-Daudé     if (unlikely(pad != 0)) {
2188a2b0a27dSPhilippe Mathieu-Daudé         /* opcode padding incorrect -> do nothing */
2189a2b0a27dSPhilippe Mathieu-Daudé     } else if (unlikely(XRa == 0)) {
2190a2b0a27dSPhilippe Mathieu-Daudé         /* destination is zero register -> do nothing */
2191a2b0a27dSPhilippe Mathieu-Daudé     } else if (unlikely((XRb == 0) && (XRc == 0))) {
2192a2b0a27dSPhilippe Mathieu-Daudé         /* both operands zero registers -> just set destination to zero */
2193a2b0a27dSPhilippe Mathieu-Daudé         tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
2194a2b0a27dSPhilippe Mathieu-Daudé     } else if (unlikely((XRb == 0) || (XRc == 0))) {
2195a2b0a27dSPhilippe Mathieu-Daudé         /* exactly one operand is zero register - find which one is not...*/
2196a2b0a27dSPhilippe Mathieu-Daudé         uint32_t XRx = XRb ? XRb : XRc;
2197a2b0a27dSPhilippe Mathieu-Daudé         /* ...and do half-word-wise max/min with one operand 0 */
2198a2b0a27dSPhilippe Mathieu-Daudé         TCGv_i32 t0 = tcg_temp_new();
2199c29e79afSRichard Henderson         TCGv_i32 t1 = tcg_constant_i32(0);
2200fc34c76fSSiarhei Volkau         TCGv_i32 t2 = tcg_temp_new();
2201a2b0a27dSPhilippe Mathieu-Daudé 
2202a2b0a27dSPhilippe Mathieu-Daudé         /* the left half-word first */
2203a2b0a27dSPhilippe Mathieu-Daudé         tcg_gen_andi_i32(t0, mxu_gpr[XRx - 1], 0xFFFF0000);
2204a2b0a27dSPhilippe Mathieu-Daudé         if (opc == OPC_MXU_D16MAX) {
2205fc34c76fSSiarhei Volkau             tcg_gen_smax_i32(t2, t0, t1);
2206a2b0a27dSPhilippe Mathieu-Daudé         } else {
2207fc34c76fSSiarhei Volkau             tcg_gen_smin_i32(t2, t0, t1);
2208a2b0a27dSPhilippe Mathieu-Daudé         }
2209a2b0a27dSPhilippe Mathieu-Daudé 
2210a2b0a27dSPhilippe Mathieu-Daudé         /* the right half-word */
2211a2b0a27dSPhilippe Mathieu-Daudé         tcg_gen_andi_i32(t0, mxu_gpr[XRx - 1], 0x0000FFFF);
2212a2b0a27dSPhilippe Mathieu-Daudé         /* move half-words to the leftmost position */
2213a2b0a27dSPhilippe Mathieu-Daudé         tcg_gen_shli_i32(t0, t0, 16);
2214a2b0a27dSPhilippe Mathieu-Daudé         /* t0 will be max/min of t0 and t1 */
2215a2b0a27dSPhilippe Mathieu-Daudé         if (opc == OPC_MXU_D16MAX) {
2216a2b0a27dSPhilippe Mathieu-Daudé             tcg_gen_smax_i32(t0, t0, t1);
2217a2b0a27dSPhilippe Mathieu-Daudé         } else {
2218a2b0a27dSPhilippe Mathieu-Daudé             tcg_gen_smin_i32(t0, t0, t1);
2219a2b0a27dSPhilippe Mathieu-Daudé         }
2220a2b0a27dSPhilippe Mathieu-Daudé         /* return resulting half-words to its original position */
2221a2b0a27dSPhilippe Mathieu-Daudé         tcg_gen_shri_i32(t0, t0, 16);
2222a2b0a27dSPhilippe Mathieu-Daudé         /* finally update the destination */
2223fc34c76fSSiarhei Volkau         tcg_gen_or_i32(mxu_gpr[XRa - 1], t2, t0);
2224a2b0a27dSPhilippe Mathieu-Daudé     } else if (unlikely(XRb == XRc)) {
2225a2b0a27dSPhilippe Mathieu-Daudé         /* both operands same -> just set destination to one of them */
2226a2b0a27dSPhilippe Mathieu-Daudé         tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
2227a2b0a27dSPhilippe Mathieu-Daudé     } else {
2228a2b0a27dSPhilippe Mathieu-Daudé         /* the most general case */
2229a2b0a27dSPhilippe Mathieu-Daudé         TCGv_i32 t0 = tcg_temp_new();
2230a2b0a27dSPhilippe Mathieu-Daudé         TCGv_i32 t1 = tcg_temp_new();
2231fc34c76fSSiarhei Volkau         TCGv_i32 t2 = tcg_temp_new();
2232a2b0a27dSPhilippe Mathieu-Daudé 
2233a2b0a27dSPhilippe Mathieu-Daudé         /* the left half-word first */
2234a2b0a27dSPhilippe Mathieu-Daudé         tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0xFFFF0000);
2235a2b0a27dSPhilippe Mathieu-Daudé         tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFFFF0000);
2236a2b0a27dSPhilippe Mathieu-Daudé         if (opc == OPC_MXU_D16MAX) {
2237fc34c76fSSiarhei Volkau             tcg_gen_smax_i32(t2, t0, t1);
2238a2b0a27dSPhilippe Mathieu-Daudé         } else {
2239fc34c76fSSiarhei Volkau             tcg_gen_smin_i32(t2, t0, t1);
2240a2b0a27dSPhilippe Mathieu-Daudé         }
2241a2b0a27dSPhilippe Mathieu-Daudé 
2242a2b0a27dSPhilippe Mathieu-Daudé         /* the right half-word */
2243a2b0a27dSPhilippe Mathieu-Daudé         tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0x0000FFFF);
2244a2b0a27dSPhilippe Mathieu-Daudé         tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0x0000FFFF);
2245a2b0a27dSPhilippe Mathieu-Daudé         /* move half-words to the leftmost position */
2246a2b0a27dSPhilippe Mathieu-Daudé         tcg_gen_shli_i32(t0, t0, 16);
2247a2b0a27dSPhilippe Mathieu-Daudé         tcg_gen_shli_i32(t1, t1, 16);
2248a2b0a27dSPhilippe Mathieu-Daudé         /* t0 will be max/min of t0 and t1 */
2249a2b0a27dSPhilippe Mathieu-Daudé         if (opc == OPC_MXU_D16MAX) {
2250a2b0a27dSPhilippe Mathieu-Daudé             tcg_gen_smax_i32(t0, t0, t1);
2251a2b0a27dSPhilippe Mathieu-Daudé         } else {
2252a2b0a27dSPhilippe Mathieu-Daudé             tcg_gen_smin_i32(t0, t0, t1);
2253a2b0a27dSPhilippe Mathieu-Daudé         }
2254a2b0a27dSPhilippe Mathieu-Daudé         /* return resulting half-words to its original position */
2255a2b0a27dSPhilippe Mathieu-Daudé         tcg_gen_shri_i32(t0, t0, 16);
2256a2b0a27dSPhilippe Mathieu-Daudé         /* finally update the destination */
2257fc34c76fSSiarhei Volkau         tcg_gen_or_i32(mxu_gpr[XRa - 1], t2, t0);
2258a2b0a27dSPhilippe Mathieu-Daudé     }
2259a2b0a27dSPhilippe Mathieu-Daudé }
2260a2b0a27dSPhilippe Mathieu-Daudé 
2261a2b0a27dSPhilippe Mathieu-Daudé /*
2262a2b0a27dSPhilippe Mathieu-Daudé  *  Q8MAX
2263a2b0a27dSPhilippe Mathieu-Daudé  *    Update XRa with the 8-bit-wise maximums of signed integers
2264a2b0a27dSPhilippe Mathieu-Daudé  *    contained in XRb and XRc.
2265a2b0a27dSPhilippe Mathieu-Daudé  *
2266a2b0a27dSPhilippe Mathieu-Daudé  *  Q8MIN
2267a2b0a27dSPhilippe Mathieu-Daudé  *    Update XRa with the 8-bit-wise minimums of signed integers
2268a2b0a27dSPhilippe Mathieu-Daudé  *    contained in XRb and XRc.
2269a2b0a27dSPhilippe Mathieu-Daudé  */
gen_mxu_Q8MAX_Q8MIN(DisasContext * ctx)2270a2b0a27dSPhilippe Mathieu-Daudé static void gen_mxu_Q8MAX_Q8MIN(DisasContext *ctx)
2271a2b0a27dSPhilippe Mathieu-Daudé {
2272a2b0a27dSPhilippe Mathieu-Daudé     uint32_t pad, opc, XRc, XRb, XRa;
2273a2b0a27dSPhilippe Mathieu-Daudé 
2274a2b0a27dSPhilippe Mathieu-Daudé     pad = extract32(ctx->opcode, 21, 5);
2275a2b0a27dSPhilippe Mathieu-Daudé     opc = extract32(ctx->opcode, 18, 3);
2276a2b0a27dSPhilippe Mathieu-Daudé     XRc = extract32(ctx->opcode, 14, 4);
2277a2b0a27dSPhilippe Mathieu-Daudé     XRb = extract32(ctx->opcode, 10, 4);
2278a2b0a27dSPhilippe Mathieu-Daudé     XRa = extract32(ctx->opcode,  6, 4);
2279a2b0a27dSPhilippe Mathieu-Daudé 
2280a2b0a27dSPhilippe Mathieu-Daudé     if (unlikely(pad != 0)) {
2281a2b0a27dSPhilippe Mathieu-Daudé         /* opcode padding incorrect -> do nothing */
2282a2b0a27dSPhilippe Mathieu-Daudé     } else if (unlikely(XRa == 0)) {
2283a2b0a27dSPhilippe Mathieu-Daudé         /* destination is zero register -> do nothing */
2284a2b0a27dSPhilippe Mathieu-Daudé     } else if (unlikely((XRb == 0) && (XRc == 0))) {
2285a2b0a27dSPhilippe Mathieu-Daudé         /* both operands zero registers -> just set destination to zero */
2286a2b0a27dSPhilippe Mathieu-Daudé         tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
2287a2b0a27dSPhilippe Mathieu-Daudé     } else if (unlikely((XRb == 0) || (XRc == 0))) {
2288a2b0a27dSPhilippe Mathieu-Daudé         /* exactly one operand is zero register - make it be the first...*/
2289a2b0a27dSPhilippe Mathieu-Daudé         uint32_t XRx = XRb ? XRb : XRc;
2290a2b0a27dSPhilippe Mathieu-Daudé         /* ...and do byte-wise max/min with one operand 0 */
2291a2b0a27dSPhilippe Mathieu-Daudé         TCGv_i32 t0 = tcg_temp_new();
2292c29e79afSRichard Henderson         TCGv_i32 t1 = tcg_constant_i32(0);
2293fc34c76fSSiarhei Volkau         TCGv_i32 t2 = tcg_temp_new();
2294a2b0a27dSPhilippe Mathieu-Daudé         int32_t i;
2295a2b0a27dSPhilippe Mathieu-Daudé 
2296a2b0a27dSPhilippe Mathieu-Daudé         /* the leftmost byte (byte 3) first */
2297a2b0a27dSPhilippe Mathieu-Daudé         tcg_gen_andi_i32(t0, mxu_gpr[XRx - 1], 0xFF000000);
2298a2b0a27dSPhilippe Mathieu-Daudé         if (opc == OPC_MXU_Q8MAX) {
2299fc34c76fSSiarhei Volkau             tcg_gen_smax_i32(t2, t0, t1);
2300a2b0a27dSPhilippe Mathieu-Daudé         } else {
2301fc34c76fSSiarhei Volkau             tcg_gen_smin_i32(t2, t0, t1);
2302a2b0a27dSPhilippe Mathieu-Daudé         }
2303a2b0a27dSPhilippe Mathieu-Daudé 
2304a2b0a27dSPhilippe Mathieu-Daudé         /* bytes 2, 1, 0 */
2305a2b0a27dSPhilippe Mathieu-Daudé         for (i = 2; i >= 0; i--) {
2306a2b0a27dSPhilippe Mathieu-Daudé             /* extract the byte */
2307a2b0a27dSPhilippe Mathieu-Daudé             tcg_gen_andi_i32(t0, mxu_gpr[XRx - 1], 0xFF << (8 * i));
2308a2b0a27dSPhilippe Mathieu-Daudé             /* move the byte to the leftmost position */
2309a2b0a27dSPhilippe Mathieu-Daudé             tcg_gen_shli_i32(t0, t0, 8 * (3 - i));
2310a2b0a27dSPhilippe Mathieu-Daudé             /* t0 will be max/min of t0 and t1 */
2311a2b0a27dSPhilippe Mathieu-Daudé             if (opc == OPC_MXU_Q8MAX) {
2312a2b0a27dSPhilippe Mathieu-Daudé                 tcg_gen_smax_i32(t0, t0, t1);
2313a2b0a27dSPhilippe Mathieu-Daudé             } else {
2314a2b0a27dSPhilippe Mathieu-Daudé                 tcg_gen_smin_i32(t0, t0, t1);
2315a2b0a27dSPhilippe Mathieu-Daudé             }
2316a2b0a27dSPhilippe Mathieu-Daudé             /* return resulting byte to its original position */
2317a2b0a27dSPhilippe Mathieu-Daudé             tcg_gen_shri_i32(t0, t0, 8 * (3 - i));
2318a2b0a27dSPhilippe Mathieu-Daudé             /* finally update the destination */
2319fc34c76fSSiarhei Volkau             tcg_gen_or_i32(t2, t2, t0);
2320a2b0a27dSPhilippe Mathieu-Daudé         }
2321fc34c76fSSiarhei Volkau         gen_store_mxu_gpr(t2, XRa);
2322a2b0a27dSPhilippe Mathieu-Daudé     } else if (unlikely(XRb == XRc)) {
2323a2b0a27dSPhilippe Mathieu-Daudé         /* both operands same -> just set destination to one of them */
2324a2b0a27dSPhilippe Mathieu-Daudé         tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
2325a2b0a27dSPhilippe Mathieu-Daudé     } else {
2326a2b0a27dSPhilippe Mathieu-Daudé         /* the most general case */
2327a2b0a27dSPhilippe Mathieu-Daudé         TCGv_i32 t0 = tcg_temp_new();
2328a2b0a27dSPhilippe Mathieu-Daudé         TCGv_i32 t1 = tcg_temp_new();
2329fc34c76fSSiarhei Volkau         TCGv_i32 t2 = tcg_temp_new();
2330a2b0a27dSPhilippe Mathieu-Daudé         int32_t i;
2331a2b0a27dSPhilippe Mathieu-Daudé 
2332a2b0a27dSPhilippe Mathieu-Daudé         /* the leftmost bytes (bytes 3) first */
2333a2b0a27dSPhilippe Mathieu-Daudé         tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0xFF000000);
2334a2b0a27dSPhilippe Mathieu-Daudé         tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFF000000);
2335a2b0a27dSPhilippe Mathieu-Daudé         if (opc == OPC_MXU_Q8MAX) {
2336fc34c76fSSiarhei Volkau             tcg_gen_smax_i32(t2, t0, t1);
2337a2b0a27dSPhilippe Mathieu-Daudé         } else {
2338fc34c76fSSiarhei Volkau             tcg_gen_smin_i32(t2, t0, t1);
2339a2b0a27dSPhilippe Mathieu-Daudé         }
2340a2b0a27dSPhilippe Mathieu-Daudé 
2341a2b0a27dSPhilippe Mathieu-Daudé         /* bytes 2, 1, 0 */
2342a2b0a27dSPhilippe Mathieu-Daudé         for (i = 2; i >= 0; i--) {
2343a2b0a27dSPhilippe Mathieu-Daudé             /* extract corresponding bytes */
2344a2b0a27dSPhilippe Mathieu-Daudé             tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0xFF << (8 * i));
2345a2b0a27dSPhilippe Mathieu-Daudé             tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFF << (8 * i));
2346a2b0a27dSPhilippe Mathieu-Daudé             /* move the bytes to the leftmost position */
2347a2b0a27dSPhilippe Mathieu-Daudé             tcg_gen_shli_i32(t0, t0, 8 * (3 - i));
2348a2b0a27dSPhilippe Mathieu-Daudé             tcg_gen_shli_i32(t1, t1, 8 * (3 - i));
2349a2b0a27dSPhilippe Mathieu-Daudé             /* t0 will be max/min of t0 and t1 */
2350a2b0a27dSPhilippe Mathieu-Daudé             if (opc == OPC_MXU_Q8MAX) {
2351a2b0a27dSPhilippe Mathieu-Daudé                 tcg_gen_smax_i32(t0, t0, t1);
2352a2b0a27dSPhilippe Mathieu-Daudé             } else {
2353a2b0a27dSPhilippe Mathieu-Daudé                 tcg_gen_smin_i32(t0, t0, t1);
2354a2b0a27dSPhilippe Mathieu-Daudé             }
2355a2b0a27dSPhilippe Mathieu-Daudé             /* return resulting byte to its original position */
2356a2b0a27dSPhilippe Mathieu-Daudé             tcg_gen_shri_i32(t0, t0, 8 * (3 - i));
2357a2b0a27dSPhilippe Mathieu-Daudé             /* finally update the destination */
2358fc34c76fSSiarhei Volkau             tcg_gen_or_i32(t2, t2, t0);
2359a2b0a27dSPhilippe Mathieu-Daudé         }
2360fc34c76fSSiarhei Volkau         gen_store_mxu_gpr(t2, XRa);
2361a2b0a27dSPhilippe Mathieu-Daudé     }
2362a2b0a27dSPhilippe Mathieu-Daudé }
2363a2b0a27dSPhilippe Mathieu-Daudé 
23644051f035SSiarhei Volkau /*
23654051f035SSiarhei Volkau  *  Q8SLT
23664051f035SSiarhei Volkau  *    Update XRa with the signed "set less than" comparison of XRb and XRc
23674051f035SSiarhei Volkau  *    on per-byte basis.
23684051f035SSiarhei Volkau  *    a.k.a. XRa[0..3] = XRb[0..3] < XRc[0..3] ? 1 : 0;
23694051f035SSiarhei Volkau  *
23704051f035SSiarhei Volkau  *  Q8SLTU
23714051f035SSiarhei Volkau  *    Update XRa with the unsigned "set less than" comparison of XRb and XRc
23724051f035SSiarhei Volkau  *    on per-byte basis.
23734051f035SSiarhei Volkau  *    a.k.a. XRa[0..3] = XRb[0..3] < XRc[0..3] ? 1 : 0;
23744051f035SSiarhei Volkau  */
gen_mxu_q8slt(DisasContext * ctx,bool sltu)23754051f035SSiarhei Volkau static void gen_mxu_q8slt(DisasContext *ctx, bool sltu)
23764051f035SSiarhei Volkau {
23774051f035SSiarhei Volkau     uint32_t pad, XRc, XRb, XRa;
23784051f035SSiarhei Volkau 
23794051f035SSiarhei Volkau     pad = extract32(ctx->opcode, 21, 5);
23804051f035SSiarhei Volkau     XRc = extract32(ctx->opcode, 14, 4);
23814051f035SSiarhei Volkau     XRb = extract32(ctx->opcode, 10, 4);
23824051f035SSiarhei Volkau     XRa = extract32(ctx->opcode,  6, 4);
23834051f035SSiarhei Volkau 
23844051f035SSiarhei Volkau     if (unlikely(pad != 0)) {
23854051f035SSiarhei Volkau         /* opcode padding incorrect -> do nothing */
23864051f035SSiarhei Volkau     } else if (unlikely(XRa == 0)) {
23874051f035SSiarhei Volkau         /* destination is zero register -> do nothing */
23884051f035SSiarhei Volkau     } else if (unlikely((XRb == 0) && (XRc == 0))) {
23894051f035SSiarhei Volkau         /* both operands zero registers -> just set destination to zero */
23904051f035SSiarhei Volkau         tcg_gen_movi_tl(mxu_gpr[XRa - 1], 0);
23914051f035SSiarhei Volkau     } else if (unlikely(XRb == XRc)) {
23924051f035SSiarhei Volkau         /* both operands same registers -> just set destination to zero */
23934051f035SSiarhei Volkau         tcg_gen_movi_tl(mxu_gpr[XRa - 1], 0);
23944051f035SSiarhei Volkau     } else {
23954051f035SSiarhei Volkau         /* the most general case */
23964051f035SSiarhei Volkau         TCGv t0 = tcg_temp_new();
23974051f035SSiarhei Volkau         TCGv t1 = tcg_temp_new();
23984051f035SSiarhei Volkau         TCGv t2 = tcg_temp_new();
23994051f035SSiarhei Volkau         TCGv t3 = tcg_temp_new();
24004051f035SSiarhei Volkau         TCGv t4 = tcg_temp_new();
24014051f035SSiarhei Volkau 
24024051f035SSiarhei Volkau         gen_load_mxu_gpr(t3, XRb);
24034051f035SSiarhei Volkau         gen_load_mxu_gpr(t4, XRc);
24044051f035SSiarhei Volkau         tcg_gen_movi_tl(t2, 0);
24054051f035SSiarhei Volkau 
24064051f035SSiarhei Volkau         for (int i = 0; i < 4; i++) {
24074051f035SSiarhei Volkau             if (sltu) {
24084051f035SSiarhei Volkau                 tcg_gen_extract_tl(t0, t3, 8 * i, 8);
24094051f035SSiarhei Volkau                 tcg_gen_extract_tl(t1, t4, 8 * i, 8);
24104051f035SSiarhei Volkau             } else {
24114051f035SSiarhei Volkau                 tcg_gen_sextract_tl(t0, t3, 8 * i, 8);
24124051f035SSiarhei Volkau                 tcg_gen_sextract_tl(t1, t4, 8 * i, 8);
24134051f035SSiarhei Volkau             }
24144051f035SSiarhei Volkau             tcg_gen_setcond_tl(TCG_COND_LT, t0, t0, t1);
24154051f035SSiarhei Volkau             tcg_gen_deposit_tl(t2, t2, t0, 8 * i, 8);
24164051f035SSiarhei Volkau         }
24174051f035SSiarhei Volkau         gen_store_mxu_gpr(t2, XRa);
24184051f035SSiarhei Volkau     }
24194051f035SSiarhei Volkau }
24204051f035SSiarhei Volkau 
2421ff7936f0SSiarhei Volkau /*
2422ff7936f0SSiarhei Volkau  *  S32SLT
2423ff7936f0SSiarhei Volkau  *    Update XRa with the signed "set less than" comparison of XRb and XRc.
2424ff7936f0SSiarhei Volkau  *    a.k.a. XRa = XRb < XRc ? 1 : 0;
2425ff7936f0SSiarhei Volkau  */
gen_mxu_S32SLT(DisasContext * ctx)2426ff7936f0SSiarhei Volkau static void gen_mxu_S32SLT(DisasContext *ctx)
2427ff7936f0SSiarhei Volkau {
2428ff7936f0SSiarhei Volkau     uint32_t pad, XRc, XRb, XRa;
2429ff7936f0SSiarhei Volkau 
2430ff7936f0SSiarhei Volkau     pad = extract32(ctx->opcode, 21, 5);
2431ff7936f0SSiarhei Volkau     XRc = extract32(ctx->opcode, 14, 4);
2432ff7936f0SSiarhei Volkau     XRb = extract32(ctx->opcode, 10, 4);
2433ff7936f0SSiarhei Volkau     XRa = extract32(ctx->opcode,  6, 4);
2434ff7936f0SSiarhei Volkau 
2435ff7936f0SSiarhei Volkau     if (unlikely(pad != 0)) {
2436ff7936f0SSiarhei Volkau         /* opcode padding incorrect -> do nothing */
2437ff7936f0SSiarhei Volkau     } else if (unlikely(XRa == 0)) {
2438ff7936f0SSiarhei Volkau         /* destination is zero register -> do nothing */
2439ff7936f0SSiarhei Volkau     } else if (unlikely((XRb == 0) && (XRc == 0))) {
2440ff7936f0SSiarhei Volkau         /* both operands zero registers -> just set destination to zero */
2441ff7936f0SSiarhei Volkau         tcg_gen_movi_tl(mxu_gpr[XRa - 1], 0);
2442ff7936f0SSiarhei Volkau     } else if (unlikely(XRb == XRc)) {
2443ff7936f0SSiarhei Volkau         /* both operands same registers -> just set destination to zero */
2444ff7936f0SSiarhei Volkau         tcg_gen_movi_tl(mxu_gpr[XRa - 1], 0);
2445ff7936f0SSiarhei Volkau     } else {
2446ff7936f0SSiarhei Volkau         /* the most general case */
2447e37fdc73SPhilippe Mathieu-Daudé         TCGv t0 = tcg_temp_new();
2448e37fdc73SPhilippe Mathieu-Daudé         TCGv t1 = tcg_temp_new();
2449e37fdc73SPhilippe Mathieu-Daudé 
2450e37fdc73SPhilippe Mathieu-Daudé         gen_load_mxu_gpr(t0, XRb);
2451e37fdc73SPhilippe Mathieu-Daudé         gen_load_mxu_gpr(t1, XRc);
2452e37fdc73SPhilippe Mathieu-Daudé         tcg_gen_setcond_tl(TCG_COND_LT, mxu_gpr[XRa - 1], t0, t1);
2453ff7936f0SSiarhei Volkau     }
2454ff7936f0SSiarhei Volkau }
2455ff7936f0SSiarhei Volkau 
2456ff7936f0SSiarhei Volkau /*
2457ff7936f0SSiarhei Volkau  *  D16SLT
2458ff7936f0SSiarhei Volkau  *    Update XRa with the signed "set less than" comparison of XRb and XRc
2459ff7936f0SSiarhei Volkau  *    on per-word basis.
2460ff7936f0SSiarhei Volkau  *    a.k.a. XRa[0..1] = XRb[0..1] < XRc[0..1] ? 1 : 0;
2461ff7936f0SSiarhei Volkau  */
gen_mxu_D16SLT(DisasContext * ctx)2462ff7936f0SSiarhei Volkau static void gen_mxu_D16SLT(DisasContext *ctx)
2463ff7936f0SSiarhei Volkau {
2464ff7936f0SSiarhei Volkau     uint32_t pad, XRc, XRb, XRa;
2465ff7936f0SSiarhei Volkau 
2466ff7936f0SSiarhei Volkau     pad = extract32(ctx->opcode, 21, 5);
2467ff7936f0SSiarhei Volkau     XRc = extract32(ctx->opcode, 14, 4);
2468ff7936f0SSiarhei Volkau     XRb = extract32(ctx->opcode, 10, 4);
2469ff7936f0SSiarhei Volkau     XRa = extract32(ctx->opcode,  6, 4);
2470ff7936f0SSiarhei Volkau 
2471ff7936f0SSiarhei Volkau     if (unlikely(pad != 0)) {
2472ff7936f0SSiarhei Volkau         /* opcode padding incorrect -> do nothing */
2473ff7936f0SSiarhei Volkau     } else if (unlikely(XRa == 0)) {
2474ff7936f0SSiarhei Volkau         /* destination is zero register -> do nothing */
2475ff7936f0SSiarhei Volkau     } else if (unlikely((XRb == 0) && (XRc == 0))) {
2476ff7936f0SSiarhei Volkau         /* both operands zero registers -> just set destination to zero */
2477ff7936f0SSiarhei Volkau         tcg_gen_movi_tl(mxu_gpr[XRa - 1], 0);
2478ff7936f0SSiarhei Volkau     } else if (unlikely(XRb == XRc)) {
2479ff7936f0SSiarhei Volkau         /* both operands same registers -> just set destination to zero */
2480ff7936f0SSiarhei Volkau         tcg_gen_movi_tl(mxu_gpr[XRa - 1], 0);
2481ff7936f0SSiarhei Volkau     } else {
2482ff7936f0SSiarhei Volkau         /* the most general case */
2483ff7936f0SSiarhei Volkau         TCGv t0 = tcg_temp_new();
2484ff7936f0SSiarhei Volkau         TCGv t1 = tcg_temp_new();
2485ff7936f0SSiarhei Volkau         TCGv t2 = tcg_temp_new();
2486ff7936f0SSiarhei Volkau         TCGv t3 = tcg_temp_new();
2487ff7936f0SSiarhei Volkau         TCGv t4 = tcg_temp_new();
2488ff7936f0SSiarhei Volkau 
2489ff7936f0SSiarhei Volkau         gen_load_mxu_gpr(t3, XRb);
2490ff7936f0SSiarhei Volkau         gen_load_mxu_gpr(t4, XRc);
2491ff7936f0SSiarhei Volkau         tcg_gen_sextract_tl(t0, t3, 16, 16);
2492ff7936f0SSiarhei Volkau         tcg_gen_sextract_tl(t1, t4, 16, 16);
2493ff7936f0SSiarhei Volkau         tcg_gen_setcond_tl(TCG_COND_LT, t0, t0, t1);
2494ff7936f0SSiarhei Volkau         tcg_gen_shli_tl(t2, t0, 16);
2495ff7936f0SSiarhei Volkau         tcg_gen_sextract_tl(t0, t3,  0, 16);
2496ff7936f0SSiarhei Volkau         tcg_gen_sextract_tl(t1, t4,  0, 16);
2497ff7936f0SSiarhei Volkau         tcg_gen_setcond_tl(TCG_COND_LT, t0, t0, t1);
2498ff7936f0SSiarhei Volkau         tcg_gen_or_tl(mxu_gpr[XRa - 1], t2, t0);
2499ff7936f0SSiarhei Volkau     }
2500ff7936f0SSiarhei Volkau }
2501ff7936f0SSiarhei Volkau 
2502ff7936f0SSiarhei Volkau /*
2503ff7936f0SSiarhei Volkau  *  D16AVG
2504ff7936f0SSiarhei Volkau  *    Update XRa with the signed average of XRb and XRc
2505ff7936f0SSiarhei Volkau  *    on per-word basis, rounding down.
2506ff7936f0SSiarhei Volkau  *    a.k.a. XRa[0..1] = (XRb[0..1] + XRc[0..1]) >> 1;
2507ff7936f0SSiarhei Volkau  *
2508ff7936f0SSiarhei Volkau  *  D16AVGR
2509ff7936f0SSiarhei Volkau  *    Update XRa with the signed average of XRb and XRc
2510ff7936f0SSiarhei Volkau  *    on per-word basis, math rounding 4/5.
2511ff7936f0SSiarhei Volkau  *    a.k.a. XRa[0..1] = (XRb[0..1] + XRc[0..1] + 1) >> 1;
2512ff7936f0SSiarhei Volkau  */
gen_mxu_d16avg(DisasContext * ctx,bool round45)2513ff7936f0SSiarhei Volkau static void gen_mxu_d16avg(DisasContext *ctx, bool round45)
2514ff7936f0SSiarhei Volkau {
2515ff7936f0SSiarhei Volkau     uint32_t pad, XRc, XRb, XRa;
2516ff7936f0SSiarhei Volkau 
2517ff7936f0SSiarhei Volkau     pad = extract32(ctx->opcode, 21, 5);
2518ff7936f0SSiarhei Volkau     XRc = extract32(ctx->opcode, 14, 4);
2519ff7936f0SSiarhei Volkau     XRb = extract32(ctx->opcode, 10, 4);
2520ff7936f0SSiarhei Volkau     XRa = extract32(ctx->opcode,  6, 4);
2521ff7936f0SSiarhei Volkau 
2522ff7936f0SSiarhei Volkau     if (unlikely(pad != 0)) {
2523ff7936f0SSiarhei Volkau         /* opcode padding incorrect -> do nothing */
2524ff7936f0SSiarhei Volkau     } else if (unlikely(XRa == 0)) {
2525ff7936f0SSiarhei Volkau         /* destination is zero register -> do nothing */
2526ff7936f0SSiarhei Volkau     } else if (unlikely((XRb == 0) && (XRc == 0))) {
2527ff7936f0SSiarhei Volkau         /* both operands zero registers -> just set destination to zero */
2528ff7936f0SSiarhei Volkau         tcg_gen_movi_tl(mxu_gpr[XRa - 1], 0);
2529ff7936f0SSiarhei Volkau     } else if (unlikely(XRb == XRc)) {
2530ff7936f0SSiarhei Volkau         /* both operands same registers -> just set destination to same */
2531ff7936f0SSiarhei Volkau         tcg_gen_mov_tl(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
2532ff7936f0SSiarhei Volkau     } else {
2533ff7936f0SSiarhei Volkau         /* the most general case */
2534ff7936f0SSiarhei Volkau         TCGv t0 = tcg_temp_new();
2535ff7936f0SSiarhei Volkau         TCGv t1 = tcg_temp_new();
2536ff7936f0SSiarhei Volkau         TCGv t2 = tcg_temp_new();
2537ff7936f0SSiarhei Volkau         TCGv t3 = tcg_temp_new();
2538ff7936f0SSiarhei Volkau         TCGv t4 = tcg_temp_new();
2539ff7936f0SSiarhei Volkau 
2540ff7936f0SSiarhei Volkau         gen_load_mxu_gpr(t3, XRb);
2541ff7936f0SSiarhei Volkau         gen_load_mxu_gpr(t4, XRc);
2542ff7936f0SSiarhei Volkau         tcg_gen_sextract_tl(t0, t3, 16, 16);
2543ff7936f0SSiarhei Volkau         tcg_gen_sextract_tl(t1, t4, 16, 16);
2544ff7936f0SSiarhei Volkau         tcg_gen_add_tl(t0, t0, t1);
2545ff7936f0SSiarhei Volkau         if (round45) {
2546ff7936f0SSiarhei Volkau             tcg_gen_addi_tl(t0, t0, 1);
2547ff7936f0SSiarhei Volkau         }
2548ff7936f0SSiarhei Volkau         tcg_gen_shli_tl(t2, t0, 15);
2549ff7936f0SSiarhei Volkau         tcg_gen_andi_tl(t2, t2, 0xffff0000);
2550ff7936f0SSiarhei Volkau         tcg_gen_sextract_tl(t0, t3,  0, 16);
2551ff7936f0SSiarhei Volkau         tcg_gen_sextract_tl(t1, t4,  0, 16);
2552ff7936f0SSiarhei Volkau         tcg_gen_add_tl(t0, t0, t1);
2553ff7936f0SSiarhei Volkau         if (round45) {
2554ff7936f0SSiarhei Volkau             tcg_gen_addi_tl(t0, t0, 1);
2555ff7936f0SSiarhei Volkau         }
2556ff7936f0SSiarhei Volkau         tcg_gen_shri_tl(t0, t0, 1);
2557ff7936f0SSiarhei Volkau         tcg_gen_deposit_tl(t2, t2, t0, 0, 16);
2558ff7936f0SSiarhei Volkau         gen_store_mxu_gpr(t2, XRa);
2559ff7936f0SSiarhei Volkau     }
2560ff7936f0SSiarhei Volkau }
2561ff7936f0SSiarhei Volkau 
2562ff7936f0SSiarhei Volkau /*
2563ff7936f0SSiarhei Volkau  *  Q8AVG
2564ff7936f0SSiarhei Volkau  *    Update XRa with the signed average of XRb and XRc
2565ff7936f0SSiarhei Volkau  *    on per-byte basis, rounding down.
2566ff7936f0SSiarhei Volkau  *    a.k.a. XRa[0..3] = (XRb[0..3] + XRc[0..3]) >> 1;
2567ff7936f0SSiarhei Volkau  *
2568ff7936f0SSiarhei Volkau  *  Q8AVGR
2569ff7936f0SSiarhei Volkau  *    Update XRa with the signed average of XRb and XRc
2570ff7936f0SSiarhei Volkau  *    on per-word basis, math rounding 4/5.
2571ff7936f0SSiarhei Volkau  *    a.k.a. XRa[0..3] = (XRb[0..3] + XRc[0..3] + 1) >> 1;
2572ff7936f0SSiarhei Volkau  */
gen_mxu_q8avg(DisasContext * ctx,bool round45)2573ff7936f0SSiarhei Volkau static void gen_mxu_q8avg(DisasContext *ctx, bool round45)
2574ff7936f0SSiarhei Volkau {
2575ff7936f0SSiarhei Volkau     uint32_t pad, XRc, XRb, XRa;
2576ff7936f0SSiarhei Volkau 
2577ff7936f0SSiarhei Volkau     pad = extract32(ctx->opcode, 21, 5);
2578ff7936f0SSiarhei Volkau     XRc = extract32(ctx->opcode, 14, 4);
2579ff7936f0SSiarhei Volkau     XRb = extract32(ctx->opcode, 10, 4);
2580ff7936f0SSiarhei Volkau     XRa = extract32(ctx->opcode,  6, 4);
2581ff7936f0SSiarhei Volkau 
2582ff7936f0SSiarhei Volkau     if (unlikely(pad != 0)) {
2583ff7936f0SSiarhei Volkau         /* opcode padding incorrect -> do nothing */
2584ff7936f0SSiarhei Volkau     } else if (unlikely(XRa == 0)) {
2585ff7936f0SSiarhei Volkau         /* destination is zero register -> do nothing */
2586ff7936f0SSiarhei Volkau     } else if (unlikely((XRb == 0) && (XRc == 0))) {
2587ff7936f0SSiarhei Volkau         /* both operands zero registers -> just set destination to zero */
2588ff7936f0SSiarhei Volkau         tcg_gen_movi_tl(mxu_gpr[XRa - 1], 0);
2589ff7936f0SSiarhei Volkau     } else if (unlikely(XRb == XRc)) {
2590ff7936f0SSiarhei Volkau         /* both operands same registers -> just set destination to same */
2591ff7936f0SSiarhei Volkau         tcg_gen_mov_tl(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
2592ff7936f0SSiarhei Volkau     } else {
2593ff7936f0SSiarhei Volkau         /* the most general case */
2594ff7936f0SSiarhei Volkau         TCGv t0 = tcg_temp_new();
2595ff7936f0SSiarhei Volkau         TCGv t1 = tcg_temp_new();
2596ff7936f0SSiarhei Volkau         TCGv t2 = tcg_temp_new();
2597ff7936f0SSiarhei Volkau         TCGv t3 = tcg_temp_new();
2598ff7936f0SSiarhei Volkau         TCGv t4 = tcg_temp_new();
2599ff7936f0SSiarhei Volkau 
2600ff7936f0SSiarhei Volkau         gen_load_mxu_gpr(t3, XRb);
2601ff7936f0SSiarhei Volkau         gen_load_mxu_gpr(t4, XRc);
2602ff7936f0SSiarhei Volkau         tcg_gen_movi_tl(t2, 0);
2603ff7936f0SSiarhei Volkau 
2604ff7936f0SSiarhei Volkau         for (int i = 0; i < 4; i++) {
2605ff7936f0SSiarhei Volkau             tcg_gen_extract_tl(t0, t3, 8 * i, 8);
2606ff7936f0SSiarhei Volkau             tcg_gen_extract_tl(t1, t4, 8 * i, 8);
2607ff7936f0SSiarhei Volkau             tcg_gen_add_tl(t0, t0, t1);
2608ff7936f0SSiarhei Volkau             if (round45) {
2609ff7936f0SSiarhei Volkau                 tcg_gen_addi_tl(t0, t0, 1);
2610ff7936f0SSiarhei Volkau             }
2611ff7936f0SSiarhei Volkau             tcg_gen_shri_tl(t0, t0, 1);
2612ff7936f0SSiarhei Volkau             tcg_gen_deposit_tl(t2, t2, t0, 8 * i, 8);
2613ff7936f0SSiarhei Volkau         }
2614ff7936f0SSiarhei Volkau         gen_store_mxu_gpr(t2, XRa);
2615ff7936f0SSiarhei Volkau     }
2616ff7936f0SSiarhei Volkau }
2617ff7936f0SSiarhei Volkau 
2618d1b6ded4SSiarhei Volkau /*
2619d1b6ded4SSiarhei Volkau  *  Q8MOVZ
2620d1b6ded4SSiarhei Volkau  *    Quadruple 8-bit packed conditional move where
2621d1b6ded4SSiarhei Volkau  *    XRb contains conditions, XRc what to move and
2622d1b6ded4SSiarhei Volkau  *    XRa is the destination.
2623d1b6ded4SSiarhei Volkau  *    a.k.a. if (XRb[0..3] == 0) { XRa[0..3] = XRc[0..3] }
2624d1b6ded4SSiarhei Volkau  *
2625d1b6ded4SSiarhei Volkau  *  Q8MOVN
2626d1b6ded4SSiarhei Volkau  *    Quadruple 8-bit packed conditional move where
2627d1b6ded4SSiarhei Volkau  *    XRb contains conditions, XRc what to move and
2628d1b6ded4SSiarhei Volkau  *    XRa is the destination.
2629d1b6ded4SSiarhei Volkau  *    a.k.a. if (XRb[0..3] != 0) { XRa[0..3] = XRc[0..3] }
2630d1b6ded4SSiarhei Volkau  */
gen_mxu_q8movzn(DisasContext * ctx,TCGCond cond)2631d1b6ded4SSiarhei Volkau static void gen_mxu_q8movzn(DisasContext *ctx, TCGCond cond)
2632d1b6ded4SSiarhei Volkau {
2633d1b6ded4SSiarhei Volkau     uint32_t XRc, XRb, XRa;
2634d1b6ded4SSiarhei Volkau 
2635d1b6ded4SSiarhei Volkau     XRa = extract32(ctx->opcode,  6, 4);
2636d1b6ded4SSiarhei Volkau     XRb = extract32(ctx->opcode, 10, 4);
2637d1b6ded4SSiarhei Volkau     XRc = extract32(ctx->opcode, 14, 4);
2638d1b6ded4SSiarhei Volkau 
2639d1b6ded4SSiarhei Volkau     TCGv t0 = tcg_temp_new();
2640d1b6ded4SSiarhei Volkau     TCGv t1 = tcg_temp_new();
2641d1b6ded4SSiarhei Volkau     TCGv t2 = tcg_temp_new();
2642d1b6ded4SSiarhei Volkau     TCGv t3 = tcg_temp_new();
2643d1b6ded4SSiarhei Volkau     TCGLabel *l_quarterdone = gen_new_label();
2644d1b6ded4SSiarhei Volkau     TCGLabel *l_halfdone = gen_new_label();
2645d1b6ded4SSiarhei Volkau     TCGLabel *l_quarterrest = gen_new_label();
2646d1b6ded4SSiarhei Volkau     TCGLabel *l_done = gen_new_label();
2647d1b6ded4SSiarhei Volkau 
2648d1b6ded4SSiarhei Volkau     gen_load_mxu_gpr(t0, XRc);
2649d1b6ded4SSiarhei Volkau     gen_load_mxu_gpr(t1, XRb);
2650d1b6ded4SSiarhei Volkau     gen_load_mxu_gpr(t2, XRa);
2651d1b6ded4SSiarhei Volkau 
2652d1b6ded4SSiarhei Volkau     tcg_gen_extract_tl(t3, t1, 24, 8);
2653d1b6ded4SSiarhei Volkau     tcg_gen_brcondi_tl(cond, t3, 0, l_quarterdone);
2654d1b6ded4SSiarhei Volkau     tcg_gen_extract_tl(t3, t0, 24, 8);
2655d1b6ded4SSiarhei Volkau     tcg_gen_deposit_tl(t2, t2, t3, 24, 8);
2656d1b6ded4SSiarhei Volkau 
2657d1b6ded4SSiarhei Volkau     gen_set_label(l_quarterdone);
2658d1b6ded4SSiarhei Volkau     tcg_gen_extract_tl(t3, t1, 16, 8);
2659d1b6ded4SSiarhei Volkau     tcg_gen_brcondi_tl(cond, t3, 0, l_halfdone);
2660d1b6ded4SSiarhei Volkau     tcg_gen_extract_tl(t3, t0, 16, 8);
2661d1b6ded4SSiarhei Volkau     tcg_gen_deposit_tl(t2, t2, t3, 16, 8);
2662d1b6ded4SSiarhei Volkau 
2663d1b6ded4SSiarhei Volkau     gen_set_label(l_halfdone);
2664d1b6ded4SSiarhei Volkau     tcg_gen_extract_tl(t3, t1, 8, 8);
2665d1b6ded4SSiarhei Volkau     tcg_gen_brcondi_tl(cond, t3, 0, l_quarterrest);
2666d1b6ded4SSiarhei Volkau     tcg_gen_extract_tl(t3, t0, 8, 8);
2667d1b6ded4SSiarhei Volkau     tcg_gen_deposit_tl(t2, t2, t3, 8, 8);
2668d1b6ded4SSiarhei Volkau 
2669d1b6ded4SSiarhei Volkau     gen_set_label(l_quarterrest);
2670d1b6ded4SSiarhei Volkau     tcg_gen_extract_tl(t3, t1, 0, 8);
2671d1b6ded4SSiarhei Volkau     tcg_gen_brcondi_tl(cond, t3, 0, l_done);
2672d1b6ded4SSiarhei Volkau     tcg_gen_extract_tl(t3, t0, 0, 8);
2673d1b6ded4SSiarhei Volkau     tcg_gen_deposit_tl(t2, t2, t3, 0, 8);
2674d1b6ded4SSiarhei Volkau 
2675d1b6ded4SSiarhei Volkau     gen_set_label(l_done);
2676d1b6ded4SSiarhei Volkau     gen_store_mxu_gpr(t2, XRa);
2677d1b6ded4SSiarhei Volkau }
2678d1b6ded4SSiarhei Volkau 
2679d1b6ded4SSiarhei Volkau /*
2680d1b6ded4SSiarhei Volkau  *  D16MOVZ
2681d1b6ded4SSiarhei Volkau  *    Double 16-bit packed conditional move where
2682d1b6ded4SSiarhei Volkau  *    XRb contains conditions, XRc what to move and
2683d1b6ded4SSiarhei Volkau  *    XRa is the destination.
2684d1b6ded4SSiarhei Volkau  *    a.k.a. if (XRb[0..1] == 0) { XRa[0..1] = XRc[0..1] }
2685d1b6ded4SSiarhei Volkau  *
2686d1b6ded4SSiarhei Volkau  *  D16MOVN
2687d1b6ded4SSiarhei Volkau  *    Double 16-bit packed conditional move where
2688d1b6ded4SSiarhei Volkau  *    XRb contains conditions, XRc what to move and
2689d1b6ded4SSiarhei Volkau  *    XRa is the destination.
2690d1b6ded4SSiarhei Volkau  *    a.k.a. if (XRb[0..3] != 0) { XRa[0..1] = XRc[0..1] }
2691d1b6ded4SSiarhei Volkau  */
gen_mxu_d16movzn(DisasContext * ctx,TCGCond cond)2692d1b6ded4SSiarhei Volkau static void gen_mxu_d16movzn(DisasContext *ctx, TCGCond cond)
2693d1b6ded4SSiarhei Volkau {
2694d1b6ded4SSiarhei Volkau     uint32_t XRc, XRb, XRa;
2695d1b6ded4SSiarhei Volkau 
2696d1b6ded4SSiarhei Volkau     XRa = extract32(ctx->opcode,  6, 4);
2697d1b6ded4SSiarhei Volkau     XRb = extract32(ctx->opcode, 10, 4);
2698d1b6ded4SSiarhei Volkau     XRc = extract32(ctx->opcode, 14, 4);
2699d1b6ded4SSiarhei Volkau 
2700d1b6ded4SSiarhei Volkau     TCGv t0 = tcg_temp_new();
2701d1b6ded4SSiarhei Volkau     TCGv t1 = tcg_temp_new();
2702d1b6ded4SSiarhei Volkau     TCGv t2 = tcg_temp_new();
2703d1b6ded4SSiarhei Volkau     TCGv t3 = tcg_temp_new();
2704d1b6ded4SSiarhei Volkau     TCGLabel *l_halfdone = gen_new_label();
2705d1b6ded4SSiarhei Volkau     TCGLabel *l_done = gen_new_label();
2706d1b6ded4SSiarhei Volkau 
2707d1b6ded4SSiarhei Volkau     gen_load_mxu_gpr(t0, XRc);
2708d1b6ded4SSiarhei Volkau     gen_load_mxu_gpr(t1, XRb);
2709d1b6ded4SSiarhei Volkau     gen_load_mxu_gpr(t2, XRa);
2710d1b6ded4SSiarhei Volkau 
2711d1b6ded4SSiarhei Volkau     tcg_gen_extract_tl(t3, t1, 16, 16);
2712d1b6ded4SSiarhei Volkau     tcg_gen_brcondi_tl(cond, t3, 0, l_halfdone);
2713d1b6ded4SSiarhei Volkau     tcg_gen_extract_tl(t3, t0, 16, 16);
2714d1b6ded4SSiarhei Volkau     tcg_gen_deposit_tl(t2, t2, t3, 16, 16);
2715d1b6ded4SSiarhei Volkau 
2716d1b6ded4SSiarhei Volkau     gen_set_label(l_halfdone);
2717d1b6ded4SSiarhei Volkau     tcg_gen_extract_tl(t3, t1, 0, 16);
2718d1b6ded4SSiarhei Volkau     tcg_gen_brcondi_tl(cond, t3, 0, l_done);
2719d1b6ded4SSiarhei Volkau     tcg_gen_extract_tl(t3, t0, 0, 16);
2720d1b6ded4SSiarhei Volkau     tcg_gen_deposit_tl(t2, t2, t3, 0, 16);
2721d1b6ded4SSiarhei Volkau 
2722d1b6ded4SSiarhei Volkau     gen_set_label(l_done);
2723d1b6ded4SSiarhei Volkau     gen_store_mxu_gpr(t2, XRa);
2724d1b6ded4SSiarhei Volkau }
2725d1b6ded4SSiarhei Volkau 
2726d1b6ded4SSiarhei Volkau /*
2727d1b6ded4SSiarhei Volkau  *  S32MOVZ
2728d1b6ded4SSiarhei Volkau  *    Quadruple 32-bit conditional move where
2729d1b6ded4SSiarhei Volkau  *    XRb contains conditions, XRc what to move and
2730d1b6ded4SSiarhei Volkau  *    XRa is the destination.
2731d1b6ded4SSiarhei Volkau  *    a.k.a. if (XRb == 0) { XRa = XRc }
2732d1b6ded4SSiarhei Volkau  *
2733d1b6ded4SSiarhei Volkau  *  S32MOVN
2734d1b6ded4SSiarhei Volkau  *    Single 32-bit conditional move where
2735d1b6ded4SSiarhei Volkau  *    XRb contains conditions, XRc what to move and
2736d1b6ded4SSiarhei Volkau  *    XRa is the destination.
2737d1b6ded4SSiarhei Volkau  *    a.k.a. if (XRb != 0) { XRa = XRc }
2738d1b6ded4SSiarhei Volkau  */
gen_mxu_s32movzn(DisasContext * ctx,TCGCond cond)2739d1b6ded4SSiarhei Volkau static void gen_mxu_s32movzn(DisasContext *ctx, TCGCond cond)
2740d1b6ded4SSiarhei Volkau {
2741d1b6ded4SSiarhei Volkau     uint32_t XRc, XRb, XRa;
2742d1b6ded4SSiarhei Volkau 
2743d1b6ded4SSiarhei Volkau     XRa = extract32(ctx->opcode,  6, 4);
2744d1b6ded4SSiarhei Volkau     XRb = extract32(ctx->opcode, 10, 4);
2745d1b6ded4SSiarhei Volkau     XRc = extract32(ctx->opcode, 14, 4);
2746d1b6ded4SSiarhei Volkau 
2747d1b6ded4SSiarhei Volkau     TCGv t0 = tcg_temp_new();
2748d1b6ded4SSiarhei Volkau     TCGv t1 = tcg_temp_new();
2749d1b6ded4SSiarhei Volkau     TCGLabel *l_done = gen_new_label();
2750d1b6ded4SSiarhei Volkau 
2751d1b6ded4SSiarhei Volkau     gen_load_mxu_gpr(t0, XRc);
2752d1b6ded4SSiarhei Volkau     gen_load_mxu_gpr(t1, XRb);
2753d1b6ded4SSiarhei Volkau 
2754d1b6ded4SSiarhei Volkau     tcg_gen_brcondi_tl(cond, t1, 0, l_done);
2755d1b6ded4SSiarhei Volkau     gen_store_mxu_gpr(t0, XRa);
2756d1b6ded4SSiarhei Volkau     gen_set_label(l_done);
2757d1b6ded4SSiarhei Volkau }
2758a2b0a27dSPhilippe Mathieu-Daudé 
2759a2b0a27dSPhilippe Mathieu-Daudé /*
2760f1e6547cSSiarhei Volkau  *      MXU instruction category: Addition and subtraction
2761f1e6547cSSiarhei Volkau  *      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2762bf1df65fSSiarhei Volkau  *
2763f1e6547cSSiarhei Volkau  *              S32CPS      D16CPS
2764bf1df65fSSiarhei Volkau  *                                       Q8ADD
2765bf1df65fSSiarhei Volkau  */
2766bf1df65fSSiarhei Volkau 
2767bf1df65fSSiarhei Volkau /*
2768f1e6547cSSiarhei Volkau  *  S32CPS
2769f1e6547cSSiarhei Volkau  *    Update XRa if XRc < 0 by value of 0 - XRb
2770f1e6547cSSiarhei Volkau  *    else XRa = XRb
2771f1e6547cSSiarhei Volkau  */
gen_mxu_S32CPS(DisasContext * ctx)2772f1e6547cSSiarhei Volkau static void gen_mxu_S32CPS(DisasContext *ctx)
2773f1e6547cSSiarhei Volkau {
2774f1e6547cSSiarhei Volkau     uint32_t pad, XRc, XRb, XRa;
2775f1e6547cSSiarhei Volkau 
2776f1e6547cSSiarhei Volkau     pad = extract32(ctx->opcode, 21, 5);
2777f1e6547cSSiarhei Volkau     XRc = extract32(ctx->opcode, 14, 4);
2778f1e6547cSSiarhei Volkau     XRb = extract32(ctx->opcode, 10, 4);
2779f1e6547cSSiarhei Volkau     XRa = extract32(ctx->opcode,  6, 4);
2780f1e6547cSSiarhei Volkau 
2781f1e6547cSSiarhei Volkau     if (unlikely(pad != 0)) {
2782f1e6547cSSiarhei Volkau         /* opcode padding incorrect -> do nothing */
2783f1e6547cSSiarhei Volkau     } else if (unlikely(XRa == 0)) {
2784f1e6547cSSiarhei Volkau         /* destination is zero register -> do nothing */
2785f1e6547cSSiarhei Volkau     } else if (unlikely(XRb == 0)) {
2786f1e6547cSSiarhei Volkau         /* XRc make no sense 0 - 0 = 0 -> just set destination to zero */
2787f1e6547cSSiarhei Volkau         tcg_gen_movi_tl(mxu_gpr[XRa - 1], 0);
2788f1e6547cSSiarhei Volkau     } else if (unlikely(XRc == 0)) {
2789f1e6547cSSiarhei Volkau         /* condition always false -> just move XRb to XRa */
2790f1e6547cSSiarhei Volkau         tcg_gen_mov_tl(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
2791f1e6547cSSiarhei Volkau     } else {
2792f1e6547cSSiarhei Volkau         /* the most general case */
2793f1e6547cSSiarhei Volkau         TCGv t0 = tcg_temp_new();
2794f1e6547cSSiarhei Volkau         TCGLabel *l_not_less = gen_new_label();
2795f1e6547cSSiarhei Volkau         TCGLabel *l_done = gen_new_label();
2796f1e6547cSSiarhei Volkau 
2797f1e6547cSSiarhei Volkau         tcg_gen_brcondi_tl(TCG_COND_GE, mxu_gpr[XRc - 1], 0, l_not_less);
2798f1e6547cSSiarhei Volkau         tcg_gen_neg_tl(t0, mxu_gpr[XRb - 1]);
2799f1e6547cSSiarhei Volkau         tcg_gen_br(l_done);
2800f1e6547cSSiarhei Volkau         gen_set_label(l_not_less);
2801f1e6547cSSiarhei Volkau         gen_load_mxu_gpr(t0, XRb);
2802f1e6547cSSiarhei Volkau         gen_set_label(l_done);
2803f1e6547cSSiarhei Volkau         gen_store_mxu_gpr(t0, XRa);
2804f1e6547cSSiarhei Volkau     }
2805f1e6547cSSiarhei Volkau }
2806f1e6547cSSiarhei Volkau 
2807f1e6547cSSiarhei Volkau /*
2808f1e6547cSSiarhei Volkau  *  D16CPS
2809f1e6547cSSiarhei Volkau  *    Update XRa[0..1] if XRc[0..1] < 0 by value of 0 - XRb[0..1]
2810f1e6547cSSiarhei Volkau  *    else XRa[0..1] = XRb[0..1]
2811f1e6547cSSiarhei Volkau  */
gen_mxu_D16CPS(DisasContext * ctx)2812f1e6547cSSiarhei Volkau static void gen_mxu_D16CPS(DisasContext *ctx)
2813f1e6547cSSiarhei Volkau {
2814f1e6547cSSiarhei Volkau     uint32_t pad, XRc, XRb, XRa;
2815f1e6547cSSiarhei Volkau 
2816f1e6547cSSiarhei Volkau     pad = extract32(ctx->opcode, 21, 5);
2817f1e6547cSSiarhei Volkau     XRc = extract32(ctx->opcode, 14, 4);
2818f1e6547cSSiarhei Volkau     XRb = extract32(ctx->opcode, 10, 4);
2819f1e6547cSSiarhei Volkau     XRa = extract32(ctx->opcode,  6, 4);
2820f1e6547cSSiarhei Volkau 
2821f1e6547cSSiarhei Volkau     if (unlikely(pad != 0)) {
2822f1e6547cSSiarhei Volkau         /* opcode padding incorrect -> do nothing */
2823f1e6547cSSiarhei Volkau     } else if (unlikely(XRa == 0)) {
2824f1e6547cSSiarhei Volkau         /* destination is zero register -> do nothing */
2825f1e6547cSSiarhei Volkau     } else if (unlikely(XRb == 0)) {
2826f1e6547cSSiarhei Volkau         /* XRc make no sense 0 - 0 = 0 -> just set destination to zero */
2827f1e6547cSSiarhei Volkau         tcg_gen_movi_tl(mxu_gpr[XRa - 1], 0);
2828f1e6547cSSiarhei Volkau     } else if (unlikely(XRc == 0)) {
2829f1e6547cSSiarhei Volkau         /* condition always false -> just move XRb to XRa */
2830f1e6547cSSiarhei Volkau         tcg_gen_mov_tl(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
2831f1e6547cSSiarhei Volkau     } else {
2832f1e6547cSSiarhei Volkau         /* the most general case */
2833f1e6547cSSiarhei Volkau         TCGv t0 = tcg_temp_new();
2834f1e6547cSSiarhei Volkau         TCGv t1 = tcg_temp_new();
2835f1e6547cSSiarhei Volkau         TCGLabel *l_done_hi = gen_new_label();
2836f1e6547cSSiarhei Volkau         TCGLabel *l_not_less_lo = gen_new_label();
2837f1e6547cSSiarhei Volkau         TCGLabel *l_done_lo = gen_new_label();
2838f1e6547cSSiarhei Volkau 
2839f1e6547cSSiarhei Volkau         tcg_gen_sextract_tl(t0, mxu_gpr[XRc - 1], 16, 16);
2840f1e6547cSSiarhei Volkau         tcg_gen_sextract_tl(t1, mxu_gpr[XRb - 1], 16, 16);
2841f1e6547cSSiarhei Volkau         tcg_gen_brcondi_tl(TCG_COND_GE, t0, 0, l_done_hi);
2842f1e6547cSSiarhei Volkau         tcg_gen_subfi_tl(t1, 0, t1);
2843f1e6547cSSiarhei Volkau 
2844f1e6547cSSiarhei Volkau         gen_set_label(l_done_hi);
2845f1e6547cSSiarhei Volkau         tcg_gen_shli_i32(t1, t1, 16);
2846f1e6547cSSiarhei Volkau 
2847f1e6547cSSiarhei Volkau         tcg_gen_sextract_tl(t0, mxu_gpr[XRc - 1],  0, 16);
2848f1e6547cSSiarhei Volkau         tcg_gen_brcondi_tl(TCG_COND_GE, t0, 0, l_not_less_lo);
2849f1e6547cSSiarhei Volkau         tcg_gen_sextract_tl(t0, mxu_gpr[XRb - 1],  0, 16);
2850f1e6547cSSiarhei Volkau         tcg_gen_subfi_tl(t0, 0, t0);
2851f1e6547cSSiarhei Volkau         tcg_gen_br(l_done_lo);
2852f1e6547cSSiarhei Volkau 
2853f1e6547cSSiarhei Volkau         gen_set_label(l_not_less_lo);
2854f1e6547cSSiarhei Volkau         tcg_gen_extract_tl(t0, mxu_gpr[XRb - 1],  0, 16);
2855f1e6547cSSiarhei Volkau 
2856f1e6547cSSiarhei Volkau         gen_set_label(l_done_lo);
2857f1e6547cSSiarhei Volkau         tcg_gen_deposit_tl(mxu_gpr[XRa - 1], t1, t0, 0, 16);
2858f1e6547cSSiarhei Volkau     }
2859f1e6547cSSiarhei Volkau }
2860f1e6547cSSiarhei Volkau 
2861f1e6547cSSiarhei Volkau /*
2862f1e6547cSSiarhei Volkau  *  Q8ABD XRa, XRb, XRc
2863f1e6547cSSiarhei Volkau  *  Gets absolute difference for quadruple of 8-bit
2864f1e6547cSSiarhei Volkau  *  packed in XRb to another one in XRc,
2865f1e6547cSSiarhei Volkau  *  put the result in XRa.
2866f1e6547cSSiarhei Volkau  *  a.k.a. XRa[0..3] = abs(XRb[0..3] - XRc[0..3]);
2867f1e6547cSSiarhei Volkau  */
gen_mxu_Q8ABD(DisasContext * ctx)2868f1e6547cSSiarhei Volkau static void gen_mxu_Q8ABD(DisasContext *ctx)
2869f1e6547cSSiarhei Volkau {
2870f1e6547cSSiarhei Volkau     uint32_t pad, XRc, XRb, XRa;
2871f1e6547cSSiarhei Volkau 
2872f1e6547cSSiarhei Volkau     pad = extract32(ctx->opcode, 21, 3);
2873f1e6547cSSiarhei Volkau     XRc = extract32(ctx->opcode, 14, 4);
2874f1e6547cSSiarhei Volkau     XRb = extract32(ctx->opcode, 10, 4);
2875f1e6547cSSiarhei Volkau     XRa = extract32(ctx->opcode,  6, 4);
2876f1e6547cSSiarhei Volkau 
2877f1e6547cSSiarhei Volkau     if (unlikely(pad != 0)) {
2878f1e6547cSSiarhei Volkau         /* opcode padding incorrect -> do nothing */
2879f1e6547cSSiarhei Volkau     } else if (unlikely(XRa == 0)) {
2880f1e6547cSSiarhei Volkau         /* destination is zero register -> do nothing */
2881f1e6547cSSiarhei Volkau     } else if (unlikely((XRb == 0) && (XRc == 0))) {
2882f1e6547cSSiarhei Volkau         /* both operands zero registers -> just set destination to zero */
2883f1e6547cSSiarhei Volkau         tcg_gen_movi_tl(mxu_gpr[XRa - 1], 0);
2884f1e6547cSSiarhei Volkau     } else {
2885f1e6547cSSiarhei Volkau         /* the most general case */
2886f1e6547cSSiarhei Volkau         TCGv t0 = tcg_temp_new();
2887f1e6547cSSiarhei Volkau         TCGv t1 = tcg_temp_new();
2888f1e6547cSSiarhei Volkau         TCGv t2 = tcg_temp_new();
2889f1e6547cSSiarhei Volkau         TCGv t3 = tcg_temp_new();
2890f1e6547cSSiarhei Volkau         TCGv t4 = tcg_temp_new();
2891f1e6547cSSiarhei Volkau 
2892f1e6547cSSiarhei Volkau         gen_load_mxu_gpr(t3, XRb);
2893f1e6547cSSiarhei Volkau         gen_load_mxu_gpr(t4, XRc);
2894f1e6547cSSiarhei Volkau         tcg_gen_movi_tl(t2, 0);
2895f1e6547cSSiarhei Volkau 
2896f1e6547cSSiarhei Volkau         for (int i = 0; i < 4; i++) {
2897f1e6547cSSiarhei Volkau             tcg_gen_extract_tl(t0, t3, 8 * i, 8);
2898f1e6547cSSiarhei Volkau             tcg_gen_extract_tl(t1, t4, 8 * i, 8);
2899f1e6547cSSiarhei Volkau 
2900f1e6547cSSiarhei Volkau             tcg_gen_sub_tl(t0, t0, t1);
2901f1e6547cSSiarhei Volkau             tcg_gen_abs_tl(t0, t0);
2902f1e6547cSSiarhei Volkau 
2903f1e6547cSSiarhei Volkau             tcg_gen_deposit_tl(t2, t2, t0, 8 * i, 8);
2904f1e6547cSSiarhei Volkau         }
2905f1e6547cSSiarhei Volkau         gen_store_mxu_gpr(t2, XRa);
2906f1e6547cSSiarhei Volkau     }
2907f1e6547cSSiarhei Volkau }
2908f1e6547cSSiarhei Volkau 
2909f1e6547cSSiarhei Volkau /*
2910bf1df65fSSiarhei Volkau  *  Q8ADD XRa, XRb, XRc, ptn2
2911bf1df65fSSiarhei Volkau  *  Add/subtract quadruple of 8-bit packed in XRb
2912bf1df65fSSiarhei Volkau  *  to another one in XRc, put the result in XRa.
2913bf1df65fSSiarhei Volkau  */
gen_mxu_Q8ADD(DisasContext * ctx)2914bf1df65fSSiarhei Volkau static void gen_mxu_Q8ADD(DisasContext *ctx)
2915bf1df65fSSiarhei Volkau {
2916bf1df65fSSiarhei Volkau     uint32_t aptn2, pad, XRc, XRb, XRa;
2917bf1df65fSSiarhei Volkau 
2918bf1df65fSSiarhei Volkau     aptn2 = extract32(ctx->opcode, 24, 2);
2919bf1df65fSSiarhei Volkau     pad   = extract32(ctx->opcode, 21, 3);
2920bf1df65fSSiarhei Volkau     XRc   = extract32(ctx->opcode, 14, 4);
2921bf1df65fSSiarhei Volkau     XRb   = extract32(ctx->opcode, 10, 4);
2922bf1df65fSSiarhei Volkau     XRa   = extract32(ctx->opcode,  6, 4);
2923bf1df65fSSiarhei Volkau 
2924bf1df65fSSiarhei Volkau     if (unlikely(pad != 0)) {
2925bf1df65fSSiarhei Volkau         /* opcode padding incorrect -> do nothing */
2926bf1df65fSSiarhei Volkau     } else if (unlikely(XRa == 0)) {
2927bf1df65fSSiarhei Volkau         /* destination is zero register -> do nothing */
2928bf1df65fSSiarhei Volkau     } else if (unlikely((XRb == 0) && (XRc == 0))) {
2929bf1df65fSSiarhei Volkau         /* both operands zero registers -> just set destination to zero */
2930bf1df65fSSiarhei Volkau         tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
2931bf1df65fSSiarhei Volkau     } else {
2932bf1df65fSSiarhei Volkau         /* the most general case */
2933bf1df65fSSiarhei Volkau         TCGv t0 = tcg_temp_new();
2934bf1df65fSSiarhei Volkau         TCGv t1 = tcg_temp_new();
2935bf1df65fSSiarhei Volkau         TCGv t2 = tcg_temp_new();
2936bf1df65fSSiarhei Volkau         TCGv t3 = tcg_temp_new();
2937bf1df65fSSiarhei Volkau         TCGv t4 = tcg_temp_new();
2938bf1df65fSSiarhei Volkau 
2939bf1df65fSSiarhei Volkau         gen_load_mxu_gpr(t3, XRb);
2940bf1df65fSSiarhei Volkau         gen_load_mxu_gpr(t4, XRc);
2941bf1df65fSSiarhei Volkau 
2942bf1df65fSSiarhei Volkau         for (int i = 0; i < 4; i++) {
2943bf1df65fSSiarhei Volkau             tcg_gen_andi_tl(t0, t3, 0xff);
2944bf1df65fSSiarhei Volkau             tcg_gen_andi_tl(t1, t4, 0xff);
2945bf1df65fSSiarhei Volkau 
2946bf1df65fSSiarhei Volkau             if (i < 2) {
2947bf1df65fSSiarhei Volkau                 if (aptn2 & 0x01) {
2948bf1df65fSSiarhei Volkau                     tcg_gen_sub_tl(t0, t0, t1);
2949bf1df65fSSiarhei Volkau                 } else {
2950bf1df65fSSiarhei Volkau                     tcg_gen_add_tl(t0, t0, t1);
2951bf1df65fSSiarhei Volkau                 }
2952bf1df65fSSiarhei Volkau             } else {
2953bf1df65fSSiarhei Volkau                 if (aptn2 & 0x02) {
2954bf1df65fSSiarhei Volkau                     tcg_gen_sub_tl(t0, t0, t1);
2955bf1df65fSSiarhei Volkau                 } else {
2956bf1df65fSSiarhei Volkau                     tcg_gen_add_tl(t0, t0, t1);
2957bf1df65fSSiarhei Volkau                 }
2958bf1df65fSSiarhei Volkau             }
2959bf1df65fSSiarhei Volkau             if (i < 3) {
2960bf1df65fSSiarhei Volkau                 tcg_gen_shri_tl(t3, t3, 8);
2961bf1df65fSSiarhei Volkau                 tcg_gen_shri_tl(t4, t4, 8);
2962bf1df65fSSiarhei Volkau             }
2963bf1df65fSSiarhei Volkau             if (i > 0) {
2964bf1df65fSSiarhei Volkau                 tcg_gen_deposit_tl(t2, t2, t0, 8 * i, 8);
2965bf1df65fSSiarhei Volkau             } else {
2966bf1df65fSSiarhei Volkau                 tcg_gen_andi_tl(t0, t0, 0xff);
2967bf1df65fSSiarhei Volkau                 tcg_gen_mov_tl(t2, t0);
2968bf1df65fSSiarhei Volkau             }
2969bf1df65fSSiarhei Volkau         }
2970bf1df65fSSiarhei Volkau         gen_store_mxu_gpr(t2, XRa);
2971bf1df65fSSiarhei Volkau     }
2972bf1df65fSSiarhei Volkau }
2973bf1df65fSSiarhei Volkau 
2974f1e6547cSSiarhei Volkau /*
2975eb79951aSSiarhei Volkau  *  Q8ADDE XRa, XRb, XRc, XRd, aptn2
2976eb79951aSSiarhei Volkau  *    Add/subtract quadruple of 8-bit packed in XRb
2977eb79951aSSiarhei Volkau  *    to another one in XRc, with zero extending
2978eb79951aSSiarhei Volkau  *    to 16-bit and put results as packed 16-bit data
2979eb79951aSSiarhei Volkau  *    into XRa and XRd.
2980d5c9fa47SMichael Tokarev  *    aptn2 manages action add or subtract of pairs of data.
2981eb79951aSSiarhei Volkau  *
2982eb79951aSSiarhei Volkau  *  Q8ACCE XRa, XRb, XRc, XRd, aptn2
2983eb79951aSSiarhei Volkau  *    Add/subtract quadruple of 8-bit packed in XRb
2984eb79951aSSiarhei Volkau  *    to another one in XRc, with zero extending
2985eb79951aSSiarhei Volkau  *    to 16-bit and accumulate results as packed 16-bit data
2986eb79951aSSiarhei Volkau  *    into XRa and XRd.
2987d5c9fa47SMichael Tokarev  *    aptn2 manages action add or subtract of pairs of data.
2988eb79951aSSiarhei Volkau  */
gen_mxu_q8adde(DisasContext * ctx,bool accumulate)2989eb79951aSSiarhei Volkau static void gen_mxu_q8adde(DisasContext *ctx, bool accumulate)
2990eb79951aSSiarhei Volkau {
2991eb79951aSSiarhei Volkau     uint32_t aptn2, XRd, XRc, XRb, XRa;
2992eb79951aSSiarhei Volkau 
2993eb79951aSSiarhei Volkau     aptn2 = extract32(ctx->opcode, 24, 2);
2994eb79951aSSiarhei Volkau     XRd   = extract32(ctx->opcode, 18, 4);
2995eb79951aSSiarhei Volkau     XRc   = extract32(ctx->opcode, 14, 4);
2996eb79951aSSiarhei Volkau     XRb   = extract32(ctx->opcode, 10, 4);
2997eb79951aSSiarhei Volkau     XRa   = extract32(ctx->opcode,  6, 4);
2998eb79951aSSiarhei Volkau 
2999eb79951aSSiarhei Volkau     if (unlikely((XRb == 0) && (XRc == 0))) {
3000eb79951aSSiarhei Volkau         /* both operands zero registers -> just set destination to zero */
3001eb79951aSSiarhei Volkau         if (XRa != 0) {
3002eb79951aSSiarhei Volkau             tcg_gen_movi_tl(mxu_gpr[XRa - 1], 0);
3003eb79951aSSiarhei Volkau         }
3004eb79951aSSiarhei Volkau         if (XRd != 0) {
3005eb79951aSSiarhei Volkau             tcg_gen_movi_tl(mxu_gpr[XRd - 1], 0);
3006eb79951aSSiarhei Volkau         }
3007eb79951aSSiarhei Volkau     } else {
3008eb79951aSSiarhei Volkau         /* the most general case */
3009eb79951aSSiarhei Volkau         TCGv t0 = tcg_temp_new();
3010eb79951aSSiarhei Volkau         TCGv t1 = tcg_temp_new();
3011eb79951aSSiarhei Volkau         TCGv t2 = tcg_temp_new();
3012eb79951aSSiarhei Volkau         TCGv t3 = tcg_temp_new();
3013eb79951aSSiarhei Volkau         TCGv t4 = tcg_temp_new();
3014eb79951aSSiarhei Volkau         TCGv t5 = tcg_temp_new();
3015eb79951aSSiarhei Volkau 
3016eb79951aSSiarhei Volkau         if (XRa != 0) {
3017fb51df0cSPhilippe Mathieu-Daudé             gen_extract_mxu_gpr(t0, XRb, 16, 8);
3018fb51df0cSPhilippe Mathieu-Daudé             gen_extract_mxu_gpr(t1, XRc, 16, 8);
3019fb51df0cSPhilippe Mathieu-Daudé             gen_extract_mxu_gpr(t2, XRb, 24, 8);
3020fb51df0cSPhilippe Mathieu-Daudé             gen_extract_mxu_gpr(t3, XRc, 24, 8);
3021eb79951aSSiarhei Volkau             if (aptn2 & 2) {
3022eb79951aSSiarhei Volkau                 tcg_gen_sub_tl(t0, t0, t1);
3023eb79951aSSiarhei Volkau                 tcg_gen_sub_tl(t2, t2, t3);
3024eb79951aSSiarhei Volkau             } else {
3025eb79951aSSiarhei Volkau                 tcg_gen_add_tl(t0, t0, t1);
3026eb79951aSSiarhei Volkau                 tcg_gen_add_tl(t2, t2, t3);
3027eb79951aSSiarhei Volkau             }
3028eb79951aSSiarhei Volkau             if (accumulate) {
3029eb79951aSSiarhei Volkau                 gen_load_mxu_gpr(t5, XRa);
3030eb79951aSSiarhei Volkau                 tcg_gen_extract_tl(t1, t5,  0, 16);
3031eb79951aSSiarhei Volkau                 tcg_gen_extract_tl(t3, t5, 16, 16);
3032eb79951aSSiarhei Volkau                 tcg_gen_add_tl(t0, t0, t1);
3033eb79951aSSiarhei Volkau                 tcg_gen_add_tl(t2, t2, t3);
3034eb79951aSSiarhei Volkau             }
3035eb79951aSSiarhei Volkau             tcg_gen_shli_tl(t2, t2, 16);
3036eb79951aSSiarhei Volkau             tcg_gen_extract_tl(t0, t0, 0, 16);
3037eb79951aSSiarhei Volkau             tcg_gen_or_tl(t4, t2, t0);
3038eb79951aSSiarhei Volkau         }
3039eb79951aSSiarhei Volkau         if (XRd != 0) {
3040fb51df0cSPhilippe Mathieu-Daudé             gen_extract_mxu_gpr(t0, XRb, 0, 8);
3041fb51df0cSPhilippe Mathieu-Daudé             gen_extract_mxu_gpr(t1, XRc, 0, 8);
3042fb51df0cSPhilippe Mathieu-Daudé             gen_extract_mxu_gpr(t2, XRb, 8, 8);
3043fb51df0cSPhilippe Mathieu-Daudé             gen_extract_mxu_gpr(t3, XRc, 8, 8);
3044eb79951aSSiarhei Volkau             if (aptn2 & 1) {
3045eb79951aSSiarhei Volkau                 tcg_gen_sub_tl(t0, t0, t1);
3046eb79951aSSiarhei Volkau                 tcg_gen_sub_tl(t2, t2, t3);
3047eb79951aSSiarhei Volkau             } else {
3048eb79951aSSiarhei Volkau                 tcg_gen_add_tl(t0, t0, t1);
3049eb79951aSSiarhei Volkau                 tcg_gen_add_tl(t2, t2, t3);
3050eb79951aSSiarhei Volkau             }
3051eb79951aSSiarhei Volkau             if (accumulate) {
3052eb79951aSSiarhei Volkau                 gen_load_mxu_gpr(t5, XRd);
3053eb79951aSSiarhei Volkau                 tcg_gen_extract_tl(t1, t5,  0, 16);
3054eb79951aSSiarhei Volkau                 tcg_gen_extract_tl(t3, t5, 16, 16);
3055eb79951aSSiarhei Volkau                 tcg_gen_add_tl(t0, t0, t1);
3056eb79951aSSiarhei Volkau                 tcg_gen_add_tl(t2, t2, t3);
3057eb79951aSSiarhei Volkau             }
3058eb79951aSSiarhei Volkau             tcg_gen_shli_tl(t2, t2, 16);
3059eb79951aSSiarhei Volkau             tcg_gen_extract_tl(t0, t0, 0, 16);
3060eb79951aSSiarhei Volkau             tcg_gen_or_tl(t5, t2, t0);
3061eb79951aSSiarhei Volkau         }
3062eb79951aSSiarhei Volkau 
3063eb79951aSSiarhei Volkau         gen_store_mxu_gpr(t4, XRa);
3064eb79951aSSiarhei Volkau         gen_store_mxu_gpr(t5, XRd);
3065eb79951aSSiarhei Volkau     }
3066eb79951aSSiarhei Volkau }
3067eb79951aSSiarhei Volkau 
3068eb79951aSSiarhei Volkau /*
3069eb79951aSSiarhei Volkau  *  D8SUM XRa, XRb, XRc
3070eb79951aSSiarhei Volkau  *    Double parallel add of quadruple unsigned 8-bit together
3071eb79951aSSiarhei Volkau  *    with zero extending to 16-bit data.
3072eb79951aSSiarhei Volkau  *  D8SUMC XRa, XRb, XRc
3073eb79951aSSiarhei Volkau  *    Double parallel add of quadruple unsigned 8-bit together
3074eb79951aSSiarhei Volkau  *    with zero extending to 16-bit data and adding 2 to each
3075eb79951aSSiarhei Volkau  *    parallel result.
3076eb79951aSSiarhei Volkau  */
gen_mxu_d8sum(DisasContext * ctx,bool sumc)3077eb79951aSSiarhei Volkau static void gen_mxu_d8sum(DisasContext *ctx, bool sumc)
3078eb79951aSSiarhei Volkau {
3079eb79951aSSiarhei Volkau     uint32_t pad, pad2, XRc, XRb, XRa;
3080eb79951aSSiarhei Volkau 
3081eb79951aSSiarhei Volkau     pad  = extract32(ctx->opcode, 24, 2);
3082eb79951aSSiarhei Volkau     pad2 = extract32(ctx->opcode, 18, 4);
3083eb79951aSSiarhei Volkau     XRc  = extract32(ctx->opcode, 14, 4);
3084eb79951aSSiarhei Volkau     XRb  = extract32(ctx->opcode, 10, 4);
3085eb79951aSSiarhei Volkau     XRa  = extract32(ctx->opcode,  6, 4);
3086eb79951aSSiarhei Volkau 
3087eb79951aSSiarhei Volkau     if (unlikely(pad != 0 || pad2 != 0)) {
3088eb79951aSSiarhei Volkau         /* opcode padding incorrect -> do nothing */
3089eb79951aSSiarhei Volkau     } else if (unlikely(XRa == 0)) {
3090eb79951aSSiarhei Volkau         /* destination is zero register -> do nothing */
3091eb79951aSSiarhei Volkau     } else if (unlikely((XRb == 0) && (XRc == 0))) {
3092eb79951aSSiarhei Volkau         /* both operands zero registers -> just set destination to zero */
3093eb79951aSSiarhei Volkau         tcg_gen_movi_tl(mxu_gpr[XRa - 1], 0);
3094eb79951aSSiarhei Volkau     } else {
3095eb79951aSSiarhei Volkau         /* the most general case */
3096eb79951aSSiarhei Volkau         TCGv t0 = tcg_temp_new();
3097eb79951aSSiarhei Volkau         TCGv t1 = tcg_temp_new();
3098eb79951aSSiarhei Volkau         TCGv t2 = tcg_temp_new();
3099eb79951aSSiarhei Volkau         TCGv t3 = tcg_temp_new();
3100eb79951aSSiarhei Volkau         TCGv t4 = tcg_temp_new();
3101eb79951aSSiarhei Volkau         TCGv t5 = tcg_temp_new();
3102eb79951aSSiarhei Volkau 
3103eb79951aSSiarhei Volkau         if (XRb != 0) {
3104eb79951aSSiarhei Volkau             tcg_gen_extract_tl(t0, mxu_gpr[XRb - 1],  0, 8);
3105eb79951aSSiarhei Volkau             tcg_gen_extract_tl(t1, mxu_gpr[XRb - 1],  8, 8);
3106eb79951aSSiarhei Volkau             tcg_gen_extract_tl(t2, mxu_gpr[XRb - 1], 16, 8);
3107eb79951aSSiarhei Volkau             tcg_gen_extract_tl(t3, mxu_gpr[XRb - 1], 24, 8);
3108eb79951aSSiarhei Volkau             tcg_gen_add_tl(t4, t0, t1);
3109eb79951aSSiarhei Volkau             tcg_gen_add_tl(t4, t4, t2);
3110eb79951aSSiarhei Volkau             tcg_gen_add_tl(t4, t4, t3);
3111eb79951aSSiarhei Volkau         } else {
3112eb79951aSSiarhei Volkau             tcg_gen_mov_tl(t4, 0);
3113eb79951aSSiarhei Volkau         }
3114eb79951aSSiarhei Volkau         if (XRc != 0) {
3115eb79951aSSiarhei Volkau             tcg_gen_extract_tl(t0, mxu_gpr[XRc - 1],  0, 8);
3116eb79951aSSiarhei Volkau             tcg_gen_extract_tl(t1, mxu_gpr[XRc - 1],  8, 8);
3117eb79951aSSiarhei Volkau             tcg_gen_extract_tl(t2, mxu_gpr[XRc - 1], 16, 8);
3118eb79951aSSiarhei Volkau             tcg_gen_extract_tl(t3, mxu_gpr[XRc - 1], 24, 8);
3119eb79951aSSiarhei Volkau             tcg_gen_add_tl(t5, t0, t1);
3120eb79951aSSiarhei Volkau             tcg_gen_add_tl(t5, t5, t2);
3121eb79951aSSiarhei Volkau             tcg_gen_add_tl(t5, t5, t3);
3122eb79951aSSiarhei Volkau         } else {
3123eb79951aSSiarhei Volkau             tcg_gen_mov_tl(t5, 0);
3124eb79951aSSiarhei Volkau         }
3125eb79951aSSiarhei Volkau 
3126eb79951aSSiarhei Volkau         if (sumc) {
3127eb79951aSSiarhei Volkau             tcg_gen_addi_tl(t4, t4, 2);
3128eb79951aSSiarhei Volkau             tcg_gen_addi_tl(t5, t5, 2);
3129eb79951aSSiarhei Volkau         }
3130eb79951aSSiarhei Volkau         tcg_gen_shli_tl(t4, t4, 16);
3131eb79951aSSiarhei Volkau 
3132eb79951aSSiarhei Volkau         tcg_gen_or_tl(mxu_gpr[XRa - 1], t4, t5);
3133eb79951aSSiarhei Volkau     }
3134eb79951aSSiarhei Volkau }
3135eb79951aSSiarhei Volkau 
3136eb79951aSSiarhei Volkau /*
3137a9bfd80bSSiarhei Volkau  * Q16ADD XRa, XRb, XRc, XRd, aptn2, optn2 - Quad packed
3138a9bfd80bSSiarhei Volkau  * 16-bit pattern addition.
3139a9bfd80bSSiarhei Volkau  */
gen_mxu_q16add(DisasContext * ctx)3140a9bfd80bSSiarhei Volkau static void gen_mxu_q16add(DisasContext *ctx)
3141a9bfd80bSSiarhei Volkau {
3142a9bfd80bSSiarhei Volkau     uint32_t aptn2, optn2, XRc, XRb, XRa, XRd;
3143a9bfd80bSSiarhei Volkau 
3144a9bfd80bSSiarhei Volkau     aptn2 = extract32(ctx->opcode, 24, 2);
3145a9bfd80bSSiarhei Volkau     optn2 = extract32(ctx->opcode, 22, 2);
3146a9bfd80bSSiarhei Volkau     XRd   = extract32(ctx->opcode, 18, 4);
3147a9bfd80bSSiarhei Volkau     XRc   = extract32(ctx->opcode, 14, 4);
3148a9bfd80bSSiarhei Volkau     XRb   = extract32(ctx->opcode, 10, 4);
3149a9bfd80bSSiarhei Volkau     XRa   = extract32(ctx->opcode,  6, 4);
3150a9bfd80bSSiarhei Volkau 
3151a9bfd80bSSiarhei Volkau     TCGv t0 = tcg_temp_new();
3152a9bfd80bSSiarhei Volkau     TCGv t1 = tcg_temp_new();
3153a9bfd80bSSiarhei Volkau     TCGv t2 = tcg_temp_new();
3154a9bfd80bSSiarhei Volkau     TCGv t3 = tcg_temp_new();
3155a9bfd80bSSiarhei Volkau     TCGv t4 = tcg_temp_new();
3156a9bfd80bSSiarhei Volkau     TCGv t5 = tcg_temp_new();
3157a9bfd80bSSiarhei Volkau 
3158a9bfd80bSSiarhei Volkau     gen_load_mxu_gpr(t1, XRb);
3159a9bfd80bSSiarhei Volkau     tcg_gen_extract_tl(t0, t1,  0, 16);
3160a9bfd80bSSiarhei Volkau     tcg_gen_extract_tl(t1, t1, 16, 16);
3161a9bfd80bSSiarhei Volkau 
3162a9bfd80bSSiarhei Volkau     gen_load_mxu_gpr(t3, XRc);
3163a9bfd80bSSiarhei Volkau     tcg_gen_extract_tl(t2, t3,  0, 16);
3164a9bfd80bSSiarhei Volkau     tcg_gen_extract_tl(t3, t3, 16, 16);
3165a9bfd80bSSiarhei Volkau 
3166a9bfd80bSSiarhei Volkau     switch (optn2) {
3167a9bfd80bSSiarhei Volkau     case MXU_OPTN2_WW: /* XRB.H+XRC.H == lop, XRB.L+XRC.L == rop */
3168a9bfd80bSSiarhei Volkau         tcg_gen_mov_tl(t4, t1);
3169a9bfd80bSSiarhei Volkau         tcg_gen_mov_tl(t5, t0);
3170a9bfd80bSSiarhei Volkau         break;
3171a9bfd80bSSiarhei Volkau     case MXU_OPTN2_LW: /* XRB.L+XRC.H == lop, XRB.L+XRC.L == rop */
3172a9bfd80bSSiarhei Volkau         tcg_gen_mov_tl(t4, t0);
3173a9bfd80bSSiarhei Volkau         tcg_gen_mov_tl(t5, t0);
3174a9bfd80bSSiarhei Volkau         break;
3175a9bfd80bSSiarhei Volkau     case MXU_OPTN2_HW: /* XRB.H+XRC.H == lop, XRB.H+XRC.L == rop */
3176a9bfd80bSSiarhei Volkau         tcg_gen_mov_tl(t4, t1);
3177a9bfd80bSSiarhei Volkau         tcg_gen_mov_tl(t5, t1);
3178a9bfd80bSSiarhei Volkau         break;
3179a9bfd80bSSiarhei Volkau     case MXU_OPTN2_XW: /* XRB.L+XRC.H == lop, XRB.H+XRC.L == rop */
3180a9bfd80bSSiarhei Volkau         tcg_gen_mov_tl(t4, t0);
3181a9bfd80bSSiarhei Volkau         tcg_gen_mov_tl(t5, t1);
3182a9bfd80bSSiarhei Volkau         break;
3183a9bfd80bSSiarhei Volkau     }
3184a9bfd80bSSiarhei Volkau 
3185a9bfd80bSSiarhei Volkau     switch (aptn2) {
3186a9bfd80bSSiarhei Volkau     case MXU_APTN2_AA: /* lop +, rop + */
3187a9bfd80bSSiarhei Volkau         tcg_gen_add_tl(t0, t4, t3);
3188a9bfd80bSSiarhei Volkau         tcg_gen_add_tl(t1, t5, t2);
3189a9bfd80bSSiarhei Volkau         tcg_gen_add_tl(t4, t4, t3);
3190a9bfd80bSSiarhei Volkau         tcg_gen_add_tl(t5, t5, t2);
3191a9bfd80bSSiarhei Volkau         break;
3192a9bfd80bSSiarhei Volkau     case MXU_APTN2_AS: /* lop +, rop + */
3193a9bfd80bSSiarhei Volkau         tcg_gen_sub_tl(t0, t4, t3);
3194a9bfd80bSSiarhei Volkau         tcg_gen_sub_tl(t1, t5, t2);
3195a9bfd80bSSiarhei Volkau         tcg_gen_add_tl(t4, t4, t3);
3196a9bfd80bSSiarhei Volkau         tcg_gen_add_tl(t5, t5, t2);
3197a9bfd80bSSiarhei Volkau         break;
3198a9bfd80bSSiarhei Volkau     case MXU_APTN2_SA: /* lop +, rop + */
3199a9bfd80bSSiarhei Volkau         tcg_gen_add_tl(t0, t4, t3);
3200a9bfd80bSSiarhei Volkau         tcg_gen_add_tl(t1, t5, t2);
3201a9bfd80bSSiarhei Volkau         tcg_gen_sub_tl(t4, t4, t3);
3202a9bfd80bSSiarhei Volkau         tcg_gen_sub_tl(t5, t5, t2);
3203a9bfd80bSSiarhei Volkau         break;
3204a9bfd80bSSiarhei Volkau     case MXU_APTN2_SS: /* lop +, rop + */
3205a9bfd80bSSiarhei Volkau         tcg_gen_sub_tl(t0, t4, t3);
3206a9bfd80bSSiarhei Volkau         tcg_gen_sub_tl(t1, t5, t2);
3207a9bfd80bSSiarhei Volkau         tcg_gen_sub_tl(t4, t4, t3);
3208a9bfd80bSSiarhei Volkau         tcg_gen_sub_tl(t5, t5, t2);
3209a9bfd80bSSiarhei Volkau         break;
3210a9bfd80bSSiarhei Volkau     }
3211a9bfd80bSSiarhei Volkau 
3212a9bfd80bSSiarhei Volkau     tcg_gen_shli_tl(t0, t0, 16);
3213a9bfd80bSSiarhei Volkau     tcg_gen_extract_tl(t1, t1, 0, 16);
3214a9bfd80bSSiarhei Volkau     tcg_gen_shli_tl(t4, t4, 16);
3215a9bfd80bSSiarhei Volkau     tcg_gen_extract_tl(t5, t5, 0, 16);
3216a9bfd80bSSiarhei Volkau 
3217a9bfd80bSSiarhei Volkau     tcg_gen_or_tl(mxu_gpr[XRa - 1], t4, t5);
3218a9bfd80bSSiarhei Volkau     tcg_gen_or_tl(mxu_gpr[XRd - 1], t0, t1);
3219a9bfd80bSSiarhei Volkau }
3220a9bfd80bSSiarhei Volkau 
3221a9bfd80bSSiarhei Volkau /*
32226191a807SSiarhei Volkau  * Q16ACC XRa, XRb, XRc, XRd, aptn2 - Quad packed
32236191a807SSiarhei Volkau  * 16-bit addition/subtraction with accumulate.
32246191a807SSiarhei Volkau  */
gen_mxu_q16acc(DisasContext * ctx)32256191a807SSiarhei Volkau static void gen_mxu_q16acc(DisasContext *ctx)
32266191a807SSiarhei Volkau {
32276191a807SSiarhei Volkau     uint32_t aptn2, XRc, XRb, XRa, XRd;
32286191a807SSiarhei Volkau 
32296191a807SSiarhei Volkau     aptn2 = extract32(ctx->opcode, 24, 2);
32306191a807SSiarhei Volkau     XRd   = extract32(ctx->opcode, 18, 4);
32316191a807SSiarhei Volkau     XRc   = extract32(ctx->opcode, 14, 4);
32326191a807SSiarhei Volkau     XRb   = extract32(ctx->opcode, 10, 4);
32336191a807SSiarhei Volkau     XRa   = extract32(ctx->opcode,  6, 4);
32346191a807SSiarhei Volkau 
32356191a807SSiarhei Volkau     TCGv t0 = tcg_temp_new();
32366191a807SSiarhei Volkau     TCGv t1 = tcg_temp_new();
32376191a807SSiarhei Volkau     TCGv t2 = tcg_temp_new();
32386191a807SSiarhei Volkau     TCGv t3 = tcg_temp_new();
32396191a807SSiarhei Volkau     TCGv s3 = tcg_temp_new();
32406191a807SSiarhei Volkau     TCGv s2 = tcg_temp_new();
32416191a807SSiarhei Volkau     TCGv s1 = tcg_temp_new();
32426191a807SSiarhei Volkau     TCGv s0 = tcg_temp_new();
32436191a807SSiarhei Volkau 
32446191a807SSiarhei Volkau     gen_load_mxu_gpr(t1, XRb);
32456191a807SSiarhei Volkau     tcg_gen_extract_tl(t0, t1,  0, 16);
32466191a807SSiarhei Volkau     tcg_gen_extract_tl(t1, t1, 16, 16);
32476191a807SSiarhei Volkau 
32486191a807SSiarhei Volkau     gen_load_mxu_gpr(t3, XRc);
32496191a807SSiarhei Volkau     tcg_gen_extract_tl(t2, t3,  0, 16);
32506191a807SSiarhei Volkau     tcg_gen_extract_tl(t3, t3, 16, 16);
32516191a807SSiarhei Volkau 
32526191a807SSiarhei Volkau     switch (aptn2) {
32536191a807SSiarhei Volkau     case MXU_APTN2_AA: /* lop +, rop + */
32546191a807SSiarhei Volkau         tcg_gen_add_tl(s3, t1, t3);
32556191a807SSiarhei Volkau         tcg_gen_add_tl(s2, t0, t2);
32566191a807SSiarhei Volkau         tcg_gen_add_tl(s1, t1, t3);
32576191a807SSiarhei Volkau         tcg_gen_add_tl(s0, t0, t2);
32586191a807SSiarhei Volkau         break;
32596191a807SSiarhei Volkau     case MXU_APTN2_AS: /* lop +, rop - */
32606191a807SSiarhei Volkau         tcg_gen_sub_tl(s3, t1, t3);
32616191a807SSiarhei Volkau         tcg_gen_sub_tl(s2, t0, t2);
32626191a807SSiarhei Volkau         tcg_gen_add_tl(s1, t1, t3);
32636191a807SSiarhei Volkau         tcg_gen_add_tl(s0, t0, t2);
32646191a807SSiarhei Volkau         break;
32656191a807SSiarhei Volkau     case MXU_APTN2_SA: /* lop -, rop + */
32666191a807SSiarhei Volkau         tcg_gen_add_tl(s3, t1, t3);
32676191a807SSiarhei Volkau         tcg_gen_add_tl(s2, t0, t2);
32686191a807SSiarhei Volkau         tcg_gen_sub_tl(s1, t1, t3);
32696191a807SSiarhei Volkau         tcg_gen_sub_tl(s0, t0, t2);
32706191a807SSiarhei Volkau         break;
32716191a807SSiarhei Volkau     case MXU_APTN2_SS: /* lop -, rop - */
32726191a807SSiarhei Volkau         tcg_gen_sub_tl(s3, t1, t3);
32736191a807SSiarhei Volkau         tcg_gen_sub_tl(s2, t0, t2);
32746191a807SSiarhei Volkau         tcg_gen_sub_tl(s1, t1, t3);
32756191a807SSiarhei Volkau         tcg_gen_sub_tl(s0, t0, t2);
32766191a807SSiarhei Volkau         break;
32776191a807SSiarhei Volkau     }
32786191a807SSiarhei Volkau 
32796191a807SSiarhei Volkau     if (XRa != 0) {
32806191a807SSiarhei Volkau         tcg_gen_add_tl(t0, mxu_gpr[XRa - 1], s0);
32816191a807SSiarhei Volkau         tcg_gen_extract_tl(t0, t0, 0, 16);
32826191a807SSiarhei Volkau         tcg_gen_extract_tl(t1, mxu_gpr[XRa - 1], 16, 16);
32836191a807SSiarhei Volkau         tcg_gen_add_tl(t1, t1, s1);
32846191a807SSiarhei Volkau         tcg_gen_shli_tl(t1, t1, 16);
32856191a807SSiarhei Volkau         tcg_gen_or_tl(mxu_gpr[XRa - 1], t1, t0);
32866191a807SSiarhei Volkau     }
32876191a807SSiarhei Volkau 
32886191a807SSiarhei Volkau     if (XRd != 0) {
32896191a807SSiarhei Volkau         tcg_gen_add_tl(t0, mxu_gpr[XRd - 1], s2);
32906191a807SSiarhei Volkau         tcg_gen_extract_tl(t0, t0, 0, 16);
32916191a807SSiarhei Volkau         tcg_gen_extract_tl(t1, mxu_gpr[XRd - 1], 16, 16);
32926191a807SSiarhei Volkau         tcg_gen_add_tl(t1, t1, s3);
32936191a807SSiarhei Volkau         tcg_gen_shli_tl(t1, t1, 16);
32946191a807SSiarhei Volkau         tcg_gen_or_tl(mxu_gpr[XRd - 1], t1, t0);
32956191a807SSiarhei Volkau     }
32966191a807SSiarhei Volkau }
32976191a807SSiarhei Volkau 
32986191a807SSiarhei Volkau /*
32996191a807SSiarhei Volkau  * Q16ACCM XRa, XRb, XRc, XRd, aptn2 - Quad packed
33006191a807SSiarhei Volkau  * 16-bit accumulate.
33016191a807SSiarhei Volkau  */
gen_mxu_q16accm(DisasContext * ctx)33026191a807SSiarhei Volkau static void gen_mxu_q16accm(DisasContext *ctx)
33036191a807SSiarhei Volkau {
33046191a807SSiarhei Volkau     uint32_t aptn2, XRc, XRb, XRa, XRd;
33056191a807SSiarhei Volkau 
33066191a807SSiarhei Volkau     aptn2 = extract32(ctx->opcode, 24, 2);
33076191a807SSiarhei Volkau     XRd   = extract32(ctx->opcode, 18, 4);
33086191a807SSiarhei Volkau     XRc   = extract32(ctx->opcode, 14, 4);
33096191a807SSiarhei Volkau     XRb   = extract32(ctx->opcode, 10, 4);
33106191a807SSiarhei Volkau     XRa   = extract32(ctx->opcode,  6, 4);
33116191a807SSiarhei Volkau 
33126191a807SSiarhei Volkau     TCGv t0 = tcg_temp_new();
33136191a807SSiarhei Volkau     TCGv t1 = tcg_temp_new();
33146191a807SSiarhei Volkau     TCGv t2 = tcg_temp_new();
33156191a807SSiarhei Volkau     TCGv t3 = tcg_temp_new();
33166191a807SSiarhei Volkau 
33176191a807SSiarhei Volkau     gen_load_mxu_gpr(t2, XRb);
33186191a807SSiarhei Volkau     gen_load_mxu_gpr(t3, XRc);
33196191a807SSiarhei Volkau 
33206191a807SSiarhei Volkau     if (XRa != 0) {
33216191a807SSiarhei Volkau         TCGv a0 = tcg_temp_new();
33226191a807SSiarhei Volkau         TCGv a1 = tcg_temp_new();
33236191a807SSiarhei Volkau 
33246191a807SSiarhei Volkau         tcg_gen_extract_tl(t0, t2,  0, 16);
33256191a807SSiarhei Volkau         tcg_gen_extract_tl(t1, t2, 16, 16);
33266191a807SSiarhei Volkau 
33276191a807SSiarhei Volkau         gen_load_mxu_gpr(a1, XRa);
33286191a807SSiarhei Volkau         tcg_gen_extract_tl(a0, a1,  0, 16);
33296191a807SSiarhei Volkau         tcg_gen_extract_tl(a1, a1, 16, 16);
33306191a807SSiarhei Volkau 
33316191a807SSiarhei Volkau         if (aptn2 & 2) {
33326191a807SSiarhei Volkau             tcg_gen_sub_tl(a0, a0, t0);
33336191a807SSiarhei Volkau             tcg_gen_sub_tl(a1, a1, t1);
33346191a807SSiarhei Volkau         } else {
33356191a807SSiarhei Volkau             tcg_gen_add_tl(a0, a0, t0);
33366191a807SSiarhei Volkau             tcg_gen_add_tl(a1, a1, t1);
33376191a807SSiarhei Volkau         }
33386191a807SSiarhei Volkau         tcg_gen_extract_tl(a0, a0, 0, 16);
33396191a807SSiarhei Volkau         tcg_gen_shli_tl(a1, a1, 16);
33406191a807SSiarhei Volkau         tcg_gen_or_tl(mxu_gpr[XRa - 1], a1, a0);
33416191a807SSiarhei Volkau     }
33426191a807SSiarhei Volkau 
33436191a807SSiarhei Volkau     if (XRd != 0) {
33446191a807SSiarhei Volkau         TCGv a0 = tcg_temp_new();
33456191a807SSiarhei Volkau         TCGv a1 = tcg_temp_new();
33466191a807SSiarhei Volkau 
33476191a807SSiarhei Volkau         tcg_gen_extract_tl(t0, t3,  0, 16);
33486191a807SSiarhei Volkau         tcg_gen_extract_tl(t1, t3, 16, 16);
33496191a807SSiarhei Volkau 
33506191a807SSiarhei Volkau         gen_load_mxu_gpr(a1, XRd);
33516191a807SSiarhei Volkau         tcg_gen_extract_tl(a0, a1,  0, 16);
33526191a807SSiarhei Volkau         tcg_gen_extract_tl(a1, a1, 16, 16);
33536191a807SSiarhei Volkau 
33546191a807SSiarhei Volkau         if (aptn2 & 1) {
33556191a807SSiarhei Volkau             tcg_gen_sub_tl(a0, a0, t0);
33566191a807SSiarhei Volkau             tcg_gen_sub_tl(a1, a1, t1);
33576191a807SSiarhei Volkau         } else {
33586191a807SSiarhei Volkau             tcg_gen_add_tl(a0, a0, t0);
33596191a807SSiarhei Volkau             tcg_gen_add_tl(a1, a1, t1);
33606191a807SSiarhei Volkau         }
33616191a807SSiarhei Volkau         tcg_gen_extract_tl(a0, a0, 0, 16);
33626191a807SSiarhei Volkau         tcg_gen_shli_tl(a1, a1, 16);
33636191a807SSiarhei Volkau         tcg_gen_or_tl(mxu_gpr[XRd - 1], a1, a0);
33646191a807SSiarhei Volkau     }
33656191a807SSiarhei Volkau }
33666191a807SSiarhei Volkau 
33676191a807SSiarhei Volkau 
33686191a807SSiarhei Volkau /*
33696191a807SSiarhei Volkau  * D16ASUM XRa, XRb, XRc, XRd, aptn2 - Double packed
33706191a807SSiarhei Volkau  * 16-bit sign extended addition and accumulate.
33716191a807SSiarhei Volkau  */
gen_mxu_d16asum(DisasContext * ctx)33726191a807SSiarhei Volkau static void gen_mxu_d16asum(DisasContext *ctx)
33736191a807SSiarhei Volkau {
33746191a807SSiarhei Volkau     uint32_t aptn2, XRc, XRb, XRa, XRd;
33756191a807SSiarhei Volkau 
33766191a807SSiarhei Volkau     aptn2 = extract32(ctx->opcode, 24, 2);
33776191a807SSiarhei Volkau     XRd   = extract32(ctx->opcode, 18, 4);
33786191a807SSiarhei Volkau     XRc   = extract32(ctx->opcode, 14, 4);
33796191a807SSiarhei Volkau     XRb   = extract32(ctx->opcode, 10, 4);
33806191a807SSiarhei Volkau     XRa   = extract32(ctx->opcode,  6, 4);
33816191a807SSiarhei Volkau 
33826191a807SSiarhei Volkau     TCGv t0 = tcg_temp_new();
33836191a807SSiarhei Volkau     TCGv t1 = tcg_temp_new();
33846191a807SSiarhei Volkau     TCGv t2 = tcg_temp_new();
33856191a807SSiarhei Volkau     TCGv t3 = tcg_temp_new();
33866191a807SSiarhei Volkau 
33876191a807SSiarhei Volkau     gen_load_mxu_gpr(t2, XRb);
33886191a807SSiarhei Volkau     gen_load_mxu_gpr(t3, XRc);
33896191a807SSiarhei Volkau 
33906191a807SSiarhei Volkau     if (XRa != 0) {
33916191a807SSiarhei Volkau         tcg_gen_sextract_tl(t0, t2,  0, 16);
33926191a807SSiarhei Volkau         tcg_gen_sextract_tl(t1, t2, 16, 16);
33936191a807SSiarhei Volkau         tcg_gen_add_tl(t0, t0, t1);
33946191a807SSiarhei Volkau         if (aptn2 & 2) {
33956191a807SSiarhei Volkau             tcg_gen_sub_tl(mxu_gpr[XRa - 1], mxu_gpr[XRa - 1], t0);
33966191a807SSiarhei Volkau         } else {
33976191a807SSiarhei Volkau             tcg_gen_add_tl(mxu_gpr[XRa - 1], mxu_gpr[XRa - 1], t0);
33986191a807SSiarhei Volkau         }
33996191a807SSiarhei Volkau     }
34006191a807SSiarhei Volkau 
34016191a807SSiarhei Volkau     if (XRd != 0) {
34026191a807SSiarhei Volkau         tcg_gen_sextract_tl(t0, t3,  0, 16);
34036191a807SSiarhei Volkau         tcg_gen_sextract_tl(t1, t3, 16, 16);
34046191a807SSiarhei Volkau         tcg_gen_add_tl(t0, t0, t1);
34056191a807SSiarhei Volkau         if (aptn2 & 1) {
34066191a807SSiarhei Volkau             tcg_gen_sub_tl(mxu_gpr[XRd - 1], mxu_gpr[XRd - 1], t0);
34076191a807SSiarhei Volkau         } else {
34086191a807SSiarhei Volkau             tcg_gen_add_tl(mxu_gpr[XRd - 1], mxu_gpr[XRd - 1], t0);
34096191a807SSiarhei Volkau         }
34106191a807SSiarhei Volkau     }
34116191a807SSiarhei Volkau }
34126191a807SSiarhei Volkau 
34136191a807SSiarhei Volkau /*
34149e51e0cdSSiarhei Volkau  * D32ADD XRa, XRb, XRc, XRd, aptn2 - Double
3415513cfdaeSSiarhei Volkau  * 32 bit pattern addition/subtraction, set carry.
3416513cfdaeSSiarhei Volkau  *
3417513cfdaeSSiarhei Volkau  * D32ADDC XRa, XRb, XRc, XRd, aptn2 - Double
3418513cfdaeSSiarhei Volkau  * 32 bit pattern addition/subtraction with carry.
34199e51e0cdSSiarhei Volkau  */
gen_mxu_d32add(DisasContext * ctx)34209e51e0cdSSiarhei Volkau static void gen_mxu_d32add(DisasContext *ctx)
34219e51e0cdSSiarhei Volkau {
3422513cfdaeSSiarhei Volkau     uint32_t aptn2, addc, XRc, XRb, XRa, XRd;
34239e51e0cdSSiarhei Volkau 
34249e51e0cdSSiarhei Volkau     aptn2 = extract32(ctx->opcode, 24, 2);
3425513cfdaeSSiarhei Volkau     addc  = extract32(ctx->opcode, 22, 2);
34269e51e0cdSSiarhei Volkau     XRd   = extract32(ctx->opcode, 18, 4);
34279e51e0cdSSiarhei Volkau     XRc   = extract32(ctx->opcode, 14, 4);
34289e51e0cdSSiarhei Volkau     XRb   = extract32(ctx->opcode, 10, 4);
34299e51e0cdSSiarhei Volkau     XRa   = extract32(ctx->opcode,  6, 4);
34309e51e0cdSSiarhei Volkau 
34319e51e0cdSSiarhei Volkau     TCGv t0 = tcg_temp_new();
34329e51e0cdSSiarhei Volkau     TCGv t1 = tcg_temp_new();
34339e51e0cdSSiarhei Volkau     TCGv t2 = tcg_temp_new();
34349e51e0cdSSiarhei Volkau     TCGv cr = tcg_temp_new();
34359e51e0cdSSiarhei Volkau 
3436513cfdaeSSiarhei Volkau     if (unlikely(addc > 1)) {
3437513cfdaeSSiarhei Volkau         /* opcode incorrect -> do nothing */
3438513cfdaeSSiarhei Volkau     } else if (addc == 1) {
3439513cfdaeSSiarhei Volkau         if (unlikely(XRa == 0 && XRd == 0)) {
3440513cfdaeSSiarhei Volkau             /* destinations are zero register -> do nothing */
3441513cfdaeSSiarhei Volkau         } else {
3442513cfdaeSSiarhei Volkau             /* FIXME ??? What if XRa == XRd ??? */
3443513cfdaeSSiarhei Volkau             /* aptn2 is unused here */
3444513cfdaeSSiarhei Volkau             gen_load_mxu_gpr(t0, XRb);
3445513cfdaeSSiarhei Volkau             gen_load_mxu_gpr(t1, XRc);
3446513cfdaeSSiarhei Volkau             gen_load_mxu_cr(cr);
3447513cfdaeSSiarhei Volkau             if (XRa != 0) {
3448513cfdaeSSiarhei Volkau                 tcg_gen_extract_tl(t2, cr, 31, 1);
3449513cfdaeSSiarhei Volkau                 tcg_gen_add_tl(t0, t0, t2);
3450513cfdaeSSiarhei Volkau                 tcg_gen_add_tl(mxu_gpr[XRa - 1], mxu_gpr[XRa - 1], t0);
3451513cfdaeSSiarhei Volkau             }
3452513cfdaeSSiarhei Volkau             if (XRd != 0) {
3453513cfdaeSSiarhei Volkau                 tcg_gen_extract_tl(t2, cr, 30, 1);
3454513cfdaeSSiarhei Volkau                 tcg_gen_add_tl(t1, t1, t2);
3455513cfdaeSSiarhei Volkau                 tcg_gen_add_tl(mxu_gpr[XRd - 1], mxu_gpr[XRd - 1], t1);
3456513cfdaeSSiarhei Volkau             }
3457513cfdaeSSiarhei Volkau         }
34589e51e0cdSSiarhei Volkau     } else if (unlikely(XRa == 0 && XRd == 0)) {
34599e51e0cdSSiarhei Volkau         /* destinations are zero register -> do nothing */
34609e51e0cdSSiarhei Volkau     } else {
34619e51e0cdSSiarhei Volkau         /* common case */
3462513cfdaeSSiarhei Volkau         /* FIXME ??? What if XRa == XRd ??? */
3463513cfdaeSSiarhei Volkau         TCGv carry = tcg_temp_new();
3464513cfdaeSSiarhei Volkau 
34659e51e0cdSSiarhei Volkau         gen_load_mxu_gpr(t0, XRb);
34669e51e0cdSSiarhei Volkau         gen_load_mxu_gpr(t1, XRc);
34679e51e0cdSSiarhei Volkau         gen_load_mxu_cr(cr);
34689e51e0cdSSiarhei Volkau         if (XRa != 0) {
34699e51e0cdSSiarhei Volkau             if (aptn2 & 2) {
34709e51e0cdSSiarhei Volkau                 tcg_gen_sub_i32(t2, t0, t1);
34719e51e0cdSSiarhei Volkau                 tcg_gen_setcond_tl(TCG_COND_GTU, carry, t0, t1);
34729e51e0cdSSiarhei Volkau             } else {
34739e51e0cdSSiarhei Volkau                 tcg_gen_add_i32(t2, t0, t1);
34749e51e0cdSSiarhei Volkau                 tcg_gen_setcond_tl(TCG_COND_GTU, carry, t0, t2);
34759e51e0cdSSiarhei Volkau             }
34769e51e0cdSSiarhei Volkau             tcg_gen_andi_tl(cr, cr, 0x7fffffff);
34779e51e0cdSSiarhei Volkau             tcg_gen_shli_tl(carry, carry, 31);
34789e51e0cdSSiarhei Volkau             tcg_gen_or_tl(cr, cr, carry);
34799e51e0cdSSiarhei Volkau             gen_store_mxu_gpr(t2, XRa);
34809e51e0cdSSiarhei Volkau         }
34819e51e0cdSSiarhei Volkau         if (XRd != 0) {
34829e51e0cdSSiarhei Volkau             if (aptn2 & 1) {
34839e51e0cdSSiarhei Volkau                 tcg_gen_sub_i32(t2, t0, t1);
34849e51e0cdSSiarhei Volkau                 tcg_gen_setcond_tl(TCG_COND_GTU, carry, t0, t1);
34859e51e0cdSSiarhei Volkau             } else {
34869e51e0cdSSiarhei Volkau                 tcg_gen_add_i32(t2, t0, t1);
34879e51e0cdSSiarhei Volkau                 tcg_gen_setcond_tl(TCG_COND_GTU, carry, t0, t2);
34889e51e0cdSSiarhei Volkau             }
34899e51e0cdSSiarhei Volkau             tcg_gen_andi_tl(cr, cr, 0xbfffffff);
34909e51e0cdSSiarhei Volkau             tcg_gen_shli_tl(carry, carry, 30);
34919e51e0cdSSiarhei Volkau             tcg_gen_or_tl(cr, cr, carry);
34929e51e0cdSSiarhei Volkau             gen_store_mxu_gpr(t2, XRd);
34939e51e0cdSSiarhei Volkau         }
34949e51e0cdSSiarhei Volkau         gen_store_mxu_cr(cr);
34959e51e0cdSSiarhei Volkau     }
34969e51e0cdSSiarhei Volkau }
34979e51e0cdSSiarhei Volkau 
34989e51e0cdSSiarhei Volkau /*
349998db7a58SSiarhei Volkau  * D32ACC XRa, XRb, XRc, XRd, aptn2 - Double
350098db7a58SSiarhei Volkau  * 32 bit pattern addition/subtraction and accumulate.
350198db7a58SSiarhei Volkau  */
gen_mxu_d32acc(DisasContext * ctx)350298db7a58SSiarhei Volkau static void gen_mxu_d32acc(DisasContext *ctx)
350398db7a58SSiarhei Volkau {
350498db7a58SSiarhei Volkau     uint32_t aptn2, XRc, XRb, XRa, XRd;
350598db7a58SSiarhei Volkau 
350698db7a58SSiarhei Volkau     aptn2 = extract32(ctx->opcode, 24, 2);
350798db7a58SSiarhei Volkau     XRd   = extract32(ctx->opcode, 18, 4);
350898db7a58SSiarhei Volkau     XRc   = extract32(ctx->opcode, 14, 4);
350998db7a58SSiarhei Volkau     XRb   = extract32(ctx->opcode, 10, 4);
351098db7a58SSiarhei Volkau     XRa   = extract32(ctx->opcode,  6, 4);
351198db7a58SSiarhei Volkau 
351298db7a58SSiarhei Volkau     TCGv t0 = tcg_temp_new();
351398db7a58SSiarhei Volkau     TCGv t1 = tcg_temp_new();
351498db7a58SSiarhei Volkau     TCGv t2 = tcg_temp_new();
351598db7a58SSiarhei Volkau 
351698db7a58SSiarhei Volkau     if (unlikely(XRa == 0 && XRd == 0)) {
351798db7a58SSiarhei Volkau         /* destinations are zero register -> do nothing */
351898db7a58SSiarhei Volkau     } else {
351998db7a58SSiarhei Volkau         /* common case */
352098db7a58SSiarhei Volkau         gen_load_mxu_gpr(t0, XRb);
352198db7a58SSiarhei Volkau         gen_load_mxu_gpr(t1, XRc);
352298db7a58SSiarhei Volkau         if (XRa != 0) {
352398db7a58SSiarhei Volkau             if (aptn2 & 2) {
352498db7a58SSiarhei Volkau                 tcg_gen_sub_tl(t2, t0, t1);
352598db7a58SSiarhei Volkau             } else {
352698db7a58SSiarhei Volkau                 tcg_gen_add_tl(t2, t0, t1);
352798db7a58SSiarhei Volkau             }
352898db7a58SSiarhei Volkau             tcg_gen_add_tl(mxu_gpr[XRa - 1], mxu_gpr[XRa - 1], t2);
352998db7a58SSiarhei Volkau         }
353098db7a58SSiarhei Volkau         if (XRd != 0) {
353198db7a58SSiarhei Volkau             if (aptn2 & 1) {
353298db7a58SSiarhei Volkau                 tcg_gen_sub_tl(t2, t0, t1);
353398db7a58SSiarhei Volkau             } else {
353498db7a58SSiarhei Volkau                 tcg_gen_add_tl(t2, t0, t1);
353598db7a58SSiarhei Volkau             }
353698db7a58SSiarhei Volkau             tcg_gen_add_tl(mxu_gpr[XRd - 1], mxu_gpr[XRd - 1], t2);
353798db7a58SSiarhei Volkau         }
353898db7a58SSiarhei Volkau     }
353998db7a58SSiarhei Volkau }
354098db7a58SSiarhei Volkau 
354198db7a58SSiarhei Volkau /*
354298db7a58SSiarhei Volkau  * D32ACCM XRa, XRb, XRc, XRd, aptn2 - Double
354398db7a58SSiarhei Volkau  * 32 bit pattern addition/subtraction and accumulate.
354498db7a58SSiarhei Volkau  */
gen_mxu_d32accm(DisasContext * ctx)354598db7a58SSiarhei Volkau static void gen_mxu_d32accm(DisasContext *ctx)
354698db7a58SSiarhei Volkau {
354798db7a58SSiarhei Volkau     uint32_t aptn2, XRc, XRb, XRa, XRd;
354898db7a58SSiarhei Volkau 
354998db7a58SSiarhei Volkau     aptn2 = extract32(ctx->opcode, 24, 2);
355098db7a58SSiarhei Volkau     XRd   = extract32(ctx->opcode, 18, 4);
355198db7a58SSiarhei Volkau     XRc   = extract32(ctx->opcode, 14, 4);
355298db7a58SSiarhei Volkau     XRb   = extract32(ctx->opcode, 10, 4);
355398db7a58SSiarhei Volkau     XRa   = extract32(ctx->opcode,  6, 4);
355498db7a58SSiarhei Volkau 
355598db7a58SSiarhei Volkau     TCGv t0 = tcg_temp_new();
355698db7a58SSiarhei Volkau     TCGv t1 = tcg_temp_new();
355798db7a58SSiarhei Volkau     TCGv t2 = tcg_temp_new();
355898db7a58SSiarhei Volkau 
355998db7a58SSiarhei Volkau     if (unlikely(XRa == 0 && XRd == 0)) {
356098db7a58SSiarhei Volkau         /* destinations are zero register -> do nothing */
356198db7a58SSiarhei Volkau     } else {
356298db7a58SSiarhei Volkau         /* common case */
356398db7a58SSiarhei Volkau         gen_load_mxu_gpr(t0, XRb);
356498db7a58SSiarhei Volkau         gen_load_mxu_gpr(t1, XRc);
356598db7a58SSiarhei Volkau         if (XRa != 0) {
356698db7a58SSiarhei Volkau             tcg_gen_add_tl(t2, t0, t1);
356798db7a58SSiarhei Volkau             if (aptn2 & 2) {
356898db7a58SSiarhei Volkau                 tcg_gen_sub_tl(mxu_gpr[XRa - 1], mxu_gpr[XRa - 1], t2);
356998db7a58SSiarhei Volkau             } else {
357098db7a58SSiarhei Volkau                 tcg_gen_add_tl(mxu_gpr[XRa - 1], mxu_gpr[XRa - 1], t2);
357198db7a58SSiarhei Volkau             }
357298db7a58SSiarhei Volkau         }
357398db7a58SSiarhei Volkau         if (XRd != 0) {
357498db7a58SSiarhei Volkau             tcg_gen_sub_tl(t2, t0, t1);
357598db7a58SSiarhei Volkau             if (aptn2 & 1) {
357698db7a58SSiarhei Volkau                 tcg_gen_sub_tl(mxu_gpr[XRd - 1], mxu_gpr[XRd - 1], t2);
357798db7a58SSiarhei Volkau             } else {
357898db7a58SSiarhei Volkau                 tcg_gen_add_tl(mxu_gpr[XRd - 1], mxu_gpr[XRd - 1], t2);
357998db7a58SSiarhei Volkau             }
358098db7a58SSiarhei Volkau         }
358198db7a58SSiarhei Volkau     }
358298db7a58SSiarhei Volkau }
358398db7a58SSiarhei Volkau 
358498db7a58SSiarhei Volkau /*
358598db7a58SSiarhei Volkau  * D32ASUM XRa, XRb, XRc, XRd, aptn2 - Double
358698db7a58SSiarhei Volkau  * 32 bit pattern addition/subtraction.
358798db7a58SSiarhei Volkau  */
gen_mxu_d32asum(DisasContext * ctx)358898db7a58SSiarhei Volkau static void gen_mxu_d32asum(DisasContext *ctx)
358998db7a58SSiarhei Volkau {
359098db7a58SSiarhei Volkau     uint32_t aptn2, XRc, XRb, XRa, XRd;
359198db7a58SSiarhei Volkau 
359298db7a58SSiarhei Volkau     aptn2 = extract32(ctx->opcode, 24, 2);
359398db7a58SSiarhei Volkau     XRd   = extract32(ctx->opcode, 18, 4);
359498db7a58SSiarhei Volkau     XRc   = extract32(ctx->opcode, 14, 4);
359598db7a58SSiarhei Volkau     XRb   = extract32(ctx->opcode, 10, 4);
359698db7a58SSiarhei Volkau     XRa   = extract32(ctx->opcode,  6, 4);
359798db7a58SSiarhei Volkau 
359898db7a58SSiarhei Volkau     TCGv t0 = tcg_temp_new();
359998db7a58SSiarhei Volkau     TCGv t1 = tcg_temp_new();
360098db7a58SSiarhei Volkau 
360198db7a58SSiarhei Volkau     if (unlikely(XRa == 0 && XRd == 0)) {
360298db7a58SSiarhei Volkau         /* destinations are zero register -> do nothing */
360398db7a58SSiarhei Volkau     } else {
360498db7a58SSiarhei Volkau         /* common case */
360598db7a58SSiarhei Volkau         gen_load_mxu_gpr(t0, XRb);
360698db7a58SSiarhei Volkau         gen_load_mxu_gpr(t1, XRc);
360798db7a58SSiarhei Volkau         if (XRa != 0) {
360898db7a58SSiarhei Volkau             if (aptn2 & 2) {
360998db7a58SSiarhei Volkau                 tcg_gen_sub_tl(mxu_gpr[XRa - 1], mxu_gpr[XRa - 1], t0);
361098db7a58SSiarhei Volkau             } else {
361198db7a58SSiarhei Volkau                 tcg_gen_add_tl(mxu_gpr[XRa - 1], mxu_gpr[XRa - 1], t0);
361298db7a58SSiarhei Volkau             }
361398db7a58SSiarhei Volkau         }
361498db7a58SSiarhei Volkau         if (XRd != 0) {
361598db7a58SSiarhei Volkau             if (aptn2 & 1) {
361698db7a58SSiarhei Volkau                 tcg_gen_sub_tl(mxu_gpr[XRd - 1], mxu_gpr[XRd - 1], t1);
361798db7a58SSiarhei Volkau             } else {
361898db7a58SSiarhei Volkau                 tcg_gen_add_tl(mxu_gpr[XRd - 1], mxu_gpr[XRd - 1], t1);
361998db7a58SSiarhei Volkau             }
362098db7a58SSiarhei Volkau         }
362198db7a58SSiarhei Volkau     }
362298db7a58SSiarhei Volkau }
362398db7a58SSiarhei Volkau 
362498db7a58SSiarhei Volkau /*
3625f1e6547cSSiarhei Volkau  *                 MXU instruction category: Miscellaneous
3626f1e6547cSSiarhei Volkau  *                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3627f1e6547cSSiarhei Volkau  *
362859259634SSiarhei Volkau  *               S32EXTR      S32LUI
362929059e72SSiarhei Volkau  *               S32EXTRV
3630f1e6547cSSiarhei Volkau  *                            Q16SAT
363168a48804SSiarhei Volkau  *                            Q16SCOP
3632f1e6547cSSiarhei Volkau  */
3633f1e6547cSSiarhei Volkau 
3634f1e6547cSSiarhei Volkau /*
363529059e72SSiarhei Volkau  *  S32EXTR XRa, XRd, rs, bits5
363629059e72SSiarhei Volkau  *    Extract bits5 bits from 64-bit pair {XRa:XRd}
363729059e72SSiarhei Volkau  *    starting from rs[4:0] offset and put to the XRa.
363829059e72SSiarhei Volkau  */
gen_mxu_s32extr(DisasContext * ctx)363929059e72SSiarhei Volkau static void gen_mxu_s32extr(DisasContext *ctx)
364029059e72SSiarhei Volkau {
364129059e72SSiarhei Volkau     TCGv t0, t1, t2, t3;
364229059e72SSiarhei Volkau     uint32_t XRa, XRd, rs, bits5;
364329059e72SSiarhei Volkau 
364429059e72SSiarhei Volkau     t0 = tcg_temp_new();
364529059e72SSiarhei Volkau     t1 = tcg_temp_new();
364629059e72SSiarhei Volkau     t2 = tcg_temp_new();
364729059e72SSiarhei Volkau     t3 = tcg_temp_new();
364829059e72SSiarhei Volkau 
364929059e72SSiarhei Volkau     XRa   = extract32(ctx->opcode,  6, 4);
365029059e72SSiarhei Volkau     XRd   = extract32(ctx->opcode, 10, 4);
365129059e72SSiarhei Volkau     bits5 = extract32(ctx->opcode, 16, 5);
365229059e72SSiarhei Volkau     rs    = extract32(ctx->opcode, 21, 5);
365329059e72SSiarhei Volkau 
365429059e72SSiarhei Volkau     /* {tmp} = {XRa:XRd} >> (64 - rt - bits5); */
365529059e72SSiarhei Volkau     /* {XRa} = extract({tmp}, 0, bits5); */
365629059e72SSiarhei Volkau     if (bits5 > 0) {
365729059e72SSiarhei Volkau         TCGLabel *l_xra_only = gen_new_label();
365829059e72SSiarhei Volkau         TCGLabel *l_done = gen_new_label();
365929059e72SSiarhei Volkau 
366029059e72SSiarhei Volkau         gen_load_mxu_gpr(t0, XRd);
366129059e72SSiarhei Volkau         gen_load_mxu_gpr(t1, XRa);
366229059e72SSiarhei Volkau         gen_load_gpr(t2, rs);
366329059e72SSiarhei Volkau         tcg_gen_andi_tl(t2, t2, 0x1f);
366429059e72SSiarhei Volkau         tcg_gen_subfi_tl(t2, 32, t2);
366529059e72SSiarhei Volkau         tcg_gen_brcondi_tl(TCG_COND_GE, t2, bits5, l_xra_only);
366629059e72SSiarhei Volkau         tcg_gen_subfi_tl(t2, bits5, t2);
366729059e72SSiarhei Volkau         tcg_gen_subfi_tl(t3, 32, t2);
366829059e72SSiarhei Volkau         tcg_gen_shr_tl(t0, t0, t3);
366929059e72SSiarhei Volkau         tcg_gen_shl_tl(t1, t1, t2);
367029059e72SSiarhei Volkau         tcg_gen_or_tl(t0, t0, t1);
367129059e72SSiarhei Volkau         tcg_gen_br(l_done);
367229059e72SSiarhei Volkau         gen_set_label(l_xra_only);
367329059e72SSiarhei Volkau         tcg_gen_subi_tl(t2, t2, bits5);
367429059e72SSiarhei Volkau         tcg_gen_shr_tl(t0, t1, t2);
367529059e72SSiarhei Volkau         gen_set_label(l_done);
367629059e72SSiarhei Volkau         tcg_gen_extract_tl(t0, t0, 0, bits5);
367729059e72SSiarhei Volkau     } else {
367829059e72SSiarhei Volkau         /* unspecified behavior but matches tests on real hardware*/
367929059e72SSiarhei Volkau         tcg_gen_movi_tl(t0, 0);
368029059e72SSiarhei Volkau     }
368129059e72SSiarhei Volkau     gen_store_mxu_gpr(t0, XRa);
368229059e72SSiarhei Volkau }
368329059e72SSiarhei Volkau 
368429059e72SSiarhei Volkau /*
368529059e72SSiarhei Volkau  *  S32EXTRV XRa, XRd, rs, rt
368629059e72SSiarhei Volkau  *    Extract rt[4:0] bits from 64-bit pair {XRa:XRd}
368729059e72SSiarhei Volkau  *    starting from rs[4:0] offset and put to the XRa.
368829059e72SSiarhei Volkau  */
gen_mxu_s32extrv(DisasContext * ctx)368929059e72SSiarhei Volkau static void gen_mxu_s32extrv(DisasContext *ctx)
369029059e72SSiarhei Volkau {
369129059e72SSiarhei Volkau     TCGv t0, t1, t2, t3, t4;
369229059e72SSiarhei Volkau     uint32_t XRa, XRd, rs, rt;
369329059e72SSiarhei Volkau 
369429059e72SSiarhei Volkau     t0 = tcg_temp_new();
369529059e72SSiarhei Volkau     t1 = tcg_temp_new();
369629059e72SSiarhei Volkau     t2 = tcg_temp_new();
369729059e72SSiarhei Volkau     t3 = tcg_temp_new();
369829059e72SSiarhei Volkau     t4 = tcg_temp_new();
369929059e72SSiarhei Volkau     TCGLabel *l_xra_only = gen_new_label();
370029059e72SSiarhei Volkau     TCGLabel *l_done = gen_new_label();
370129059e72SSiarhei Volkau     TCGLabel *l_zero = gen_new_label();
370229059e72SSiarhei Volkau     TCGLabel *l_extract = gen_new_label();
370329059e72SSiarhei Volkau 
370429059e72SSiarhei Volkau     XRa = extract32(ctx->opcode,  6, 4);
370529059e72SSiarhei Volkau     XRd = extract32(ctx->opcode, 10, 4);
370629059e72SSiarhei Volkau     rt  = extract32(ctx->opcode, 16, 5);
370729059e72SSiarhei Volkau     rs  = extract32(ctx->opcode, 21, 5);
370829059e72SSiarhei Volkau 
370929059e72SSiarhei Volkau     /* {tmp} = {XRa:XRd} >> (64 - rs - rt) */
371029059e72SSiarhei Volkau     gen_load_mxu_gpr(t0, XRd);
371129059e72SSiarhei Volkau     gen_load_mxu_gpr(t1, XRa);
371229059e72SSiarhei Volkau     gen_load_gpr(t2, rs);
371329059e72SSiarhei Volkau     gen_load_gpr(t4, rt);
371429059e72SSiarhei Volkau     tcg_gen_brcondi_tl(TCG_COND_EQ, t4, 0, l_zero);
371529059e72SSiarhei Volkau     tcg_gen_andi_tl(t2, t2, 0x1f);
371629059e72SSiarhei Volkau     tcg_gen_subfi_tl(t2, 32, t2);
371729059e72SSiarhei Volkau     tcg_gen_brcond_tl(TCG_COND_GE, t2, t4, l_xra_only);
371829059e72SSiarhei Volkau     tcg_gen_sub_tl(t2, t4, t2);
371929059e72SSiarhei Volkau     tcg_gen_subfi_tl(t3, 32, t2);
372029059e72SSiarhei Volkau     tcg_gen_shr_tl(t0, t0, t3);
372129059e72SSiarhei Volkau     tcg_gen_shl_tl(t1, t1, t2);
372229059e72SSiarhei Volkau     tcg_gen_or_tl(t0, t0, t1);
372329059e72SSiarhei Volkau     tcg_gen_br(l_extract);
372429059e72SSiarhei Volkau 
372529059e72SSiarhei Volkau     gen_set_label(l_xra_only);
372629059e72SSiarhei Volkau     tcg_gen_sub_tl(t2, t2, t4);
372729059e72SSiarhei Volkau     tcg_gen_shr_tl(t0, t1, t2);
372829059e72SSiarhei Volkau     tcg_gen_br(l_extract);
372929059e72SSiarhei Volkau 
373029059e72SSiarhei Volkau     /* unspecified behavior but matches tests on real hardware*/
373129059e72SSiarhei Volkau     gen_set_label(l_zero);
373229059e72SSiarhei Volkau     tcg_gen_movi_tl(t0, 0);
373329059e72SSiarhei Volkau     tcg_gen_br(l_done);
373429059e72SSiarhei Volkau 
373529059e72SSiarhei Volkau     /* {XRa} = extract({tmp}, 0, rt) */
373629059e72SSiarhei Volkau     gen_set_label(l_extract);
373729059e72SSiarhei Volkau     tcg_gen_subfi_tl(t4, 32, t4);
373829059e72SSiarhei Volkau     tcg_gen_shl_tl(t0, t0, t4);
373929059e72SSiarhei Volkau     tcg_gen_shr_tl(t0, t0, t4);
374029059e72SSiarhei Volkau 
374129059e72SSiarhei Volkau     gen_set_label(l_done);
374229059e72SSiarhei Volkau     gen_store_mxu_gpr(t0, XRa);
374329059e72SSiarhei Volkau }
374429059e72SSiarhei Volkau 
374529059e72SSiarhei Volkau /*
374659259634SSiarhei Volkau  *  S32LUI XRa, S8, optn3
374759259634SSiarhei Volkau  *    Permutate the immediate S8 value to form a word
374859259634SSiarhei Volkau  *    to update XRa.
374959259634SSiarhei Volkau  */
gen_mxu_s32lui(DisasContext * ctx)375059259634SSiarhei Volkau static void gen_mxu_s32lui(DisasContext *ctx)
375159259634SSiarhei Volkau {
375259259634SSiarhei Volkau     uint32_t XRa, s8, optn3, pad;
375359259634SSiarhei Volkau 
375459259634SSiarhei Volkau     XRa   = extract32(ctx->opcode,  6, 4);
375559259634SSiarhei Volkau     s8    = extract32(ctx->opcode, 10, 8);
375659259634SSiarhei Volkau     pad   = extract32(ctx->opcode, 21, 2);
375759259634SSiarhei Volkau     optn3 = extract32(ctx->opcode, 23, 3);
375859259634SSiarhei Volkau 
375959259634SSiarhei Volkau     if (unlikely(pad != 0)) {
376059259634SSiarhei Volkau         /* opcode padding incorrect -> do nothing */
376159259634SSiarhei Volkau     } else if (unlikely(XRa == 0)) {
376259259634SSiarhei Volkau         /* destination is zero register -> do nothing */
376359259634SSiarhei Volkau     } else {
376459259634SSiarhei Volkau         uint32_t s16;
376559259634SSiarhei Volkau         TCGv t0 = tcg_temp_new();
376659259634SSiarhei Volkau 
376759259634SSiarhei Volkau         switch (optn3) {
376859259634SSiarhei Volkau         case 0:
376959259634SSiarhei Volkau             tcg_gen_movi_tl(t0, s8);
377059259634SSiarhei Volkau             break;
377159259634SSiarhei Volkau         case 1:
377259259634SSiarhei Volkau             tcg_gen_movi_tl(t0, s8 << 8);
377359259634SSiarhei Volkau             break;
377459259634SSiarhei Volkau         case 2:
377559259634SSiarhei Volkau             tcg_gen_movi_tl(t0, s8 << 16);
377659259634SSiarhei Volkau             break;
377759259634SSiarhei Volkau         case 3:
377859259634SSiarhei Volkau             tcg_gen_movi_tl(t0, s8 << 24);
377959259634SSiarhei Volkau             break;
378059259634SSiarhei Volkau         case 4:
378159259634SSiarhei Volkau             tcg_gen_movi_tl(t0, (s8 << 16) | s8);
378259259634SSiarhei Volkau             break;
378359259634SSiarhei Volkau         case 5:
378459259634SSiarhei Volkau             tcg_gen_movi_tl(t0, (s8 << 24) | (s8 << 8));
378559259634SSiarhei Volkau             break;
378659259634SSiarhei Volkau         case 6:
378759259634SSiarhei Volkau             s16 = (uint16_t)(int16_t)(int8_t)s8;
378859259634SSiarhei Volkau             tcg_gen_movi_tl(t0, (s16 << 16) | s16);
378959259634SSiarhei Volkau             break;
379059259634SSiarhei Volkau         case 7:
379159259634SSiarhei Volkau             tcg_gen_movi_tl(t0, (s8 << 24) | (s8 << 16) | (s8 << 8) | s8);
379259259634SSiarhei Volkau             break;
379359259634SSiarhei Volkau         }
379459259634SSiarhei Volkau         gen_store_mxu_gpr(t0, XRa);
379559259634SSiarhei Volkau     }
379659259634SSiarhei Volkau }
379759259634SSiarhei Volkau 
379859259634SSiarhei Volkau /*
3799f1e6547cSSiarhei Volkau  *  Q16SAT XRa, XRb, XRc
3800f1e6547cSSiarhei Volkau  *  Packs four 16-bit signed integers in XRb and XRc to
3801f1e6547cSSiarhei Volkau  *  four saturated unsigned 8-bit into XRa.
3802f1e6547cSSiarhei Volkau  *
3803f1e6547cSSiarhei Volkau  */
gen_mxu_Q16SAT(DisasContext * ctx)3804f1e6547cSSiarhei Volkau static void gen_mxu_Q16SAT(DisasContext *ctx)
3805f1e6547cSSiarhei Volkau {
3806f1e6547cSSiarhei Volkau     uint32_t pad, XRc, XRb, XRa;
3807f1e6547cSSiarhei Volkau 
3808f1e6547cSSiarhei Volkau     pad = extract32(ctx->opcode, 21, 3);
3809f1e6547cSSiarhei Volkau     XRc = extract32(ctx->opcode, 14, 4);
3810f1e6547cSSiarhei Volkau     XRb = extract32(ctx->opcode, 10, 4);
3811f1e6547cSSiarhei Volkau     XRa = extract32(ctx->opcode,  6, 4);
3812f1e6547cSSiarhei Volkau 
3813f1e6547cSSiarhei Volkau     if (unlikely(pad != 0)) {
3814f1e6547cSSiarhei Volkau         /* opcode padding incorrect -> do nothing */
3815f1e6547cSSiarhei Volkau     } else if (unlikely(XRa == 0)) {
3816f1e6547cSSiarhei Volkau         /* destination is zero register -> do nothing */
3817f1e6547cSSiarhei Volkau     } else {
3818f1e6547cSSiarhei Volkau         /* the most general case */
3819f1e6547cSSiarhei Volkau         TCGv t0 = tcg_temp_new();
3820f1e6547cSSiarhei Volkau         TCGv t1 = tcg_temp_new();
3821f1e6547cSSiarhei Volkau         TCGv t2 = tcg_temp_new();
3822f1e6547cSSiarhei Volkau 
3823f1e6547cSSiarhei Volkau         tcg_gen_movi_tl(t2, 0);
3824f1e6547cSSiarhei Volkau         if (XRb != 0) {
3825f1e6547cSSiarhei Volkau             TCGLabel *l_less_hi = gen_new_label();
3826f1e6547cSSiarhei Volkau             TCGLabel *l_less_lo = gen_new_label();
3827f1e6547cSSiarhei Volkau             TCGLabel *l_lo = gen_new_label();
3828f1e6547cSSiarhei Volkau             TCGLabel *l_greater_hi = gen_new_label();
3829f1e6547cSSiarhei Volkau             TCGLabel *l_greater_lo = gen_new_label();
3830f1e6547cSSiarhei Volkau             TCGLabel *l_done = gen_new_label();
3831f1e6547cSSiarhei Volkau 
3832f1e6547cSSiarhei Volkau             tcg_gen_sari_tl(t0, mxu_gpr[XRb - 1], 16);
3833f1e6547cSSiarhei Volkau             tcg_gen_brcondi_tl(TCG_COND_LT, t0, 0, l_less_hi);
3834f1e6547cSSiarhei Volkau             tcg_gen_brcondi_tl(TCG_COND_GT, t0, 255, l_greater_hi);
3835f1e6547cSSiarhei Volkau             tcg_gen_br(l_lo);
3836f1e6547cSSiarhei Volkau             gen_set_label(l_less_hi);
3837f1e6547cSSiarhei Volkau             tcg_gen_movi_tl(t0, 0);
3838f1e6547cSSiarhei Volkau             tcg_gen_br(l_lo);
3839f1e6547cSSiarhei Volkau             gen_set_label(l_greater_hi);
3840f1e6547cSSiarhei Volkau             tcg_gen_movi_tl(t0, 255);
3841f1e6547cSSiarhei Volkau 
3842f1e6547cSSiarhei Volkau             gen_set_label(l_lo);
3843f1e6547cSSiarhei Volkau             tcg_gen_shli_tl(t1, mxu_gpr[XRb - 1], 16);
3844f1e6547cSSiarhei Volkau             tcg_gen_sari_tl(t1, t1, 16);
3845f1e6547cSSiarhei Volkau             tcg_gen_brcondi_tl(TCG_COND_LT, t1, 0, l_less_lo);
3846f1e6547cSSiarhei Volkau             tcg_gen_brcondi_tl(TCG_COND_GT, t1, 255, l_greater_lo);
3847f1e6547cSSiarhei Volkau             tcg_gen_br(l_done);
3848f1e6547cSSiarhei Volkau             gen_set_label(l_less_lo);
3849f1e6547cSSiarhei Volkau             tcg_gen_movi_tl(t1, 0);
3850f1e6547cSSiarhei Volkau             tcg_gen_br(l_done);
3851f1e6547cSSiarhei Volkau             gen_set_label(l_greater_lo);
3852f1e6547cSSiarhei Volkau             tcg_gen_movi_tl(t1, 255);
3853f1e6547cSSiarhei Volkau 
3854f1e6547cSSiarhei Volkau             gen_set_label(l_done);
3855f1e6547cSSiarhei Volkau             tcg_gen_shli_tl(t2, t0, 24);
3856f1e6547cSSiarhei Volkau             tcg_gen_shli_tl(t1, t1, 16);
3857f1e6547cSSiarhei Volkau             tcg_gen_or_tl(t2, t2, t1);
3858f1e6547cSSiarhei Volkau         }
3859f1e6547cSSiarhei Volkau 
3860f1e6547cSSiarhei Volkau         if (XRc != 0) {
3861f1e6547cSSiarhei Volkau             TCGLabel *l_less_hi = gen_new_label();
3862f1e6547cSSiarhei Volkau             TCGLabel *l_less_lo = gen_new_label();
3863f1e6547cSSiarhei Volkau             TCGLabel *l_lo = gen_new_label();
3864f1e6547cSSiarhei Volkau             TCGLabel *l_greater_hi = gen_new_label();
3865f1e6547cSSiarhei Volkau             TCGLabel *l_greater_lo = gen_new_label();
3866f1e6547cSSiarhei Volkau             TCGLabel *l_done = gen_new_label();
3867f1e6547cSSiarhei Volkau 
3868f1e6547cSSiarhei Volkau             tcg_gen_sari_tl(t0, mxu_gpr[XRc - 1], 16);
3869f1e6547cSSiarhei Volkau             tcg_gen_brcondi_tl(TCG_COND_LT, t0, 0, l_less_hi);
3870f1e6547cSSiarhei Volkau             tcg_gen_brcondi_tl(TCG_COND_GT, t0, 255, l_greater_hi);
3871f1e6547cSSiarhei Volkau             tcg_gen_br(l_lo);
3872f1e6547cSSiarhei Volkau             gen_set_label(l_less_hi);
3873f1e6547cSSiarhei Volkau             tcg_gen_movi_tl(t0, 0);
3874f1e6547cSSiarhei Volkau             tcg_gen_br(l_lo);
3875f1e6547cSSiarhei Volkau             gen_set_label(l_greater_hi);
3876f1e6547cSSiarhei Volkau             tcg_gen_movi_tl(t0, 255);
3877f1e6547cSSiarhei Volkau 
3878f1e6547cSSiarhei Volkau             gen_set_label(l_lo);
3879f1e6547cSSiarhei Volkau             tcg_gen_shli_tl(t1, mxu_gpr[XRc - 1], 16);
3880f1e6547cSSiarhei Volkau             tcg_gen_sari_tl(t1, t1, 16);
3881f1e6547cSSiarhei Volkau             tcg_gen_brcondi_tl(TCG_COND_LT, t1, 0, l_less_lo);
3882f1e6547cSSiarhei Volkau             tcg_gen_brcondi_tl(TCG_COND_GT, t1, 255, l_greater_lo);
3883f1e6547cSSiarhei Volkau             tcg_gen_br(l_done);
3884f1e6547cSSiarhei Volkau             gen_set_label(l_less_lo);
3885f1e6547cSSiarhei Volkau             tcg_gen_movi_tl(t1, 0);
3886f1e6547cSSiarhei Volkau             tcg_gen_br(l_done);
3887f1e6547cSSiarhei Volkau             gen_set_label(l_greater_lo);
3888f1e6547cSSiarhei Volkau             tcg_gen_movi_tl(t1, 255);
3889f1e6547cSSiarhei Volkau 
3890f1e6547cSSiarhei Volkau             gen_set_label(l_done);
3891f1e6547cSSiarhei Volkau             tcg_gen_shli_tl(t0, t0, 8);
3892f1e6547cSSiarhei Volkau             tcg_gen_or_tl(t2, t2, t0);
3893f1e6547cSSiarhei Volkau             tcg_gen_or_tl(t2, t2, t1);
3894f1e6547cSSiarhei Volkau         }
3895f1e6547cSSiarhei Volkau         gen_store_mxu_gpr(t2, XRa);
3896f1e6547cSSiarhei Volkau     }
3897f1e6547cSSiarhei Volkau }
3898f1e6547cSSiarhei Volkau 
389968a48804SSiarhei Volkau /*
390068a48804SSiarhei Volkau  *  Q16SCOP XRa, XRd, XRb, XRc
390168a48804SSiarhei Volkau  *    Determine sign of quad packed 16-bit signed values
390268a48804SSiarhei Volkau  *    in XRb and XRc put result in XRa and XRd respectively.
390368a48804SSiarhei Volkau  */
gen_mxu_q16scop(DisasContext * ctx)390468a48804SSiarhei Volkau static void gen_mxu_q16scop(DisasContext *ctx)
390568a48804SSiarhei Volkau {
390668a48804SSiarhei Volkau     uint32_t XRd, XRc, XRb, XRa;
390768a48804SSiarhei Volkau 
390868a48804SSiarhei Volkau     XRd  = extract32(ctx->opcode, 18, 4);
390968a48804SSiarhei Volkau     XRc  = extract32(ctx->opcode, 14, 4);
391068a48804SSiarhei Volkau     XRb  = extract32(ctx->opcode, 10, 4);
391168a48804SSiarhei Volkau     XRa  = extract32(ctx->opcode,  6, 4);
391268a48804SSiarhei Volkau 
391368a48804SSiarhei Volkau     TCGv t0 = tcg_temp_new();
391468a48804SSiarhei Volkau     TCGv t1 = tcg_temp_new();
391568a48804SSiarhei Volkau     TCGv t2 = tcg_temp_new();
391668a48804SSiarhei Volkau     TCGv t3 = tcg_temp_new();
391768a48804SSiarhei Volkau     TCGv t4 = tcg_temp_new();
391868a48804SSiarhei Volkau 
391968a48804SSiarhei Volkau     TCGLabel *l_b_hi_lt = gen_new_label();
392068a48804SSiarhei Volkau     TCGLabel *l_b_hi_gt = gen_new_label();
392168a48804SSiarhei Volkau     TCGLabel *l_b_lo = gen_new_label();
392268a48804SSiarhei Volkau     TCGLabel *l_b_lo_lt = gen_new_label();
392368a48804SSiarhei Volkau     TCGLabel *l_c_hi = gen_new_label();
392468a48804SSiarhei Volkau     TCGLabel *l_c_hi_lt = gen_new_label();
392568a48804SSiarhei Volkau     TCGLabel *l_c_hi_gt = gen_new_label();
392668a48804SSiarhei Volkau     TCGLabel *l_c_lo = gen_new_label();
392768a48804SSiarhei Volkau     TCGLabel *l_c_lo_lt = gen_new_label();
392868a48804SSiarhei Volkau     TCGLabel *l_done = gen_new_label();
392968a48804SSiarhei Volkau 
393068a48804SSiarhei Volkau     gen_load_mxu_gpr(t0, XRb);
393168a48804SSiarhei Volkau     gen_load_mxu_gpr(t1, XRc);
393268a48804SSiarhei Volkau 
393368a48804SSiarhei Volkau     tcg_gen_sextract_tl(t2, t0, 16, 16);
393468a48804SSiarhei Volkau     tcg_gen_brcondi_tl(TCG_COND_LT, t2, 0, l_b_hi_lt);
393568a48804SSiarhei Volkau     tcg_gen_brcondi_tl(TCG_COND_GT, t2, 0, l_b_hi_gt);
393668a48804SSiarhei Volkau     tcg_gen_movi_tl(t3, 0);
393768a48804SSiarhei Volkau     tcg_gen_br(l_b_lo);
393868a48804SSiarhei Volkau     gen_set_label(l_b_hi_lt);
393968a48804SSiarhei Volkau     tcg_gen_movi_tl(t3, 0xffff0000);
394068a48804SSiarhei Volkau     tcg_gen_br(l_b_lo);
394168a48804SSiarhei Volkau     gen_set_label(l_b_hi_gt);
394268a48804SSiarhei Volkau     tcg_gen_movi_tl(t3, 0x00010000);
394368a48804SSiarhei Volkau 
394468a48804SSiarhei Volkau     gen_set_label(l_b_lo);
394568a48804SSiarhei Volkau     tcg_gen_sextract_tl(t2, t0, 0, 16);
394668a48804SSiarhei Volkau     tcg_gen_brcondi_tl(TCG_COND_EQ, t2, 0, l_c_hi);
394768a48804SSiarhei Volkau     tcg_gen_brcondi_tl(TCG_COND_LT, t2, 0, l_b_lo_lt);
394868a48804SSiarhei Volkau     tcg_gen_ori_tl(t3, t3, 0x00000001);
394968a48804SSiarhei Volkau     tcg_gen_br(l_c_hi);
395068a48804SSiarhei Volkau     gen_set_label(l_b_lo_lt);
395168a48804SSiarhei Volkau     tcg_gen_ori_tl(t3, t3, 0x0000ffff);
395268a48804SSiarhei Volkau     tcg_gen_br(l_c_hi);
395368a48804SSiarhei Volkau 
395468a48804SSiarhei Volkau     gen_set_label(l_c_hi);
395568a48804SSiarhei Volkau     tcg_gen_sextract_tl(t2, t1, 16, 16);
395668a48804SSiarhei Volkau     tcg_gen_brcondi_tl(TCG_COND_LT, t2, 0, l_c_hi_lt);
395768a48804SSiarhei Volkau     tcg_gen_brcondi_tl(TCG_COND_GT, t2, 0, l_c_hi_gt);
395868a48804SSiarhei Volkau     tcg_gen_movi_tl(t4, 0);
395968a48804SSiarhei Volkau     tcg_gen_br(l_c_lo);
396068a48804SSiarhei Volkau     gen_set_label(l_c_hi_lt);
396168a48804SSiarhei Volkau     tcg_gen_movi_tl(t4, 0xffff0000);
396268a48804SSiarhei Volkau     tcg_gen_br(l_c_lo);
396368a48804SSiarhei Volkau     gen_set_label(l_c_hi_gt);
396468a48804SSiarhei Volkau     tcg_gen_movi_tl(t4, 0x00010000);
396568a48804SSiarhei Volkau 
396668a48804SSiarhei Volkau     gen_set_label(l_c_lo);
396768a48804SSiarhei Volkau     tcg_gen_sextract_tl(t2, t1, 0, 16);
396868a48804SSiarhei Volkau     tcg_gen_brcondi_tl(TCG_COND_EQ, t2, 0, l_done);
396968a48804SSiarhei Volkau     tcg_gen_brcondi_tl(TCG_COND_LT, t2, 0, l_c_lo_lt);
397068a48804SSiarhei Volkau     tcg_gen_ori_tl(t4, t4, 0x00000001);
397168a48804SSiarhei Volkau     tcg_gen_br(l_done);
397268a48804SSiarhei Volkau     gen_set_label(l_c_lo_lt);
397368a48804SSiarhei Volkau     tcg_gen_ori_tl(t4, t4, 0x0000ffff);
397468a48804SSiarhei Volkau 
397568a48804SSiarhei Volkau     gen_set_label(l_done);
397668a48804SSiarhei Volkau     gen_store_mxu_gpr(t3, XRa);
397768a48804SSiarhei Volkau     gen_store_mxu_gpr(t4, XRd);
397868a48804SSiarhei Volkau }
3979bf1df65fSSiarhei Volkau 
3980bf1df65fSSiarhei Volkau /*
39814b9680d3SSiarhei Volkau  *  S32SFL XRa, XRd, XRb, XRc
39824b9680d3SSiarhei Volkau  *    Shuffle bytes according to one of four patterns.
39834b9680d3SSiarhei Volkau  */
gen_mxu_s32sfl(DisasContext * ctx)39844b9680d3SSiarhei Volkau static void gen_mxu_s32sfl(DisasContext *ctx)
39854b9680d3SSiarhei Volkau {
39864b9680d3SSiarhei Volkau     uint32_t XRd, XRc, XRb, XRa, ptn2;
39874b9680d3SSiarhei Volkau 
39884b9680d3SSiarhei Volkau     XRd  = extract32(ctx->opcode, 18, 4);
39894b9680d3SSiarhei Volkau     XRc  = extract32(ctx->opcode, 14, 4);
39904b9680d3SSiarhei Volkau     XRb  = extract32(ctx->opcode, 10, 4);
39914b9680d3SSiarhei Volkau     XRa  = extract32(ctx->opcode,  6, 4);
39924b9680d3SSiarhei Volkau     ptn2 = extract32(ctx->opcode, 24, 2);
39934b9680d3SSiarhei Volkau 
39944b9680d3SSiarhei Volkau     TCGv t0 = tcg_temp_new();
39954b9680d3SSiarhei Volkau     TCGv t1 = tcg_temp_new();
39964b9680d3SSiarhei Volkau     TCGv t2 = tcg_temp_new();
39974b9680d3SSiarhei Volkau     TCGv t3 = tcg_temp_new();
39984b9680d3SSiarhei Volkau 
39994b9680d3SSiarhei Volkau     gen_load_mxu_gpr(t0, XRb);
40004b9680d3SSiarhei Volkau     gen_load_mxu_gpr(t1, XRc);
40014b9680d3SSiarhei Volkau 
40024b9680d3SSiarhei Volkau     switch (ptn2) {
40034b9680d3SSiarhei Volkau     case 0:
40044b9680d3SSiarhei Volkau         tcg_gen_andi_tl(t2, t0, 0xff000000);
40054b9680d3SSiarhei Volkau         tcg_gen_andi_tl(t3, t1, 0x000000ff);
40064b9680d3SSiarhei Volkau         tcg_gen_deposit_tl(t3, t3, t0,  8, 8);
40074b9680d3SSiarhei Volkau         tcg_gen_shri_tl(t0, t0,  8);
40084b9680d3SSiarhei Volkau         tcg_gen_shri_tl(t1, t1,  8);
40094b9680d3SSiarhei Volkau         tcg_gen_deposit_tl(t3, t3, t0, 24, 8);
40104b9680d3SSiarhei Volkau         tcg_gen_deposit_tl(t3, t3, t1, 16, 8);
40114b9680d3SSiarhei Volkau         tcg_gen_shri_tl(t0, t0,  8);
40124b9680d3SSiarhei Volkau         tcg_gen_shri_tl(t1, t1,  8);
40134b9680d3SSiarhei Volkau         tcg_gen_deposit_tl(t2, t2, t0,  8, 8);
40144b9680d3SSiarhei Volkau         tcg_gen_deposit_tl(t2, t2, t1,  0, 8);
40154b9680d3SSiarhei Volkau         tcg_gen_shri_tl(t1, t1,  8);
40164b9680d3SSiarhei Volkau         tcg_gen_deposit_tl(t2, t2, t1, 16, 8);
40174b9680d3SSiarhei Volkau         break;
40184b9680d3SSiarhei Volkau     case 1:
40194b9680d3SSiarhei Volkau         tcg_gen_andi_tl(t2, t0, 0xff000000);
40204b9680d3SSiarhei Volkau         tcg_gen_andi_tl(t3, t1, 0x000000ff);
40214b9680d3SSiarhei Volkau         tcg_gen_deposit_tl(t3, t3, t0, 16, 8);
40224b9680d3SSiarhei Volkau         tcg_gen_shri_tl(t0, t0,  8);
40234b9680d3SSiarhei Volkau         tcg_gen_shri_tl(t1, t1,  8);
40244b9680d3SSiarhei Volkau         tcg_gen_deposit_tl(t2, t2, t0, 16, 8);
40254b9680d3SSiarhei Volkau         tcg_gen_deposit_tl(t2, t2, t1,  0, 8);
40264b9680d3SSiarhei Volkau         tcg_gen_shri_tl(t0, t0,  8);
40274b9680d3SSiarhei Volkau         tcg_gen_shri_tl(t1, t1,  8);
40284b9680d3SSiarhei Volkau         tcg_gen_deposit_tl(t3, t3, t0, 24, 8);
40294b9680d3SSiarhei Volkau         tcg_gen_deposit_tl(t3, t3, t1,  8, 8);
40304b9680d3SSiarhei Volkau         tcg_gen_shri_tl(t1, t1,  8);
40314b9680d3SSiarhei Volkau         tcg_gen_deposit_tl(t2, t2, t1,  8, 8);
40324b9680d3SSiarhei Volkau         break;
40334b9680d3SSiarhei Volkau     case 2:
40344b9680d3SSiarhei Volkau         tcg_gen_andi_tl(t2, t0, 0xff00ff00);
40354b9680d3SSiarhei Volkau         tcg_gen_andi_tl(t3, t1, 0x00ff00ff);
40364b9680d3SSiarhei Volkau         tcg_gen_deposit_tl(t3, t3, t0,  8, 8);
40374b9680d3SSiarhei Volkau         tcg_gen_shri_tl(t0, t0, 16);
40384b9680d3SSiarhei Volkau         tcg_gen_shri_tl(t1, t1,  8);
40394b9680d3SSiarhei Volkau         tcg_gen_deposit_tl(t2, t2, t1,  0, 8);
40404b9680d3SSiarhei Volkau         tcg_gen_deposit_tl(t3, t3, t0, 24, 8);
40414b9680d3SSiarhei Volkau         tcg_gen_shri_tl(t1, t1, 16);
40424b9680d3SSiarhei Volkau         tcg_gen_deposit_tl(t2, t2, t1, 16, 8);
40434b9680d3SSiarhei Volkau         break;
40444b9680d3SSiarhei Volkau     case 3:
40454b9680d3SSiarhei Volkau         tcg_gen_andi_tl(t2, t0, 0xffff0000);
40464b9680d3SSiarhei Volkau         tcg_gen_andi_tl(t3, t1, 0x0000ffff);
40474b9680d3SSiarhei Volkau         tcg_gen_shri_tl(t1, t1, 16);
40484b9680d3SSiarhei Volkau         tcg_gen_deposit_tl(t2, t2, t1,  0, 16);
40494b9680d3SSiarhei Volkau         tcg_gen_deposit_tl(t3, t3, t0, 16, 16);
40504b9680d3SSiarhei Volkau         break;
40514b9680d3SSiarhei Volkau     }
40524b9680d3SSiarhei Volkau 
40534b9680d3SSiarhei Volkau     gen_store_mxu_gpr(t2, XRa);
40544b9680d3SSiarhei Volkau     gen_store_mxu_gpr(t3, XRd);
40554b9680d3SSiarhei Volkau }
40564b9680d3SSiarhei Volkau 
40574b9680d3SSiarhei Volkau /*
40588aedfb64SSiarhei Volkau  *  Q8SAD XRa, XRd, XRb, XRc
4059d5c9fa47SMichael Tokarev  *    Typical SAD operation for motion estimation.
40608aedfb64SSiarhei Volkau  */
gen_mxu_q8sad(DisasContext * ctx)40618aedfb64SSiarhei Volkau static void gen_mxu_q8sad(DisasContext *ctx)
40628aedfb64SSiarhei Volkau {
40638aedfb64SSiarhei Volkau     uint32_t XRd, XRc, XRb, XRa;
40648aedfb64SSiarhei Volkau 
40658aedfb64SSiarhei Volkau     XRd = extract32(ctx->opcode, 18, 4);
40668aedfb64SSiarhei Volkau     XRc = extract32(ctx->opcode, 14, 4);
40678aedfb64SSiarhei Volkau     XRb = extract32(ctx->opcode, 10, 4);
40688aedfb64SSiarhei Volkau     XRa = extract32(ctx->opcode,  6, 4);
40698aedfb64SSiarhei Volkau 
40708aedfb64SSiarhei Volkau     TCGv t0 = tcg_temp_new();
40718aedfb64SSiarhei Volkau     TCGv t1 = tcg_temp_new();
40728aedfb64SSiarhei Volkau     TCGv t2 = tcg_temp_new();
40738aedfb64SSiarhei Volkau     TCGv t3 = tcg_temp_new();
40748aedfb64SSiarhei Volkau     TCGv t4 = tcg_temp_new();
40758aedfb64SSiarhei Volkau     TCGv t5 = tcg_temp_new();
40768aedfb64SSiarhei Volkau 
40778aedfb64SSiarhei Volkau     gen_load_mxu_gpr(t2, XRb);
40788aedfb64SSiarhei Volkau     gen_load_mxu_gpr(t3, XRc);
40798aedfb64SSiarhei Volkau     gen_load_mxu_gpr(t5, XRd);
40808aedfb64SSiarhei Volkau     tcg_gen_movi_tl(t4, 0);
40818aedfb64SSiarhei Volkau 
40828aedfb64SSiarhei Volkau     for (int i = 0; i < 4; i++) {
40838aedfb64SSiarhei Volkau         tcg_gen_andi_tl(t0, t2, 0xff);
40848aedfb64SSiarhei Volkau         tcg_gen_andi_tl(t1, t3, 0xff);
40858aedfb64SSiarhei Volkau         tcg_gen_sub_tl(t0, t0, t1);
40868aedfb64SSiarhei Volkau         tcg_gen_abs_tl(t0, t0);
40878aedfb64SSiarhei Volkau         tcg_gen_add_tl(t4, t4, t0);
40888aedfb64SSiarhei Volkau         if (i < 3) {
40898aedfb64SSiarhei Volkau             tcg_gen_shri_tl(t2, t2, 8);
40908aedfb64SSiarhei Volkau             tcg_gen_shri_tl(t3, t3, 8);
40918aedfb64SSiarhei Volkau         }
40928aedfb64SSiarhei Volkau     }
40938aedfb64SSiarhei Volkau     tcg_gen_add_tl(t5, t5, t4);
40948aedfb64SSiarhei Volkau     gen_store_mxu_gpr(t4, XRa);
40958aedfb64SSiarhei Volkau     gen_store_mxu_gpr(t5, XRd);
40968aedfb64SSiarhei Volkau }
40978aedfb64SSiarhei Volkau 
40988aedfb64SSiarhei Volkau /*
4099a2b0a27dSPhilippe Mathieu-Daudé  *                 MXU instruction category: align
4100a2b0a27dSPhilippe Mathieu-Daudé  *                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4101a2b0a27dSPhilippe Mathieu-Daudé  *
4102a2b0a27dSPhilippe Mathieu-Daudé  *                       S32ALN     S32ALNI
4103a2b0a27dSPhilippe Mathieu-Daudé  */
4104a2b0a27dSPhilippe Mathieu-Daudé 
4105a2b0a27dSPhilippe Mathieu-Daudé /*
4106a2b0a27dSPhilippe Mathieu-Daudé  *  S32ALNI XRc, XRb, XRa, optn3
4107a2b0a27dSPhilippe Mathieu-Daudé  *    Arrange bytes from XRb and XRc according to one of five sets of
4108a2b0a27dSPhilippe Mathieu-Daudé  *    rules determined by optn3, and place the result in XRa.
4109a2b0a27dSPhilippe Mathieu-Daudé  */
gen_mxu_S32ALNI(DisasContext * ctx)4110a2b0a27dSPhilippe Mathieu-Daudé static void gen_mxu_S32ALNI(DisasContext *ctx)
4111a2b0a27dSPhilippe Mathieu-Daudé {
4112a2b0a27dSPhilippe Mathieu-Daudé     uint32_t optn3, pad, XRc, XRb, XRa;
4113a2b0a27dSPhilippe Mathieu-Daudé 
4114a2b0a27dSPhilippe Mathieu-Daudé     optn3 = extract32(ctx->opcode,  23, 3);
4115a2b0a27dSPhilippe Mathieu-Daudé     pad   = extract32(ctx->opcode,  21, 2);
4116a2b0a27dSPhilippe Mathieu-Daudé     XRc   = extract32(ctx->opcode, 14, 4);
4117a2b0a27dSPhilippe Mathieu-Daudé     XRb   = extract32(ctx->opcode, 10, 4);
4118a2b0a27dSPhilippe Mathieu-Daudé     XRa   = extract32(ctx->opcode,  6, 4);
4119a2b0a27dSPhilippe Mathieu-Daudé 
4120a2b0a27dSPhilippe Mathieu-Daudé     if (unlikely(pad != 0)) {
4121a2b0a27dSPhilippe Mathieu-Daudé         /* opcode padding incorrect -> do nothing */
4122a2b0a27dSPhilippe Mathieu-Daudé     } else if (unlikely(XRa == 0)) {
4123a2b0a27dSPhilippe Mathieu-Daudé         /* destination is zero register -> do nothing */
4124a2b0a27dSPhilippe Mathieu-Daudé     } else if (unlikely((XRb == 0) && (XRc == 0))) {
4125a2b0a27dSPhilippe Mathieu-Daudé         /* both operands zero registers -> just set destination to all 0s */
4126a2b0a27dSPhilippe Mathieu-Daudé         tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
4127a2b0a27dSPhilippe Mathieu-Daudé     } else if (unlikely(XRb == 0)) {
4128a2b0a27dSPhilippe Mathieu-Daudé         /* XRb zero register -> just appropriatelly shift XRc into XRa */
4129a2b0a27dSPhilippe Mathieu-Daudé         switch (optn3) {
4130a2b0a27dSPhilippe Mathieu-Daudé         case MXU_OPTN3_PTN0:
4131a2b0a27dSPhilippe Mathieu-Daudé             tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
4132a2b0a27dSPhilippe Mathieu-Daudé             break;
4133a2b0a27dSPhilippe Mathieu-Daudé         case MXU_OPTN3_PTN1:
4134a2b0a27dSPhilippe Mathieu-Daudé         case MXU_OPTN3_PTN2:
4135a2b0a27dSPhilippe Mathieu-Daudé         case MXU_OPTN3_PTN3:
4136a2b0a27dSPhilippe Mathieu-Daudé             tcg_gen_shri_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1],
4137a2b0a27dSPhilippe Mathieu-Daudé                              8 * (4 - optn3));
4138a2b0a27dSPhilippe Mathieu-Daudé             break;
4139a2b0a27dSPhilippe Mathieu-Daudé         case MXU_OPTN3_PTN4:
4140a2b0a27dSPhilippe Mathieu-Daudé             tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]);
4141a2b0a27dSPhilippe Mathieu-Daudé             break;
4142a2b0a27dSPhilippe Mathieu-Daudé         }
4143a2b0a27dSPhilippe Mathieu-Daudé     } else if (unlikely(XRc == 0)) {
4144a2b0a27dSPhilippe Mathieu-Daudé         /* XRc zero register -> just appropriatelly shift XRb into XRa */
4145a2b0a27dSPhilippe Mathieu-Daudé         switch (optn3) {
4146a2b0a27dSPhilippe Mathieu-Daudé         case MXU_OPTN3_PTN0:
4147a2b0a27dSPhilippe Mathieu-Daudé             tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
4148a2b0a27dSPhilippe Mathieu-Daudé             break;
4149a2b0a27dSPhilippe Mathieu-Daudé         case MXU_OPTN3_PTN1:
4150a2b0a27dSPhilippe Mathieu-Daudé         case MXU_OPTN3_PTN2:
4151a2b0a27dSPhilippe Mathieu-Daudé         case MXU_OPTN3_PTN3:
4152a2b0a27dSPhilippe Mathieu-Daudé             tcg_gen_shri_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], 8 * optn3);
4153a2b0a27dSPhilippe Mathieu-Daudé             break;
4154a2b0a27dSPhilippe Mathieu-Daudé         case MXU_OPTN3_PTN4:
4155a2b0a27dSPhilippe Mathieu-Daudé             tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
4156a2b0a27dSPhilippe Mathieu-Daudé             break;
4157a2b0a27dSPhilippe Mathieu-Daudé         }
4158a2b0a27dSPhilippe Mathieu-Daudé     } else if (unlikely(XRb == XRc)) {
4159a2b0a27dSPhilippe Mathieu-Daudé         /* both operands same -> just rotation or moving from any of them */
4160a2b0a27dSPhilippe Mathieu-Daudé         switch (optn3) {
4161a2b0a27dSPhilippe Mathieu-Daudé         case MXU_OPTN3_PTN0:
4162a2b0a27dSPhilippe Mathieu-Daudé         case MXU_OPTN3_PTN4:
4163a2b0a27dSPhilippe Mathieu-Daudé             tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
4164a2b0a27dSPhilippe Mathieu-Daudé             break;
4165a2b0a27dSPhilippe Mathieu-Daudé         case MXU_OPTN3_PTN1:
4166a2b0a27dSPhilippe Mathieu-Daudé         case MXU_OPTN3_PTN2:
4167a2b0a27dSPhilippe Mathieu-Daudé         case MXU_OPTN3_PTN3:
4168a2b0a27dSPhilippe Mathieu-Daudé             tcg_gen_rotli_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], 8 * optn3);
4169a2b0a27dSPhilippe Mathieu-Daudé             break;
4170a2b0a27dSPhilippe Mathieu-Daudé         }
4171a2b0a27dSPhilippe Mathieu-Daudé     } else {
4172a2b0a27dSPhilippe Mathieu-Daudé         /* the most general case */
4173a2b0a27dSPhilippe Mathieu-Daudé         switch (optn3) {
4174a2b0a27dSPhilippe Mathieu-Daudé         case MXU_OPTN3_PTN0:
4175a2b0a27dSPhilippe Mathieu-Daudé             {
4176a2b0a27dSPhilippe Mathieu-Daudé                 /*                                         */
4177a2b0a27dSPhilippe Mathieu-Daudé                 /*         XRb                XRc          */
4178a2b0a27dSPhilippe Mathieu-Daudé                 /*  +---------------+                      */
4179a2b0a27dSPhilippe Mathieu-Daudé                 /*  | A   B   C   D |    E   F   G   H     */
4180a2b0a27dSPhilippe Mathieu-Daudé                 /*  +-------+-------+                      */
4181a2b0a27dSPhilippe Mathieu-Daudé                 /*          |                              */
4182a2b0a27dSPhilippe Mathieu-Daudé                 /*         XRa                             */
4183a2b0a27dSPhilippe Mathieu-Daudé                 /*                                         */
4184a2b0a27dSPhilippe Mathieu-Daudé 
4185a2b0a27dSPhilippe Mathieu-Daudé                 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
4186a2b0a27dSPhilippe Mathieu-Daudé             }
4187a2b0a27dSPhilippe Mathieu-Daudé             break;
4188a2b0a27dSPhilippe Mathieu-Daudé         case MXU_OPTN3_PTN1:
4189a2b0a27dSPhilippe Mathieu-Daudé             {
4190a2b0a27dSPhilippe Mathieu-Daudé                 /*                                         */
4191a2b0a27dSPhilippe Mathieu-Daudé                 /*         XRb                 XRc         */
4192a2b0a27dSPhilippe Mathieu-Daudé                 /*      +-------------------+              */
4193a2b0a27dSPhilippe Mathieu-Daudé                 /*    A | B   C   D       E | F   G   H    */
4194a2b0a27dSPhilippe Mathieu-Daudé                 /*      +---------+---------+              */
4195a2b0a27dSPhilippe Mathieu-Daudé                 /*                |                        */
4196a2b0a27dSPhilippe Mathieu-Daudé                 /*               XRa                       */
4197a2b0a27dSPhilippe Mathieu-Daudé                 /*                                         */
4198a2b0a27dSPhilippe Mathieu-Daudé 
4199a2b0a27dSPhilippe Mathieu-Daudé                 TCGv_i32 t0 = tcg_temp_new();
4200a2b0a27dSPhilippe Mathieu-Daudé                 TCGv_i32 t1 = tcg_temp_new();
4201a2b0a27dSPhilippe Mathieu-Daudé 
4202a2b0a27dSPhilippe Mathieu-Daudé                 tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0x00FFFFFF);
4203a2b0a27dSPhilippe Mathieu-Daudé                 tcg_gen_shli_i32(t0, t0, 8);
4204a2b0a27dSPhilippe Mathieu-Daudé 
4205a2b0a27dSPhilippe Mathieu-Daudé                 tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFF000000);
4206a2b0a27dSPhilippe Mathieu-Daudé                 tcg_gen_shri_i32(t1, t1, 24);
4207a2b0a27dSPhilippe Mathieu-Daudé 
4208a2b0a27dSPhilippe Mathieu-Daudé                 tcg_gen_or_i32(mxu_gpr[XRa - 1], t0, t1);
4209a2b0a27dSPhilippe Mathieu-Daudé             }
4210a2b0a27dSPhilippe Mathieu-Daudé             break;
4211a2b0a27dSPhilippe Mathieu-Daudé         case MXU_OPTN3_PTN2:
4212a2b0a27dSPhilippe Mathieu-Daudé             {
4213a2b0a27dSPhilippe Mathieu-Daudé                 /*                                         */
4214a2b0a27dSPhilippe Mathieu-Daudé                 /*         XRb                 XRc         */
4215a2b0a27dSPhilippe Mathieu-Daudé                 /*          +-------------------+          */
4216a2b0a27dSPhilippe Mathieu-Daudé                 /*    A   B | C   D       E   F | G   H    */
4217a2b0a27dSPhilippe Mathieu-Daudé                 /*          +---------+---------+          */
4218a2b0a27dSPhilippe Mathieu-Daudé                 /*                    |                    */
4219a2b0a27dSPhilippe Mathieu-Daudé                 /*                   XRa                   */
4220a2b0a27dSPhilippe Mathieu-Daudé                 /*                                         */
4221a2b0a27dSPhilippe Mathieu-Daudé 
4222a2b0a27dSPhilippe Mathieu-Daudé                 TCGv_i32 t0 = tcg_temp_new();
4223a2b0a27dSPhilippe Mathieu-Daudé                 TCGv_i32 t1 = tcg_temp_new();
4224a2b0a27dSPhilippe Mathieu-Daudé 
4225a2b0a27dSPhilippe Mathieu-Daudé                 tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0x0000FFFF);
4226a2b0a27dSPhilippe Mathieu-Daudé                 tcg_gen_shli_i32(t0, t0, 16);
4227a2b0a27dSPhilippe Mathieu-Daudé 
4228a2b0a27dSPhilippe Mathieu-Daudé                 tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFFFF0000);
4229a2b0a27dSPhilippe Mathieu-Daudé                 tcg_gen_shri_i32(t1, t1, 16);
4230a2b0a27dSPhilippe Mathieu-Daudé 
4231a2b0a27dSPhilippe Mathieu-Daudé                 tcg_gen_or_i32(mxu_gpr[XRa - 1], t0, t1);
4232a2b0a27dSPhilippe Mathieu-Daudé             }
4233a2b0a27dSPhilippe Mathieu-Daudé             break;
4234a2b0a27dSPhilippe Mathieu-Daudé         case MXU_OPTN3_PTN3:
4235a2b0a27dSPhilippe Mathieu-Daudé             {
4236a2b0a27dSPhilippe Mathieu-Daudé                 /*                                         */
4237a2b0a27dSPhilippe Mathieu-Daudé                 /*         XRb                 XRc         */
4238a2b0a27dSPhilippe Mathieu-Daudé                 /*              +-------------------+      */
4239a2b0a27dSPhilippe Mathieu-Daudé                 /*    A   B   C | D       E   F   G | H    */
4240a2b0a27dSPhilippe Mathieu-Daudé                 /*              +---------+---------+      */
4241a2b0a27dSPhilippe Mathieu-Daudé                 /*                        |                */
4242a2b0a27dSPhilippe Mathieu-Daudé                 /*                       XRa               */
4243a2b0a27dSPhilippe Mathieu-Daudé                 /*                                         */
4244a2b0a27dSPhilippe Mathieu-Daudé 
4245a2b0a27dSPhilippe Mathieu-Daudé                 TCGv_i32 t0 = tcg_temp_new();
4246a2b0a27dSPhilippe Mathieu-Daudé                 TCGv_i32 t1 = tcg_temp_new();
4247a2b0a27dSPhilippe Mathieu-Daudé 
4248a2b0a27dSPhilippe Mathieu-Daudé                 tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0x000000FF);
4249a2b0a27dSPhilippe Mathieu-Daudé                 tcg_gen_shli_i32(t0, t0, 24);
4250a2b0a27dSPhilippe Mathieu-Daudé 
4251a2b0a27dSPhilippe Mathieu-Daudé                 tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFFFFFF00);
4252a2b0a27dSPhilippe Mathieu-Daudé                 tcg_gen_shri_i32(t1, t1, 8);
4253a2b0a27dSPhilippe Mathieu-Daudé 
4254a2b0a27dSPhilippe Mathieu-Daudé                 tcg_gen_or_i32(mxu_gpr[XRa - 1], t0, t1);
4255a2b0a27dSPhilippe Mathieu-Daudé             }
4256a2b0a27dSPhilippe Mathieu-Daudé             break;
4257a2b0a27dSPhilippe Mathieu-Daudé         case MXU_OPTN3_PTN4:
4258a2b0a27dSPhilippe Mathieu-Daudé             {
4259a2b0a27dSPhilippe Mathieu-Daudé                 /*                                         */
4260a2b0a27dSPhilippe Mathieu-Daudé                 /*         XRb                 XRc         */
4261a2b0a27dSPhilippe Mathieu-Daudé                 /*                     +---------------+   */
4262a2b0a27dSPhilippe Mathieu-Daudé                 /*    A   B   C   D    | E   F   G   H |   */
4263a2b0a27dSPhilippe Mathieu-Daudé                 /*                     +-------+-------+   */
4264a2b0a27dSPhilippe Mathieu-Daudé                 /*                             |           */
4265a2b0a27dSPhilippe Mathieu-Daudé                 /*                            XRa          */
4266a2b0a27dSPhilippe Mathieu-Daudé                 /*                                         */
4267a2b0a27dSPhilippe Mathieu-Daudé 
4268a2b0a27dSPhilippe Mathieu-Daudé                 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]);
4269a2b0a27dSPhilippe Mathieu-Daudé             }
4270a2b0a27dSPhilippe Mathieu-Daudé             break;
4271a2b0a27dSPhilippe Mathieu-Daudé         }
4272a2b0a27dSPhilippe Mathieu-Daudé     }
4273a2b0a27dSPhilippe Mathieu-Daudé }
4274a2b0a27dSPhilippe Mathieu-Daudé 
4275199fc7d2SSiarhei Volkau /*
427659259634SSiarhei Volkau  *  S32ALN XRc, XRb, XRa, rs
427759259634SSiarhei Volkau  *    Arrange bytes from XRb and XRc according to one of five sets of
427859259634SSiarhei Volkau  *    rules determined by rs[2:0], and place the result in XRa.
427959259634SSiarhei Volkau  */
gen_mxu_S32ALN(DisasContext * ctx)428059259634SSiarhei Volkau static void gen_mxu_S32ALN(DisasContext *ctx)
428159259634SSiarhei Volkau {
428259259634SSiarhei Volkau     uint32_t rs, XRc, XRb, XRa;
428359259634SSiarhei Volkau 
428459259634SSiarhei Volkau     rs  = extract32(ctx->opcode, 21, 5);
428559259634SSiarhei Volkau     XRc = extract32(ctx->opcode, 14, 4);
428659259634SSiarhei Volkau     XRb = extract32(ctx->opcode, 10, 4);
428759259634SSiarhei Volkau     XRa = extract32(ctx->opcode,  6, 4);
428859259634SSiarhei Volkau 
428959259634SSiarhei Volkau     if (unlikely(XRa == 0)) {
429059259634SSiarhei Volkau         /* destination is zero register -> do nothing */
429159259634SSiarhei Volkau     } else if (unlikely((XRb == 0) && (XRc == 0))) {
429259259634SSiarhei Volkau         /* both operands zero registers -> just set destination to all 0s */
429359259634SSiarhei Volkau         tcg_gen_movi_tl(mxu_gpr[XRa - 1], 0);
429459259634SSiarhei Volkau     } else {
429559259634SSiarhei Volkau         /* the most general case */
429659259634SSiarhei Volkau         TCGv t0 = tcg_temp_new();
429759259634SSiarhei Volkau         TCGv t1 = tcg_temp_new();
429859259634SSiarhei Volkau         TCGv t2 = tcg_temp_new();
429959259634SSiarhei Volkau         TCGv t3 = tcg_temp_new();
430059259634SSiarhei Volkau         TCGLabel *l_exit = gen_new_label();
430159259634SSiarhei Volkau         TCGLabel *l_b_only = gen_new_label();
430259259634SSiarhei Volkau         TCGLabel *l_c_only = gen_new_label();
430359259634SSiarhei Volkau 
430459259634SSiarhei Volkau         gen_load_mxu_gpr(t0, XRb);
430559259634SSiarhei Volkau         gen_load_mxu_gpr(t1, XRc);
430659259634SSiarhei Volkau         gen_load_gpr(t2, rs);
430759259634SSiarhei Volkau         tcg_gen_andi_tl(t2, t2, 0x07);
430859259634SSiarhei Volkau 
430959259634SSiarhei Volkau         /* do nothing for undefined cases */
431059259634SSiarhei Volkau         tcg_gen_brcondi_tl(TCG_COND_GE, t2, 5, l_exit);
431159259634SSiarhei Volkau 
431259259634SSiarhei Volkau         tcg_gen_brcondi_tl(TCG_COND_EQ, t2, 0, l_b_only);
431359259634SSiarhei Volkau         tcg_gen_brcondi_tl(TCG_COND_EQ, t2, 4, l_c_only);
431459259634SSiarhei Volkau 
431559259634SSiarhei Volkau         tcg_gen_shli_tl(t2, t2, 3);
431659259634SSiarhei Volkau         tcg_gen_subfi_tl(t3, 32, t2);
431759259634SSiarhei Volkau 
431859259634SSiarhei Volkau         tcg_gen_shl_tl(t0, t0, t2);
431959259634SSiarhei Volkau         tcg_gen_shr_tl(t1, t1, t3);
432059259634SSiarhei Volkau         tcg_gen_or_tl(mxu_gpr[XRa - 1], t0, t1);
432159259634SSiarhei Volkau         tcg_gen_br(l_exit);
432259259634SSiarhei Volkau 
432359259634SSiarhei Volkau         gen_set_label(l_b_only);
432459259634SSiarhei Volkau         gen_store_mxu_gpr(t0, XRa);
432559259634SSiarhei Volkau         tcg_gen_br(l_exit);
432659259634SSiarhei Volkau 
432759259634SSiarhei Volkau         gen_set_label(l_c_only);
432859259634SSiarhei Volkau         gen_store_mxu_gpr(t1, XRa);
432959259634SSiarhei Volkau 
433059259634SSiarhei Volkau         gen_set_label(l_exit);
433159259634SSiarhei Volkau     }
433259259634SSiarhei Volkau }
433359259634SSiarhei Volkau 
433459259634SSiarhei Volkau /*
4335199fc7d2SSiarhei Volkau  *  S32MADD XRa, XRd, rb, rc
4336199fc7d2SSiarhei Volkau  *    32 to 64 bit signed multiply with subsequent add
4337199fc7d2SSiarhei Volkau  *    result stored in {XRa, XRd} pair, stain HI/LO.
4338199fc7d2SSiarhei Volkau  *  S32MADDU XRa, XRd, rb, rc
4339199fc7d2SSiarhei Volkau  *    32 to 64 bit unsigned multiply with subsequent add
4340199fc7d2SSiarhei Volkau  *    result stored in {XRa, XRd} pair, stain HI/LO.
4341199fc7d2SSiarhei Volkau  *  S32MSUB XRa, XRd, rb, rc
4342199fc7d2SSiarhei Volkau  *    32 to 64 bit signed multiply with subsequent subtract
4343199fc7d2SSiarhei Volkau  *    result stored in {XRa, XRd} pair, stain HI/LO.
4344199fc7d2SSiarhei Volkau  *  S32MSUBU XRa, XRd, rb, rc
4345199fc7d2SSiarhei Volkau  *    32 to 64 bit unsigned multiply with subsequent subtract
4346199fc7d2SSiarhei Volkau  *    result stored in {XRa, XRd} pair, stain HI/LO.
4347199fc7d2SSiarhei Volkau  */
gen_mxu_s32madd_sub(DisasContext * ctx,bool sub,bool uns)4348199fc7d2SSiarhei Volkau static void gen_mxu_s32madd_sub(DisasContext *ctx, bool sub, bool uns)
4349199fc7d2SSiarhei Volkau {
4350199fc7d2SSiarhei Volkau     uint32_t XRa, XRd, Rb, Rc;
4351199fc7d2SSiarhei Volkau 
4352199fc7d2SSiarhei Volkau     XRa  = extract32(ctx->opcode,  6, 4);
4353199fc7d2SSiarhei Volkau     XRd  = extract32(ctx->opcode, 10, 4);
4354199fc7d2SSiarhei Volkau     Rb   = extract32(ctx->opcode, 16, 5);
4355199fc7d2SSiarhei Volkau     Rc   = extract32(ctx->opcode, 21, 5);
4356199fc7d2SSiarhei Volkau 
4357199fc7d2SSiarhei Volkau     if (unlikely(Rb == 0 || Rc == 0)) {
4358199fc7d2SSiarhei Volkau         /* do nothing because x + 0 * y => x */
4359199fc7d2SSiarhei Volkau     } else if (unlikely(XRa == 0 && XRd == 0)) {
4360199fc7d2SSiarhei Volkau         /* do nothing because result just dropped */
4361199fc7d2SSiarhei Volkau     } else {
4362199fc7d2SSiarhei Volkau         TCGv t0 = tcg_temp_new();
4363199fc7d2SSiarhei Volkau         TCGv t1 = tcg_temp_new();
4364199fc7d2SSiarhei Volkau         TCGv_i64 t2 = tcg_temp_new_i64();
4365199fc7d2SSiarhei Volkau         TCGv_i64 t3 = tcg_temp_new_i64();
4366199fc7d2SSiarhei Volkau 
4367199fc7d2SSiarhei Volkau         gen_load_gpr(t0, Rb);
4368199fc7d2SSiarhei Volkau         gen_load_gpr(t1, Rc);
4369199fc7d2SSiarhei Volkau 
4370199fc7d2SSiarhei Volkau         if (uns) {
4371199fc7d2SSiarhei Volkau             tcg_gen_extu_tl_i64(t2, t0);
4372199fc7d2SSiarhei Volkau             tcg_gen_extu_tl_i64(t3, t1);
4373199fc7d2SSiarhei Volkau         } else {
4374199fc7d2SSiarhei Volkau             tcg_gen_ext_tl_i64(t2, t0);
4375199fc7d2SSiarhei Volkau             tcg_gen_ext_tl_i64(t3, t1);
4376199fc7d2SSiarhei Volkau         }
4377199fc7d2SSiarhei Volkau         tcg_gen_mul_i64(t2, t2, t3);
4378199fc7d2SSiarhei Volkau 
4379199fc7d2SSiarhei Volkau         gen_load_mxu_gpr(t0, XRa);
4380199fc7d2SSiarhei Volkau         gen_load_mxu_gpr(t1, XRd);
4381199fc7d2SSiarhei Volkau 
4382199fc7d2SSiarhei Volkau         tcg_gen_concat_tl_i64(t3, t1, t0);
4383199fc7d2SSiarhei Volkau         if (sub) {
4384199fc7d2SSiarhei Volkau             tcg_gen_sub_i64(t3, t3, t2);
4385199fc7d2SSiarhei Volkau         } else {
4386199fc7d2SSiarhei Volkau             tcg_gen_add_i64(t3, t3, t2);
4387199fc7d2SSiarhei Volkau         }
4388199fc7d2SSiarhei Volkau         gen_move_low32(t1, t3);
4389199fc7d2SSiarhei Volkau         gen_move_high32(t0, t3);
4390199fc7d2SSiarhei Volkau 
4391199fc7d2SSiarhei Volkau         tcg_gen_mov_tl(cpu_HI[0], t0);
4392199fc7d2SSiarhei Volkau         tcg_gen_mov_tl(cpu_LO[0], t1);
4393199fc7d2SSiarhei Volkau 
4394199fc7d2SSiarhei Volkau         gen_store_mxu_gpr(t1, XRd);
4395199fc7d2SSiarhei Volkau         gen_store_mxu_gpr(t0, XRa);
4396199fc7d2SSiarhei Volkau     }
4397199fc7d2SSiarhei Volkau }
4398a2b0a27dSPhilippe Mathieu-Daudé 
4399a2b0a27dSPhilippe Mathieu-Daudé /*
4400a2b0a27dSPhilippe Mathieu-Daudé  * Decoding engine for MXU
4401a2b0a27dSPhilippe Mathieu-Daudé  * =======================
4402a2b0a27dSPhilippe Mathieu-Daudé  */
4403a2b0a27dSPhilippe Mathieu-Daudé 
decode_opc_mxu__pool00(DisasContext * ctx)4404a2b0a27dSPhilippe Mathieu-Daudé static void decode_opc_mxu__pool00(DisasContext *ctx)
4405a2b0a27dSPhilippe Mathieu-Daudé {
4406a2b0a27dSPhilippe Mathieu-Daudé     uint32_t opcode = extract32(ctx->opcode, 18, 3);
4407a2b0a27dSPhilippe Mathieu-Daudé 
4408a2b0a27dSPhilippe Mathieu-Daudé     switch (opcode) {
4409a2b0a27dSPhilippe Mathieu-Daudé     case OPC_MXU_S32MAX:
4410a2b0a27dSPhilippe Mathieu-Daudé     case OPC_MXU_S32MIN:
4411a2b0a27dSPhilippe Mathieu-Daudé         gen_mxu_S32MAX_S32MIN(ctx);
4412a2b0a27dSPhilippe Mathieu-Daudé         break;
4413a2b0a27dSPhilippe Mathieu-Daudé     case OPC_MXU_D16MAX:
4414a2b0a27dSPhilippe Mathieu-Daudé     case OPC_MXU_D16MIN:
4415a2b0a27dSPhilippe Mathieu-Daudé         gen_mxu_D16MAX_D16MIN(ctx);
4416a2b0a27dSPhilippe Mathieu-Daudé         break;
4417a2b0a27dSPhilippe Mathieu-Daudé     case OPC_MXU_Q8MAX:
4418a2b0a27dSPhilippe Mathieu-Daudé     case OPC_MXU_Q8MIN:
4419a2b0a27dSPhilippe Mathieu-Daudé         gen_mxu_Q8MAX_Q8MIN(ctx);
4420a2b0a27dSPhilippe Mathieu-Daudé         break;
44214051f035SSiarhei Volkau     case OPC_MXU_Q8SLT:
44224051f035SSiarhei Volkau         gen_mxu_q8slt(ctx, false);
44234051f035SSiarhei Volkau         break;
44244051f035SSiarhei Volkau     case OPC_MXU_Q8SLTU:
44254051f035SSiarhei Volkau         gen_mxu_q8slt(ctx, true);
44264051f035SSiarhei Volkau         break;
4427a2b0a27dSPhilippe Mathieu-Daudé     default:
4428a2b0a27dSPhilippe Mathieu-Daudé         MIPS_INVAL("decode_opc_mxu");
4429a2b0a27dSPhilippe Mathieu-Daudé         gen_reserved_instruction(ctx);
4430a2b0a27dSPhilippe Mathieu-Daudé         break;
4431a2b0a27dSPhilippe Mathieu-Daudé     }
4432a2b0a27dSPhilippe Mathieu-Daudé }
4433a2b0a27dSPhilippe Mathieu-Daudé 
decode_opc_mxu_s32madd_sub(DisasContext * ctx)4434199fc7d2SSiarhei Volkau static bool decode_opc_mxu_s32madd_sub(DisasContext *ctx)
4435199fc7d2SSiarhei Volkau {
4436199fc7d2SSiarhei Volkau     uint32_t opcode = extract32(ctx->opcode, 0, 6);
4437199fc7d2SSiarhei Volkau     uint32_t pad  = extract32(ctx->opcode, 14, 2);
4438199fc7d2SSiarhei Volkau 
4439199fc7d2SSiarhei Volkau     if (pad != 2) {
4440199fc7d2SSiarhei Volkau         /* MIPS32R1 MADD/MADDU/MSUB/MSUBU are on pad == 0 */
4441199fc7d2SSiarhei Volkau         return false;
4442199fc7d2SSiarhei Volkau     }
4443199fc7d2SSiarhei Volkau 
4444199fc7d2SSiarhei Volkau     switch (opcode) {
4445199fc7d2SSiarhei Volkau     case OPC_MXU_S32MADD:
4446199fc7d2SSiarhei Volkau         gen_mxu_s32madd_sub(ctx, false, false);
4447199fc7d2SSiarhei Volkau         break;
4448199fc7d2SSiarhei Volkau     case OPC_MXU_S32MADDU:
4449199fc7d2SSiarhei Volkau         gen_mxu_s32madd_sub(ctx, false, true);
4450199fc7d2SSiarhei Volkau         break;
4451199fc7d2SSiarhei Volkau     case OPC_MXU_S32MSUB:
4452199fc7d2SSiarhei Volkau         gen_mxu_s32madd_sub(ctx, true, false);
4453199fc7d2SSiarhei Volkau         break;
4454199fc7d2SSiarhei Volkau     case OPC_MXU_S32MSUBU:
4455199fc7d2SSiarhei Volkau         gen_mxu_s32madd_sub(ctx, true, true);
4456199fc7d2SSiarhei Volkau         break;
4457199fc7d2SSiarhei Volkau     default:
4458199fc7d2SSiarhei Volkau         return false;
4459199fc7d2SSiarhei Volkau     }
4460199fc7d2SSiarhei Volkau     return true;
4461199fc7d2SSiarhei Volkau }
4462199fc7d2SSiarhei Volkau 
decode_opc_mxu__pool01(DisasContext * ctx)4463ff7936f0SSiarhei Volkau static void decode_opc_mxu__pool01(DisasContext *ctx)
4464ff7936f0SSiarhei Volkau {
4465ff7936f0SSiarhei Volkau     uint32_t opcode = extract32(ctx->opcode, 18, 3);
4466ff7936f0SSiarhei Volkau 
4467ff7936f0SSiarhei Volkau     switch (opcode) {
4468ff7936f0SSiarhei Volkau     case OPC_MXU_S32SLT:
4469ff7936f0SSiarhei Volkau         gen_mxu_S32SLT(ctx);
4470ff7936f0SSiarhei Volkau         break;
4471ff7936f0SSiarhei Volkau     case OPC_MXU_D16SLT:
4472ff7936f0SSiarhei Volkau         gen_mxu_D16SLT(ctx);
4473ff7936f0SSiarhei Volkau         break;
4474ff7936f0SSiarhei Volkau     case OPC_MXU_D16AVG:
4475ff7936f0SSiarhei Volkau         gen_mxu_d16avg(ctx, false);
4476ff7936f0SSiarhei Volkau         break;
4477ff7936f0SSiarhei Volkau     case OPC_MXU_D16AVGR:
4478ff7936f0SSiarhei Volkau         gen_mxu_d16avg(ctx, true);
4479ff7936f0SSiarhei Volkau         break;
4480ff7936f0SSiarhei Volkau     case OPC_MXU_Q8AVG:
4481ff7936f0SSiarhei Volkau         gen_mxu_q8avg(ctx, false);
4482ff7936f0SSiarhei Volkau         break;
4483ff7936f0SSiarhei Volkau     case OPC_MXU_Q8AVGR:
4484ff7936f0SSiarhei Volkau         gen_mxu_q8avg(ctx, true);
4485ff7936f0SSiarhei Volkau         break;
4486bf1df65fSSiarhei Volkau     case OPC_MXU_Q8ADD:
4487bf1df65fSSiarhei Volkau         gen_mxu_Q8ADD(ctx);
4488bf1df65fSSiarhei Volkau         break;
4489ff7936f0SSiarhei Volkau     default:
4490ff7936f0SSiarhei Volkau         MIPS_INVAL("decode_opc_mxu");
4491ff7936f0SSiarhei Volkau         gen_reserved_instruction(ctx);
4492ff7936f0SSiarhei Volkau         break;
4493ff7936f0SSiarhei Volkau     }
4494ff7936f0SSiarhei Volkau }
4495f1e6547cSSiarhei Volkau 
decode_opc_mxu__pool02(DisasContext * ctx)4496f1e6547cSSiarhei Volkau static void decode_opc_mxu__pool02(DisasContext *ctx)
4497f1e6547cSSiarhei Volkau {
4498f1e6547cSSiarhei Volkau     uint32_t opcode = extract32(ctx->opcode, 18, 3);
4499f1e6547cSSiarhei Volkau 
4500f1e6547cSSiarhei Volkau     switch (opcode) {
4501f1e6547cSSiarhei Volkau     case OPC_MXU_S32CPS:
4502f1e6547cSSiarhei Volkau         gen_mxu_S32CPS(ctx);
4503f1e6547cSSiarhei Volkau         break;
4504f1e6547cSSiarhei Volkau     case OPC_MXU_D16CPS:
4505f1e6547cSSiarhei Volkau         gen_mxu_D16CPS(ctx);
4506f1e6547cSSiarhei Volkau         break;
4507f1e6547cSSiarhei Volkau     case OPC_MXU_Q8ABD:
4508f1e6547cSSiarhei Volkau         gen_mxu_Q8ABD(ctx);
4509f1e6547cSSiarhei Volkau         break;
4510f1e6547cSSiarhei Volkau     case OPC_MXU_Q16SAT:
4511f1e6547cSSiarhei Volkau         gen_mxu_Q16SAT(ctx);
4512f1e6547cSSiarhei Volkau         break;
4513f1e6547cSSiarhei Volkau     default:
4514f1e6547cSSiarhei Volkau         MIPS_INVAL("decode_opc_mxu");
4515f1e6547cSSiarhei Volkau         gen_reserved_instruction(ctx);
4516f1e6547cSSiarhei Volkau         break;
4517f1e6547cSSiarhei Volkau     }
4518f1e6547cSSiarhei Volkau }
4519f1e6547cSSiarhei Volkau 
decode_opc_mxu__pool03(DisasContext * ctx)452027dc0e28SSiarhei Volkau static void decode_opc_mxu__pool03(DisasContext *ctx)
452127dc0e28SSiarhei Volkau {
452227dc0e28SSiarhei Volkau     uint32_t opcode = extract32(ctx->opcode, 24, 2);
452327dc0e28SSiarhei Volkau 
452427dc0e28SSiarhei Volkau     switch (opcode) {
452527dc0e28SSiarhei Volkau     case OPC_MXU_D16MULF:
452627dc0e28SSiarhei Volkau         gen_mxu_d16mul(ctx, true, true);
452727dc0e28SSiarhei Volkau         break;
452827dc0e28SSiarhei Volkau     case OPC_MXU_D16MULE:
452927dc0e28SSiarhei Volkau         gen_mxu_d16mul(ctx, true, false);
453027dc0e28SSiarhei Volkau         break;
453127dc0e28SSiarhei Volkau     default:
453227dc0e28SSiarhei Volkau         MIPS_INVAL("decode_opc_mxu");
453327dc0e28SSiarhei Volkau         gen_reserved_instruction(ctx);
453427dc0e28SSiarhei Volkau         break;
453527dc0e28SSiarhei Volkau     }
453627dc0e28SSiarhei Volkau }
453727dc0e28SSiarhei Volkau 
decode_opc_mxu__pool04(DisasContext * ctx)4538a2b0a27dSPhilippe Mathieu-Daudé static void decode_opc_mxu__pool04(DisasContext *ctx)
4539a2b0a27dSPhilippe Mathieu-Daudé {
454059db9465SSiarhei Volkau     uint32_t reversed = extract32(ctx->opcode, 20, 1);
454159db9465SSiarhei Volkau     uint32_t opcode = extract32(ctx->opcode, 10, 4);
454259db9465SSiarhei Volkau 
454359db9465SSiarhei Volkau     /* Don't care about opcode bits as their meaning is unknown yet */
454459db9465SSiarhei Volkau     switch (opcode) {
454559db9465SSiarhei Volkau     default:
454659db9465SSiarhei Volkau         gen_mxu_s32ldxx(ctx, reversed, false);
454759db9465SSiarhei Volkau         break;
454859db9465SSiarhei Volkau     }
454959db9465SSiarhei Volkau }
455059db9465SSiarhei Volkau 
decode_opc_mxu__pool05(DisasContext * ctx)455159db9465SSiarhei Volkau static void decode_opc_mxu__pool05(DisasContext *ctx)
455259db9465SSiarhei Volkau {
455359db9465SSiarhei Volkau     uint32_t reversed = extract32(ctx->opcode, 20, 1);
455459db9465SSiarhei Volkau     uint32_t opcode = extract32(ctx->opcode, 10, 4);
455559db9465SSiarhei Volkau 
455659db9465SSiarhei Volkau     /* Don't care about opcode bits as their meaning is unknown yet */
455759db9465SSiarhei Volkau     switch (opcode) {
455859db9465SSiarhei Volkau     default:
455959db9465SSiarhei Volkau         gen_mxu_s32stxx(ctx, reversed, false);
456059db9465SSiarhei Volkau         break;
456159db9465SSiarhei Volkau     }
456259db9465SSiarhei Volkau }
456359db9465SSiarhei Volkau 
decode_opc_mxu__pool06(DisasContext * ctx)456459db9465SSiarhei Volkau static void decode_opc_mxu__pool06(DisasContext *ctx)
456559db9465SSiarhei Volkau {
456659db9465SSiarhei Volkau     uint32_t opcode = extract32(ctx->opcode, 10, 4);
456759db9465SSiarhei Volkau     uint32_t strd2  = extract32(ctx->opcode, 14, 2);
4568a2b0a27dSPhilippe Mathieu-Daudé 
4569a2b0a27dSPhilippe Mathieu-Daudé     switch (opcode) {
457059db9465SSiarhei Volkau     case OPC_MXU_S32LDST:
457159db9465SSiarhei Volkau     case OPC_MXU_S32LDSTR:
457259db9465SSiarhei Volkau         if (strd2 <= 2) {
457359db9465SSiarhei Volkau             gen_mxu_s32ldxvx(ctx, opcode, false, strd2);
4574a2b0a27dSPhilippe Mathieu-Daudé             break;
457559db9465SSiarhei Volkau         }
457659db9465SSiarhei Volkau         /* fallthrough */
457759db9465SSiarhei Volkau     default:
457859db9465SSiarhei Volkau         MIPS_INVAL("decode_opc_mxu");
457959db9465SSiarhei Volkau         gen_reserved_instruction(ctx);
458059db9465SSiarhei Volkau         break;
458159db9465SSiarhei Volkau     }
458259db9465SSiarhei Volkau }
458359db9465SSiarhei Volkau 
decode_opc_mxu__pool07(DisasContext * ctx)458459db9465SSiarhei Volkau static void decode_opc_mxu__pool07(DisasContext *ctx)
458559db9465SSiarhei Volkau {
458659db9465SSiarhei Volkau     uint32_t opcode = extract32(ctx->opcode, 10, 4);
458759db9465SSiarhei Volkau     uint32_t strd2  = extract32(ctx->opcode, 14, 2);
458859db9465SSiarhei Volkau 
458959db9465SSiarhei Volkau     switch (opcode) {
459059db9465SSiarhei Volkau     case OPC_MXU_S32LDST:
459159db9465SSiarhei Volkau     case OPC_MXU_S32LDSTR:
459259db9465SSiarhei Volkau         if (strd2 <= 2) {
459359db9465SSiarhei Volkau             gen_mxu_s32stxvx(ctx, opcode, false, strd2);
459459db9465SSiarhei Volkau             break;
459559db9465SSiarhei Volkau         }
459659db9465SSiarhei Volkau         /* fallthrough */
459759db9465SSiarhei Volkau     default:
459859db9465SSiarhei Volkau         MIPS_INVAL("decode_opc_mxu");
459959db9465SSiarhei Volkau         gen_reserved_instruction(ctx);
460059db9465SSiarhei Volkau         break;
460159db9465SSiarhei Volkau     }
460259db9465SSiarhei Volkau }
460359db9465SSiarhei Volkau 
decode_opc_mxu__pool08(DisasContext * ctx)460459db9465SSiarhei Volkau static void decode_opc_mxu__pool08(DisasContext *ctx)
460559db9465SSiarhei Volkau {
460659db9465SSiarhei Volkau     uint32_t reversed = extract32(ctx->opcode, 20, 1);
460759db9465SSiarhei Volkau     uint32_t opcode = extract32(ctx->opcode, 10, 4);
460859db9465SSiarhei Volkau 
460959db9465SSiarhei Volkau     /* Don't care about opcode bits as their meaning is unknown yet */
461059db9465SSiarhei Volkau     switch (opcode) {
461159db9465SSiarhei Volkau     default:
461259db9465SSiarhei Volkau         gen_mxu_s32ldxx(ctx, reversed, true);
461359db9465SSiarhei Volkau         break;
461459db9465SSiarhei Volkau     }
461559db9465SSiarhei Volkau }
461659db9465SSiarhei Volkau 
decode_opc_mxu__pool09(DisasContext * ctx)461759db9465SSiarhei Volkau static void decode_opc_mxu__pool09(DisasContext *ctx)
461859db9465SSiarhei Volkau {
461959db9465SSiarhei Volkau     uint32_t reversed = extract32(ctx->opcode, 20, 1);
462059db9465SSiarhei Volkau     uint32_t opcode = extract32(ctx->opcode, 10, 4);
462159db9465SSiarhei Volkau 
462259db9465SSiarhei Volkau     /* Don't care about opcode bits as their meaning is unknown yet */
462359db9465SSiarhei Volkau     switch (opcode) {
462459db9465SSiarhei Volkau     default:
462559db9465SSiarhei Volkau         gen_mxu_s32stxx(ctx, reversed, true);
462659db9465SSiarhei Volkau         break;
462759db9465SSiarhei Volkau     }
462859db9465SSiarhei Volkau }
462959db9465SSiarhei Volkau 
decode_opc_mxu__pool10(DisasContext * ctx)463059db9465SSiarhei Volkau static void decode_opc_mxu__pool10(DisasContext *ctx)
463159db9465SSiarhei Volkau {
463259db9465SSiarhei Volkau     uint32_t opcode = extract32(ctx->opcode, 10, 4);
463359db9465SSiarhei Volkau     uint32_t strd2  = extract32(ctx->opcode, 14, 2);
463459db9465SSiarhei Volkau 
463559db9465SSiarhei Volkau     switch (opcode) {
463659db9465SSiarhei Volkau     case OPC_MXU_S32LDST:
463759db9465SSiarhei Volkau     case OPC_MXU_S32LDSTR:
463859db9465SSiarhei Volkau         if (strd2 <= 2) {
463959db9465SSiarhei Volkau             gen_mxu_s32ldxvx(ctx, opcode, true, strd2);
464059db9465SSiarhei Volkau             break;
464159db9465SSiarhei Volkau         }
464259db9465SSiarhei Volkau         /* fallthrough */
464359db9465SSiarhei Volkau     default:
464459db9465SSiarhei Volkau         MIPS_INVAL("decode_opc_mxu");
464559db9465SSiarhei Volkau         gen_reserved_instruction(ctx);
464659db9465SSiarhei Volkau         break;
464759db9465SSiarhei Volkau     }
464859db9465SSiarhei Volkau }
464959db9465SSiarhei Volkau 
decode_opc_mxu__pool11(DisasContext * ctx)465059db9465SSiarhei Volkau static void decode_opc_mxu__pool11(DisasContext *ctx)
465159db9465SSiarhei Volkau {
465259db9465SSiarhei Volkau     uint32_t opcode = extract32(ctx->opcode, 10, 4);
465359db9465SSiarhei Volkau     uint32_t strd2  = extract32(ctx->opcode, 14, 2);
465459db9465SSiarhei Volkau 
465559db9465SSiarhei Volkau     switch (opcode) {
465659db9465SSiarhei Volkau     case OPC_MXU_S32LDST:
465759db9465SSiarhei Volkau     case OPC_MXU_S32LDSTR:
465859db9465SSiarhei Volkau         if (strd2 <= 2) {
465959db9465SSiarhei Volkau             gen_mxu_s32stxvx(ctx, opcode, true, strd2);
466059db9465SSiarhei Volkau             break;
466159db9465SSiarhei Volkau         }
466259db9465SSiarhei Volkau         /* fallthrough */
4663a2b0a27dSPhilippe Mathieu-Daudé     default:
4664a2b0a27dSPhilippe Mathieu-Daudé         MIPS_INVAL("decode_opc_mxu");
4665a2b0a27dSPhilippe Mathieu-Daudé         gen_reserved_instruction(ctx);
4666a2b0a27dSPhilippe Mathieu-Daudé         break;
4667a2b0a27dSPhilippe Mathieu-Daudé     }
4668a2b0a27dSPhilippe Mathieu-Daudé }
4669a2b0a27dSPhilippe Mathieu-Daudé 
decode_opc_mxu__pool12(DisasContext * ctx)467098db7a58SSiarhei Volkau static void decode_opc_mxu__pool12(DisasContext *ctx)
467198db7a58SSiarhei Volkau {
467298db7a58SSiarhei Volkau     uint32_t opcode = extract32(ctx->opcode, 22, 2);
467398db7a58SSiarhei Volkau 
467498db7a58SSiarhei Volkau     switch (opcode) {
467598db7a58SSiarhei Volkau     case OPC_MXU_D32ACC:
467698db7a58SSiarhei Volkau         gen_mxu_d32acc(ctx);
467798db7a58SSiarhei Volkau         break;
467898db7a58SSiarhei Volkau     case OPC_MXU_D32ACCM:
467998db7a58SSiarhei Volkau         gen_mxu_d32accm(ctx);
468098db7a58SSiarhei Volkau         break;
468198db7a58SSiarhei Volkau     case OPC_MXU_D32ASUM:
468298db7a58SSiarhei Volkau         gen_mxu_d32asum(ctx);
468398db7a58SSiarhei Volkau         break;
468498db7a58SSiarhei Volkau     default:
468598db7a58SSiarhei Volkau         MIPS_INVAL("decode_opc_mxu");
468698db7a58SSiarhei Volkau         gen_reserved_instruction(ctx);
468798db7a58SSiarhei Volkau         break;
468898db7a58SSiarhei Volkau     }
468998db7a58SSiarhei Volkau }
469098db7a58SSiarhei Volkau 
decode_opc_mxu__pool13(DisasContext * ctx)46916191a807SSiarhei Volkau static void decode_opc_mxu__pool13(DisasContext *ctx)
46926191a807SSiarhei Volkau {
46936191a807SSiarhei Volkau     uint32_t opcode = extract32(ctx->opcode, 22, 2);
46946191a807SSiarhei Volkau 
46956191a807SSiarhei Volkau     switch (opcode) {
46966191a807SSiarhei Volkau     case OPC_MXU_Q16ACC:
46976191a807SSiarhei Volkau         gen_mxu_q16acc(ctx);
46986191a807SSiarhei Volkau         break;
46996191a807SSiarhei Volkau     case OPC_MXU_Q16ACCM:
47006191a807SSiarhei Volkau         gen_mxu_q16accm(ctx);
47016191a807SSiarhei Volkau         break;
47026191a807SSiarhei Volkau     case OPC_MXU_D16ASUM:
47036191a807SSiarhei Volkau         gen_mxu_d16asum(ctx);
47046191a807SSiarhei Volkau         break;
47056191a807SSiarhei Volkau     default:
47066191a807SSiarhei Volkau         MIPS_INVAL("decode_opc_mxu");
47076191a807SSiarhei Volkau         gen_reserved_instruction(ctx);
47086191a807SSiarhei Volkau         break;
47096191a807SSiarhei Volkau     }
47106191a807SSiarhei Volkau }
47116191a807SSiarhei Volkau 
decode_opc_mxu__pool14(DisasContext * ctx)4712eb79951aSSiarhei Volkau static void decode_opc_mxu__pool14(DisasContext *ctx)
4713eb79951aSSiarhei Volkau {
4714eb79951aSSiarhei Volkau     uint32_t opcode = extract32(ctx->opcode, 22, 2);
4715eb79951aSSiarhei Volkau 
4716eb79951aSSiarhei Volkau     switch (opcode) {
4717eb79951aSSiarhei Volkau     case OPC_MXU_Q8ADDE:
4718eb79951aSSiarhei Volkau         gen_mxu_q8adde(ctx, false);
4719eb79951aSSiarhei Volkau         break;
4720eb79951aSSiarhei Volkau     case OPC_MXU_D8SUM:
4721eb79951aSSiarhei Volkau         gen_mxu_d8sum(ctx, false);
4722eb79951aSSiarhei Volkau         break;
4723eb79951aSSiarhei Volkau     case OPC_MXU_D8SUMC:
4724eb79951aSSiarhei Volkau         gen_mxu_d8sum(ctx, true);
4725eb79951aSSiarhei Volkau         break;
4726eb79951aSSiarhei Volkau     default:
4727eb79951aSSiarhei Volkau         MIPS_INVAL("decode_opc_mxu");
4728eb79951aSSiarhei Volkau         gen_reserved_instruction(ctx);
4729eb79951aSSiarhei Volkau         break;
4730eb79951aSSiarhei Volkau     }
4731eb79951aSSiarhei Volkau }
4732eb79951aSSiarhei Volkau 
decode_opc_mxu__pool15(DisasContext * ctx)473329059e72SSiarhei Volkau static void decode_opc_mxu__pool15(DisasContext *ctx)
473429059e72SSiarhei Volkau {
473529059e72SSiarhei Volkau     uint32_t opcode = extract32(ctx->opcode, 14, 2);
473629059e72SSiarhei Volkau 
473729059e72SSiarhei Volkau     switch (opcode) {
473829059e72SSiarhei Volkau     case OPC_MXU_S32MUL:
473929059e72SSiarhei Volkau         gen_mxu_s32mul(ctx, false);
474029059e72SSiarhei Volkau         break;
474129059e72SSiarhei Volkau     case OPC_MXU_S32MULU:
474229059e72SSiarhei Volkau         gen_mxu_s32mul(ctx, true);
474329059e72SSiarhei Volkau         break;
474429059e72SSiarhei Volkau     case OPC_MXU_S32EXTR:
474529059e72SSiarhei Volkau         gen_mxu_s32extr(ctx);
474629059e72SSiarhei Volkau         break;
474729059e72SSiarhei Volkau     case OPC_MXU_S32EXTRV:
474829059e72SSiarhei Volkau         gen_mxu_s32extrv(ctx);
474929059e72SSiarhei Volkau         break;
475029059e72SSiarhei Volkau     default:
475129059e72SSiarhei Volkau         MIPS_INVAL("decode_opc_mxu");
475229059e72SSiarhei Volkau         gen_reserved_instruction(ctx);
475329059e72SSiarhei Volkau         break;
475429059e72SSiarhei Volkau     }
475529059e72SSiarhei Volkau }
475629059e72SSiarhei Volkau 
decode_opc_mxu__pool16(DisasContext * ctx)4757a2b0a27dSPhilippe Mathieu-Daudé static void decode_opc_mxu__pool16(DisasContext *ctx)
4758a2b0a27dSPhilippe Mathieu-Daudé {
4759a2b0a27dSPhilippe Mathieu-Daudé     uint32_t opcode = extract32(ctx->opcode, 18, 3);
4760a2b0a27dSPhilippe Mathieu-Daudé 
4761a2b0a27dSPhilippe Mathieu-Daudé     switch (opcode) {
4762f900da76SSiarhei Volkau     case OPC_MXU_D32SARW:
4763f900da76SSiarhei Volkau         gen_mxu_d32sarl(ctx, true);
4764f900da76SSiarhei Volkau         break;
476559259634SSiarhei Volkau     case OPC_MXU_S32ALN:
476659259634SSiarhei Volkau         gen_mxu_S32ALN(ctx);
476759259634SSiarhei Volkau         break;
4768a2b0a27dSPhilippe Mathieu-Daudé     case OPC_MXU_S32ALNI:
4769a2b0a27dSPhilippe Mathieu-Daudé         gen_mxu_S32ALNI(ctx);
4770a2b0a27dSPhilippe Mathieu-Daudé         break;
477159259634SSiarhei Volkau     case OPC_MXU_S32LUI:
477259259634SSiarhei Volkau         gen_mxu_s32lui(ctx);
477359259634SSiarhei Volkau         break;
4774a2b0a27dSPhilippe Mathieu-Daudé     case OPC_MXU_S32NOR:
4775a2b0a27dSPhilippe Mathieu-Daudé         gen_mxu_S32NOR(ctx);
4776a2b0a27dSPhilippe Mathieu-Daudé         break;
4777a2b0a27dSPhilippe Mathieu-Daudé     case OPC_MXU_S32AND:
4778a2b0a27dSPhilippe Mathieu-Daudé         gen_mxu_S32AND(ctx);
4779a2b0a27dSPhilippe Mathieu-Daudé         break;
4780a2b0a27dSPhilippe Mathieu-Daudé     case OPC_MXU_S32OR:
4781a2b0a27dSPhilippe Mathieu-Daudé         gen_mxu_S32OR(ctx);
4782a2b0a27dSPhilippe Mathieu-Daudé         break;
4783a2b0a27dSPhilippe Mathieu-Daudé     case OPC_MXU_S32XOR:
4784a2b0a27dSPhilippe Mathieu-Daudé         gen_mxu_S32XOR(ctx);
4785a2b0a27dSPhilippe Mathieu-Daudé         break;
4786a2b0a27dSPhilippe Mathieu-Daudé     default:
4787a2b0a27dSPhilippe Mathieu-Daudé         MIPS_INVAL("decode_opc_mxu");
4788a2b0a27dSPhilippe Mathieu-Daudé         gen_reserved_instruction(ctx);
4789a2b0a27dSPhilippe Mathieu-Daudé         break;
4790a2b0a27dSPhilippe Mathieu-Daudé     }
4791a2b0a27dSPhilippe Mathieu-Daudé }
4792a2b0a27dSPhilippe Mathieu-Daudé 
decode_opc_mxu__pool17(DisasContext * ctx)479373c260c1SSiarhei Volkau static void decode_opc_mxu__pool17(DisasContext *ctx)
479473c260c1SSiarhei Volkau {
479573c260c1SSiarhei Volkau     uint32_t opcode = extract32(ctx->opcode, 6, 3);
479673c260c1SSiarhei Volkau     uint32_t strd2  = extract32(ctx->opcode, 9, 2);
479773c260c1SSiarhei Volkau 
479873c260c1SSiarhei Volkau     if (strd2 > 2) {
479973c260c1SSiarhei Volkau         MIPS_INVAL("decode_opc_mxu");
480073c260c1SSiarhei Volkau         gen_reserved_instruction(ctx);
480173c260c1SSiarhei Volkau         return;
480273c260c1SSiarhei Volkau     }
480373c260c1SSiarhei Volkau 
480473c260c1SSiarhei Volkau     switch (opcode) {
480573c260c1SSiarhei Volkau     case OPC_MXU_LXW:
480673c260c1SSiarhei Volkau           gen_mxu_lxx(ctx, strd2, MO_TE | MO_UL);
480773c260c1SSiarhei Volkau           break;
480873c260c1SSiarhei Volkau     case OPC_MXU_LXB:
480973c260c1SSiarhei Volkau           gen_mxu_lxx(ctx, strd2, MO_TE | MO_SB);
481073c260c1SSiarhei Volkau           break;
481173c260c1SSiarhei Volkau     case OPC_MXU_LXH:
481273c260c1SSiarhei Volkau           gen_mxu_lxx(ctx, strd2, MO_TE | MO_SW);
481373c260c1SSiarhei Volkau           break;
481473c260c1SSiarhei Volkau     case OPC_MXU_LXBU:
481573c260c1SSiarhei Volkau           gen_mxu_lxx(ctx, strd2, MO_TE | MO_UB);
481673c260c1SSiarhei Volkau           break;
481773c260c1SSiarhei Volkau     case OPC_MXU_LXHU:
481873c260c1SSiarhei Volkau           gen_mxu_lxx(ctx, strd2, MO_TE | MO_UW);
481973c260c1SSiarhei Volkau           break;
482073c260c1SSiarhei Volkau     default:
482173c260c1SSiarhei Volkau         MIPS_INVAL("decode_opc_mxu");
482273c260c1SSiarhei Volkau         gen_reserved_instruction(ctx);
482373c260c1SSiarhei Volkau         break;
482473c260c1SSiarhei Volkau     }
482573c260c1SSiarhei Volkau }
482673c260c1SSiarhei Volkau 
decode_opc_mxu__pool18(DisasContext * ctx)482707c92895SSiarhei Volkau static void decode_opc_mxu__pool18(DisasContext *ctx)
482807c92895SSiarhei Volkau {
482907c92895SSiarhei Volkau     uint32_t opcode = extract32(ctx->opcode, 18, 3);
483007c92895SSiarhei Volkau 
483107c92895SSiarhei Volkau     switch (opcode) {
483207c92895SSiarhei Volkau     case OPC_MXU_D32SLLV:
483307c92895SSiarhei Volkau         gen_mxu_d32sxxv(ctx, false, false);
483407c92895SSiarhei Volkau         break;
483507c92895SSiarhei Volkau     case OPC_MXU_D32SLRV:
483607c92895SSiarhei Volkau         gen_mxu_d32sxxv(ctx, true, false);
483707c92895SSiarhei Volkau         break;
483807c92895SSiarhei Volkau     case OPC_MXU_D32SARV:
483907c92895SSiarhei Volkau         gen_mxu_d32sxxv(ctx, true, true);
484007c92895SSiarhei Volkau         break;
484107c92895SSiarhei Volkau     case OPC_MXU_Q16SLLV:
484207c92895SSiarhei Volkau         gen_mxu_q16sxxv(ctx, false, false);
484307c92895SSiarhei Volkau         break;
484407c92895SSiarhei Volkau     case OPC_MXU_Q16SLRV:
484507c92895SSiarhei Volkau         gen_mxu_q16sxxv(ctx, true, false);
484607c92895SSiarhei Volkau         break;
484707c92895SSiarhei Volkau     case OPC_MXU_Q16SARV:
484807c92895SSiarhei Volkau         gen_mxu_q16sxxv(ctx, true, true);
484907c92895SSiarhei Volkau         break;
485007c92895SSiarhei Volkau     default:
485107c92895SSiarhei Volkau         MIPS_INVAL("decode_opc_mxu");
485207c92895SSiarhei Volkau         gen_reserved_instruction(ctx);
485307c92895SSiarhei Volkau         break;
485407c92895SSiarhei Volkau     }
485507c92895SSiarhei Volkau }
485607c92895SSiarhei Volkau 
decode_opc_mxu__pool19(DisasContext * ctx)4857a2b0a27dSPhilippe Mathieu-Daudé static void decode_opc_mxu__pool19(DisasContext *ctx)
4858a2b0a27dSPhilippe Mathieu-Daudé {
48597bb1206aSSiarhei Volkau     uint32_t opcode = extract32(ctx->opcode, 22, 4);
4860a2b0a27dSPhilippe Mathieu-Daudé 
4861a2b0a27dSPhilippe Mathieu-Daudé     switch (opcode) {
4862a2b0a27dSPhilippe Mathieu-Daudé     case OPC_MXU_Q8MUL:
48637bb1206aSSiarhei Volkau         gen_mxu_q8mul_mac(ctx, false, false);
48647bb1206aSSiarhei Volkau         break;
4865a2b0a27dSPhilippe Mathieu-Daudé     case OPC_MXU_Q8MULSU:
48667bb1206aSSiarhei Volkau         gen_mxu_q8mul_mac(ctx, true, false);
4867a2b0a27dSPhilippe Mathieu-Daudé         break;
4868a2b0a27dSPhilippe Mathieu-Daudé     default:
4869a2b0a27dSPhilippe Mathieu-Daudé         MIPS_INVAL("decode_opc_mxu");
4870a2b0a27dSPhilippe Mathieu-Daudé         gen_reserved_instruction(ctx);
4871a2b0a27dSPhilippe Mathieu-Daudé         break;
4872a2b0a27dSPhilippe Mathieu-Daudé     }
4873a2b0a27dSPhilippe Mathieu-Daudé }
4874a2b0a27dSPhilippe Mathieu-Daudé 
decode_opc_mxu__pool20(DisasContext * ctx)4875d1b6ded4SSiarhei Volkau static void decode_opc_mxu__pool20(DisasContext *ctx)
4876d1b6ded4SSiarhei Volkau {
4877d1b6ded4SSiarhei Volkau     uint32_t opcode = extract32(ctx->opcode, 18, 3);
4878d1b6ded4SSiarhei Volkau 
4879d1b6ded4SSiarhei Volkau     switch (opcode) {
4880d1b6ded4SSiarhei Volkau     case OPC_MXU_Q8MOVZ:
4881d1b6ded4SSiarhei Volkau         gen_mxu_q8movzn(ctx, TCG_COND_NE);
4882d1b6ded4SSiarhei Volkau         break;
4883d1b6ded4SSiarhei Volkau     case OPC_MXU_Q8MOVN:
4884d1b6ded4SSiarhei Volkau         gen_mxu_q8movzn(ctx, TCG_COND_EQ);
4885d1b6ded4SSiarhei Volkau         break;
4886d1b6ded4SSiarhei Volkau     case OPC_MXU_D16MOVZ:
4887d1b6ded4SSiarhei Volkau         gen_mxu_d16movzn(ctx, TCG_COND_NE);
4888d1b6ded4SSiarhei Volkau         break;
4889d1b6ded4SSiarhei Volkau     case OPC_MXU_D16MOVN:
4890d1b6ded4SSiarhei Volkau         gen_mxu_d16movzn(ctx, TCG_COND_EQ);
4891d1b6ded4SSiarhei Volkau         break;
4892d1b6ded4SSiarhei Volkau     case OPC_MXU_S32MOVZ:
4893d1b6ded4SSiarhei Volkau         gen_mxu_s32movzn(ctx, TCG_COND_NE);
4894d1b6ded4SSiarhei Volkau         break;
4895d1b6ded4SSiarhei Volkau     case OPC_MXU_S32MOVN:
4896d1b6ded4SSiarhei Volkau         gen_mxu_s32movzn(ctx, TCG_COND_EQ);
4897d1b6ded4SSiarhei Volkau         break;
4898d1b6ded4SSiarhei Volkau     default:
4899d1b6ded4SSiarhei Volkau         MIPS_INVAL("decode_opc_mxu");
4900d1b6ded4SSiarhei Volkau         gen_reserved_instruction(ctx);
4901d1b6ded4SSiarhei Volkau         break;
4902d1b6ded4SSiarhei Volkau     }
4903d1b6ded4SSiarhei Volkau }
4904d1b6ded4SSiarhei Volkau 
decode_opc_mxu__pool21(DisasContext * ctx)49057bb1206aSSiarhei Volkau static void decode_opc_mxu__pool21(DisasContext *ctx)
49067bb1206aSSiarhei Volkau {
49077bb1206aSSiarhei Volkau     uint32_t opcode = extract32(ctx->opcode, 22, 2);
49087bb1206aSSiarhei Volkau 
49097bb1206aSSiarhei Volkau     switch (opcode) {
49107bb1206aSSiarhei Volkau     case OPC_MXU_Q8MAC:
49117bb1206aSSiarhei Volkau         gen_mxu_q8mul_mac(ctx, false, true);
49127bb1206aSSiarhei Volkau         break;
49137bb1206aSSiarhei Volkau     case OPC_MXU_Q8MACSU:
49147bb1206aSSiarhei Volkau         gen_mxu_q8mul_mac(ctx, true, true);
49157bb1206aSSiarhei Volkau         break;
49167bb1206aSSiarhei Volkau     default:
49177bb1206aSSiarhei Volkau         MIPS_INVAL("decode_opc_mxu");
49187bb1206aSSiarhei Volkau         gen_reserved_instruction(ctx);
49197bb1206aSSiarhei Volkau         break;
49207bb1206aSSiarhei Volkau     }
49217bb1206aSSiarhei Volkau }
49227bb1206aSSiarhei Volkau 
49237bb1206aSSiarhei Volkau 
decode_ase_mxu(DisasContext * ctx,uint32_t insn)4924a2b0a27dSPhilippe Mathieu-Daudé bool decode_ase_mxu(DisasContext *ctx, uint32_t insn)
4925a2b0a27dSPhilippe Mathieu-Daudé {
4926a2b0a27dSPhilippe Mathieu-Daudé     uint32_t opcode = extract32(insn, 0, 6);
4927a2b0a27dSPhilippe Mathieu-Daudé 
4928a2b0a27dSPhilippe Mathieu-Daudé     if (opcode == OPC_MXU_S32M2I) {
4929a2b0a27dSPhilippe Mathieu-Daudé         gen_mxu_s32m2i(ctx);
4930a2b0a27dSPhilippe Mathieu-Daudé         return true;
4931a2b0a27dSPhilippe Mathieu-Daudé     }
4932a2b0a27dSPhilippe Mathieu-Daudé 
4933a2b0a27dSPhilippe Mathieu-Daudé     if (opcode == OPC_MXU_S32I2M) {
4934a2b0a27dSPhilippe Mathieu-Daudé         gen_mxu_s32i2m(ctx);
4935a2b0a27dSPhilippe Mathieu-Daudé         return true;
4936a2b0a27dSPhilippe Mathieu-Daudé     }
4937a2b0a27dSPhilippe Mathieu-Daudé 
4938a2b0a27dSPhilippe Mathieu-Daudé     {
4939a2b0a27dSPhilippe Mathieu-Daudé         TCGv t_mxu_cr = tcg_temp_new();
4940a2b0a27dSPhilippe Mathieu-Daudé         TCGLabel *l_exit = gen_new_label();
4941a2b0a27dSPhilippe Mathieu-Daudé 
4942a2b0a27dSPhilippe Mathieu-Daudé         gen_load_mxu_cr(t_mxu_cr);
4943a2b0a27dSPhilippe Mathieu-Daudé         tcg_gen_andi_tl(t_mxu_cr, t_mxu_cr, MXU_CR_MXU_EN);
4944a2b0a27dSPhilippe Mathieu-Daudé         tcg_gen_brcondi_tl(TCG_COND_NE, t_mxu_cr, MXU_CR_MXU_EN, l_exit);
4945a2b0a27dSPhilippe Mathieu-Daudé 
4946a2b0a27dSPhilippe Mathieu-Daudé         switch (opcode) {
4947199fc7d2SSiarhei Volkau         case OPC_MXU_S32MADD:
4948199fc7d2SSiarhei Volkau         case OPC_MXU_S32MADDU:
4949199fc7d2SSiarhei Volkau         case OPC_MXU_S32MSUB:
4950199fc7d2SSiarhei Volkau         case OPC_MXU_S32MSUBU:
4951199fc7d2SSiarhei Volkau             return decode_opc_mxu_s32madd_sub(ctx);
4952a2b0a27dSPhilippe Mathieu-Daudé         case OPC_MXU__POOL00:
4953a2b0a27dSPhilippe Mathieu-Daudé             decode_opc_mxu__pool00(ctx);
4954a2b0a27dSPhilippe Mathieu-Daudé             break;
4955a2b0a27dSPhilippe Mathieu-Daudé         case OPC_MXU_D16MUL:
495627dc0e28SSiarhei Volkau             gen_mxu_d16mul(ctx, false, false);
4957a2b0a27dSPhilippe Mathieu-Daudé             break;
4958a2b0a27dSPhilippe Mathieu-Daudé         case OPC_MXU_D16MAC:
49592ebc66e4SSiarhei Volkau             gen_mxu_d16mac(ctx, false, false);
49602ebc66e4SSiarhei Volkau             break;
49612ebc66e4SSiarhei Volkau         case OPC_MXU_D16MACF:
49622ebc66e4SSiarhei Volkau             gen_mxu_d16mac(ctx, true, true);
49632ebc66e4SSiarhei Volkau             break;
496415830fa2SSiarhei Volkau         case OPC_MXU_D16MADL:
496515830fa2SSiarhei Volkau             gen_mxu_d16madl(ctx);
496615830fa2SSiarhei Volkau             break;
4967e722e680SSiarhei Volkau         case OPC_MXU_S16MAD:
4968e722e680SSiarhei Volkau             gen_mxu_s16mad(ctx);
4969e722e680SSiarhei Volkau             break;
4970a9bfd80bSSiarhei Volkau         case OPC_MXU_Q16ADD:
4971a9bfd80bSSiarhei Volkau             gen_mxu_q16add(ctx);
4972a9bfd80bSSiarhei Volkau             break;
49732ebc66e4SSiarhei Volkau         case OPC_MXU_D16MACE:
49742ebc66e4SSiarhei Volkau             gen_mxu_d16mac(ctx, true, false);
4975a2b0a27dSPhilippe Mathieu-Daudé             break;
4976ff7936f0SSiarhei Volkau         case OPC_MXU__POOL01:
4977ff7936f0SSiarhei Volkau             decode_opc_mxu__pool01(ctx);
4978ff7936f0SSiarhei Volkau             break;
4979f1e6547cSSiarhei Volkau         case OPC_MXU__POOL02:
4980f1e6547cSSiarhei Volkau             decode_opc_mxu__pool02(ctx);
4981f1e6547cSSiarhei Volkau             break;
498227dc0e28SSiarhei Volkau         case OPC_MXU__POOL03:
498327dc0e28SSiarhei Volkau             decode_opc_mxu__pool03(ctx);
498427dc0e28SSiarhei Volkau             break;
4985a2b0a27dSPhilippe Mathieu-Daudé         case OPC_MXU__POOL04:
4986a2b0a27dSPhilippe Mathieu-Daudé             decode_opc_mxu__pool04(ctx);
4987a2b0a27dSPhilippe Mathieu-Daudé             break;
498859db9465SSiarhei Volkau         case OPC_MXU__POOL05:
498959db9465SSiarhei Volkau             decode_opc_mxu__pool05(ctx);
499059db9465SSiarhei Volkau             break;
499159db9465SSiarhei Volkau         case OPC_MXU__POOL06:
499259db9465SSiarhei Volkau             decode_opc_mxu__pool06(ctx);
499359db9465SSiarhei Volkau             break;
499459db9465SSiarhei Volkau         case OPC_MXU__POOL07:
499559db9465SSiarhei Volkau             decode_opc_mxu__pool07(ctx);
499659db9465SSiarhei Volkau             break;
499759db9465SSiarhei Volkau         case OPC_MXU__POOL08:
499859db9465SSiarhei Volkau             decode_opc_mxu__pool08(ctx);
499959db9465SSiarhei Volkau             break;
500059db9465SSiarhei Volkau         case OPC_MXU__POOL09:
500159db9465SSiarhei Volkau             decode_opc_mxu__pool09(ctx);
500259db9465SSiarhei Volkau             break;
500359db9465SSiarhei Volkau         case OPC_MXU__POOL10:
500459db9465SSiarhei Volkau             decode_opc_mxu__pool10(ctx);
500559db9465SSiarhei Volkau             break;
500659db9465SSiarhei Volkau         case OPC_MXU__POOL11:
500759db9465SSiarhei Volkau             decode_opc_mxu__pool11(ctx);
500859db9465SSiarhei Volkau             break;
50099e51e0cdSSiarhei Volkau         case OPC_MXU_D32ADD:
50109e51e0cdSSiarhei Volkau             gen_mxu_d32add(ctx);
50119e51e0cdSSiarhei Volkau             break;
501298db7a58SSiarhei Volkau         case OPC_MXU__POOL12:
501398db7a58SSiarhei Volkau             decode_opc_mxu__pool12(ctx);
501498db7a58SSiarhei Volkau             break;
50156191a807SSiarhei Volkau         case OPC_MXU__POOL13:
50166191a807SSiarhei Volkau             decode_opc_mxu__pool13(ctx);
50176191a807SSiarhei Volkau             break;
5018eb79951aSSiarhei Volkau         case OPC_MXU__POOL14:
5019eb79951aSSiarhei Volkau             decode_opc_mxu__pool14(ctx);
5020eb79951aSSiarhei Volkau             break;
5021eb79951aSSiarhei Volkau         case OPC_MXU_Q8ACCE:
5022eb79951aSSiarhei Volkau             gen_mxu_q8adde(ctx, true);
5023eb79951aSSiarhei Volkau             break;
5024a2b0a27dSPhilippe Mathieu-Daudé         case OPC_MXU_S8LDD:
50253f0e94c1SSiarhei Volkau             gen_mxu_s8ldd(ctx, false);
50263f0e94c1SSiarhei Volkau             break;
50273f0e94c1SSiarhei Volkau         case OPC_MXU_S8STD:
50283f0e94c1SSiarhei Volkau             gen_mxu_s8std(ctx, false);
50293f0e94c1SSiarhei Volkau             break;
50303f0e94c1SSiarhei Volkau         case OPC_MXU_S8LDI:
50313f0e94c1SSiarhei Volkau             gen_mxu_s8ldd(ctx, true);
50323f0e94c1SSiarhei Volkau             break;
50333f0e94c1SSiarhei Volkau         case OPC_MXU_S8SDI:
50343f0e94c1SSiarhei Volkau             gen_mxu_s8std(ctx, true);
5035a2b0a27dSPhilippe Mathieu-Daudé             break;
503629059e72SSiarhei Volkau         case OPC_MXU__POOL15:
503729059e72SSiarhei Volkau             decode_opc_mxu__pool15(ctx);
503829059e72SSiarhei Volkau             break;
5039a2b0a27dSPhilippe Mathieu-Daudé         case OPC_MXU__POOL16:
5040a2b0a27dSPhilippe Mathieu-Daudé             decode_opc_mxu__pool16(ctx);
5041a2b0a27dSPhilippe Mathieu-Daudé             break;
504273c260c1SSiarhei Volkau         case OPC_MXU__POOL17:
504373c260c1SSiarhei Volkau             decode_opc_mxu__pool17(ctx);
504473c260c1SSiarhei Volkau             break;
5045968045b6SSiarhei Volkau         case OPC_MXU_S16LDD:
5046968045b6SSiarhei Volkau             gen_mxu_s16ldd(ctx, false);
5047968045b6SSiarhei Volkau             break;
5048968045b6SSiarhei Volkau         case OPC_MXU_S16STD:
5049968045b6SSiarhei Volkau             gen_mxu_s16std(ctx, false);
5050968045b6SSiarhei Volkau             break;
5051968045b6SSiarhei Volkau         case OPC_MXU_S16LDI:
5052968045b6SSiarhei Volkau             gen_mxu_s16ldd(ctx, true);
5053968045b6SSiarhei Volkau             break;
5054968045b6SSiarhei Volkau         case OPC_MXU_S16SDI:
5055968045b6SSiarhei Volkau             gen_mxu_s16std(ctx, true);
5056968045b6SSiarhei Volkau             break;
5057f1fb1038SSiarhei Volkau         case OPC_MXU_D32SLL:
5058f1fb1038SSiarhei Volkau             gen_mxu_d32sxx(ctx, false, false);
5059f1fb1038SSiarhei Volkau             break;
5060f1fb1038SSiarhei Volkau         case OPC_MXU_D32SLR:
5061f1fb1038SSiarhei Volkau             gen_mxu_d32sxx(ctx, true, false);
5062f1fb1038SSiarhei Volkau             break;
5063f900da76SSiarhei Volkau         case OPC_MXU_D32SARL:
5064f900da76SSiarhei Volkau             gen_mxu_d32sarl(ctx, false);
5065f900da76SSiarhei Volkau             break;
5066f1fb1038SSiarhei Volkau         case OPC_MXU_D32SAR:
5067f1fb1038SSiarhei Volkau             gen_mxu_d32sxx(ctx, true, true);
5068f1fb1038SSiarhei Volkau             break;
506952fe25d4SSiarhei Volkau         case OPC_MXU_Q16SLL:
507052fe25d4SSiarhei Volkau             gen_mxu_q16sxx(ctx, false, false);
507152fe25d4SSiarhei Volkau             break;
507207c92895SSiarhei Volkau         case OPC_MXU__POOL18:
507307c92895SSiarhei Volkau             decode_opc_mxu__pool18(ctx);
507407c92895SSiarhei Volkau             break;
507552fe25d4SSiarhei Volkau         case OPC_MXU_Q16SLR:
507652fe25d4SSiarhei Volkau             gen_mxu_q16sxx(ctx, true, false);
507752fe25d4SSiarhei Volkau             break;
507852fe25d4SSiarhei Volkau         case OPC_MXU_Q16SAR:
507952fe25d4SSiarhei Volkau             gen_mxu_q16sxx(ctx, true, true);
508052fe25d4SSiarhei Volkau             break;
5081a2b0a27dSPhilippe Mathieu-Daudé         case OPC_MXU__POOL19:
5082a2b0a27dSPhilippe Mathieu-Daudé             decode_opc_mxu__pool19(ctx);
5083a2b0a27dSPhilippe Mathieu-Daudé             break;
5084d1b6ded4SSiarhei Volkau         case OPC_MXU__POOL20:
5085d1b6ded4SSiarhei Volkau             decode_opc_mxu__pool20(ctx);
5086d1b6ded4SSiarhei Volkau             break;
50877bb1206aSSiarhei Volkau         case OPC_MXU__POOL21:
50887bb1206aSSiarhei Volkau             decode_opc_mxu__pool21(ctx);
50897bb1206aSSiarhei Volkau             break;
509068a48804SSiarhei Volkau         case OPC_MXU_Q16SCOP:
509168a48804SSiarhei Volkau             gen_mxu_q16scop(ctx);
509268a48804SSiarhei Volkau             break;
5093b72e2b3aSSiarhei Volkau         case OPC_MXU_Q8MADL:
5094b72e2b3aSSiarhei Volkau             gen_mxu_q8madl(ctx);
5095b72e2b3aSSiarhei Volkau             break;
50964b9680d3SSiarhei Volkau         case OPC_MXU_S32SFL:
50974b9680d3SSiarhei Volkau             gen_mxu_s32sfl(ctx);
50984b9680d3SSiarhei Volkau             break;
50998aedfb64SSiarhei Volkau         case OPC_MXU_Q8SAD:
51008aedfb64SSiarhei Volkau             gen_mxu_q8sad(ctx);
51018aedfb64SSiarhei Volkau             break;
5102a2b0a27dSPhilippe Mathieu-Daudé         default:
5103199fc7d2SSiarhei Volkau             return false;
5104a2b0a27dSPhilippe Mathieu-Daudé         }
5105a2b0a27dSPhilippe Mathieu-Daudé 
5106a2b0a27dSPhilippe Mathieu-Daudé         gen_set_label(l_exit);
5107a2b0a27dSPhilippe Mathieu-Daudé     }
5108a2b0a27dSPhilippe Mathieu-Daudé 
5109a2b0a27dSPhilippe Mathieu-Daudé     return true;
5110a2b0a27dSPhilippe Mathieu-Daudé }
5111