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