2 * Ingenic XBurst Media eXtension Unit (MXU) translation routines.
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)
10 * SPDX-License-Identifier: LGPL-2.1-or-later
14 * "XBurst® Instruction Set Architecture MIPS eXtension/enhanced Unit
15 * Programming Manual", Ingenic Semiconductor Co, Ltd., revision June 2, 2017
18 #include "qemu/osdep.h"
19 #include "tcg/tcg-op.h"
20 #include "exec/helper-gen.h"
21 #include "translate.h"
25 * AN OVERVIEW OF MXU EXTENSION INSTRUCTION SET
26 * ============================================
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.
34 * MXU unit contains 17 registers called X0-X16. X0 is always zero, and X16 is
35 * the control register.
38 * The notation used in MXU assembler mnemonics
39 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
43 * XRa, XRb, XRc, XRd - MXU registers
44 * Rb, Rc, Rd, Rs, Rt - general purpose MIPS registers
46 * Non-register operands:
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
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
65 * ADD - Add or subtract
66 * ADDC - Add with carry-in
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
73 * AND - Logical bitwise 'and' operation
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
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
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
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
108 * F - Fixed point multiplication
109 * L - Low part result
111 * V - Variable instead of immediate
112 * W - Combine above L and V
115 * The list of MXU instructions grouped by functionality
116 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
118 * Load/Store instructions Multiplication instructions
119 * ----------------------- ---------------------------
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 ------------------
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
195 * The opcode organization of MXU instructions
196 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
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:
205 * ┌─ 000000 ─ OPC_MXU_S32MADD
206 * ├─ 000001 ─ OPC_MXU_S32MADDU
207 * ├─ 000010 ─ <not assigned> (non-MXU OPC_MUL)
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
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
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
247 * ├─ 010001 ─ OPC_MXU__POOL05 ─┬─ 0 ─ OPC_MXU_S32STD
248 * │ └─ 1 ─ OPC_MXU_S32STDR
251 * ├─ 010010 ─ OPC_MXU__POOL06 ─┬─ 0000 ─ OPC_MXU_S32LDDV
252 * │ └─ 0001 ─ OPC_MXU_S32LDDVR
255 * ├─ 010011 ─ OPC_MXU__POOL07 ─┬─ 0000 ─ OPC_MXU_S32STDV
256 * │ └─ 0001 ─ OPC_MXU_S32STDVR
259 * ├─ 010100 ─ OPC_MXU__POOL08 ─┬─ 0 ─ OPC_MXU_S32LDI
260 * │ └─ 1 ─ OPC_MXU_S32LDIR
263 * ├─ 010101 ─ OPC_MXU__POOL09 ─┬─ 0 ─ OPC_MXU_S32SDI
264 * │ └─ 1 ─ OPC_MXU_S32SDIR
267 * ├─ 010110 ─ OPC_MXU__POOL10 ─┬─ 0000 ─ OPC_MXU_S32LDIV
268 * │ └─ 0001 ─ OPC_MXU_S32LDIVR
271 * ├─ 010111 ─ OPC_MXU__POOL11 ─┬─ 0000 ─ OPC_MXU_S32SDIV
272 * │ └─ 0001 ─ OPC_MXU_S32SDIVR
273 * ├─ 011000 ─ OPC_MXU_D32ADD
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>
280 * ├─ 011011 ─ OPC_MXU__POOL13 ─┬─ 00 ─ OPC_MXU_Q16ACC
281 * │ ├─ 01 ─ OPC_MXU_Q16ACCM
282 * │ └─ 10 ─ OPC_MXU_Q16ASUM
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
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
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
328 * ├─ 110111 ─ OPC_MXU_Q16SAR
330 * ├─ 111000 ─ OPC_MXU__POOL19 ─┬─ 00 ─ OPC_MXU_Q8MUL
331 * │ └─ 01 ─ OPC_MXU_Q8MULSU
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
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)
353 * "XBurst® Instruction Set Architecture MIPS eXtension/enhanced Unit
354 * Programming Manual", Ingenic Semiconductor Co, Ltd., revision June 2, 2017
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,
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,
386 OPC_MXU_S32LDD
= 0x00,
387 OPC_MXU_S32LDDR
= 0x01,
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,
405 OPC_MXU_Q8MUL
= 0x00,
406 OPC_MXU_Q8MULSU
= 0x01,
409 /* MXU accumulate add/subtract 1-bit pattern 'aptn1' */
410 #define MXU_APTN1_A 0
411 #define MXU_APTN1_S 1
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
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
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
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
447 static TCGv mxu_gpr
[NUMBER_OF_MXU_REGISTERS
- 1];
450 static const char mxuregnames
[][4] = {
451 "XR1", "XR2", "XR3", "XR4", "XR5", "XR6", "XR7", "XR8",
452 "XR9", "XR10", "XR11", "XR12", "XR13", "XR14", "XR15", "XCR",
455 void mxu_translate_init(void)
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
]),
463 mxu_CR
= tcg_global_mem_new(cpu_env
,
464 offsetof(CPUMIPSState
, active_tc
.mxu_cr
),
465 mxuregnames
[NUMBER_OF_MXU_REGISTERS
- 1]);
468 /* MXU General purpose registers moves. */
469 static inline void gen_load_mxu_gpr(TCGv t
, unsigned int reg
)
472 tcg_gen_movi_tl(t
, 0);
473 } else if (reg
<= 15) {
474 tcg_gen_mov_tl(t
, mxu_gpr
[reg
- 1]);
478 static inline void gen_store_mxu_gpr(TCGv t
, unsigned int reg
)
480 if (reg
> 0 && reg
<= 15) {
481 tcg_gen_mov_tl(mxu_gpr
[reg
- 1], t
);
485 /* MXU control register moves. */
486 static inline void gen_load_mxu_cr(TCGv t
)
488 tcg_gen_mov_tl(t
, mxu_CR
);
491 static inline void gen_store_mxu_cr(TCGv t
)
493 /* TODO: Add handling of RW rules for MXU_CR. */
494 tcg_gen_mov_tl(mxu_CR
, t
);
498 * S32I2M XRa, rb - Register move from GRF to XRF
500 static void gen_mxu_s32i2m(DisasContext
*ctx
)
507 XRa
= extract32(ctx
->opcode
, 6, 5);
508 Rb
= extract32(ctx
->opcode
, 16, 5);
510 gen_load_gpr(t0
, Rb
);
512 gen_store_mxu_gpr(t0
, XRa
);
513 } else if (XRa
== 16) {
514 gen_store_mxu_cr(t0
);
521 * S32M2I XRa, rb - Register move from XRF to GRF
523 static void gen_mxu_s32m2i(DisasContext
*ctx
)
530 XRa
= extract32(ctx
->opcode
, 6, 5);
531 Rb
= extract32(ctx
->opcode
, 16, 5);
534 gen_load_mxu_gpr(t0
, XRa
);
535 } else if (XRa
== 16) {
539 gen_store_gpr(t0
, Rb
);
545 * S8LDD XRa, Rb, s8, optn3 - Load a byte from memory to XRF
547 static void gen_mxu_s8ldd(DisasContext
*ctx
)
550 uint32_t XRa
, Rb
, s8
, optn3
;
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);
560 gen_load_gpr(t0
, Rb
);
561 tcg_gen_addi_tl(t0
, t0
, (int8_t)s8
);
564 /* XRa[7:0] = tmp8 */
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);
570 /* XRa[15:8] = tmp8 */
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);
576 /* XRa[23:16] = tmp8 */
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);
582 /* XRa[31:24] = tmp8 */
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);
588 /* XRa = {8'b0, tmp8, 8'b0, tmp8} */
590 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
591 tcg_gen_deposit_tl(t0
, t1
, t1
, 16, 16);
593 /* XRa = {tmp8, 8'b0, tmp8, 8'b0} */
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);
599 /* XRa = {{8{sign of tmp8}}, tmp8, {8{sign of tmp8}}, tmp8} */
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
);
607 /* XRa = {tmp8, tmp8, tmp8, tmp8} */
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);
615 gen_store_mxu_gpr(t0
, XRa
);
622 * D16MUL XRa, XRb, XRc, XRd, optn2 - Signed 16 bit pattern multiplication
624 static void gen_mxu_d16mul(DisasContext
*ctx
)
627 uint32_t XRa
, XRb
, XRc
, XRd
, optn2
;
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);
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);
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
);
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
);
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
);
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
);
665 gen_store_mxu_gpr(t3
, XRa
);
666 gen_store_mxu_gpr(t2
, XRd
);
675 * D16MAC XRa, XRb, XRc, XRd, aptn2, optn2 - Signed 16 bit pattern multiply
678 static void gen_mxu_d16mac(DisasContext
*ctx
)
681 uint32_t XRa
, XRb
, XRc
, XRd
, optn2
, aptn2
;
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);
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);
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);
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
);
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
);
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
);
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
);
721 gen_load_mxu_gpr(t0
, XRa
);
722 gen_load_mxu_gpr(t1
, XRd
);
726 tcg_gen_add_tl(t3
, t0
, t3
);
727 tcg_gen_add_tl(t2
, t1
, t2
);
730 tcg_gen_add_tl(t3
, t0
, t3
);
731 tcg_gen_sub_tl(t2
, t1
, t2
);
734 tcg_gen_sub_tl(t3
, t0
, t3
);
735 tcg_gen_add_tl(t2
, t1
, t2
);
738 tcg_gen_sub_tl(t3
, t0
, t3
);
739 tcg_gen_sub_tl(t2
, t1
, t2
);
742 gen_store_mxu_gpr(t3
, XRa
);
743 gen_store_mxu_gpr(t2
, XRd
);
752 * Q8MUL XRa, XRb, XRc, XRd - Parallel unsigned 8 bit pattern multiply
753 * Q8MULSU XRa, XRb, XRc, XRd - Parallel signed 8 bit pattern multiply
755 static void gen_mxu_q8mul_q8mulsu(DisasContext
*ctx
)
757 TCGv t0
, t1
, t2
, t3
, t4
, t5
, t6
, t7
;
758 uint32_t XRa
, XRb
, XRc
, XRd
, sel
;
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);
775 gen_load_mxu_gpr(t3
, XRb
);
776 gen_load_mxu_gpr(t7
, XRc
);
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
);
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
);
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
);
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
);
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);
816 tcg_gen_shli_tl(t1
, t1
, 16);
817 tcg_gen_shli_tl(t3
, t3
, 16);
819 tcg_gen_or_tl(t0
, t0
, t1
);
820 tcg_gen_or_tl(t1
, t2
, t3
);
822 gen_store_mxu_gpr(t0
, XRd
);
823 gen_store_mxu_gpr(t1
, XRa
);
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.
839 static void gen_mxu_s32ldd_s32lddr(DisasContext
*ctx
)
842 uint32_t XRa
, Rb
, s12
, sel
;
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);
852 gen_load_gpr(t0
, Rb
);
854 tcg_gen_movi_tl(t1
, s12
);
855 tcg_gen_shli_tl(t1
, t1
, 2);
857 tcg_gen_ori_tl(t1
, t1
, 0xFFFFF000);
859 tcg_gen_add_tl(t1
, t0
, t1
);
860 tcg_gen_qemu_ld_tl(t1
, t1
, ctx
->mem_idx
, MO_SL
);
864 tcg_gen_bswap32_tl(t1
, t1
);
866 gen_store_mxu_gpr(t1
, XRa
);
874 * MXU instruction category: logic
875 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
877 * S32NOR S32AND S32OR S32XOR
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.
885 static void gen_mxu_S32NOR(DisasContext
*ctx
)
887 uint32_t pad
, XRc
, XRb
, XRa
;
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);
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]);
911 /* the most general case */
912 tcg_gen_nor_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1], mxu_gpr
[XRc
- 1]);
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.
921 static void gen_mxu_S32AND(DisasContext
*ctx
)
923 uint32_t pad
, XRc
, XRb
, XRa
;
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);
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]);
941 /* the most general case */
942 tcg_gen_and_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1], mxu_gpr
[XRc
- 1]);
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.
951 static void gen_mxu_S32OR(DisasContext
*ctx
)
953 uint32_t pad
, XRc
, XRb
, XRa
;
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);
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]);
977 /* the most general case */
978 tcg_gen_or_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1], mxu_gpr
[XRc
- 1]);
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.
987 static void gen_mxu_S32XOR(DisasContext
*ctx
)
989 uint32_t pad
, XRc
, XRb
, XRa
;
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);
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);
1013 /* the most general case */
1014 tcg_gen_xor_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1], mxu_gpr
[XRc
- 1]);
1020 * MXU instruction category max/min
1021 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1023 * S32MAX D16MAX Q8MAX
1024 * S32MIN D16MIN Q8MIN
1028 * S32MAX XRa, XRb, XRc
1029 * Update XRa with the maximum of signed 32-bit integers contained
1032 * S32MIN XRa, XRb, XRc
1033 * Update XRa with the minimum of signed 32-bit integers contained
1036 static void gen_mxu_S32MAX_S32MIN(DisasContext
*ctx
)
1038 uint32_t pad
, opc
, XRc
, XRb
, XRa
;
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);
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);
1060 tcg_gen_smin_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRx
- 1], 0);
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]);
1066 /* the most general case */
1067 if (opc
== OPC_MXU_S32MAX
) {
1068 tcg_gen_smax_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1],
1071 tcg_gen_smin_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1],
1079 * Update XRa with the 16-bit-wise maximums of signed integers
1080 * contained in XRb and XRc.
1083 * Update XRa with the 16-bit-wise minimums of signed integers
1084 * contained in XRb and XRc.
1086 static void gen_mxu_D16MAX_D16MIN(DisasContext
*ctx
)
1088 uint32_t pad
, opc
, XRc
, XRb
, XRa
;
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);
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);
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
);
1115 tcg_gen_smin_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
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
);
1126 tcg_gen_smin_i32(t0
, t0
, t1
);
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
);
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]);
1139 /* the most general case */
1140 TCGv_i32 t0
= tcg_temp_new();
1141 TCGv_i32 t1
= tcg_temp_new();
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
);
1149 tcg_gen_smin_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
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
);
1162 tcg_gen_smin_i32(t0
, t0
, t1
);
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
);
1176 * Update XRa with the 8-bit-wise maximums of signed integers
1177 * contained in XRb and XRc.
1180 * Update XRa with the 8-bit-wise minimums of signed integers
1181 * contained in XRb and XRc.
1183 static void gen_mxu_Q8MAX_Q8MIN(DisasContext
*ctx
)
1185 uint32_t pad
, opc
, XRc
, XRb
, XRa
;
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);
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);
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
);
1213 tcg_gen_smin_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
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
);
1226 tcg_gen_smin_i32(t0
, t0
, t1
);
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
);
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]);
1240 /* the most general case */
1241 TCGv_i32 t0
= tcg_temp_new();
1242 TCGv_i32 t1
= tcg_temp_new();
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
);
1251 tcg_gen_smin_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
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
);
1266 tcg_gen_smin_i32(t0
, t0
, t1
);
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
);
1281 * MXU instruction category: align
1282 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
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.
1292 static void gen_mxu_S32ALNI(DisasContext
*ctx
)
1294 uint32_t optn3
, pad
, XRc
, XRb
, XRa
;
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);
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 */
1312 case MXU_OPTN3_PTN0
:
1313 tcg_gen_movi_i32(mxu_gpr
[XRa
- 1], 0);
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],
1321 case MXU_OPTN3_PTN4
:
1322 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRc
- 1]);
1325 } else if (unlikely(XRc
== 0)) {
1326 /* XRc zero register -> just appropriatelly shift XRb into XRa */
1328 case MXU_OPTN3_PTN0
:
1329 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
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
);
1336 case MXU_OPTN3_PTN4
:
1337 tcg_gen_movi_i32(mxu_gpr
[XRa
- 1], 0);
1340 } else if (unlikely(XRb
== XRc
)) {
1341 /* both operands same -> just rotation or moving from any of them */
1343 case MXU_OPTN3_PTN0
:
1344 case MXU_OPTN3_PTN4
:
1345 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
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
);
1354 /* the most general case */
1356 case MXU_OPTN3_PTN0
:
1360 /* +---------------+ */
1361 /* | A B C D | E F G H */
1362 /* +-------+-------+ */
1367 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
1370 case MXU_OPTN3_PTN1
:
1374 /* +-------------------+ */
1375 /* A | B C D E | F G H */
1376 /* +---------+---------+ */
1381 TCGv_i32 t0
= tcg_temp_new();
1382 TCGv_i32 t1
= tcg_temp_new();
1384 tcg_gen_andi_i32(t0
, mxu_gpr
[XRb
- 1], 0x00FFFFFF);
1385 tcg_gen_shli_i32(t0
, t0
, 8);
1387 tcg_gen_andi_i32(t1
, mxu_gpr
[XRc
- 1], 0xFF000000);
1388 tcg_gen_shri_i32(t1
, t1
, 24);
1390 tcg_gen_or_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
1396 case MXU_OPTN3_PTN2
:
1400 /* +-------------------+ */
1401 /* A B | C D E F | G H */
1402 /* +---------+---------+ */
1407 TCGv_i32 t0
= tcg_temp_new();
1408 TCGv_i32 t1
= tcg_temp_new();
1410 tcg_gen_andi_i32(t0
, mxu_gpr
[XRb
- 1], 0x0000FFFF);
1411 tcg_gen_shli_i32(t0
, t0
, 16);
1413 tcg_gen_andi_i32(t1
, mxu_gpr
[XRc
- 1], 0xFFFF0000);
1414 tcg_gen_shri_i32(t1
, t1
, 16);
1416 tcg_gen_or_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
1422 case MXU_OPTN3_PTN3
:
1426 /* +-------------------+ */
1427 /* A B C | D E F G | H */
1428 /* +---------+---------+ */
1433 TCGv_i32 t0
= tcg_temp_new();
1434 TCGv_i32 t1
= tcg_temp_new();
1436 tcg_gen_andi_i32(t0
, mxu_gpr
[XRb
- 1], 0x000000FF);
1437 tcg_gen_shli_i32(t0
, t0
, 24);
1439 tcg_gen_andi_i32(t1
, mxu_gpr
[XRc
- 1], 0xFFFFFF00);
1440 tcg_gen_shri_i32(t1
, t1
, 8);
1442 tcg_gen_or_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
1448 case MXU_OPTN3_PTN4
:
1452 /* +---------------+ */
1453 /* A B C D | E F G H | */
1454 /* +-------+-------+ */
1459 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRc
- 1]);
1468 * Decoding engine for MXU
1469 * =======================
1472 static void decode_opc_mxu__pool00(DisasContext
*ctx
)
1474 uint32_t opcode
= extract32(ctx
->opcode
, 18, 3);
1477 case OPC_MXU_S32MAX
:
1478 case OPC_MXU_S32MIN
:
1479 gen_mxu_S32MAX_S32MIN(ctx
);
1481 case OPC_MXU_D16MAX
:
1482 case OPC_MXU_D16MIN
:
1483 gen_mxu_D16MAX_D16MIN(ctx
);
1487 gen_mxu_Q8MAX_Q8MIN(ctx
);
1490 MIPS_INVAL("decode_opc_mxu");
1491 gen_reserved_instruction(ctx
);
1496 static void decode_opc_mxu__pool04(DisasContext
*ctx
)
1498 uint32_t opcode
= extract32(ctx
->opcode
, 20, 1);
1501 case OPC_MXU_S32LDD
:
1502 case OPC_MXU_S32LDDR
:
1503 gen_mxu_s32ldd_s32lddr(ctx
);
1506 MIPS_INVAL("decode_opc_mxu");
1507 gen_reserved_instruction(ctx
);
1512 static void decode_opc_mxu__pool16(DisasContext
*ctx
)
1514 uint32_t opcode
= extract32(ctx
->opcode
, 18, 3);
1517 case OPC_MXU_S32ALNI
:
1518 gen_mxu_S32ALNI(ctx
);
1520 case OPC_MXU_S32NOR
:
1521 gen_mxu_S32NOR(ctx
);
1523 case OPC_MXU_S32AND
:
1524 gen_mxu_S32AND(ctx
);
1529 case OPC_MXU_S32XOR
:
1530 gen_mxu_S32XOR(ctx
);
1533 MIPS_INVAL("decode_opc_mxu");
1534 gen_reserved_instruction(ctx
);
1539 static void decode_opc_mxu__pool19(DisasContext
*ctx
)
1541 uint32_t opcode
= extract32(ctx
->opcode
, 22, 2);
1545 case OPC_MXU_Q8MULSU
:
1546 gen_mxu_q8mul_q8mulsu(ctx
);
1549 MIPS_INVAL("decode_opc_mxu");
1550 gen_reserved_instruction(ctx
);
1555 bool decode_ase_mxu(DisasContext
*ctx
, uint32_t insn
)
1557 uint32_t opcode
= extract32(insn
, 0, 6);
1559 if (opcode
== OPC_MXU_S32M2I
) {
1560 gen_mxu_s32m2i(ctx
);
1564 if (opcode
== OPC_MXU_S32I2M
) {
1565 gen_mxu_s32i2m(ctx
);
1570 TCGv t_mxu_cr
= tcg_temp_new();
1571 TCGLabel
*l_exit
= gen_new_label();
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
);
1578 case OPC_MXU__POOL00
:
1579 decode_opc_mxu__pool00(ctx
);
1581 case OPC_MXU_D16MUL
:
1582 gen_mxu_d16mul(ctx
);
1584 case OPC_MXU_D16MAC
:
1585 gen_mxu_d16mac(ctx
);
1587 case OPC_MXU__POOL04
:
1588 decode_opc_mxu__pool04(ctx
);
1593 case OPC_MXU__POOL16
:
1594 decode_opc_mxu__pool16(ctx
);
1596 case OPC_MXU__POOL19
:
1597 decode_opc_mxu__pool19(ctx
);
1600 MIPS_INVAL("decode_opc_mxu");
1601 gen_reserved_instruction(ctx
);
1604 gen_set_label(l_exit
);
1605 tcg_temp_free(t_mxu_cr
);