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