target/mips: Add missing default_tcg_memop_mask
[qemu/ar7.git] / target / mips / tcg / mxu_translate.c
blobbe038b5f07a48336fdfb88859d3eb60ec7a55936
1 /*
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
12 * Datasheet:
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 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
41 * Register operands:
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
56 * Prefixes:
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
63 * Operations:
65 * ADD - Add or subtract
66 * ADDC - Add with carry-in
67 * ACC - Accumulate
68 * ASUM - Sum together then accumulate (add or subtract)
69 * ASUMC - Sum together then accumulate (add or subtract) with carry-in
70 * AVG - Average between 2 operands
71 * ABD - Absolute difference
72 * ALN - Align data
73 * AND - Logical bitwise 'and' operation
74 * CPS - Copy sign
75 * EXTR - Extract bits
76 * I2M - Move from GPR register to MXU register
77 * LDD - Load data from memory to XRF
78 * LDI - Load data from memory to XRF (and increase the address base)
79 * LUI - Load unsigned immediate
80 * MUL - Multiply
81 * MULU - Unsigned multiply
82 * MADD - 64-bit operand add 32x32 product
83 * MSUB - 64-bit operand subtract 32x32 product
84 * MAC - Multiply and accumulate (add or subtract)
85 * MAD - Multiply and add or subtract
86 * MAX - Maximum between 2 operands
87 * MIN - Minimum between 2 operands
88 * M2I - Move from MXU register to GPR register
89 * MOVZ - Move if zero
90 * MOVN - Move if non-zero
91 * NOR - Logical bitwise 'nor' operation
92 * OR - Logical bitwise 'or' operation
93 * STD - Store data from XRF to memory
94 * SDI - Store data from XRF to memory (and increase the address base)
95 * SLT - Set of less than comparison
96 * SAD - Sum of absolute differences
97 * SLL - Logical shift left
98 * SLR - Logical shift right
99 * SAR - Arithmetic shift right
100 * SAT - Saturation
101 * SFL - Shuffle
102 * SCOP - Calculate x’s scope (-1, means x<0; 0, means x==0; 1, means x>0)
103 * XOR - Logical bitwise 'exclusive or' operation
105 * Suffixes:
107 * E - Expand results
108 * F - Fixed point multiplication
109 * L - Low part result
110 * R - Doing rounding
111 * V - Variable instead of immediate
112 * W - Combine above L and V
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:
202 * bits
203 * 05..00
205 * ┌─ 000000 ─ OPC_MXU_S32MADD
206 * ├─ 000001 ─ OPC_MXU_S32MADDU
207 * ├─ 000010 ─ <not assigned> (non-MXU OPC_MUL)
208 * │
209 * │ 20..18
210 * ├─ 000011 ─ OPC_MXU__POOL00 ─┬─ 000 ─ OPC_MXU_S32MAX
211 * │ ├─ 001 ─ OPC_MXU_S32MIN
212 * │ ├─ 010 ─ OPC_MXU_D16MAX
213 * │ ├─ 011 ─ OPC_MXU_D16MIN
214 * │ ├─ 100 ─ OPC_MXU_Q8MAX
215 * │ ├─ 101 ─ OPC_MXU_Q8MIN
216 * │ ├─ 110 ─ OPC_MXU_Q8SLT
217 * │ └─ 111 ─ OPC_MXU_Q8SLTU
218 * ├─ 000100 ─ OPC_MXU_S32MSUB
219 * ├─ 000101 ─ OPC_MXU_S32MSUBU 20..18
220 * ├─ 000110 ─ OPC_MXU__POOL01 ─┬─ 000 ─ OPC_MXU_S32SLT
221 * │ ├─ 001 ─ OPC_MXU_D16SLT
222 * │ ├─ 010 ─ OPC_MXU_D16AVG
223 * │ ├─ 011 ─ OPC_MXU_D16AVGR
224 * │ ├─ 100 ─ OPC_MXU_Q8AVG
225 * │ ├─ 101 ─ OPC_MXU_Q8AVGR
226 * │ └─ 111 ─ OPC_MXU_Q8ADD
227 * │
228 * │ 20..18
229 * ├─ 000111 ─ OPC_MXU__POOL02 ─┬─ 000 ─ OPC_MXU_S32CPS
230 * │ ├─ 010 ─ OPC_MXU_D16CPS
231 * │ ├─ 100 ─ OPC_MXU_Q8ABD
232 * │ └─ 110 ─ OPC_MXU_Q16SAT
233 * ├─ 001000 ─ OPC_MXU_D16MUL
234 * │ 25..24
235 * ├─ 001001 ─ OPC_MXU__POOL03 ─┬─ 00 ─ OPC_MXU_D16MULF
236 * │ └─ 01 ─ OPC_MXU_D16MULE
237 * ├─ 001010 ─ OPC_MXU_D16MAC
238 * ├─ 001011 ─ OPC_MXU_D16MACF
239 * ├─ 001100 ─ OPC_MXU_D16MADL
240 * ├─ 001101 ─ OPC_MXU_S16MAD
241 * ├─ 001110 ─ OPC_MXU_Q16ADD
242 * ├─ 001111 ─ OPC_MXU_D16MACE 23
243 * │ ┌─ 0 ─ OPC_MXU_S32LDD
244 * ├─ 010000 ─ OPC_MXU__POOL04 ─┴─ 1 ─ OPC_MXU_S32LDDR
245 * │
246 * │ 23
247 * ├─ 010001 ─ OPC_MXU__POOL05 ─┬─ 0 ─ OPC_MXU_S32STD
248 * │ └─ 1 ─ OPC_MXU_S32STDR
249 * │
250 * │ 13..10
251 * ├─ 010010 ─ OPC_MXU__POOL06 ─┬─ 0000 ─ OPC_MXU_S32LDDV
252 * │ └─ 0001 ─ OPC_MXU_S32LDDVR
253 * │
254 * │ 13..10
255 * ├─ 010011 ─ OPC_MXU__POOL07 ─┬─ 0000 ─ OPC_MXU_S32STDV
256 * │ └─ 0001 ─ OPC_MXU_S32STDVR
257 * │
258 * │ 23
259 * ├─ 010100 ─ OPC_MXU__POOL08 ─┬─ 0 ─ OPC_MXU_S32LDI
260 * │ └─ 1 ─ OPC_MXU_S32LDIR
261 * │
262 * │ 23
263 * ├─ 010101 ─ OPC_MXU__POOL09 ─┬─ 0 ─ OPC_MXU_S32SDI
264 * │ └─ 1 ─ OPC_MXU_S32SDIR
265 * │
266 * │ 13..10
267 * ├─ 010110 ─ OPC_MXU__POOL10 ─┬─ 0000 ─ OPC_MXU_S32LDIV
268 * │ └─ 0001 ─ OPC_MXU_S32LDIVR
269 * │
270 * │ 13..10
271 * ├─ 010111 ─ OPC_MXU__POOL11 ─┬─ 0000 ─ OPC_MXU_S32SDIV
272 * │ └─ 0001 ─ OPC_MXU_S32SDIVR
273 * ├─ 011000 ─ OPC_MXU_D32ADD
274 * │ 23..22
275 * MXU ├─ 011001 ─ OPC_MXU__POOL12 ─┬─ 00 ─ OPC_MXU_D32ACC
276 * opcodes ─┤ ├─ 01 ─ OPC_MXU_D32ACCM
277 * │ └─ 10 ─ OPC_MXU_D32ASUM
278 * ├─ 011010 ─ <not assigned>
279 * │ 23..22
280 * ├─ 011011 ─ OPC_MXU__POOL13 ─┬─ 00 ─ OPC_MXU_Q16ACC
281 * │ ├─ 01 ─ OPC_MXU_Q16ACCM
282 * │ └─ 10 ─ OPC_MXU_Q16ASUM
283 * │
284 * │ 23..22
285 * ├─ 011100 ─ OPC_MXU__POOL14 ─┬─ 00 ─ OPC_MXU_Q8ADDE
286 * │ ├─ 01 ─ OPC_MXU_D8SUM
287 * ├─ 011101 ─ OPC_MXU_Q8ACCE └─ 10 ─ OPC_MXU_D8SUMC
288 * ├─ 011110 ─ <not assigned>
289 * ├─ 011111 ─ <not assigned>
290 * ├─ 100000 ─ <not assigned> (overlaps with CLZ)
291 * ├─ 100001 ─ <not assigned> (overlaps with CLO)
292 * ├─ 100010 ─ OPC_MXU_S8LDD
293 * ├─ 100011 ─ OPC_MXU_S8STD 15..14
294 * ├─ 100100 ─ OPC_MXU_S8LDI ┌─ 00 ─ OPC_MXU_S32MUL
295 * ├─ 100101 ─ OPC_MXU_S8SDI ├─ 00 ─ OPC_MXU_S32MULU
296 * │ ├─ 00 ─ OPC_MXU_S32EXTR
297 * ├─ 100110 ─ OPC_MXU__POOL15 ─┴─ 00 ─ OPC_MXU_S32EXTRV
298 * │
299 * │ 20..18
300 * ├─ 100111 ─ OPC_MXU__POOL16 ─┬─ 000 ─ OPC_MXU_D32SARW
301 * │ ├─ 001 ─ OPC_MXU_S32ALN
302 * │ ├─ 010 ─ OPC_MXU_S32ALNI
303 * │ ├─ 011 ─ OPC_MXU_S32LUI
304 * │ ├─ 100 ─ OPC_MXU_S32NOR
305 * │ ├─ 101 ─ OPC_MXU_S32AND
306 * │ ├─ 110 ─ OPC_MXU_S32OR
307 * │ └─ 111 ─ OPC_MXU_S32XOR
308 * │
309 * │ 7..5
310 * ├─ 101000 ─ OPC_MXU__POOL17 ─┬─ 000 ─ OPC_MXU_LXB
311 * │ ├─ 001 ─ OPC_MXU_LXH
312 * ├─ 101001 ─ <not assigned> ├─ 011 ─ OPC_MXU_LXW
313 * ├─ 101010 ─ OPC_MXU_S16LDD ├─ 100 ─ OPC_MXU_LXBU
314 * ├─ 101011 ─ OPC_MXU_S16STD └─ 101 ─ OPC_MXU_LXHU
315 * ├─ 101100 ─ OPC_MXU_S16LDI
316 * ├─ 101101 ─ OPC_MXU_S16SDI
317 * ├─ 101110 ─ OPC_MXU_S32M2I
318 * ├─ 101111 ─ OPC_MXU_S32I2M
319 * ├─ 110000 ─ OPC_MXU_D32SLL
320 * ├─ 110001 ─ OPC_MXU_D32SLR 20..18
321 * ├─ 110010 ─ OPC_MXU_D32SARL ┌─ 000 ─ OPC_MXU_D32SLLV
322 * ├─ 110011 ─ OPC_MXU_D32SAR ├─ 001 ─ OPC_MXU_D32SLRV
323 * ├─ 110100 ─ OPC_MXU_Q16SLL ├─ 010 ─ OPC_MXU_D32SARV
324 * ├─ 110101 ─ OPC_MXU_Q16SLR ├─ 011 ─ OPC_MXU_Q16SLLV
325 * │ ├─ 100 ─ OPC_MXU_Q16SLRV
326 * ├─ 110110 ─ OPC_MXU__POOL18 ─┴─ 101 ─ OPC_MXU_Q16SARV
327 * │
328 * ├─ 110111 ─ OPC_MXU_Q16SAR
329 * │ 23..22
330 * ├─ 111000 ─ OPC_MXU__POOL19 ─┬─ 00 ─ OPC_MXU_Q8MUL
331 * │ └─ 01 ─ OPC_MXU_Q8MULSU
332 * │
333 * │ 20..18
334 * ├─ 111001 ─ OPC_MXU__POOL20 ─┬─ 000 ─ OPC_MXU_Q8MOVZ
335 * │ ├─ 001 ─ OPC_MXU_Q8MOVN
336 * │ ├─ 010 ─ OPC_MXU_D16MOVZ
337 * │ ├─ 011 ─ OPC_MXU_D16MOVN
338 * │ ├─ 100 ─ OPC_MXU_S32MOVZ
339 * │ └─ 101 ─ OPC_MXU_S32MOVN
340 * │
341 * │ 23..22
342 * ├─ 111010 ─ OPC_MXU__POOL21 ─┬─ 00 ─ OPC_MXU_Q8MAC
343 * │ └─ 10 ─ OPC_MXU_Q8MACSU
344 * ├─ 111011 ─ OPC_MXU_Q16SCOP
345 * ├─ 111100 ─ OPC_MXU_Q8MADL
346 * ├─ 111101 ─ OPC_MXU_S32SFL
347 * ├─ 111110 ─ OPC_MXU_Q8SAD
348 * └─ 111111 ─ <not assigned> (overlaps with SDBBP)
351 * Compiled after:
353 * "XBurst® Instruction Set Architecture MIPS eXtension/enhanced Unit
354 * Programming Manual", Ingenic Semiconductor Co, Ltd., revision June 2, 2017
357 enum {
358 OPC_MXU__POOL00 = 0x03,
359 OPC_MXU_D16MUL = 0x08,
360 OPC_MXU_D16MAC = 0x0A,
361 OPC_MXU__POOL04 = 0x10,
362 OPC_MXU_S8LDD = 0x22,
363 OPC_MXU__POOL16 = 0x27,
364 OPC_MXU_S32M2I = 0x2E,
365 OPC_MXU_S32I2M = 0x2F,
366 OPC_MXU__POOL19 = 0x38,
371 * MXU pool 00
373 enum {
374 OPC_MXU_S32MAX = 0x00,
375 OPC_MXU_S32MIN = 0x01,
376 OPC_MXU_D16MAX = 0x02,
377 OPC_MXU_D16MIN = 0x03,
378 OPC_MXU_Q8MAX = 0x04,
379 OPC_MXU_Q8MIN = 0x05,
383 * MXU pool 04
385 enum {
386 OPC_MXU_S32LDD = 0x00,
387 OPC_MXU_S32LDDR = 0x01,
391 * MXU pool 16
393 enum {
394 OPC_MXU_S32ALNI = 0x02,
395 OPC_MXU_S32NOR = 0x04,
396 OPC_MXU_S32AND = 0x05,
397 OPC_MXU_S32OR = 0x06,
398 OPC_MXU_S32XOR = 0x07,
402 * MXU pool 19
404 enum {
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
446 /* MXU registers */
447 static TCGv mxu_gpr[NUMBER_OF_MXU_REGISTERS - 1];
448 static TCGv mxu_CR;
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]),
460 mxuregnames[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)
471 if (reg == 0) {
472 tcg_gen_movi_tl(t, 0);
473 } else if (reg <= 15) {
474 tcg_gen_mov_tl(t, mxu_gpr[reg - 1]);
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)
502 TCGv t0;
503 uint32_t XRa, Rb;
505 t0 = tcg_temp_new();
507 XRa = extract32(ctx->opcode, 6, 5);
508 Rb = extract32(ctx->opcode, 16, 5);
510 gen_load_gpr(t0, Rb);
511 if (XRa <= 15) {
512 gen_store_mxu_gpr(t0, XRa);
513 } else if (XRa == 16) {
514 gen_store_mxu_cr(t0);
519 * S32M2I XRa, rb - Register move from XRF to GRF
521 static void gen_mxu_s32m2i(DisasContext *ctx)
523 TCGv t0;
524 uint32_t XRa, Rb;
526 t0 = tcg_temp_new();
528 XRa = extract32(ctx->opcode, 6, 5);
529 Rb = extract32(ctx->opcode, 16, 5);
531 if (XRa <= 15) {
532 gen_load_mxu_gpr(t0, XRa);
533 } else if (XRa == 16) {
534 gen_load_mxu_cr(t0);
537 gen_store_gpr(t0, Rb);
541 * S8LDD XRa, Rb, s8, optn3 - Load a byte from memory to XRF
543 static void gen_mxu_s8ldd(DisasContext *ctx)
545 TCGv t0, t1;
546 uint32_t XRa, Rb, s8, optn3;
548 t0 = tcg_temp_new();
549 t1 = tcg_temp_new();
551 XRa = extract32(ctx->opcode, 6, 4);
552 s8 = extract32(ctx->opcode, 10, 8);
553 optn3 = extract32(ctx->opcode, 18, 3);
554 Rb = extract32(ctx->opcode, 21, 5);
556 gen_load_gpr(t0, Rb);
557 tcg_gen_addi_tl(t0, t0, (int8_t)s8);
559 switch (optn3) {
560 /* XRa[7:0] = tmp8 */
561 case MXU_OPTN3_PTN0:
562 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
563 gen_load_mxu_gpr(t0, XRa);
564 tcg_gen_deposit_tl(t0, t0, t1, 0, 8);
565 break;
566 /* XRa[15:8] = tmp8 */
567 case MXU_OPTN3_PTN1:
568 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
569 gen_load_mxu_gpr(t0, XRa);
570 tcg_gen_deposit_tl(t0, t0, t1, 8, 8);
571 break;
572 /* XRa[23:16] = tmp8 */
573 case MXU_OPTN3_PTN2:
574 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
575 gen_load_mxu_gpr(t0, XRa);
576 tcg_gen_deposit_tl(t0, t0, t1, 16, 8);
577 break;
578 /* XRa[31:24] = tmp8 */
579 case MXU_OPTN3_PTN3:
580 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
581 gen_load_mxu_gpr(t0, XRa);
582 tcg_gen_deposit_tl(t0, t0, t1, 24, 8);
583 break;
584 /* XRa = {8'b0, tmp8, 8'b0, tmp8} */
585 case MXU_OPTN3_PTN4:
586 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
587 tcg_gen_deposit_tl(t0, t1, t1, 16, 16);
588 break;
589 /* XRa = {tmp8, 8'b0, tmp8, 8'b0} */
590 case MXU_OPTN3_PTN5:
591 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
592 tcg_gen_shli_tl(t1, t1, 8);
593 tcg_gen_deposit_tl(t0, t1, t1, 16, 16);
594 break;
595 /* XRa = {{8{sign of tmp8}}, tmp8, {8{sign of tmp8}}, tmp8} */
596 case MXU_OPTN3_PTN6:
597 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_SB);
598 tcg_gen_mov_tl(t0, t1);
599 tcg_gen_andi_tl(t0, t0, 0xFF00FFFF);
600 tcg_gen_shli_tl(t1, t1, 16);
601 tcg_gen_or_tl(t0, t0, t1);
602 break;
603 /* XRa = {tmp8, tmp8, tmp8, tmp8} */
604 case MXU_OPTN3_PTN7:
605 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
606 tcg_gen_deposit_tl(t1, t1, t1, 8, 8);
607 tcg_gen_deposit_tl(t0, t1, t1, 16, 16);
608 break;
611 gen_store_mxu_gpr(t0, XRa);
615 * D16MUL XRa, XRb, XRc, XRd, optn2 - Signed 16 bit pattern multiplication
617 static void gen_mxu_d16mul(DisasContext *ctx)
619 TCGv t0, t1, t2, t3;
620 uint32_t XRa, XRb, XRc, XRd, optn2;
622 t0 = tcg_temp_new();
623 t1 = tcg_temp_new();
624 t2 = tcg_temp_new();
625 t3 = tcg_temp_new();
627 XRa = extract32(ctx->opcode, 6, 4);
628 XRb = extract32(ctx->opcode, 10, 4);
629 XRc = extract32(ctx->opcode, 14, 4);
630 XRd = extract32(ctx->opcode, 18, 4);
631 optn2 = extract32(ctx->opcode, 22, 2);
633 gen_load_mxu_gpr(t1, XRb);
634 tcg_gen_sextract_tl(t0, t1, 0, 16);
635 tcg_gen_sextract_tl(t1, t1, 16, 16);
636 gen_load_mxu_gpr(t3, XRc);
637 tcg_gen_sextract_tl(t2, t3, 0, 16);
638 tcg_gen_sextract_tl(t3, t3, 16, 16);
640 switch (optn2) {
641 case MXU_OPTN2_WW: /* XRB.H*XRC.H == lop, XRB.L*XRC.L == rop */
642 tcg_gen_mul_tl(t3, t1, t3);
643 tcg_gen_mul_tl(t2, t0, t2);
644 break;
645 case MXU_OPTN2_LW: /* XRB.L*XRC.H == lop, XRB.L*XRC.L == rop */
646 tcg_gen_mul_tl(t3, t0, t3);
647 tcg_gen_mul_tl(t2, t0, t2);
648 break;
649 case MXU_OPTN2_HW: /* XRB.H*XRC.H == lop, XRB.H*XRC.L == rop */
650 tcg_gen_mul_tl(t3, t1, t3);
651 tcg_gen_mul_tl(t2, t1, t2);
652 break;
653 case MXU_OPTN2_XW: /* XRB.L*XRC.H == lop, XRB.H*XRC.L == rop */
654 tcg_gen_mul_tl(t3, t0, t3);
655 tcg_gen_mul_tl(t2, t1, t2);
656 break;
658 gen_store_mxu_gpr(t3, XRa);
659 gen_store_mxu_gpr(t2, XRd);
663 * D16MAC XRa, XRb, XRc, XRd, aptn2, optn2 - Signed 16 bit pattern multiply
664 * and accumulate
666 static void gen_mxu_d16mac(DisasContext *ctx)
668 TCGv t0, t1, t2, t3;
669 uint32_t XRa, XRb, XRc, XRd, optn2, aptn2;
671 t0 = tcg_temp_new();
672 t1 = tcg_temp_new();
673 t2 = tcg_temp_new();
674 t3 = tcg_temp_new();
676 XRa = extract32(ctx->opcode, 6, 4);
677 XRb = extract32(ctx->opcode, 10, 4);
678 XRc = extract32(ctx->opcode, 14, 4);
679 XRd = extract32(ctx->opcode, 18, 4);
680 optn2 = extract32(ctx->opcode, 22, 2);
681 aptn2 = extract32(ctx->opcode, 24, 2);
683 gen_load_mxu_gpr(t1, XRb);
684 tcg_gen_sextract_tl(t0, t1, 0, 16);
685 tcg_gen_sextract_tl(t1, t1, 16, 16);
687 gen_load_mxu_gpr(t3, XRc);
688 tcg_gen_sextract_tl(t2, t3, 0, 16);
689 tcg_gen_sextract_tl(t3, t3, 16, 16);
691 switch (optn2) {
692 case MXU_OPTN2_WW: /* XRB.H*XRC.H == lop, XRB.L*XRC.L == rop */
693 tcg_gen_mul_tl(t3, t1, t3);
694 tcg_gen_mul_tl(t2, t0, t2);
695 break;
696 case MXU_OPTN2_LW: /* XRB.L*XRC.H == lop, XRB.L*XRC.L == rop */
697 tcg_gen_mul_tl(t3, t0, t3);
698 tcg_gen_mul_tl(t2, t0, t2);
699 break;
700 case MXU_OPTN2_HW: /* XRB.H*XRC.H == lop, XRB.H*XRC.L == rop */
701 tcg_gen_mul_tl(t3, t1, t3);
702 tcg_gen_mul_tl(t2, t1, t2);
703 break;
704 case MXU_OPTN2_XW: /* XRB.L*XRC.H == lop, XRB.H*XRC.L == rop */
705 tcg_gen_mul_tl(t3, t0, t3);
706 tcg_gen_mul_tl(t2, t1, t2);
707 break;
709 gen_load_mxu_gpr(t0, XRa);
710 gen_load_mxu_gpr(t1, XRd);
712 switch (aptn2) {
713 case MXU_APTN2_AA:
714 tcg_gen_add_tl(t3, t0, t3);
715 tcg_gen_add_tl(t2, t1, t2);
716 break;
717 case MXU_APTN2_AS:
718 tcg_gen_add_tl(t3, t0, t3);
719 tcg_gen_sub_tl(t2, t1, t2);
720 break;
721 case MXU_APTN2_SA:
722 tcg_gen_sub_tl(t3, t0, t3);
723 tcg_gen_add_tl(t2, t1, t2);
724 break;
725 case MXU_APTN2_SS:
726 tcg_gen_sub_tl(t3, t0, t3);
727 tcg_gen_sub_tl(t2, t1, t2);
728 break;
730 gen_store_mxu_gpr(t3, XRa);
731 gen_store_mxu_gpr(t2, XRd);
735 * Q8MUL XRa, XRb, XRc, XRd - Parallel unsigned 8 bit pattern multiply
736 * Q8MULSU XRa, XRb, XRc, XRd - Parallel signed 8 bit pattern multiply
738 static void gen_mxu_q8mul_q8mulsu(DisasContext *ctx)
740 TCGv t0, t1, t2, t3, t4, t5, t6, t7;
741 uint32_t XRa, XRb, XRc, XRd, sel;
743 t0 = tcg_temp_new();
744 t1 = tcg_temp_new();
745 t2 = tcg_temp_new();
746 t3 = tcg_temp_new();
747 t4 = tcg_temp_new();
748 t5 = tcg_temp_new();
749 t6 = tcg_temp_new();
750 t7 = tcg_temp_new();
752 XRa = extract32(ctx->opcode, 6, 4);
753 XRb = extract32(ctx->opcode, 10, 4);
754 XRc = extract32(ctx->opcode, 14, 4);
755 XRd = extract32(ctx->opcode, 18, 4);
756 sel = extract32(ctx->opcode, 22, 2);
758 gen_load_mxu_gpr(t3, XRb);
759 gen_load_mxu_gpr(t7, XRc);
761 if (sel == 0x2) {
762 /* Q8MULSU */
763 tcg_gen_ext8s_tl(t0, t3);
764 tcg_gen_shri_tl(t3, t3, 8);
765 tcg_gen_ext8s_tl(t1, t3);
766 tcg_gen_shri_tl(t3, t3, 8);
767 tcg_gen_ext8s_tl(t2, t3);
768 tcg_gen_shri_tl(t3, t3, 8);
769 tcg_gen_ext8s_tl(t3, t3);
770 } else {
771 /* Q8MUL */
772 tcg_gen_ext8u_tl(t0, t3);
773 tcg_gen_shri_tl(t3, t3, 8);
774 tcg_gen_ext8u_tl(t1, t3);
775 tcg_gen_shri_tl(t3, t3, 8);
776 tcg_gen_ext8u_tl(t2, t3);
777 tcg_gen_shri_tl(t3, t3, 8);
778 tcg_gen_ext8u_tl(t3, t3);
781 tcg_gen_ext8u_tl(t4, t7);
782 tcg_gen_shri_tl(t7, t7, 8);
783 tcg_gen_ext8u_tl(t5, t7);
784 tcg_gen_shri_tl(t7, t7, 8);
785 tcg_gen_ext8u_tl(t6, t7);
786 tcg_gen_shri_tl(t7, t7, 8);
787 tcg_gen_ext8u_tl(t7, t7);
789 tcg_gen_mul_tl(t0, t0, t4);
790 tcg_gen_mul_tl(t1, t1, t5);
791 tcg_gen_mul_tl(t2, t2, t6);
792 tcg_gen_mul_tl(t3, t3, t7);
794 tcg_gen_andi_tl(t0, t0, 0xFFFF);
795 tcg_gen_andi_tl(t1, t1, 0xFFFF);
796 tcg_gen_andi_tl(t2, t2, 0xFFFF);
797 tcg_gen_andi_tl(t3, t3, 0xFFFF);
799 tcg_gen_shli_tl(t1, t1, 16);
800 tcg_gen_shli_tl(t3, t3, 16);
802 tcg_gen_or_tl(t0, t0, t1);
803 tcg_gen_or_tl(t1, t2, t3);
805 gen_store_mxu_gpr(t0, XRd);
806 gen_store_mxu_gpr(t1, XRa);
810 * S32LDD XRa, Rb, S12 - Load a word from memory to XRF
811 * S32LDDR XRa, Rb, S12 - Load a word from memory to XRF, reversed byte seq.
813 static void gen_mxu_s32ldd_s32lddr(DisasContext *ctx)
815 TCGv t0, t1;
816 uint32_t XRa, Rb, s12, sel;
818 t0 = tcg_temp_new();
819 t1 = tcg_temp_new();
821 XRa = extract32(ctx->opcode, 6, 4);
822 s12 = extract32(ctx->opcode, 10, 10);
823 sel = extract32(ctx->opcode, 20, 1);
824 Rb = extract32(ctx->opcode, 21, 5);
826 gen_load_gpr(t0, Rb);
828 tcg_gen_movi_tl(t1, s12);
829 tcg_gen_shli_tl(t1, t1, 2);
830 if (s12 & 0x200) {
831 tcg_gen_ori_tl(t1, t1, 0xFFFFF000);
833 tcg_gen_add_tl(t1, t0, t1);
834 tcg_gen_qemu_ld_tl(t1, t1, ctx->mem_idx, (MO_TESL ^ (sel * MO_BSWAP)) |
835 ctx->default_tcg_memop_mask);
837 gen_store_mxu_gpr(t1, XRa);
842 * MXU instruction category: logic
843 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
845 * S32NOR S32AND S32OR S32XOR
849 * S32NOR XRa, XRb, XRc
850 * Update XRa with the result of logical bitwise 'nor' operation
851 * applied to the content of XRb and XRc.
853 static void gen_mxu_S32NOR(DisasContext *ctx)
855 uint32_t pad, XRc, XRb, XRa;
857 pad = extract32(ctx->opcode, 21, 5);
858 XRc = extract32(ctx->opcode, 14, 4);
859 XRb = extract32(ctx->opcode, 10, 4);
860 XRa = extract32(ctx->opcode, 6, 4);
862 if (unlikely(pad != 0)) {
863 /* opcode padding incorrect -> do nothing */
864 } else if (unlikely(XRa == 0)) {
865 /* destination is zero register -> do nothing */
866 } else if (unlikely((XRb == 0) && (XRc == 0))) {
867 /* both operands zero registers -> just set destination to all 1s */
868 tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0xFFFFFFFF);
869 } else if (unlikely(XRb == 0)) {
870 /* XRb zero register -> just set destination to the negation of XRc */
871 tcg_gen_not_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]);
872 } else if (unlikely(XRc == 0)) {
873 /* XRa zero register -> just set destination to the negation of XRb */
874 tcg_gen_not_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
875 } else if (unlikely(XRb == XRc)) {
876 /* both operands same -> just set destination to the negation of XRb */
877 tcg_gen_not_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
878 } else {
879 /* the most general case */
880 tcg_gen_nor_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], mxu_gpr[XRc - 1]);
885 * S32AND XRa, XRb, XRc
886 * Update XRa with the result of logical bitwise 'and' operation
887 * applied to the content of XRb and XRc.
889 static void gen_mxu_S32AND(DisasContext *ctx)
891 uint32_t pad, XRc, XRb, XRa;
893 pad = extract32(ctx->opcode, 21, 5);
894 XRc = extract32(ctx->opcode, 14, 4);
895 XRb = extract32(ctx->opcode, 10, 4);
896 XRa = extract32(ctx->opcode, 6, 4);
898 if (unlikely(pad != 0)) {
899 /* opcode padding incorrect -> do nothing */
900 } else if (unlikely(XRa == 0)) {
901 /* destination is zero register -> do nothing */
902 } else if (unlikely((XRb == 0) || (XRc == 0))) {
903 /* one of operands zero register -> just set destination to all 0s */
904 tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
905 } else if (unlikely(XRb == XRc)) {
906 /* both operands same -> just set destination to one of them */
907 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
908 } else {
909 /* the most general case */
910 tcg_gen_and_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], mxu_gpr[XRc - 1]);
915 * S32OR XRa, XRb, XRc
916 * Update XRa with the result of logical bitwise 'or' operation
917 * applied to the content of XRb and XRc.
919 static void gen_mxu_S32OR(DisasContext *ctx)
921 uint32_t pad, XRc, XRb, XRa;
923 pad = extract32(ctx->opcode, 21, 5);
924 XRc = extract32(ctx->opcode, 14, 4);
925 XRb = extract32(ctx->opcode, 10, 4);
926 XRa = extract32(ctx->opcode, 6, 4);
928 if (unlikely(pad != 0)) {
929 /* opcode padding incorrect -> do nothing */
930 } else if (unlikely(XRa == 0)) {
931 /* destination is zero register -> do nothing */
932 } else if (unlikely((XRb == 0) && (XRc == 0))) {
933 /* both operands zero registers -> just set destination to all 0s */
934 tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
935 } else if (unlikely(XRb == 0)) {
936 /* XRb zero register -> just set destination to the content of XRc */
937 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]);
938 } else if (unlikely(XRc == 0)) {
939 /* XRc zero register -> just set destination to the content of XRb */
940 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
941 } else if (unlikely(XRb == XRc)) {
942 /* both operands same -> just set destination to one of them */
943 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
944 } else {
945 /* the most general case */
946 tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], mxu_gpr[XRc - 1]);
951 * S32XOR XRa, XRb, XRc
952 * Update XRa with the result of logical bitwise 'xor' operation
953 * applied to the content of XRb and XRc.
955 static void gen_mxu_S32XOR(DisasContext *ctx)
957 uint32_t pad, XRc, XRb, XRa;
959 pad = extract32(ctx->opcode, 21, 5);
960 XRc = extract32(ctx->opcode, 14, 4);
961 XRb = extract32(ctx->opcode, 10, 4);
962 XRa = extract32(ctx->opcode, 6, 4);
964 if (unlikely(pad != 0)) {
965 /* opcode padding incorrect -> do nothing */
966 } else if (unlikely(XRa == 0)) {
967 /* destination is zero register -> do nothing */
968 } else if (unlikely((XRb == 0) && (XRc == 0))) {
969 /* both operands zero registers -> just set destination to all 0s */
970 tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
971 } else if (unlikely(XRb == 0)) {
972 /* XRb zero register -> just set destination to the content of XRc */
973 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]);
974 } else if (unlikely(XRc == 0)) {
975 /* XRc zero register -> just set destination to the content of XRb */
976 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
977 } else if (unlikely(XRb == XRc)) {
978 /* both operands same -> just set destination to all 0s */
979 tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
980 } else {
981 /* the most general case */
982 tcg_gen_xor_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], mxu_gpr[XRc - 1]);
988 * MXU instruction category max/min
989 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
991 * S32MAX D16MAX Q8MAX
992 * S32MIN D16MIN Q8MIN
996 * S32MAX XRa, XRb, XRc
997 * Update XRa with the maximum of signed 32-bit integers contained
998 * in XRb and XRc.
1000 * S32MIN XRa, XRb, XRc
1001 * Update XRa with the minimum of signed 32-bit integers contained
1002 * in XRb and XRc.
1004 static void gen_mxu_S32MAX_S32MIN(DisasContext *ctx)
1006 uint32_t pad, opc, XRc, XRb, XRa;
1008 pad = extract32(ctx->opcode, 21, 5);
1009 opc = extract32(ctx->opcode, 18, 3);
1010 XRc = extract32(ctx->opcode, 14, 4);
1011 XRb = extract32(ctx->opcode, 10, 4);
1012 XRa = extract32(ctx->opcode, 6, 4);
1014 if (unlikely(pad != 0)) {
1015 /* opcode padding incorrect -> do nothing */
1016 } else if (unlikely(XRa == 0)) {
1017 /* destination is zero register -> do nothing */
1018 } else if (unlikely((XRb == 0) && (XRc == 0))) {
1019 /* both operands zero registers -> just set destination to zero */
1020 tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
1021 } else if (unlikely((XRb == 0) || (XRc == 0))) {
1022 /* exactly one operand is zero register - find which one is not...*/
1023 uint32_t XRx = XRb ? XRb : XRc;
1024 /* ...and do max/min operation with one operand 0 */
1025 if (opc == OPC_MXU_S32MAX) {
1026 tcg_gen_smax_i32(mxu_gpr[XRa - 1], mxu_gpr[XRx - 1], 0);
1027 } else {
1028 tcg_gen_smin_i32(mxu_gpr[XRa - 1], mxu_gpr[XRx - 1], 0);
1030 } else if (unlikely(XRb == XRc)) {
1031 /* both operands same -> just set destination to one of them */
1032 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
1033 } else {
1034 /* the most general case */
1035 if (opc == OPC_MXU_S32MAX) {
1036 tcg_gen_smax_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1],
1037 mxu_gpr[XRc - 1]);
1038 } else {
1039 tcg_gen_smin_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1],
1040 mxu_gpr[XRc - 1]);
1046 * D16MAX
1047 * Update XRa with the 16-bit-wise maximums of signed integers
1048 * contained in XRb and XRc.
1050 * D16MIN
1051 * Update XRa with the 16-bit-wise minimums of signed integers
1052 * contained in XRb and XRc.
1054 static void gen_mxu_D16MAX_D16MIN(DisasContext *ctx)
1056 uint32_t pad, opc, XRc, XRb, XRa;
1058 pad = extract32(ctx->opcode, 21, 5);
1059 opc = extract32(ctx->opcode, 18, 3);
1060 XRc = extract32(ctx->opcode, 14, 4);
1061 XRb = extract32(ctx->opcode, 10, 4);
1062 XRa = extract32(ctx->opcode, 6, 4);
1064 if (unlikely(pad != 0)) {
1065 /* opcode padding incorrect -> do nothing */
1066 } else if (unlikely(XRa == 0)) {
1067 /* destination is zero register -> do nothing */
1068 } else if (unlikely((XRb == 0) && (XRc == 0))) {
1069 /* both operands zero registers -> just set destination to zero */
1070 tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
1071 } else if (unlikely((XRb == 0) || (XRc == 0))) {
1072 /* exactly one operand is zero register - find which one is not...*/
1073 uint32_t XRx = XRb ? XRb : XRc;
1074 /* ...and do half-word-wise max/min with one operand 0 */
1075 TCGv_i32 t0 = tcg_temp_new();
1076 TCGv_i32 t1 = tcg_constant_i32(0);
1078 /* the left half-word first */
1079 tcg_gen_andi_i32(t0, mxu_gpr[XRx - 1], 0xFFFF0000);
1080 if (opc == OPC_MXU_D16MAX) {
1081 tcg_gen_smax_i32(mxu_gpr[XRa - 1], t0, t1);
1082 } else {
1083 tcg_gen_smin_i32(mxu_gpr[XRa - 1], t0, t1);
1086 /* the right half-word */
1087 tcg_gen_andi_i32(t0, mxu_gpr[XRx - 1], 0x0000FFFF);
1088 /* move half-words to the leftmost position */
1089 tcg_gen_shli_i32(t0, t0, 16);
1090 /* t0 will be max/min of t0 and t1 */
1091 if (opc == OPC_MXU_D16MAX) {
1092 tcg_gen_smax_i32(t0, t0, t1);
1093 } else {
1094 tcg_gen_smin_i32(t0, t0, t1);
1096 /* return resulting half-words to its original position */
1097 tcg_gen_shri_i32(t0, t0, 16);
1098 /* finally update the destination */
1099 tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRa - 1], t0);
1100 } else if (unlikely(XRb == XRc)) {
1101 /* both operands same -> just set destination to one of them */
1102 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
1103 } else {
1104 /* the most general case */
1105 TCGv_i32 t0 = tcg_temp_new();
1106 TCGv_i32 t1 = tcg_temp_new();
1108 /* the left half-word first */
1109 tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0xFFFF0000);
1110 tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFFFF0000);
1111 if (opc == OPC_MXU_D16MAX) {
1112 tcg_gen_smax_i32(mxu_gpr[XRa - 1], t0, t1);
1113 } else {
1114 tcg_gen_smin_i32(mxu_gpr[XRa - 1], t0, t1);
1117 /* the right half-word */
1118 tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0x0000FFFF);
1119 tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0x0000FFFF);
1120 /* move half-words to the leftmost position */
1121 tcg_gen_shli_i32(t0, t0, 16);
1122 tcg_gen_shli_i32(t1, t1, 16);
1123 /* t0 will be max/min of t0 and t1 */
1124 if (opc == OPC_MXU_D16MAX) {
1125 tcg_gen_smax_i32(t0, t0, t1);
1126 } else {
1127 tcg_gen_smin_i32(t0, t0, t1);
1129 /* return resulting half-words to its original position */
1130 tcg_gen_shri_i32(t0, t0, 16);
1131 /* finally update the destination */
1132 tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRa - 1], t0);
1137 * Q8MAX
1138 * Update XRa with the 8-bit-wise maximums of signed integers
1139 * contained in XRb and XRc.
1141 * Q8MIN
1142 * Update XRa with the 8-bit-wise minimums of signed integers
1143 * contained in XRb and XRc.
1145 static void gen_mxu_Q8MAX_Q8MIN(DisasContext *ctx)
1147 uint32_t pad, opc, XRc, XRb, XRa;
1149 pad = extract32(ctx->opcode, 21, 5);
1150 opc = extract32(ctx->opcode, 18, 3);
1151 XRc = extract32(ctx->opcode, 14, 4);
1152 XRb = extract32(ctx->opcode, 10, 4);
1153 XRa = extract32(ctx->opcode, 6, 4);
1155 if (unlikely(pad != 0)) {
1156 /* opcode padding incorrect -> do nothing */
1157 } else if (unlikely(XRa == 0)) {
1158 /* destination is zero register -> do nothing */
1159 } else if (unlikely((XRb == 0) && (XRc == 0))) {
1160 /* both operands zero registers -> just set destination to zero */
1161 tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
1162 } else if (unlikely((XRb == 0) || (XRc == 0))) {
1163 /* exactly one operand is zero register - make it be the first...*/
1164 uint32_t XRx = XRb ? XRb : XRc;
1165 /* ...and do byte-wise max/min with one operand 0 */
1166 TCGv_i32 t0 = tcg_temp_new();
1167 TCGv_i32 t1 = tcg_constant_i32(0);
1168 int32_t i;
1170 /* the leftmost byte (byte 3) first */
1171 tcg_gen_andi_i32(t0, mxu_gpr[XRx - 1], 0xFF000000);
1172 if (opc == OPC_MXU_Q8MAX) {
1173 tcg_gen_smax_i32(mxu_gpr[XRa - 1], t0, t1);
1174 } else {
1175 tcg_gen_smin_i32(mxu_gpr[XRa - 1], t0, t1);
1178 /* bytes 2, 1, 0 */
1179 for (i = 2; i >= 0; i--) {
1180 /* extract the byte */
1181 tcg_gen_andi_i32(t0, mxu_gpr[XRx - 1], 0xFF << (8 * i));
1182 /* move the byte to the leftmost position */
1183 tcg_gen_shli_i32(t0, t0, 8 * (3 - i));
1184 /* t0 will be max/min of t0 and t1 */
1185 if (opc == OPC_MXU_Q8MAX) {
1186 tcg_gen_smax_i32(t0, t0, t1);
1187 } else {
1188 tcg_gen_smin_i32(t0, t0, t1);
1190 /* return resulting byte to its original position */
1191 tcg_gen_shri_i32(t0, t0, 8 * (3 - i));
1192 /* finally update the destination */
1193 tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRa - 1], t0);
1195 } else if (unlikely(XRb == XRc)) {
1196 /* both operands same -> just set destination to one of them */
1197 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
1198 } else {
1199 /* the most general case */
1200 TCGv_i32 t0 = tcg_temp_new();
1201 TCGv_i32 t1 = tcg_temp_new();
1202 int32_t i;
1204 /* the leftmost bytes (bytes 3) first */
1205 tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0xFF000000);
1206 tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFF000000);
1207 if (opc == OPC_MXU_Q8MAX) {
1208 tcg_gen_smax_i32(mxu_gpr[XRa - 1], t0, t1);
1209 } else {
1210 tcg_gen_smin_i32(mxu_gpr[XRa - 1], t0, t1);
1213 /* bytes 2, 1, 0 */
1214 for (i = 2; i >= 0; i--) {
1215 /* extract corresponding bytes */
1216 tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0xFF << (8 * i));
1217 tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFF << (8 * i));
1218 /* move the bytes to the leftmost position */
1219 tcg_gen_shli_i32(t0, t0, 8 * (3 - i));
1220 tcg_gen_shli_i32(t1, t1, 8 * (3 - i));
1221 /* t0 will be max/min of t0 and t1 */
1222 if (opc == OPC_MXU_Q8MAX) {
1223 tcg_gen_smax_i32(t0, t0, t1);
1224 } else {
1225 tcg_gen_smin_i32(t0, t0, t1);
1227 /* return resulting byte to its original position */
1228 tcg_gen_shri_i32(t0, t0, 8 * (3 - i));
1229 /* finally update the destination */
1230 tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRa - 1], t0);
1237 * MXU instruction category: align
1238 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1240 * S32ALN S32ALNI
1244 * S32ALNI XRc, XRb, XRa, optn3
1245 * Arrange bytes from XRb and XRc according to one of five sets of
1246 * rules determined by optn3, and place the result in XRa.
1248 static void gen_mxu_S32ALNI(DisasContext *ctx)
1250 uint32_t optn3, pad, XRc, XRb, XRa;
1252 optn3 = extract32(ctx->opcode, 23, 3);
1253 pad = extract32(ctx->opcode, 21, 2);
1254 XRc = extract32(ctx->opcode, 14, 4);
1255 XRb = extract32(ctx->opcode, 10, 4);
1256 XRa = extract32(ctx->opcode, 6, 4);
1258 if (unlikely(pad != 0)) {
1259 /* opcode padding incorrect -> do nothing */
1260 } else if (unlikely(XRa == 0)) {
1261 /* destination is zero register -> do nothing */
1262 } else if (unlikely((XRb == 0) && (XRc == 0))) {
1263 /* both operands zero registers -> just set destination to all 0s */
1264 tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
1265 } else if (unlikely(XRb == 0)) {
1266 /* XRb zero register -> just appropriatelly shift XRc into XRa */
1267 switch (optn3) {
1268 case MXU_OPTN3_PTN0:
1269 tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
1270 break;
1271 case MXU_OPTN3_PTN1:
1272 case MXU_OPTN3_PTN2:
1273 case MXU_OPTN3_PTN3:
1274 tcg_gen_shri_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1],
1275 8 * (4 - optn3));
1276 break;
1277 case MXU_OPTN3_PTN4:
1278 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]);
1279 break;
1281 } else if (unlikely(XRc == 0)) {
1282 /* XRc zero register -> just appropriatelly shift XRb into XRa */
1283 switch (optn3) {
1284 case MXU_OPTN3_PTN0:
1285 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
1286 break;
1287 case MXU_OPTN3_PTN1:
1288 case MXU_OPTN3_PTN2:
1289 case MXU_OPTN3_PTN3:
1290 tcg_gen_shri_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], 8 * optn3);
1291 break;
1292 case MXU_OPTN3_PTN4:
1293 tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
1294 break;
1296 } else if (unlikely(XRb == XRc)) {
1297 /* both operands same -> just rotation or moving from any of them */
1298 switch (optn3) {
1299 case MXU_OPTN3_PTN0:
1300 case MXU_OPTN3_PTN4:
1301 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
1302 break;
1303 case MXU_OPTN3_PTN1:
1304 case MXU_OPTN3_PTN2:
1305 case MXU_OPTN3_PTN3:
1306 tcg_gen_rotli_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], 8 * optn3);
1307 break;
1309 } else {
1310 /* the most general case */
1311 switch (optn3) {
1312 case MXU_OPTN3_PTN0:
1314 /* */
1315 /* XRb XRc */
1316 /* +---------------+ */
1317 /* | A B C D | E F G H */
1318 /* +-------+-------+ */
1319 /* | */
1320 /* XRa */
1321 /* */
1323 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
1325 break;
1326 case MXU_OPTN3_PTN1:
1328 /* */
1329 /* XRb XRc */
1330 /* +-------------------+ */
1331 /* A | B C D E | F G H */
1332 /* +---------+---------+ */
1333 /* | */
1334 /* XRa */
1335 /* */
1337 TCGv_i32 t0 = tcg_temp_new();
1338 TCGv_i32 t1 = tcg_temp_new();
1340 tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0x00FFFFFF);
1341 tcg_gen_shli_i32(t0, t0, 8);
1343 tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFF000000);
1344 tcg_gen_shri_i32(t1, t1, 24);
1346 tcg_gen_or_i32(mxu_gpr[XRa - 1], t0, t1);
1348 break;
1349 case MXU_OPTN3_PTN2:
1351 /* */
1352 /* XRb XRc */
1353 /* +-------------------+ */
1354 /* A B | C D E F | G H */
1355 /* +---------+---------+ */
1356 /* | */
1357 /* XRa */
1358 /* */
1360 TCGv_i32 t0 = tcg_temp_new();
1361 TCGv_i32 t1 = tcg_temp_new();
1363 tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0x0000FFFF);
1364 tcg_gen_shli_i32(t0, t0, 16);
1366 tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFFFF0000);
1367 tcg_gen_shri_i32(t1, t1, 16);
1369 tcg_gen_or_i32(mxu_gpr[XRa - 1], t0, t1);
1371 break;
1372 case MXU_OPTN3_PTN3:
1374 /* */
1375 /* XRb XRc */
1376 /* +-------------------+ */
1377 /* A B C | D E F G | H */
1378 /* +---------+---------+ */
1379 /* | */
1380 /* XRa */
1381 /* */
1383 TCGv_i32 t0 = tcg_temp_new();
1384 TCGv_i32 t1 = tcg_temp_new();
1386 tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0x000000FF);
1387 tcg_gen_shli_i32(t0, t0, 24);
1389 tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFFFFFF00);
1390 tcg_gen_shri_i32(t1, t1, 8);
1392 tcg_gen_or_i32(mxu_gpr[XRa - 1], t0, t1);
1394 break;
1395 case MXU_OPTN3_PTN4:
1397 /* */
1398 /* XRb XRc */
1399 /* +---------------+ */
1400 /* A B C D | E F G H | */
1401 /* +-------+-------+ */
1402 /* | */
1403 /* XRa */
1404 /* */
1406 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]);
1408 break;
1415 * Decoding engine for MXU
1416 * =======================
1419 static void decode_opc_mxu__pool00(DisasContext *ctx)
1421 uint32_t opcode = extract32(ctx->opcode, 18, 3);
1423 switch (opcode) {
1424 case OPC_MXU_S32MAX:
1425 case OPC_MXU_S32MIN:
1426 gen_mxu_S32MAX_S32MIN(ctx);
1427 break;
1428 case OPC_MXU_D16MAX:
1429 case OPC_MXU_D16MIN:
1430 gen_mxu_D16MAX_D16MIN(ctx);
1431 break;
1432 case OPC_MXU_Q8MAX:
1433 case OPC_MXU_Q8MIN:
1434 gen_mxu_Q8MAX_Q8MIN(ctx);
1435 break;
1436 default:
1437 MIPS_INVAL("decode_opc_mxu");
1438 gen_reserved_instruction(ctx);
1439 break;
1443 static void decode_opc_mxu__pool04(DisasContext *ctx)
1445 uint32_t opcode = extract32(ctx->opcode, 20, 1);
1447 switch (opcode) {
1448 case OPC_MXU_S32LDD:
1449 case OPC_MXU_S32LDDR:
1450 gen_mxu_s32ldd_s32lddr(ctx);
1451 break;
1452 default:
1453 MIPS_INVAL("decode_opc_mxu");
1454 gen_reserved_instruction(ctx);
1455 break;
1459 static void decode_opc_mxu__pool16(DisasContext *ctx)
1461 uint32_t opcode = extract32(ctx->opcode, 18, 3);
1463 switch (opcode) {
1464 case OPC_MXU_S32ALNI:
1465 gen_mxu_S32ALNI(ctx);
1466 break;
1467 case OPC_MXU_S32NOR:
1468 gen_mxu_S32NOR(ctx);
1469 break;
1470 case OPC_MXU_S32AND:
1471 gen_mxu_S32AND(ctx);
1472 break;
1473 case OPC_MXU_S32OR:
1474 gen_mxu_S32OR(ctx);
1475 break;
1476 case OPC_MXU_S32XOR:
1477 gen_mxu_S32XOR(ctx);
1478 break;
1479 default:
1480 MIPS_INVAL("decode_opc_mxu");
1481 gen_reserved_instruction(ctx);
1482 break;
1486 static void decode_opc_mxu__pool19(DisasContext *ctx)
1488 uint32_t opcode = extract32(ctx->opcode, 22, 2);
1490 switch (opcode) {
1491 case OPC_MXU_Q8MUL:
1492 case OPC_MXU_Q8MULSU:
1493 gen_mxu_q8mul_q8mulsu(ctx);
1494 break;
1495 default:
1496 MIPS_INVAL("decode_opc_mxu");
1497 gen_reserved_instruction(ctx);
1498 break;
1502 bool decode_ase_mxu(DisasContext *ctx, uint32_t insn)
1504 uint32_t opcode = extract32(insn, 0, 6);
1506 if (opcode == OPC_MXU_S32M2I) {
1507 gen_mxu_s32m2i(ctx);
1508 return true;
1511 if (opcode == OPC_MXU_S32I2M) {
1512 gen_mxu_s32i2m(ctx);
1513 return true;
1517 TCGv t_mxu_cr = tcg_temp_new();
1518 TCGLabel *l_exit = gen_new_label();
1520 gen_load_mxu_cr(t_mxu_cr);
1521 tcg_gen_andi_tl(t_mxu_cr, t_mxu_cr, MXU_CR_MXU_EN);
1522 tcg_gen_brcondi_tl(TCG_COND_NE, t_mxu_cr, MXU_CR_MXU_EN, l_exit);
1524 switch (opcode) {
1525 case OPC_MXU__POOL00:
1526 decode_opc_mxu__pool00(ctx);
1527 break;
1528 case OPC_MXU_D16MUL:
1529 gen_mxu_d16mul(ctx);
1530 break;
1531 case OPC_MXU_D16MAC:
1532 gen_mxu_d16mac(ctx);
1533 break;
1534 case OPC_MXU__POOL04:
1535 decode_opc_mxu__pool04(ctx);
1536 break;
1537 case OPC_MXU_S8LDD:
1538 gen_mxu_s8ldd(ctx);
1539 break;
1540 case OPC_MXU__POOL16:
1541 decode_opc_mxu__pool16(ctx);
1542 break;
1543 case OPC_MXU__POOL19:
1544 decode_opc_mxu__pool19(ctx);
1545 break;
1546 default:
1547 MIPS_INVAL("decode_opc_mxu");
1548 gen_reserved_instruction(ctx);
1551 gen_set_label(l_exit);
1554 return true;