xref: /openbmc/qemu/target/mips/tcg/mxu_translate.c (revision f101c9fe)
1 /*
2  *  Ingenic XBurst Media eXtension Unit (MXU) translation routines.
3  *
4  *  Copyright (c) 2004-2005 Jocelyn Mayer
5  *  Copyright (c) 2006 Marius Groeger (FPU operations)
6  *  Copyright (c) 2006 Thiemo Seufer (MIPS32R2 support)
7  *  Copyright (c) 2009 CodeSourcery (MIPS16 and microMIPS support)
8  *  Copyright (c) 2012 Jia Liu & Dongxue Zhang (MIPS ASE DSP support)
9  *
10  * SPDX-License-Identifier: LGPL-2.1-or-later
11  *
12  * Datasheet:
13  *
14  *   "XBurst® Instruction Set Architecture MIPS eXtension/enhanced Unit
15  *   Programming Manual", Ingenic Semiconductor Co, Ltd., revision June 2, 2017
16  */
17 
18 #include "qemu/osdep.h"
19 #include "tcg/tcg-op.h"
20 #include "exec/helper-gen.h"
21 #include "translate.h"
22 
23 /*
24  *
25  *       AN OVERVIEW OF MXU EXTENSION INSTRUCTION SET
26  *       ============================================
27  *
28  *
29  * MXU (full name: MIPS eXtension/enhanced Unit) is a SIMD extension of MIPS32
30  * instructions set. It is designed to fit the needs of signal, graphical and
31  * video processing applications. MXU instruction set is used in Xburst family
32  * of microprocessors by Ingenic.
33  *
34  * MXU unit contains 17 registers called X0-X16. X0 is always zero, and X16 is
35  * the control register.
36  *
37  *
38  *     The notation used in MXU assembler mnemonics
39  *     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
40  *
41  *  Register operands:
42  *
43  *   XRa, XRb, XRc, XRd - MXU registers
44  *   Rb, Rc, Rd, Rs, Rt - general purpose MIPS registers
45  *
46  *  Non-register operands:
47  *
48  *   aptn1 - 1-bit accumulate add/subtract pattern
49  *   aptn2 - 2-bit accumulate add/subtract pattern
50  *   eptn2 - 2-bit execute add/subtract pattern
51  *   optn2 - 2-bit operand pattern
52  *   optn3 - 3-bit operand pattern
53  *   sft4  - 4-bit shift amount
54  *   strd2 - 2-bit stride amount
55  *
56  *  Prefixes:
57  *
58  *   Level of parallelism:                Operand size:
59  *    S - single operation at a time       32 - word
60  *    D - two operations in parallel       16 - half word
61  *    Q - four operations in parallel       8 - byte
62  *
63  *  Operations:
64  *
65  *   ADD   - Add or subtract
66  *   ADDC  - Add with carry-in
67  *   ACC   - Accumulate
68  *   ASUM  - Sum together then accumulate (add or subtract)
69  *   ASUMC - Sum together then accumulate (add or subtract) with carry-in
70  *   AVG   - Average between 2 operands
71  *   ABD   - Absolute difference
72  *   ALN   - Align data
73  *   AND   - Logical bitwise 'and' operation
74  *   CPS   - Copy sign
75  *   EXTR  - Extract bits
76  *   I2M   - Move from GPR register to MXU register
77  *   LDD   - Load data from memory to XRF
78  *   LDI   - Load data from memory to XRF (and increase the address base)
79  *   LUI   - Load unsigned immediate
80  *   MUL   - Multiply
81  *   MULU  - Unsigned multiply
82  *   MADD  - 64-bit operand add 32x32 product
83  *   MSUB  - 64-bit operand subtract 32x32 product
84  *   MAC   - Multiply and accumulate (add or subtract)
85  *   MAD   - Multiply and add or subtract
86  *   MAX   - Maximum between 2 operands
87  *   MIN   - Minimum between 2 operands
88  *   M2I   - Move from MXU register to GPR register
89  *   MOVZ  - Move if zero
90  *   MOVN  - Move if non-zero
91  *   NOR   - Logical bitwise 'nor' operation
92  *   OR    - Logical bitwise 'or' operation
93  *   STD   - Store data from XRF to memory
94  *   SDI   - Store data from XRF to memory (and increase the address base)
95  *   SLT   - Set of less than comparison
96  *   SAD   - Sum of absolute differences
97  *   SLL   - Logical shift left
98  *   SLR   - Logical shift right
99  *   SAR   - Arithmetic shift right
100  *   SAT   - Saturation
101  *   SFL   - Shuffle
102  *   SCOP  - Calculate x’s scope (-1, means x<0; 0, means x==0; 1, means x>0)
103  *   XOR   - Logical bitwise 'exclusive or' operation
104  *
105  *  Suffixes:
106  *
107  *   E - Expand results
108  *   F - Fixed point multiplication
109  *   L - Low part result
110  *   R - Doing rounding
111  *   V - Variable instead of immediate
112  *   W - Combine above L and V
113  *
114  *
115  *     The list of MXU instructions grouped by functionality
116  *     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
117  *
118  * Load/Store instructions           Multiplication instructions
119  * -----------------------           ---------------------------
120  *
121  *  S32LDD XRa, Rb, s12               S32MADD XRa, XRd, Rs, Rt
122  *  S32STD XRa, Rb, s12               S32MADDU XRa, XRd, Rs, Rt
123  *  S32LDDV XRa, Rb, rc, strd2        S32MSUB XRa, XRd, Rs, Rt
124  *  S32STDV XRa, Rb, rc, strd2        S32MSUBU XRa, XRd, Rs, Rt
125  *  S32LDI XRa, Rb, s12               S32MUL XRa, XRd, Rs, Rt
126  *  S32SDI XRa, Rb, s12               S32MULU XRa, XRd, Rs, Rt
127  *  S32LDIV XRa, Rb, rc, strd2        D16MUL XRa, XRb, XRc, XRd, optn2
128  *  S32SDIV XRa, Rb, rc, strd2        D16MULE XRa, XRb, XRc, optn2
129  *  S32LDDR XRa, Rb, s12              D16MULF XRa, XRb, XRc, optn2
130  *  S32STDR XRa, Rb, s12              D16MAC XRa, XRb, XRc, XRd, aptn2, optn2
131  *  S32LDDVR XRa, Rb, rc, strd2       D16MACE XRa, XRb, XRc, XRd, aptn2, optn2
132  *  S32STDVR XRa, Rb, rc, strd2       D16MACF XRa, XRb, XRc, XRd, aptn2, optn2
133  *  S32LDIR XRa, Rb, s12              D16MADL XRa, XRb, XRc, XRd, aptn2, optn2
134  *  S32SDIR XRa, Rb, s12              S16MAD XRa, XRb, XRc, XRd, aptn1, optn2
135  *  S32LDIVR XRa, Rb, rc, strd2       Q8MUL XRa, XRb, XRc, XRd
136  *  S32SDIVR XRa, Rb, rc, strd2       Q8MULSU XRa, XRb, XRc, XRd
137  *  S16LDD XRa, Rb, s10, eptn2        Q8MAC XRa, XRb, XRc, XRd, aptn2
138  *  S16STD XRa, Rb, s10, eptn2        Q8MACSU XRa, XRb, XRc, XRd, aptn2
139  *  S16LDI XRa, Rb, s10, eptn2        Q8MADL XRa, XRb, XRc, XRd, aptn2
140  *  S16SDI XRa, Rb, s10, eptn2
141  *  S8LDD XRa, Rb, s8, eptn3
142  *  S8STD XRa, Rb, s8, eptn3         Addition and subtraction instructions
143  *  S8LDI XRa, Rb, s8, eptn3         -------------------------------------
144  *  S8SDI XRa, Rb, s8, eptn3
145  *  LXW Rd, Rs, Rt, strd2             D32ADD XRa, XRb, XRc, XRd, eptn2
146  *  LXH Rd, Rs, Rt, strd2             D32ADDC XRa, XRb, XRc, XRd
147  *  LXHU Rd, Rs, Rt, strd2            D32ACC XRa, XRb, XRc, XRd, eptn2
148  *  LXB Rd, Rs, Rt, strd2             D32ACCM XRa, XRb, XRc, XRd, eptn2
149  *  LXBU Rd, Rs, Rt, strd2            D32ASUM XRa, XRb, XRc, XRd, eptn2
150  *                                    S32CPS XRa, XRb, XRc
151  *                                    Q16ADD XRa, XRb, XRc, XRd, eptn2, optn2
152  * Comparison instructions            Q16ACC XRa, XRb, XRc, XRd, eptn2
153  * -----------------------            Q16ACCM XRa, XRb, XRc, XRd, eptn2
154  *                                    D16ASUM XRa, XRb, XRc, XRd, eptn2
155  *  S32MAX XRa, XRb, XRc              D16CPS XRa, XRb,
156  *  S32MIN XRa, XRb, XRc              D16AVG XRa, XRb, XRc
157  *  S32SLT XRa, XRb, XRc              D16AVGR XRa, XRb, XRc
158  *  S32MOVZ XRa, XRb, XRc             Q8ADD XRa, XRb, XRc, eptn2
159  *  S32MOVN XRa, XRb, XRc             Q8ADDE XRa, XRb, XRc, XRd, eptn2
160  *  D16MAX XRa, XRb, XRc              Q8ACCE XRa, XRb, XRc, XRd, eptn2
161  *  D16MIN XRa, XRb, XRc              Q8ABD XRa, XRb, XRc
162  *  D16SLT XRa, XRb, XRc              Q8SAD XRa, XRb, XRc, XRd
163  *  D16MOVZ XRa, XRb, XRc             Q8AVG XRa, XRb, XRc
164  *  D16MOVN XRa, XRb, XRc             Q8AVGR XRa, XRb, XRc
165  *  Q8MAX XRa, XRb, XRc               D8SUM XRa, XRb, XRc, XRd
166  *  Q8MIN XRa, XRb, XRc               D8SUMC XRa, XRb, XRc, XRd
167  *  Q8SLT XRa, XRb, XRc
168  *  Q8SLTU XRa, XRb, XRc
169  *  Q8MOVZ XRa, XRb, XRc             Shift instructions
170  *  Q8MOVN XRa, XRb, XRc             ------------------
171  *
172  *                                    D32SLL XRa, XRb, XRc, XRd, sft4
173  * Bitwise instructions               D32SLR XRa, XRb, XRc, XRd, sft4
174  * --------------------               D32SAR XRa, XRb, XRc, XRd, sft4
175  *                                    D32SARL XRa, XRb, XRc, sft4
176  *  S32NOR XRa, XRb, XRc              D32SLLV XRa, XRb, Rb
177  *  S32AND XRa, XRb, XRc              D32SLRV XRa, XRb, Rb
178  *  S32XOR XRa, XRb, XRc              D32SARV XRa, XRb, Rb
179  *  S32OR XRa, XRb, XRc               D32SARW XRa, XRb, XRc, Rb
180  *                                    Q16SLL XRa, XRb, XRc, XRd, sft4
181  *                                    Q16SLR XRa, XRb, XRc, XRd, sft4
182  * Miscellaneous instructions         Q16SAR XRa, XRb, XRc, XRd, sft4
183  * -------------------------          Q16SLLV XRa, XRb, Rb
184  *                                    Q16SLRV XRa, XRb, Rb
185  *  S32SFL XRa, XRb, XRc, XRd, optn2  Q16SARV XRa, XRb, Rb
186  *  S32ALN XRa, XRb, XRc, Rb
187  *  S32ALNI XRa, XRb, XRc, s3
188  *  S32LUI XRa, s8, optn3            Move instructions
189  *  S32EXTR XRa, XRb, Rb, bits5      -----------------
190  *  S32EXTRV XRa, XRb, Rs, Rt
191  *  Q16SCOP XRa, XRb, XRc, XRd        S32M2I XRa, Rb
192  *  Q16SAT XRa, XRb, XRc              S32I2M XRa, Rb
193  *
194  *
195  *     The opcode organization of MXU instructions
196  *     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
197  *
198  * The bits 31..26 of all MXU instructions are equal to 0x1C (also referred
199  * as opcode SPECIAL2 in the base MIPS ISA). The organization and meaning of
200  * other bits up to the instruction level is as follows:
201  *
202  *              bits
203  *             05..00
204  *
205  *          ┌─ 000000 ─ OPC_MXU_S32MADD
206  *          ├─ 000001 ─ OPC_MXU_S32MADDU
207  *          ├─ 000010 ─ <not assigned>   (non-MXU OPC_MUL)
208  *          │
209  *          │                               20..18
210  *          ├─ 000011 ─ OPC_MXU__POOL00 ─┬─ 000 ─ OPC_MXU_S32MAX
211  *          │                            ├─ 001 ─ OPC_MXU_S32MIN
212  *          │                            ├─ 010 ─ OPC_MXU_D16MAX
213  *          │                            ├─ 011 ─ OPC_MXU_D16MIN
214  *          │                            ├─ 100 ─ OPC_MXU_Q8MAX
215  *          │                            ├─ 101 ─ OPC_MXU_Q8MIN
216  *          │                            ├─ 110 ─ OPC_MXU_Q8SLT
217  *          │                            └─ 111 ─ OPC_MXU_Q8SLTU
218  *          ├─ 000100 ─ OPC_MXU_S32MSUB
219  *          ├─ 000101 ─ OPC_MXU_S32MSUBU    20..18
220  *          ├─ 000110 ─ OPC_MXU__POOL01 ─┬─ 000 ─ OPC_MXU_S32SLT
221  *          │                            ├─ 001 ─ OPC_MXU_D16SLT
222  *          │                            ├─ 010 ─ OPC_MXU_D16AVG
223  *          │                            ├─ 011 ─ OPC_MXU_D16AVGR
224  *          │                            ├─ 100 ─ OPC_MXU_Q8AVG
225  *          │                            ├─ 101 ─ OPC_MXU_Q8AVGR
226  *          │                            └─ 111 ─ OPC_MXU_Q8ADD
227  *          │
228  *          │                               20..18
229  *          ├─ 000111 ─ OPC_MXU__POOL02 ─┬─ 000 ─ OPC_MXU_S32CPS
230  *          │                            ├─ 010 ─ OPC_MXU_D16CPS
231  *          │                            ├─ 100 ─ OPC_MXU_Q8ABD
232  *          │                            └─ 110 ─ OPC_MXU_Q16SAT
233  *          ├─ 001000 ─ OPC_MXU_D16MUL
234  *          │                               25..24
235  *          ├─ 001001 ─ OPC_MXU__POOL03 ─┬─ 00 ─ OPC_MXU_D16MULF
236  *          │                            └─ 01 ─ OPC_MXU_D16MULE
237  *          ├─ 001010 ─ OPC_MXU_D16MAC
238  *          ├─ 001011 ─ OPC_MXU_D16MACF
239  *          ├─ 001100 ─ OPC_MXU_D16MADL
240  *          ├─ 001101 ─ OPC_MXU_S16MAD
241  *          ├─ 001110 ─ OPC_MXU_Q16ADD
242  *          ├─ 001111 ─ OPC_MXU_D16MACE     23
243  *          │                            ┌─ 0 ─ OPC_MXU_S32LDD
244  *          ├─ 010000 ─ OPC_MXU__POOL04 ─┴─ 1 ─ OPC_MXU_S32LDDR
245  *          │
246  *          │                               23
247  *          ├─ 010001 ─ OPC_MXU__POOL05 ─┬─ 0 ─ OPC_MXU_S32STD
248  *          │                            └─ 1 ─ OPC_MXU_S32STDR
249  *          │
250  *          │                               13..10
251  *          ├─ 010010 ─ OPC_MXU__POOL06 ─┬─ 0000 ─ OPC_MXU_S32LDDV
252  *          │                            └─ 0001 ─ OPC_MXU_S32LDDVR
253  *          │
254  *          │                               13..10
255  *          ├─ 010011 ─ OPC_MXU__POOL07 ─┬─ 0000 ─ OPC_MXU_S32STDV
256  *          │                            └─ 0001 ─ OPC_MXU_S32STDVR
257  *          │
258  *          │                               23
259  *          ├─ 010100 ─ OPC_MXU__POOL08 ─┬─ 0 ─ OPC_MXU_S32LDI
260  *          │                            └─ 1 ─ OPC_MXU_S32LDIR
261  *          │
262  *          │                               23
263  *          ├─ 010101 ─ OPC_MXU__POOL09 ─┬─ 0 ─ OPC_MXU_S32SDI
264  *          │                            └─ 1 ─ OPC_MXU_S32SDIR
265  *          │
266  *          │                               13..10
267  *          ├─ 010110 ─ OPC_MXU__POOL10 ─┬─ 0000 ─ OPC_MXU_S32LDIV
268  *          │                            └─ 0001 ─ OPC_MXU_S32LDIVR
269  *          │
270  *          │                               13..10
271  *          ├─ 010111 ─ OPC_MXU__POOL11 ─┬─ 0000 ─ OPC_MXU_S32SDIV
272  *          │                            └─ 0001 ─ OPC_MXU_S32SDIVR
273  *          ├─ 011000 ─ OPC_MXU_D32ADD
274  *          │                               23..22
275  *   MXU    ├─ 011001 ─ OPC_MXU__POOL12 ─┬─ 00 ─ OPC_MXU_D32ACC
276  * opcodes ─┤                            ├─ 01 ─ OPC_MXU_D32ACCM
277  *          │                            └─ 10 ─ OPC_MXU_D32ASUM
278  *          ├─ 011010 ─ <not assigned>
279  *          │                               23..22
280  *          ├─ 011011 ─ OPC_MXU__POOL13 ─┬─ 00 ─ OPC_MXU_Q16ACC
281  *          │                            ├─ 01 ─ OPC_MXU_Q16ACCM
282  *          │                            └─ 10 ─ OPC_MXU_Q16ASUM
283  *          │
284  *          │                               23..22
285  *          ├─ 011100 ─ OPC_MXU__POOL14 ─┬─ 00 ─ OPC_MXU_Q8ADDE
286  *          │                            ├─ 01 ─ OPC_MXU_D8SUM
287  *          ├─ 011101 ─ OPC_MXU_Q8ACCE   └─ 10 ─ OPC_MXU_D8SUMC
288  *          ├─ 011110 ─ <not assigned>
289  *          ├─ 011111 ─ <not assigned>
290  *          ├─ 100000 ─ <not assigned>   (overlaps with CLZ)
291  *          ├─ 100001 ─ <not assigned>   (overlaps with CLO)
292  *          ├─ 100010 ─ OPC_MXU_S8LDD
293  *          ├─ 100011 ─ OPC_MXU_S8STD       15..14
294  *          ├─ 100100 ─ OPC_MXU_S8LDI    ┌─ 00 ─ OPC_MXU_S32MUL
295  *          ├─ 100101 ─ OPC_MXU_S8SDI    ├─ 00 ─ OPC_MXU_S32MULU
296  *          │                            ├─ 00 ─ OPC_MXU_S32EXTR
297  *          ├─ 100110 ─ OPC_MXU__POOL15 ─┴─ 00 ─ OPC_MXU_S32EXTRV
298  *          │
299  *          │                               20..18
300  *          ├─ 100111 ─ OPC_MXU__POOL16 ─┬─ 000 ─ OPC_MXU_D32SARW
301  *          │                            ├─ 001 ─ OPC_MXU_S32ALN
302  *          │                            ├─ 010 ─ OPC_MXU_S32ALNI
303  *          │                            ├─ 011 ─ OPC_MXU_S32LUI
304  *          │                            ├─ 100 ─ OPC_MXU_S32NOR
305  *          │                            ├─ 101 ─ OPC_MXU_S32AND
306  *          │                            ├─ 110 ─ OPC_MXU_S32OR
307  *          │                            └─ 111 ─ OPC_MXU_S32XOR
308  *          │
309  *          │                               7..5
310  *          ├─ 101000 ─ OPC_MXU__POOL17 ─┬─ 000 ─ OPC_MXU_LXB
311  *          │                            ├─ 001 ─ OPC_MXU_LXH
312  *          ├─ 101001 ─ <not assigned>   ├─ 011 ─ OPC_MXU_LXW
313  *          ├─ 101010 ─ OPC_MXU_S16LDD   ├─ 100 ─ OPC_MXU_LXBU
314  *          ├─ 101011 ─ OPC_MXU_S16STD   └─ 101 ─ OPC_MXU_LXHU
315  *          ├─ 101100 ─ OPC_MXU_S16LDI
316  *          ├─ 101101 ─ OPC_MXU_S16SDI
317  *          ├─ 101110 ─ OPC_MXU_S32M2I
318  *          ├─ 101111 ─ OPC_MXU_S32I2M
319  *          ├─ 110000 ─ OPC_MXU_D32SLL
320  *          ├─ 110001 ─ OPC_MXU_D32SLR      20..18
321  *          ├─ 110010 ─ OPC_MXU_D32SARL  ┌─ 000 ─ OPC_MXU_D32SLLV
322  *          ├─ 110011 ─ OPC_MXU_D32SAR   ├─ 001 ─ OPC_MXU_D32SLRV
323  *          ├─ 110100 ─ OPC_MXU_Q16SLL   ├─ 010 ─ OPC_MXU_D32SARV
324  *          ├─ 110101 ─ OPC_MXU_Q16SLR   ├─ 011 ─ OPC_MXU_Q16SLLV
325  *          │                            ├─ 100 ─ OPC_MXU_Q16SLRV
326  *          ├─ 110110 ─ OPC_MXU__POOL18 ─┴─ 101 ─ OPC_MXU_Q16SARV
327  *          │
328  *          ├─ 110111 ─ OPC_MXU_Q16SAR
329  *          │                               23..22
330  *          ├─ 111000 ─ OPC_MXU__POOL19 ─┬─ 00 ─ OPC_MXU_Q8MUL
331  *          │                            └─ 01 ─ OPC_MXU_Q8MULSU
332  *          │
333  *          │                               20..18
334  *          ├─ 111001 ─ OPC_MXU__POOL20 ─┬─ 000 ─ OPC_MXU_Q8MOVZ
335  *          │                            ├─ 001 ─ OPC_MXU_Q8MOVN
336  *          │                            ├─ 010 ─ OPC_MXU_D16MOVZ
337  *          │                            ├─ 011 ─ OPC_MXU_D16MOVN
338  *          │                            ├─ 100 ─ OPC_MXU_S32MOVZ
339  *          │                            └─ 101 ─ OPC_MXU_S32MOVN
340  *          │
341  *          │                               23..22
342  *          ├─ 111010 ─ OPC_MXU__POOL21 ─┬─ 00 ─ OPC_MXU_Q8MAC
343  *          │                            └─ 10 ─ OPC_MXU_Q8MACSU
344  *          ├─ 111011 ─ OPC_MXU_Q16SCOP
345  *          ├─ 111100 ─ OPC_MXU_Q8MADL
346  *          ├─ 111101 ─ OPC_MXU_S32SFL
347  *          ├─ 111110 ─ OPC_MXU_Q8SAD
348  *          └─ 111111 ─ <not assigned>   (overlaps with SDBBP)
349  *
350  *
351  * Compiled after:
352  *
353  *   "XBurst® Instruction Set Architecture MIPS eXtension/enhanced Unit
354  *   Programming Manual", Ingenic Semiconductor Co, Ltd., revision June 2, 2017
355  */
356 
357 enum {
358     OPC_MXU__POOL00  = 0x03,
359     OPC_MXU_D16MUL   = 0x08,
360     OPC_MXU_D16MAC   = 0x0A,
361     OPC_MXU__POOL04  = 0x10,
362     OPC_MXU_S8LDD    = 0x22,
363     OPC_MXU__POOL16  = 0x27,
364     OPC_MXU_S32M2I   = 0x2E,
365     OPC_MXU_S32I2M   = 0x2F,
366     OPC_MXU__POOL19  = 0x38,
367 };
368 
369 
370 /*
371  * MXU pool 00
372  */
373 enum {
374     OPC_MXU_S32MAX   = 0x00,
375     OPC_MXU_S32MIN   = 0x01,
376     OPC_MXU_D16MAX   = 0x02,
377     OPC_MXU_D16MIN   = 0x03,
378     OPC_MXU_Q8MAX    = 0x04,
379     OPC_MXU_Q8MIN    = 0x05,
380 };
381 
382 /*
383  * MXU pool 04
384  */
385 enum {
386     OPC_MXU_S32LDD   = 0x00,
387     OPC_MXU_S32LDDR  = 0x01,
388 };
389 
390 /*
391  * MXU pool 16
392  */
393 enum {
394     OPC_MXU_S32ALNI  = 0x02,
395     OPC_MXU_S32NOR   = 0x04,
396     OPC_MXU_S32AND   = 0x05,
397     OPC_MXU_S32OR    = 0x06,
398     OPC_MXU_S32XOR   = 0x07,
399 };
400 
401 /*
402  * MXU pool 19
403  */
404 enum {
405     OPC_MXU_Q8MUL    = 0x00,
406     OPC_MXU_Q8MULSU  = 0x01,
407 };
408 
409 /* MXU accumulate add/subtract 1-bit pattern 'aptn1' */
410 #define MXU_APTN1_A    0
411 #define MXU_APTN1_S    1
412 
413 /* MXU accumulate add/subtract 2-bit pattern 'aptn2' */
414 #define MXU_APTN2_AA    0
415 #define MXU_APTN2_AS    1
416 #define MXU_APTN2_SA    2
417 #define MXU_APTN2_SS    3
418 
419 /* MXU execute add/subtract 2-bit pattern 'eptn2' */
420 #define MXU_EPTN2_AA    0
421 #define MXU_EPTN2_AS    1
422 #define MXU_EPTN2_SA    2
423 #define MXU_EPTN2_SS    3
424 
425 /* MXU operand getting pattern 'optn2' */
426 #define MXU_OPTN2_PTN0  0
427 #define MXU_OPTN2_PTN1  1
428 #define MXU_OPTN2_PTN2  2
429 #define MXU_OPTN2_PTN3  3
430 /* alternative naming scheme for 'optn2' */
431 #define MXU_OPTN2_WW    0
432 #define MXU_OPTN2_LW    1
433 #define MXU_OPTN2_HW    2
434 #define MXU_OPTN2_XW    3
435 
436 /* MXU operand getting pattern 'optn3' */
437 #define MXU_OPTN3_PTN0  0
438 #define MXU_OPTN3_PTN1  1
439 #define MXU_OPTN3_PTN2  2
440 #define MXU_OPTN3_PTN3  3
441 #define MXU_OPTN3_PTN4  4
442 #define MXU_OPTN3_PTN5  5
443 #define MXU_OPTN3_PTN6  6
444 #define MXU_OPTN3_PTN7  7
445 
446 /* MXU registers */
447 static TCGv mxu_gpr[NUMBER_OF_MXU_REGISTERS - 1];
448 static TCGv mxu_CR;
449 
450 static const char * const mxuregnames[] = {
451     "XR1",  "XR2",  "XR3",  "XR4",  "XR5",  "XR6",  "XR7",  "XR8",
452     "XR9",  "XR10", "XR11", "XR12", "XR13", "XR14", "XR15", "MXU_CR",
453 };
454 
455 void mxu_translate_init(void)
456 {
457     for (unsigned i = 0; i < NUMBER_OF_MXU_REGISTERS - 1; i++) {
458         mxu_gpr[i] = tcg_global_mem_new(cpu_env,
459                                         offsetof(CPUMIPSState, active_tc.mxu_gpr[i]),
460                                         mxuregnames[i]);
461     }
462 
463     mxu_CR = tcg_global_mem_new(cpu_env,
464                                 offsetof(CPUMIPSState, active_tc.mxu_cr),
465                                 mxuregnames[NUMBER_OF_MXU_REGISTERS - 1]);
466 }
467 
468 /* MXU General purpose registers moves. */
469 static inline void gen_load_mxu_gpr(TCGv t, unsigned int reg)
470 {
471     if (reg == 0) {
472         tcg_gen_movi_tl(t, 0);
473     } else if (reg <= 15) {
474         tcg_gen_mov_tl(t, mxu_gpr[reg - 1]);
475     }
476 }
477 
478 static inline void gen_store_mxu_gpr(TCGv t, unsigned int reg)
479 {
480     if (reg > 0 && reg <= 15) {
481         tcg_gen_mov_tl(mxu_gpr[reg - 1], t);
482     }
483 }
484 
485 /* MXU control register moves. */
486 static inline void gen_load_mxu_cr(TCGv t)
487 {
488     tcg_gen_mov_tl(t, mxu_CR);
489 }
490 
491 static inline void gen_store_mxu_cr(TCGv t)
492 {
493     /* TODO: Add handling of RW rules for MXU_CR. */
494     tcg_gen_mov_tl(mxu_CR, t);
495 }
496 
497 /*
498  * S32I2M XRa, rb - Register move from GRF to XRF
499  */
500 static void gen_mxu_s32i2m(DisasContext *ctx)
501 {
502     TCGv t0;
503     uint32_t XRa, Rb;
504 
505     t0 = tcg_temp_new();
506 
507     XRa = extract32(ctx->opcode, 6, 5);
508     Rb = extract32(ctx->opcode, 16, 5);
509 
510     gen_load_gpr(t0, Rb);
511     if (XRa <= 15) {
512         gen_store_mxu_gpr(t0, XRa);
513     } else if (XRa == 16) {
514         gen_store_mxu_cr(t0);
515     }
516 
517     tcg_temp_free(t0);
518 }
519 
520 /*
521  * S32M2I XRa, rb - Register move from XRF to GRF
522  */
523 static void gen_mxu_s32m2i(DisasContext *ctx)
524 {
525     TCGv t0;
526     uint32_t XRa, Rb;
527 
528     t0 = tcg_temp_new();
529 
530     XRa = extract32(ctx->opcode, 6, 5);
531     Rb = extract32(ctx->opcode, 16, 5);
532 
533     if (XRa <= 15) {
534         gen_load_mxu_gpr(t0, XRa);
535     } else if (XRa == 16) {
536         gen_load_mxu_cr(t0);
537     }
538 
539     gen_store_gpr(t0, Rb);
540 
541     tcg_temp_free(t0);
542 }
543 
544 /*
545  * S8LDD XRa, Rb, s8, optn3 - Load a byte from memory to XRF
546  */
547 static void gen_mxu_s8ldd(DisasContext *ctx)
548 {
549     TCGv t0, t1;
550     uint32_t XRa, Rb, s8, optn3;
551 
552     t0 = tcg_temp_new();
553     t1 = tcg_temp_new();
554 
555     XRa = extract32(ctx->opcode, 6, 4);
556     s8 = extract32(ctx->opcode, 10, 8);
557     optn3 = extract32(ctx->opcode, 18, 3);
558     Rb = extract32(ctx->opcode, 21, 5);
559 
560     gen_load_gpr(t0, Rb);
561     tcg_gen_addi_tl(t0, t0, (int8_t)s8);
562 
563     switch (optn3) {
564     /* XRa[7:0] = tmp8 */
565     case MXU_OPTN3_PTN0:
566         tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
567         gen_load_mxu_gpr(t0, XRa);
568         tcg_gen_deposit_tl(t0, t0, t1, 0, 8);
569         break;
570     /* XRa[15:8] = tmp8 */
571     case MXU_OPTN3_PTN1:
572         tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
573         gen_load_mxu_gpr(t0, XRa);
574         tcg_gen_deposit_tl(t0, t0, t1, 8, 8);
575         break;
576     /* XRa[23:16] = tmp8 */
577     case MXU_OPTN3_PTN2:
578         tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
579         gen_load_mxu_gpr(t0, XRa);
580         tcg_gen_deposit_tl(t0, t0, t1, 16, 8);
581         break;
582     /* XRa[31:24] = tmp8 */
583     case MXU_OPTN3_PTN3:
584         tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
585         gen_load_mxu_gpr(t0, XRa);
586         tcg_gen_deposit_tl(t0, t0, t1, 24, 8);
587         break;
588     /* XRa = {8'b0, tmp8, 8'b0, tmp8} */
589     case MXU_OPTN3_PTN4:
590         tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
591         tcg_gen_deposit_tl(t0, t1, t1, 16, 16);
592         break;
593     /* XRa = {tmp8, 8'b0, tmp8, 8'b0} */
594     case MXU_OPTN3_PTN5:
595         tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
596         tcg_gen_shli_tl(t1, t1, 8);
597         tcg_gen_deposit_tl(t0, t1, t1, 16, 16);
598         break;
599     /* XRa = {{8{sign of tmp8}}, tmp8, {8{sign of tmp8}}, tmp8} */
600     case MXU_OPTN3_PTN6:
601         tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_SB);
602         tcg_gen_mov_tl(t0, t1);
603         tcg_gen_andi_tl(t0, t0, 0xFF00FFFF);
604         tcg_gen_shli_tl(t1, t1, 16);
605         tcg_gen_or_tl(t0, t0, t1);
606         break;
607     /* XRa = {tmp8, tmp8, tmp8, tmp8} */
608     case MXU_OPTN3_PTN7:
609         tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
610         tcg_gen_deposit_tl(t1, t1, t1, 8, 8);
611         tcg_gen_deposit_tl(t0, t1, t1, 16, 16);
612         break;
613     }
614 
615     gen_store_mxu_gpr(t0, XRa);
616 
617     tcg_temp_free(t0);
618     tcg_temp_free(t1);
619 }
620 
621 /*
622  * D16MUL XRa, XRb, XRc, XRd, optn2 - Signed 16 bit pattern multiplication
623  */
624 static void gen_mxu_d16mul(DisasContext *ctx)
625 {
626     TCGv t0, t1, t2, t3;
627     uint32_t XRa, XRb, XRc, XRd, optn2;
628 
629     t0 = tcg_temp_new();
630     t1 = tcg_temp_new();
631     t2 = tcg_temp_new();
632     t3 = tcg_temp_new();
633 
634     XRa = extract32(ctx->opcode, 6, 4);
635     XRb = extract32(ctx->opcode, 10, 4);
636     XRc = extract32(ctx->opcode, 14, 4);
637     XRd = extract32(ctx->opcode, 18, 4);
638     optn2 = extract32(ctx->opcode, 22, 2);
639 
640     gen_load_mxu_gpr(t1, XRb);
641     tcg_gen_sextract_tl(t0, t1, 0, 16);
642     tcg_gen_sextract_tl(t1, t1, 16, 16);
643     gen_load_mxu_gpr(t3, XRc);
644     tcg_gen_sextract_tl(t2, t3, 0, 16);
645     tcg_gen_sextract_tl(t3, t3, 16, 16);
646 
647     switch (optn2) {
648     case MXU_OPTN2_WW: /* XRB.H*XRC.H == lop, XRB.L*XRC.L == rop */
649         tcg_gen_mul_tl(t3, t1, t3);
650         tcg_gen_mul_tl(t2, t0, t2);
651         break;
652     case MXU_OPTN2_LW: /* XRB.L*XRC.H == lop, XRB.L*XRC.L == rop */
653         tcg_gen_mul_tl(t3, t0, t3);
654         tcg_gen_mul_tl(t2, t0, t2);
655         break;
656     case MXU_OPTN2_HW: /* XRB.H*XRC.H == lop, XRB.H*XRC.L == rop */
657         tcg_gen_mul_tl(t3, t1, t3);
658         tcg_gen_mul_tl(t2, t1, t2);
659         break;
660     case MXU_OPTN2_XW: /* XRB.L*XRC.H == lop, XRB.H*XRC.L == rop */
661         tcg_gen_mul_tl(t3, t0, t3);
662         tcg_gen_mul_tl(t2, t1, t2);
663         break;
664     }
665     gen_store_mxu_gpr(t3, XRa);
666     gen_store_mxu_gpr(t2, XRd);
667 
668     tcg_temp_free(t0);
669     tcg_temp_free(t1);
670     tcg_temp_free(t2);
671     tcg_temp_free(t3);
672 }
673 
674 /*
675  * D16MAC XRa, XRb, XRc, XRd, aptn2, optn2 - Signed 16 bit pattern multiply
676  *                                           and accumulate
677  */
678 static void gen_mxu_d16mac(DisasContext *ctx)
679 {
680     TCGv t0, t1, t2, t3;
681     uint32_t XRa, XRb, XRc, XRd, optn2, aptn2;
682 
683     t0 = tcg_temp_new();
684     t1 = tcg_temp_new();
685     t2 = tcg_temp_new();
686     t3 = tcg_temp_new();
687 
688     XRa = extract32(ctx->opcode, 6, 4);
689     XRb = extract32(ctx->opcode, 10, 4);
690     XRc = extract32(ctx->opcode, 14, 4);
691     XRd = extract32(ctx->opcode, 18, 4);
692     optn2 = extract32(ctx->opcode, 22, 2);
693     aptn2 = extract32(ctx->opcode, 24, 2);
694 
695     gen_load_mxu_gpr(t1, XRb);
696     tcg_gen_sextract_tl(t0, t1, 0, 16);
697     tcg_gen_sextract_tl(t1, t1, 16, 16);
698 
699     gen_load_mxu_gpr(t3, XRc);
700     tcg_gen_sextract_tl(t2, t3, 0, 16);
701     tcg_gen_sextract_tl(t3, t3, 16, 16);
702 
703     switch (optn2) {
704     case MXU_OPTN2_WW: /* XRB.H*XRC.H == lop, XRB.L*XRC.L == rop */
705         tcg_gen_mul_tl(t3, t1, t3);
706         tcg_gen_mul_tl(t2, t0, t2);
707         break;
708     case MXU_OPTN2_LW: /* XRB.L*XRC.H == lop, XRB.L*XRC.L == rop */
709         tcg_gen_mul_tl(t3, t0, t3);
710         tcg_gen_mul_tl(t2, t0, t2);
711         break;
712     case MXU_OPTN2_HW: /* XRB.H*XRC.H == lop, XRB.H*XRC.L == rop */
713         tcg_gen_mul_tl(t3, t1, t3);
714         tcg_gen_mul_tl(t2, t1, t2);
715         break;
716     case MXU_OPTN2_XW: /* XRB.L*XRC.H == lop, XRB.H*XRC.L == rop */
717         tcg_gen_mul_tl(t3, t0, t3);
718         tcg_gen_mul_tl(t2, t1, t2);
719         break;
720     }
721     gen_load_mxu_gpr(t0, XRa);
722     gen_load_mxu_gpr(t1, XRd);
723 
724     switch (aptn2) {
725     case MXU_APTN2_AA:
726         tcg_gen_add_tl(t3, t0, t3);
727         tcg_gen_add_tl(t2, t1, t2);
728         break;
729     case MXU_APTN2_AS:
730         tcg_gen_add_tl(t3, t0, t3);
731         tcg_gen_sub_tl(t2, t1, t2);
732         break;
733     case MXU_APTN2_SA:
734         tcg_gen_sub_tl(t3, t0, t3);
735         tcg_gen_add_tl(t2, t1, t2);
736         break;
737     case MXU_APTN2_SS:
738         tcg_gen_sub_tl(t3, t0, t3);
739         tcg_gen_sub_tl(t2, t1, t2);
740         break;
741     }
742     gen_store_mxu_gpr(t3, XRa);
743     gen_store_mxu_gpr(t2, XRd);
744 
745     tcg_temp_free(t0);
746     tcg_temp_free(t1);
747     tcg_temp_free(t2);
748     tcg_temp_free(t3);
749 }
750 
751 /*
752  * Q8MUL   XRa, XRb, XRc, XRd - Parallel unsigned 8 bit pattern multiply
753  * Q8MULSU XRa, XRb, XRc, XRd - Parallel signed 8 bit pattern multiply
754  */
755 static void gen_mxu_q8mul_q8mulsu(DisasContext *ctx)
756 {
757     TCGv t0, t1, t2, t3, t4, t5, t6, t7;
758     uint32_t XRa, XRb, XRc, XRd, sel;
759 
760     t0 = tcg_temp_new();
761     t1 = tcg_temp_new();
762     t2 = tcg_temp_new();
763     t3 = tcg_temp_new();
764     t4 = tcg_temp_new();
765     t5 = tcg_temp_new();
766     t6 = tcg_temp_new();
767     t7 = tcg_temp_new();
768 
769     XRa = extract32(ctx->opcode, 6, 4);
770     XRb = extract32(ctx->opcode, 10, 4);
771     XRc = extract32(ctx->opcode, 14, 4);
772     XRd = extract32(ctx->opcode, 18, 4);
773     sel = extract32(ctx->opcode, 22, 2);
774 
775     gen_load_mxu_gpr(t3, XRb);
776     gen_load_mxu_gpr(t7, XRc);
777 
778     if (sel == 0x2) {
779         /* Q8MULSU */
780         tcg_gen_ext8s_tl(t0, t3);
781         tcg_gen_shri_tl(t3, t3, 8);
782         tcg_gen_ext8s_tl(t1, t3);
783         tcg_gen_shri_tl(t3, t3, 8);
784         tcg_gen_ext8s_tl(t2, t3);
785         tcg_gen_shri_tl(t3, t3, 8);
786         tcg_gen_ext8s_tl(t3, t3);
787     } else {
788         /* Q8MUL */
789         tcg_gen_ext8u_tl(t0, t3);
790         tcg_gen_shri_tl(t3, t3, 8);
791         tcg_gen_ext8u_tl(t1, t3);
792         tcg_gen_shri_tl(t3, t3, 8);
793         tcg_gen_ext8u_tl(t2, t3);
794         tcg_gen_shri_tl(t3, t3, 8);
795         tcg_gen_ext8u_tl(t3, t3);
796     }
797 
798     tcg_gen_ext8u_tl(t4, t7);
799     tcg_gen_shri_tl(t7, t7, 8);
800     tcg_gen_ext8u_tl(t5, t7);
801     tcg_gen_shri_tl(t7, t7, 8);
802     tcg_gen_ext8u_tl(t6, t7);
803     tcg_gen_shri_tl(t7, t7, 8);
804     tcg_gen_ext8u_tl(t7, t7);
805 
806     tcg_gen_mul_tl(t0, t0, t4);
807     tcg_gen_mul_tl(t1, t1, t5);
808     tcg_gen_mul_tl(t2, t2, t6);
809     tcg_gen_mul_tl(t3, t3, t7);
810 
811     tcg_gen_andi_tl(t0, t0, 0xFFFF);
812     tcg_gen_andi_tl(t1, t1, 0xFFFF);
813     tcg_gen_andi_tl(t2, t2, 0xFFFF);
814     tcg_gen_andi_tl(t3, t3, 0xFFFF);
815 
816     tcg_gen_shli_tl(t1, t1, 16);
817     tcg_gen_shli_tl(t3, t3, 16);
818 
819     tcg_gen_or_tl(t0, t0, t1);
820     tcg_gen_or_tl(t1, t2, t3);
821 
822     gen_store_mxu_gpr(t0, XRd);
823     gen_store_mxu_gpr(t1, XRa);
824 
825     tcg_temp_free(t0);
826     tcg_temp_free(t1);
827     tcg_temp_free(t2);
828     tcg_temp_free(t3);
829     tcg_temp_free(t4);
830     tcg_temp_free(t5);
831     tcg_temp_free(t6);
832     tcg_temp_free(t7);
833 }
834 
835 /*
836  * S32LDD  XRa, Rb, S12 - Load a word from memory to XRF
837  * S32LDDR XRa, Rb, S12 - Load a word from memory to XRF, reversed byte seq.
838  */
839 static void gen_mxu_s32ldd_s32lddr(DisasContext *ctx)
840 {
841     TCGv t0, t1;
842     uint32_t XRa, Rb, s12, sel;
843 
844     t0 = tcg_temp_new();
845     t1 = tcg_temp_new();
846 
847     XRa = extract32(ctx->opcode, 6, 4);
848     s12 = extract32(ctx->opcode, 10, 10);
849     sel = extract32(ctx->opcode, 20, 1);
850     Rb = extract32(ctx->opcode, 21, 5);
851 
852     gen_load_gpr(t0, Rb);
853 
854     tcg_gen_movi_tl(t1, s12);
855     tcg_gen_shli_tl(t1, t1, 2);
856     if (s12 & 0x200) {
857         tcg_gen_ori_tl(t1, t1, 0xFFFFF000);
858     }
859     tcg_gen_add_tl(t1, t0, t1);
860     tcg_gen_qemu_ld_tl(t1, t1, ctx->mem_idx, MO_SL);
861 
862     if (sel == 1) {
863         /* S32LDDR */
864         tcg_gen_bswap32_tl(t1, t1);
865     }
866     gen_store_mxu_gpr(t1, XRa);
867 
868     tcg_temp_free(t0);
869     tcg_temp_free(t1);
870 }
871 
872 
873 /*
874  *                 MXU instruction category: logic
875  *                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
876  *
877  *               S32NOR    S32AND    S32OR    S32XOR
878  */
879 
880 /*
881  *  S32NOR XRa, XRb, XRc
882  *    Update XRa with the result of logical bitwise 'nor' operation
883  *    applied to the content of XRb and XRc.
884  */
885 static void gen_mxu_S32NOR(DisasContext *ctx)
886 {
887     uint32_t pad, XRc, XRb, XRa;
888 
889     pad = extract32(ctx->opcode, 21, 5);
890     XRc = extract32(ctx->opcode, 14, 4);
891     XRb = extract32(ctx->opcode, 10, 4);
892     XRa = extract32(ctx->opcode,  6, 4);
893 
894     if (unlikely(pad != 0)) {
895         /* opcode padding incorrect -> do nothing */
896     } else if (unlikely(XRa == 0)) {
897         /* destination is zero register -> do nothing */
898     } else if (unlikely((XRb == 0) && (XRc == 0))) {
899         /* both operands zero registers -> just set destination to all 1s */
900         tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0xFFFFFFFF);
901     } else if (unlikely(XRb == 0)) {
902         /* XRb zero register -> just set destination to the negation of XRc */
903         tcg_gen_not_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]);
904     } else if (unlikely(XRc == 0)) {
905         /* XRa zero register -> just set destination to the negation of XRb */
906         tcg_gen_not_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
907     } else if (unlikely(XRb == XRc)) {
908         /* both operands same -> just set destination to the negation of XRb */
909         tcg_gen_not_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
910     } else {
911         /* the most general case */
912         tcg_gen_nor_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], mxu_gpr[XRc - 1]);
913     }
914 }
915 
916 /*
917  *  S32AND XRa, XRb, XRc
918  *    Update XRa with the result of logical bitwise 'and' operation
919  *    applied to the content of XRb and XRc.
920  */
921 static void gen_mxu_S32AND(DisasContext *ctx)
922 {
923     uint32_t pad, XRc, XRb, XRa;
924 
925     pad = extract32(ctx->opcode, 21, 5);
926     XRc = extract32(ctx->opcode, 14, 4);
927     XRb = extract32(ctx->opcode, 10, 4);
928     XRa = extract32(ctx->opcode,  6, 4);
929 
930     if (unlikely(pad != 0)) {
931         /* opcode padding incorrect -> do nothing */
932     } else if (unlikely(XRa == 0)) {
933         /* destination is zero register -> do nothing */
934     } else if (unlikely((XRb == 0) || (XRc == 0))) {
935         /* one of operands zero register -> just set destination to all 0s */
936         tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
937     } else if (unlikely(XRb == XRc)) {
938         /* both operands same -> just set destination to one of them */
939         tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
940     } else {
941         /* the most general case */
942         tcg_gen_and_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], mxu_gpr[XRc - 1]);
943     }
944 }
945 
946 /*
947  *  S32OR XRa, XRb, XRc
948  *    Update XRa with the result of logical bitwise 'or' operation
949  *    applied to the content of XRb and XRc.
950  */
951 static void gen_mxu_S32OR(DisasContext *ctx)
952 {
953     uint32_t pad, XRc, XRb, XRa;
954 
955     pad = extract32(ctx->opcode, 21, 5);
956     XRc = extract32(ctx->opcode, 14, 4);
957     XRb = extract32(ctx->opcode, 10, 4);
958     XRa = extract32(ctx->opcode,  6, 4);
959 
960     if (unlikely(pad != 0)) {
961         /* opcode padding incorrect -> do nothing */
962     } else if (unlikely(XRa == 0)) {
963         /* destination is zero register -> do nothing */
964     } else if (unlikely((XRb == 0) && (XRc == 0))) {
965         /* both operands zero registers -> just set destination to all 0s */
966         tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
967     } else if (unlikely(XRb == 0)) {
968         /* XRb zero register -> just set destination to the content of XRc */
969         tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]);
970     } else if (unlikely(XRc == 0)) {
971         /* XRc zero register -> just set destination to the content of XRb */
972         tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
973     } else if (unlikely(XRb == XRc)) {
974         /* both operands same -> just set destination to one of them */
975         tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
976     } else {
977         /* the most general case */
978         tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], mxu_gpr[XRc - 1]);
979     }
980 }
981 
982 /*
983  *  S32XOR XRa, XRb, XRc
984  *    Update XRa with the result of logical bitwise 'xor' operation
985  *    applied to the content of XRb and XRc.
986  */
987 static void gen_mxu_S32XOR(DisasContext *ctx)
988 {
989     uint32_t pad, XRc, XRb, XRa;
990 
991     pad = extract32(ctx->opcode, 21, 5);
992     XRc = extract32(ctx->opcode, 14, 4);
993     XRb = extract32(ctx->opcode, 10, 4);
994     XRa = extract32(ctx->opcode,  6, 4);
995 
996     if (unlikely(pad != 0)) {
997         /* opcode padding incorrect -> do nothing */
998     } else if (unlikely(XRa == 0)) {
999         /* destination is zero register -> do nothing */
1000     } else if (unlikely((XRb == 0) && (XRc == 0))) {
1001         /* both operands zero registers -> just set destination to all 0s */
1002         tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
1003     } else if (unlikely(XRb == 0)) {
1004         /* XRb zero register -> just set destination to the content of XRc */
1005         tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]);
1006     } else if (unlikely(XRc == 0)) {
1007         /* XRc zero register -> just set destination to the content of XRb */
1008         tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
1009     } else if (unlikely(XRb == XRc)) {
1010         /* both operands same -> just set destination to all 0s */
1011         tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
1012     } else {
1013         /* the most general case */
1014         tcg_gen_xor_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], mxu_gpr[XRc - 1]);
1015     }
1016 }
1017 
1018 
1019 /*
1020  *                   MXU instruction category max/min
1021  *                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1022  *
1023  *                     S32MAX     D16MAX     Q8MAX
1024  *                     S32MIN     D16MIN     Q8MIN
1025  */
1026 
1027 /*
1028  *  S32MAX XRa, XRb, XRc
1029  *    Update XRa with the maximum of signed 32-bit integers contained
1030  *    in XRb and XRc.
1031  *
1032  *  S32MIN XRa, XRb, XRc
1033  *    Update XRa with the minimum of signed 32-bit integers contained
1034  *    in XRb and XRc.
1035  */
1036 static void gen_mxu_S32MAX_S32MIN(DisasContext *ctx)
1037 {
1038     uint32_t pad, opc, XRc, XRb, XRa;
1039 
1040     pad = extract32(ctx->opcode, 21, 5);
1041     opc = extract32(ctx->opcode, 18, 3);
1042     XRc = extract32(ctx->opcode, 14, 4);
1043     XRb = extract32(ctx->opcode, 10, 4);
1044     XRa = extract32(ctx->opcode,  6, 4);
1045 
1046     if (unlikely(pad != 0)) {
1047         /* opcode padding incorrect -> do nothing */
1048     } else if (unlikely(XRa == 0)) {
1049         /* destination is zero register -> do nothing */
1050     } else if (unlikely((XRb == 0) && (XRc == 0))) {
1051         /* both operands zero registers -> just set destination to zero */
1052         tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
1053     } else if (unlikely((XRb == 0) || (XRc == 0))) {
1054         /* exactly one operand is zero register - find which one is not...*/
1055         uint32_t XRx = XRb ? XRb : XRc;
1056         /* ...and do max/min operation with one operand 0 */
1057         if (opc == OPC_MXU_S32MAX) {
1058             tcg_gen_smax_i32(mxu_gpr[XRa - 1], mxu_gpr[XRx - 1], 0);
1059         } else {
1060             tcg_gen_smin_i32(mxu_gpr[XRa - 1], mxu_gpr[XRx - 1], 0);
1061         }
1062     } else if (unlikely(XRb == XRc)) {
1063         /* both operands same -> just set destination to one of them */
1064         tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
1065     } else {
1066         /* the most general case */
1067         if (opc == OPC_MXU_S32MAX) {
1068             tcg_gen_smax_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1],
1069                                                mxu_gpr[XRc - 1]);
1070         } else {
1071             tcg_gen_smin_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1],
1072                                                mxu_gpr[XRc - 1]);
1073         }
1074     }
1075 }
1076 
1077 /*
1078  *  D16MAX
1079  *    Update XRa with the 16-bit-wise maximums of signed integers
1080  *    contained in XRb and XRc.
1081  *
1082  *  D16MIN
1083  *    Update XRa with the 16-bit-wise minimums of signed integers
1084  *    contained in XRb and XRc.
1085  */
1086 static void gen_mxu_D16MAX_D16MIN(DisasContext *ctx)
1087 {
1088     uint32_t pad, opc, XRc, XRb, XRa;
1089 
1090     pad = extract32(ctx->opcode, 21, 5);
1091     opc = extract32(ctx->opcode, 18, 3);
1092     XRc = extract32(ctx->opcode, 14, 4);
1093     XRb = extract32(ctx->opcode, 10, 4);
1094     XRa = extract32(ctx->opcode,  6, 4);
1095 
1096     if (unlikely(pad != 0)) {
1097         /* opcode padding incorrect -> do nothing */
1098     } else if (unlikely(XRa == 0)) {
1099         /* destination is zero register -> do nothing */
1100     } else if (unlikely((XRb == 0) && (XRc == 0))) {
1101         /* both operands zero registers -> just set destination to zero */
1102         tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
1103     } else if (unlikely((XRb == 0) || (XRc == 0))) {
1104         /* exactly one operand is zero register - find which one is not...*/
1105         uint32_t XRx = XRb ? XRb : XRc;
1106         /* ...and do half-word-wise max/min with one operand 0 */
1107         TCGv_i32 t0 = tcg_temp_new();
1108         TCGv_i32 t1 = tcg_const_i32(0);
1109 
1110         /* the left half-word first */
1111         tcg_gen_andi_i32(t0, mxu_gpr[XRx - 1], 0xFFFF0000);
1112         if (opc == OPC_MXU_D16MAX) {
1113             tcg_gen_smax_i32(mxu_gpr[XRa - 1], t0, t1);
1114         } else {
1115             tcg_gen_smin_i32(mxu_gpr[XRa - 1], t0, t1);
1116         }
1117 
1118         /* the right half-word */
1119         tcg_gen_andi_i32(t0, mxu_gpr[XRx - 1], 0x0000FFFF);
1120         /* move half-words to the leftmost position */
1121         tcg_gen_shli_i32(t0, t0, 16);
1122         /* t0 will be max/min of t0 and t1 */
1123         if (opc == OPC_MXU_D16MAX) {
1124             tcg_gen_smax_i32(t0, t0, t1);
1125         } else {
1126             tcg_gen_smin_i32(t0, t0, t1);
1127         }
1128         /* return resulting half-words to its original position */
1129         tcg_gen_shri_i32(t0, t0, 16);
1130         /* finally update the destination */
1131         tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRa - 1], t0);
1132 
1133         tcg_temp_free(t1);
1134         tcg_temp_free(t0);
1135     } else if (unlikely(XRb == XRc)) {
1136         /* both operands same -> just set destination to one of them */
1137         tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
1138     } else {
1139         /* the most general case */
1140         TCGv_i32 t0 = tcg_temp_new();
1141         TCGv_i32 t1 = tcg_temp_new();
1142 
1143         /* the left half-word first */
1144         tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0xFFFF0000);
1145         tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFFFF0000);
1146         if (opc == OPC_MXU_D16MAX) {
1147             tcg_gen_smax_i32(mxu_gpr[XRa - 1], t0, t1);
1148         } else {
1149             tcg_gen_smin_i32(mxu_gpr[XRa - 1], t0, t1);
1150         }
1151 
1152         /* the right half-word */
1153         tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0x0000FFFF);
1154         tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0x0000FFFF);
1155         /* move half-words to the leftmost position */
1156         tcg_gen_shli_i32(t0, t0, 16);
1157         tcg_gen_shli_i32(t1, t1, 16);
1158         /* t0 will be max/min of t0 and t1 */
1159         if (opc == OPC_MXU_D16MAX) {
1160             tcg_gen_smax_i32(t0, t0, t1);
1161         } else {
1162             tcg_gen_smin_i32(t0, t0, t1);
1163         }
1164         /* return resulting half-words to its original position */
1165         tcg_gen_shri_i32(t0, t0, 16);
1166         /* finally update the destination */
1167         tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRa - 1], t0);
1168 
1169         tcg_temp_free(t1);
1170         tcg_temp_free(t0);
1171     }
1172 }
1173 
1174 /*
1175  *  Q8MAX
1176  *    Update XRa with the 8-bit-wise maximums of signed integers
1177  *    contained in XRb and XRc.
1178  *
1179  *  Q8MIN
1180  *    Update XRa with the 8-bit-wise minimums of signed integers
1181  *    contained in XRb and XRc.
1182  */
1183 static void gen_mxu_Q8MAX_Q8MIN(DisasContext *ctx)
1184 {
1185     uint32_t pad, opc, XRc, XRb, XRa;
1186 
1187     pad = extract32(ctx->opcode, 21, 5);
1188     opc = extract32(ctx->opcode, 18, 3);
1189     XRc = extract32(ctx->opcode, 14, 4);
1190     XRb = extract32(ctx->opcode, 10, 4);
1191     XRa = extract32(ctx->opcode,  6, 4);
1192 
1193     if (unlikely(pad != 0)) {
1194         /* opcode padding incorrect -> do nothing */
1195     } else if (unlikely(XRa == 0)) {
1196         /* destination is zero register -> do nothing */
1197     } else if (unlikely((XRb == 0) && (XRc == 0))) {
1198         /* both operands zero registers -> just set destination to zero */
1199         tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
1200     } else if (unlikely((XRb == 0) || (XRc == 0))) {
1201         /* exactly one operand is zero register - make it be the first...*/
1202         uint32_t XRx = XRb ? XRb : XRc;
1203         /* ...and do byte-wise max/min with one operand 0 */
1204         TCGv_i32 t0 = tcg_temp_new();
1205         TCGv_i32 t1 = tcg_const_i32(0);
1206         int32_t i;
1207 
1208         /* the leftmost byte (byte 3) first */
1209         tcg_gen_andi_i32(t0, mxu_gpr[XRx - 1], 0xFF000000);
1210         if (opc == OPC_MXU_Q8MAX) {
1211             tcg_gen_smax_i32(mxu_gpr[XRa - 1], t0, t1);
1212         } else {
1213             tcg_gen_smin_i32(mxu_gpr[XRa - 1], t0, t1);
1214         }
1215 
1216         /* bytes 2, 1, 0 */
1217         for (i = 2; i >= 0; i--) {
1218             /* extract the byte */
1219             tcg_gen_andi_i32(t0, mxu_gpr[XRx - 1], 0xFF << (8 * i));
1220             /* move the byte to the leftmost position */
1221             tcg_gen_shli_i32(t0, t0, 8 * (3 - i));
1222             /* t0 will be max/min of t0 and t1 */
1223             if (opc == OPC_MXU_Q8MAX) {
1224                 tcg_gen_smax_i32(t0, t0, t1);
1225             } else {
1226                 tcg_gen_smin_i32(t0, t0, t1);
1227             }
1228             /* return resulting byte to its original position */
1229             tcg_gen_shri_i32(t0, t0, 8 * (3 - i));
1230             /* finally update the destination */
1231             tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRa - 1], t0);
1232         }
1233 
1234         tcg_temp_free(t1);
1235         tcg_temp_free(t0);
1236     } else if (unlikely(XRb == XRc)) {
1237         /* both operands same -> just set destination to one of them */
1238         tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
1239     } else {
1240         /* the most general case */
1241         TCGv_i32 t0 = tcg_temp_new();
1242         TCGv_i32 t1 = tcg_temp_new();
1243         int32_t i;
1244 
1245         /* the leftmost bytes (bytes 3) first */
1246         tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0xFF000000);
1247         tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFF000000);
1248         if (opc == OPC_MXU_Q8MAX) {
1249             tcg_gen_smax_i32(mxu_gpr[XRa - 1], t0, t1);
1250         } else {
1251             tcg_gen_smin_i32(mxu_gpr[XRa - 1], t0, t1);
1252         }
1253 
1254         /* bytes 2, 1, 0 */
1255         for (i = 2; i >= 0; i--) {
1256             /* extract corresponding bytes */
1257             tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0xFF << (8 * i));
1258             tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFF << (8 * i));
1259             /* move the bytes to the leftmost position */
1260             tcg_gen_shli_i32(t0, t0, 8 * (3 - i));
1261             tcg_gen_shli_i32(t1, t1, 8 * (3 - i));
1262             /* t0 will be max/min of t0 and t1 */
1263             if (opc == OPC_MXU_Q8MAX) {
1264                 tcg_gen_smax_i32(t0, t0, t1);
1265             } else {
1266                 tcg_gen_smin_i32(t0, t0, t1);
1267             }
1268             /* return resulting byte to its original position */
1269             tcg_gen_shri_i32(t0, t0, 8 * (3 - i));
1270             /* finally update the destination */
1271             tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRa - 1], t0);
1272         }
1273 
1274         tcg_temp_free(t1);
1275         tcg_temp_free(t0);
1276     }
1277 }
1278 
1279 
1280 /*
1281  *                 MXU instruction category: align
1282  *                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1283  *
1284  *                       S32ALN     S32ALNI
1285  */
1286 
1287 /*
1288  *  S32ALNI XRc, XRb, XRa, optn3
1289  *    Arrange bytes from XRb and XRc according to one of five sets of
1290  *    rules determined by optn3, and place the result in XRa.
1291  */
1292 static void gen_mxu_S32ALNI(DisasContext *ctx)
1293 {
1294     uint32_t optn3, pad, XRc, XRb, XRa;
1295 
1296     optn3 = extract32(ctx->opcode,  23, 3);
1297     pad   = extract32(ctx->opcode,  21, 2);
1298     XRc   = extract32(ctx->opcode, 14, 4);
1299     XRb   = extract32(ctx->opcode, 10, 4);
1300     XRa   = extract32(ctx->opcode,  6, 4);
1301 
1302     if (unlikely(pad != 0)) {
1303         /* opcode padding incorrect -> do nothing */
1304     } else if (unlikely(XRa == 0)) {
1305         /* destination is zero register -> do nothing */
1306     } else if (unlikely((XRb == 0) && (XRc == 0))) {
1307         /* both operands zero registers -> just set destination to all 0s */
1308         tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
1309     } else if (unlikely(XRb == 0)) {
1310         /* XRb zero register -> just appropriatelly shift XRc into XRa */
1311         switch (optn3) {
1312         case MXU_OPTN3_PTN0:
1313             tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
1314             break;
1315         case MXU_OPTN3_PTN1:
1316         case MXU_OPTN3_PTN2:
1317         case MXU_OPTN3_PTN3:
1318             tcg_gen_shri_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1],
1319                              8 * (4 - optn3));
1320             break;
1321         case MXU_OPTN3_PTN4:
1322             tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]);
1323             break;
1324         }
1325     } else if (unlikely(XRc == 0)) {
1326         /* XRc zero register -> just appropriatelly shift XRb into XRa */
1327         switch (optn3) {
1328         case MXU_OPTN3_PTN0:
1329             tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
1330             break;
1331         case MXU_OPTN3_PTN1:
1332         case MXU_OPTN3_PTN2:
1333         case MXU_OPTN3_PTN3:
1334             tcg_gen_shri_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], 8 * optn3);
1335             break;
1336         case MXU_OPTN3_PTN4:
1337             tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
1338             break;
1339         }
1340     } else if (unlikely(XRb == XRc)) {
1341         /* both operands same -> just rotation or moving from any of them */
1342         switch (optn3) {
1343         case MXU_OPTN3_PTN0:
1344         case MXU_OPTN3_PTN4:
1345             tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
1346             break;
1347         case MXU_OPTN3_PTN1:
1348         case MXU_OPTN3_PTN2:
1349         case MXU_OPTN3_PTN3:
1350             tcg_gen_rotli_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], 8 * optn3);
1351             break;
1352         }
1353     } else {
1354         /* the most general case */
1355         switch (optn3) {
1356         case MXU_OPTN3_PTN0:
1357             {
1358                 /*                                         */
1359                 /*         XRb                XRc          */
1360                 /*  +---------------+                      */
1361                 /*  | A   B   C   D |    E   F   G   H     */
1362                 /*  +-------+-------+                      */
1363                 /*          |                              */
1364                 /*         XRa                             */
1365                 /*                                         */
1366 
1367                 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
1368             }
1369             break;
1370         case MXU_OPTN3_PTN1:
1371             {
1372                 /*                                         */
1373                 /*         XRb                 XRc         */
1374                 /*      +-------------------+              */
1375                 /*    A | B   C   D       E | F   G   H    */
1376                 /*      +---------+---------+              */
1377                 /*                |                        */
1378                 /*               XRa                       */
1379                 /*                                         */
1380 
1381                 TCGv_i32 t0 = tcg_temp_new();
1382                 TCGv_i32 t1 = tcg_temp_new();
1383 
1384                 tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0x00FFFFFF);
1385                 tcg_gen_shli_i32(t0, t0, 8);
1386 
1387                 tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFF000000);
1388                 tcg_gen_shri_i32(t1, t1, 24);
1389 
1390                 tcg_gen_or_i32(mxu_gpr[XRa - 1], t0, t1);
1391 
1392                 tcg_temp_free(t1);
1393                 tcg_temp_free(t0);
1394             }
1395             break;
1396         case MXU_OPTN3_PTN2:
1397             {
1398                 /*                                         */
1399                 /*         XRb                 XRc         */
1400                 /*          +-------------------+          */
1401                 /*    A   B | C   D       E   F | G   H    */
1402                 /*          +---------+---------+          */
1403                 /*                    |                    */
1404                 /*                   XRa                   */
1405                 /*                                         */
1406 
1407                 TCGv_i32 t0 = tcg_temp_new();
1408                 TCGv_i32 t1 = tcg_temp_new();
1409 
1410                 tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0x0000FFFF);
1411                 tcg_gen_shli_i32(t0, t0, 16);
1412 
1413                 tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFFFF0000);
1414                 tcg_gen_shri_i32(t1, t1, 16);
1415 
1416                 tcg_gen_or_i32(mxu_gpr[XRa - 1], t0, t1);
1417 
1418                 tcg_temp_free(t1);
1419                 tcg_temp_free(t0);
1420             }
1421             break;
1422         case MXU_OPTN3_PTN3:
1423             {
1424                 /*                                         */
1425                 /*         XRb                 XRc         */
1426                 /*              +-------------------+      */
1427                 /*    A   B   C | D       E   F   G | H    */
1428                 /*              +---------+---------+      */
1429                 /*                        |                */
1430                 /*                       XRa               */
1431                 /*                                         */
1432 
1433                 TCGv_i32 t0 = tcg_temp_new();
1434                 TCGv_i32 t1 = tcg_temp_new();
1435 
1436                 tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0x000000FF);
1437                 tcg_gen_shli_i32(t0, t0, 24);
1438 
1439                 tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFFFFFF00);
1440                 tcg_gen_shri_i32(t1, t1, 8);
1441 
1442                 tcg_gen_or_i32(mxu_gpr[XRa - 1], t0, t1);
1443 
1444                 tcg_temp_free(t1);
1445                 tcg_temp_free(t0);
1446             }
1447             break;
1448         case MXU_OPTN3_PTN4:
1449             {
1450                 /*                                         */
1451                 /*         XRb                 XRc         */
1452                 /*                     +---------------+   */
1453                 /*    A   B   C   D    | E   F   G   H |   */
1454                 /*                     +-------+-------+   */
1455                 /*                             |           */
1456                 /*                            XRa          */
1457                 /*                                         */
1458 
1459                 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]);
1460             }
1461             break;
1462         }
1463     }
1464 }
1465 
1466 
1467 /*
1468  * Decoding engine for MXU
1469  * =======================
1470  */
1471 
1472 static void decode_opc_mxu__pool00(DisasContext *ctx)
1473 {
1474     uint32_t opcode = extract32(ctx->opcode, 18, 3);
1475 
1476     switch (opcode) {
1477     case OPC_MXU_S32MAX:
1478     case OPC_MXU_S32MIN:
1479         gen_mxu_S32MAX_S32MIN(ctx);
1480         break;
1481     case OPC_MXU_D16MAX:
1482     case OPC_MXU_D16MIN:
1483         gen_mxu_D16MAX_D16MIN(ctx);
1484         break;
1485     case OPC_MXU_Q8MAX:
1486     case OPC_MXU_Q8MIN:
1487         gen_mxu_Q8MAX_Q8MIN(ctx);
1488         break;
1489     default:
1490         MIPS_INVAL("decode_opc_mxu");
1491         gen_reserved_instruction(ctx);
1492         break;
1493     }
1494 }
1495 
1496 static void decode_opc_mxu__pool04(DisasContext *ctx)
1497 {
1498     uint32_t opcode = extract32(ctx->opcode, 20, 1);
1499 
1500     switch (opcode) {
1501     case OPC_MXU_S32LDD:
1502     case OPC_MXU_S32LDDR:
1503         gen_mxu_s32ldd_s32lddr(ctx);
1504         break;
1505     default:
1506         MIPS_INVAL("decode_opc_mxu");
1507         gen_reserved_instruction(ctx);
1508         break;
1509     }
1510 }
1511 
1512 static void decode_opc_mxu__pool16(DisasContext *ctx)
1513 {
1514     uint32_t opcode = extract32(ctx->opcode, 18, 3);
1515 
1516     switch (opcode) {
1517     case OPC_MXU_S32ALNI:
1518         gen_mxu_S32ALNI(ctx);
1519         break;
1520     case OPC_MXU_S32NOR:
1521         gen_mxu_S32NOR(ctx);
1522         break;
1523     case OPC_MXU_S32AND:
1524         gen_mxu_S32AND(ctx);
1525         break;
1526     case OPC_MXU_S32OR:
1527         gen_mxu_S32OR(ctx);
1528         break;
1529     case OPC_MXU_S32XOR:
1530         gen_mxu_S32XOR(ctx);
1531         break;
1532     default:
1533         MIPS_INVAL("decode_opc_mxu");
1534         gen_reserved_instruction(ctx);
1535         break;
1536     }
1537 }
1538 
1539 static void decode_opc_mxu__pool19(DisasContext *ctx)
1540 {
1541     uint32_t opcode = extract32(ctx->opcode, 22, 2);
1542 
1543     switch (opcode) {
1544     case OPC_MXU_Q8MUL:
1545     case OPC_MXU_Q8MULSU:
1546         gen_mxu_q8mul_q8mulsu(ctx);
1547         break;
1548     default:
1549         MIPS_INVAL("decode_opc_mxu");
1550         gen_reserved_instruction(ctx);
1551         break;
1552     }
1553 }
1554 
1555 bool decode_ase_mxu(DisasContext *ctx, uint32_t insn)
1556 {
1557     uint32_t opcode = extract32(insn, 0, 6);
1558 
1559     if (opcode == OPC_MXU_S32M2I) {
1560         gen_mxu_s32m2i(ctx);
1561         return true;
1562     }
1563 
1564     if (opcode == OPC_MXU_S32I2M) {
1565         gen_mxu_s32i2m(ctx);
1566         return true;
1567     }
1568 
1569     {
1570         TCGv t_mxu_cr = tcg_temp_new();
1571         TCGLabel *l_exit = gen_new_label();
1572 
1573         gen_load_mxu_cr(t_mxu_cr);
1574         tcg_gen_andi_tl(t_mxu_cr, t_mxu_cr, MXU_CR_MXU_EN);
1575         tcg_gen_brcondi_tl(TCG_COND_NE, t_mxu_cr, MXU_CR_MXU_EN, l_exit);
1576 
1577         switch (opcode) {
1578         case OPC_MXU__POOL00:
1579             decode_opc_mxu__pool00(ctx);
1580             break;
1581         case OPC_MXU_D16MUL:
1582             gen_mxu_d16mul(ctx);
1583             break;
1584         case OPC_MXU_D16MAC:
1585             gen_mxu_d16mac(ctx);
1586             break;
1587         case OPC_MXU__POOL04:
1588             decode_opc_mxu__pool04(ctx);
1589             break;
1590         case OPC_MXU_S8LDD:
1591             gen_mxu_s8ldd(ctx);
1592             break;
1593         case OPC_MXU__POOL16:
1594             decode_opc_mxu__pool16(ctx);
1595             break;
1596         case OPC_MXU__POOL19:
1597             decode_opc_mxu__pool19(ctx);
1598             break;
1599         default:
1600             MIPS_INVAL("decode_opc_mxu");
1601             gen_reserved_instruction(ctx);
1602         }
1603 
1604         gen_set_label(l_exit);
1605         tcg_temp_free(t_mxu_cr);
1606     }
1607 
1608     return true;
1609 }
1610