target/mips: Introduce mxu_translate_init() helper
[qemu/ar7.git] / target / mips / translate.c
bloba1a9a8500851df87d1465953c1d394a3b059c0fe
1 /*
2 * MIPS emulation for QEMU - main translation routines
4 * Copyright (c) 2004-2005 Jocelyn Mayer
5 * Copyright (c) 2006 Marius Groeger (FPU operations)
6 * Copyright (c) 2006 Thiemo Seufer (MIPS32R2 support)
7 * Copyright (c) 2009 CodeSourcery (MIPS16 and microMIPS support)
8 * Copyright (c) 2012 Jia Liu & Dongxue Zhang (MIPS ASE DSP support)
9 * Copyright (c) 2020 Philippe Mathieu-Daudé
11 * This library is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Lesser General Public
13 * License as published by the Free Software Foundation; either
14 * version 2.1 of the License, or (at your option) any later version.
16 * This library is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * Lesser General Public License for more details.
21 * You should have received a copy of the GNU Lesser General Public
22 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
25 #include "qemu/osdep.h"
26 #include "cpu.h"
27 #include "internal.h"
28 #include "tcg/tcg-op.h"
29 #include "exec/translator.h"
30 #include "exec/helper-proto.h"
31 #include "exec/helper-gen.h"
32 #include "semihosting/semihost.h"
34 #include "target/mips/trace.h"
35 #include "trace-tcg.h"
36 #include "exec/translator.h"
37 #include "exec/log.h"
38 #include "qemu/qemu-print.h"
39 #include "fpu_helper.h"
40 #include "translate.h"
42 enum {
43 /* indirect opcode tables */
44 OPC_SPECIAL = (0x00 << 26),
45 OPC_REGIMM = (0x01 << 26),
46 OPC_CP0 = (0x10 << 26),
47 OPC_CP2 = (0x12 << 26),
48 OPC_CP3 = (0x13 << 26),
49 OPC_SPECIAL2 = (0x1C << 26),
50 OPC_SPECIAL3 = (0x1F << 26),
51 /* arithmetic with immediate */
52 OPC_ADDI = (0x08 << 26),
53 OPC_ADDIU = (0x09 << 26),
54 OPC_SLTI = (0x0A << 26),
55 OPC_SLTIU = (0x0B << 26),
56 /* logic with immediate */
57 OPC_ANDI = (0x0C << 26),
58 OPC_ORI = (0x0D << 26),
59 OPC_XORI = (0x0E << 26),
60 OPC_LUI = (0x0F << 26),
61 /* arithmetic with immediate */
62 OPC_DADDI = (0x18 << 26),
63 OPC_DADDIU = (0x19 << 26),
64 /* Jump and branches */
65 OPC_J = (0x02 << 26),
66 OPC_JAL = (0x03 << 26),
67 OPC_BEQ = (0x04 << 26), /* Unconditional if rs = rt = 0 (B) */
68 OPC_BEQL = (0x14 << 26),
69 OPC_BNE = (0x05 << 26),
70 OPC_BNEL = (0x15 << 26),
71 OPC_BLEZ = (0x06 << 26),
72 OPC_BLEZL = (0x16 << 26),
73 OPC_BGTZ = (0x07 << 26),
74 OPC_BGTZL = (0x17 << 26),
75 OPC_JALX = (0x1D << 26),
76 OPC_DAUI = (0x1D << 26),
77 /* Load and stores */
78 OPC_LDL = (0x1A << 26),
79 OPC_LDR = (0x1B << 26),
80 OPC_LB = (0x20 << 26),
81 OPC_LH = (0x21 << 26),
82 OPC_LWL = (0x22 << 26),
83 OPC_LW = (0x23 << 26),
84 OPC_LWPC = OPC_LW | 0x5,
85 OPC_LBU = (0x24 << 26),
86 OPC_LHU = (0x25 << 26),
87 OPC_LWR = (0x26 << 26),
88 OPC_LWU = (0x27 << 26),
89 OPC_SB = (0x28 << 26),
90 OPC_SH = (0x29 << 26),
91 OPC_SWL = (0x2A << 26),
92 OPC_SW = (0x2B << 26),
93 OPC_SDL = (0x2C << 26),
94 OPC_SDR = (0x2D << 26),
95 OPC_SWR = (0x2E << 26),
96 OPC_LL = (0x30 << 26),
97 OPC_LLD = (0x34 << 26),
98 OPC_LD = (0x37 << 26),
99 OPC_LDPC = OPC_LD | 0x5,
100 OPC_SC = (0x38 << 26),
101 OPC_SCD = (0x3C << 26),
102 OPC_SD = (0x3F << 26),
103 /* Floating point load/store */
104 OPC_LWC1 = (0x31 << 26),
105 OPC_LWC2 = (0x32 << 26),
106 OPC_LDC1 = (0x35 << 26),
107 OPC_LDC2 = (0x36 << 26),
108 OPC_SWC1 = (0x39 << 26),
109 OPC_SWC2 = (0x3A << 26),
110 OPC_SDC1 = (0x3D << 26),
111 OPC_SDC2 = (0x3E << 26),
112 /* Compact Branches */
113 OPC_BLEZALC = (0x06 << 26),
114 OPC_BGEZALC = (0x06 << 26),
115 OPC_BGEUC = (0x06 << 26),
116 OPC_BGTZALC = (0x07 << 26),
117 OPC_BLTZALC = (0x07 << 26),
118 OPC_BLTUC = (0x07 << 26),
119 OPC_BOVC = (0x08 << 26),
120 OPC_BEQZALC = (0x08 << 26),
121 OPC_BEQC = (0x08 << 26),
122 OPC_BLEZC = (0x16 << 26),
123 OPC_BGEZC = (0x16 << 26),
124 OPC_BGEC = (0x16 << 26),
125 OPC_BGTZC = (0x17 << 26),
126 OPC_BLTZC = (0x17 << 26),
127 OPC_BLTC = (0x17 << 26),
128 OPC_BNVC = (0x18 << 26),
129 OPC_BNEZALC = (0x18 << 26),
130 OPC_BNEC = (0x18 << 26),
131 OPC_BC = (0x32 << 26),
132 OPC_BEQZC = (0x36 << 26),
133 OPC_JIC = (0x36 << 26),
134 OPC_BALC = (0x3A << 26),
135 OPC_BNEZC = (0x3E << 26),
136 OPC_JIALC = (0x3E << 26),
137 /* MDMX ASE specific */
138 OPC_MDMX = (0x1E << 26),
139 /* Cache and prefetch */
140 OPC_CACHE = (0x2F << 26),
141 OPC_PREF = (0x33 << 26),
142 /* PC-relative address computation / loads */
143 OPC_PCREL = (0x3B << 26),
146 /* PC-relative address computation / loads */
147 #define MASK_OPC_PCREL_TOP2BITS(op) (MASK_OP_MAJOR(op) | (op & (3 << 19)))
148 #define MASK_OPC_PCREL_TOP5BITS(op) (MASK_OP_MAJOR(op) | (op & (0x1f << 16)))
149 enum {
150 /* Instructions determined by bits 19 and 20 */
151 OPC_ADDIUPC = OPC_PCREL | (0 << 19),
152 R6_OPC_LWPC = OPC_PCREL | (1 << 19),
153 OPC_LWUPC = OPC_PCREL | (2 << 19),
155 /* Instructions determined by bits 16 ... 20 */
156 OPC_AUIPC = OPC_PCREL | (0x1e << 16),
157 OPC_ALUIPC = OPC_PCREL | (0x1f << 16),
159 /* Other */
160 R6_OPC_LDPC = OPC_PCREL | (6 << 18),
163 /* MIPS special opcodes */
164 #define MASK_SPECIAL(op) (MASK_OP_MAJOR(op) | (op & 0x3F))
166 enum {
167 /* Shifts */
168 OPC_SLL = 0x00 | OPC_SPECIAL,
169 /* NOP is SLL r0, r0, 0 */
170 /* SSNOP is SLL r0, r0, 1 */
171 /* EHB is SLL r0, r0, 3 */
172 OPC_SRL = 0x02 | OPC_SPECIAL, /* also ROTR */
173 OPC_ROTR = OPC_SRL | (1 << 21),
174 OPC_SRA = 0x03 | OPC_SPECIAL,
175 OPC_SLLV = 0x04 | OPC_SPECIAL,
176 OPC_SRLV = 0x06 | OPC_SPECIAL, /* also ROTRV */
177 OPC_ROTRV = OPC_SRLV | (1 << 6),
178 OPC_SRAV = 0x07 | OPC_SPECIAL,
179 OPC_DSLLV = 0x14 | OPC_SPECIAL,
180 OPC_DSRLV = 0x16 | OPC_SPECIAL, /* also DROTRV */
181 OPC_DROTRV = OPC_DSRLV | (1 << 6),
182 OPC_DSRAV = 0x17 | OPC_SPECIAL,
183 OPC_DSLL = 0x38 | OPC_SPECIAL,
184 OPC_DSRL = 0x3A | OPC_SPECIAL, /* also DROTR */
185 OPC_DROTR = OPC_DSRL | (1 << 21),
186 OPC_DSRA = 0x3B | OPC_SPECIAL,
187 OPC_DSLL32 = 0x3C | OPC_SPECIAL,
188 OPC_DSRL32 = 0x3E | OPC_SPECIAL, /* also DROTR32 */
189 OPC_DROTR32 = OPC_DSRL32 | (1 << 21),
190 OPC_DSRA32 = 0x3F | OPC_SPECIAL,
191 /* Multiplication / division */
192 OPC_MULT = 0x18 | OPC_SPECIAL,
193 OPC_MULTU = 0x19 | OPC_SPECIAL,
194 OPC_DIV = 0x1A | OPC_SPECIAL,
195 OPC_DIVU = 0x1B | OPC_SPECIAL,
196 OPC_DMULT = 0x1C | OPC_SPECIAL,
197 OPC_DMULTU = 0x1D | OPC_SPECIAL,
198 OPC_DDIV = 0x1E | OPC_SPECIAL,
199 OPC_DDIVU = 0x1F | OPC_SPECIAL,
201 /* 2 registers arithmetic / logic */
202 OPC_ADD = 0x20 | OPC_SPECIAL,
203 OPC_ADDU = 0x21 | OPC_SPECIAL,
204 OPC_SUB = 0x22 | OPC_SPECIAL,
205 OPC_SUBU = 0x23 | OPC_SPECIAL,
206 OPC_AND = 0x24 | OPC_SPECIAL,
207 OPC_OR = 0x25 | OPC_SPECIAL,
208 OPC_XOR = 0x26 | OPC_SPECIAL,
209 OPC_NOR = 0x27 | OPC_SPECIAL,
210 OPC_SLT = 0x2A | OPC_SPECIAL,
211 OPC_SLTU = 0x2B | OPC_SPECIAL,
212 OPC_DADD = 0x2C | OPC_SPECIAL,
213 OPC_DADDU = 0x2D | OPC_SPECIAL,
214 OPC_DSUB = 0x2E | OPC_SPECIAL,
215 OPC_DSUBU = 0x2F | OPC_SPECIAL,
216 /* Jumps */
217 OPC_JR = 0x08 | OPC_SPECIAL, /* Also JR.HB */
218 OPC_JALR = 0x09 | OPC_SPECIAL, /* Also JALR.HB */
219 /* Traps */
220 OPC_TGE = 0x30 | OPC_SPECIAL,
221 OPC_TGEU = 0x31 | OPC_SPECIAL,
222 OPC_TLT = 0x32 | OPC_SPECIAL,
223 OPC_TLTU = 0x33 | OPC_SPECIAL,
224 OPC_TEQ = 0x34 | OPC_SPECIAL,
225 OPC_TNE = 0x36 | OPC_SPECIAL,
226 /* HI / LO registers load & stores */
227 OPC_MFHI = 0x10 | OPC_SPECIAL,
228 OPC_MTHI = 0x11 | OPC_SPECIAL,
229 OPC_MFLO = 0x12 | OPC_SPECIAL,
230 OPC_MTLO = 0x13 | OPC_SPECIAL,
231 /* Conditional moves */
232 OPC_MOVZ = 0x0A | OPC_SPECIAL,
233 OPC_MOVN = 0x0B | OPC_SPECIAL,
235 OPC_SELEQZ = 0x35 | OPC_SPECIAL,
236 OPC_SELNEZ = 0x37 | OPC_SPECIAL,
238 OPC_MOVCI = 0x01 | OPC_SPECIAL,
240 /* Special */
241 OPC_PMON = 0x05 | OPC_SPECIAL, /* unofficial */
242 OPC_SYSCALL = 0x0C | OPC_SPECIAL,
243 OPC_BREAK = 0x0D | OPC_SPECIAL,
244 OPC_SPIM = 0x0E | OPC_SPECIAL, /* unofficial */
245 OPC_SYNC = 0x0F | OPC_SPECIAL,
247 OPC_SPECIAL28_RESERVED = 0x28 | OPC_SPECIAL,
248 OPC_SPECIAL29_RESERVED = 0x29 | OPC_SPECIAL,
249 OPC_SPECIAL39_RESERVED = 0x39 | OPC_SPECIAL,
250 OPC_SPECIAL3D_RESERVED = 0x3D | OPC_SPECIAL,
254 * R6 Multiply and Divide instructions have the same opcode
255 * and function field as legacy OPC_MULT[U]/OPC_DIV[U]
257 #define MASK_R6_MULDIV(op) (MASK_SPECIAL(op) | (op & (0x7ff)))
259 enum {
260 R6_OPC_MUL = OPC_MULT | (2 << 6),
261 R6_OPC_MUH = OPC_MULT | (3 << 6),
262 R6_OPC_MULU = OPC_MULTU | (2 << 6),
263 R6_OPC_MUHU = OPC_MULTU | (3 << 6),
264 R6_OPC_DIV = OPC_DIV | (2 << 6),
265 R6_OPC_MOD = OPC_DIV | (3 << 6),
266 R6_OPC_DIVU = OPC_DIVU | (2 << 6),
267 R6_OPC_MODU = OPC_DIVU | (3 << 6),
269 R6_OPC_DMUL = OPC_DMULT | (2 << 6),
270 R6_OPC_DMUH = OPC_DMULT | (3 << 6),
271 R6_OPC_DMULU = OPC_DMULTU | (2 << 6),
272 R6_OPC_DMUHU = OPC_DMULTU | (3 << 6),
273 R6_OPC_DDIV = OPC_DDIV | (2 << 6),
274 R6_OPC_DMOD = OPC_DDIV | (3 << 6),
275 R6_OPC_DDIVU = OPC_DDIVU | (2 << 6),
276 R6_OPC_DMODU = OPC_DDIVU | (3 << 6),
278 R6_OPC_CLZ = 0x10 | OPC_SPECIAL,
279 R6_OPC_CLO = 0x11 | OPC_SPECIAL,
280 R6_OPC_DCLZ = 0x12 | OPC_SPECIAL,
281 R6_OPC_DCLO = 0x13 | OPC_SPECIAL,
282 R6_OPC_SDBBP = 0x0e | OPC_SPECIAL,
285 /* Multiplication variants of the vr54xx. */
286 #define MASK_MUL_VR54XX(op) (MASK_SPECIAL(op) | (op & (0x1F << 6)))
288 enum {
289 OPC_VR54XX_MULS = (0x03 << 6) | OPC_MULT,
290 OPC_VR54XX_MULSU = (0x03 << 6) | OPC_MULTU,
291 OPC_VR54XX_MACC = (0x05 << 6) | OPC_MULT,
292 OPC_VR54XX_MACCU = (0x05 << 6) | OPC_MULTU,
293 OPC_VR54XX_MSAC = (0x07 << 6) | OPC_MULT,
294 OPC_VR54XX_MSACU = (0x07 << 6) | OPC_MULTU,
295 OPC_VR54XX_MULHI = (0x09 << 6) | OPC_MULT,
296 OPC_VR54XX_MULHIU = (0x09 << 6) | OPC_MULTU,
297 OPC_VR54XX_MULSHI = (0x0B << 6) | OPC_MULT,
298 OPC_VR54XX_MULSHIU = (0x0B << 6) | OPC_MULTU,
299 OPC_VR54XX_MACCHI = (0x0D << 6) | OPC_MULT,
300 OPC_VR54XX_MACCHIU = (0x0D << 6) | OPC_MULTU,
301 OPC_VR54XX_MSACHI = (0x0F << 6) | OPC_MULT,
302 OPC_VR54XX_MSACHIU = (0x0F << 6) | OPC_MULTU,
305 /* REGIMM (rt field) opcodes */
306 #define MASK_REGIMM(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 16)))
308 enum {
309 OPC_BLTZ = (0x00 << 16) | OPC_REGIMM,
310 OPC_BLTZL = (0x02 << 16) | OPC_REGIMM,
311 OPC_BGEZ = (0x01 << 16) | OPC_REGIMM,
312 OPC_BGEZL = (0x03 << 16) | OPC_REGIMM,
313 OPC_BLTZAL = (0x10 << 16) | OPC_REGIMM,
314 OPC_BLTZALL = (0x12 << 16) | OPC_REGIMM,
315 OPC_BGEZAL = (0x11 << 16) | OPC_REGIMM,
316 OPC_BGEZALL = (0x13 << 16) | OPC_REGIMM,
317 OPC_TGEI = (0x08 << 16) | OPC_REGIMM,
318 OPC_TGEIU = (0x09 << 16) | OPC_REGIMM,
319 OPC_TLTI = (0x0A << 16) | OPC_REGIMM,
320 OPC_TLTIU = (0x0B << 16) | OPC_REGIMM,
321 OPC_TEQI = (0x0C << 16) | OPC_REGIMM,
322 OPC_TNEI = (0x0E << 16) | OPC_REGIMM,
323 OPC_SIGRIE = (0x17 << 16) | OPC_REGIMM,
324 OPC_SYNCI = (0x1F << 16) | OPC_REGIMM,
326 OPC_DAHI = (0x06 << 16) | OPC_REGIMM,
327 OPC_DATI = (0x1e << 16) | OPC_REGIMM,
330 /* Special2 opcodes */
331 #define MASK_SPECIAL2(op) (MASK_OP_MAJOR(op) | (op & 0x3F))
333 enum {
334 /* Multiply & xxx operations */
335 OPC_MADD = 0x00 | OPC_SPECIAL2,
336 OPC_MADDU = 0x01 | OPC_SPECIAL2,
337 OPC_MUL = 0x02 | OPC_SPECIAL2,
338 OPC_MSUB = 0x04 | OPC_SPECIAL2,
339 OPC_MSUBU = 0x05 | OPC_SPECIAL2,
340 /* Loongson 2F */
341 OPC_MULT_G_2F = 0x10 | OPC_SPECIAL2,
342 OPC_DMULT_G_2F = 0x11 | OPC_SPECIAL2,
343 OPC_MULTU_G_2F = 0x12 | OPC_SPECIAL2,
344 OPC_DMULTU_G_2F = 0x13 | OPC_SPECIAL2,
345 OPC_DIV_G_2F = 0x14 | OPC_SPECIAL2,
346 OPC_DDIV_G_2F = 0x15 | OPC_SPECIAL2,
347 OPC_DIVU_G_2F = 0x16 | OPC_SPECIAL2,
348 OPC_DDIVU_G_2F = 0x17 | OPC_SPECIAL2,
349 OPC_MOD_G_2F = 0x1c | OPC_SPECIAL2,
350 OPC_DMOD_G_2F = 0x1d | OPC_SPECIAL2,
351 OPC_MODU_G_2F = 0x1e | OPC_SPECIAL2,
352 OPC_DMODU_G_2F = 0x1f | OPC_SPECIAL2,
353 /* Misc */
354 OPC_CLZ = 0x20 | OPC_SPECIAL2,
355 OPC_CLO = 0x21 | OPC_SPECIAL2,
356 OPC_DCLZ = 0x24 | OPC_SPECIAL2,
357 OPC_DCLO = 0x25 | OPC_SPECIAL2,
358 /* Special */
359 OPC_SDBBP = 0x3F | OPC_SPECIAL2,
362 /* Special3 opcodes */
363 #define MASK_SPECIAL3(op) (MASK_OP_MAJOR(op) | (op & 0x3F))
365 enum {
366 OPC_EXT = 0x00 | OPC_SPECIAL3,
367 OPC_DEXTM = 0x01 | OPC_SPECIAL3,
368 OPC_DEXTU = 0x02 | OPC_SPECIAL3,
369 OPC_DEXT = 0x03 | OPC_SPECIAL3,
370 OPC_INS = 0x04 | OPC_SPECIAL3,
371 OPC_DINSM = 0x05 | OPC_SPECIAL3,
372 OPC_DINSU = 0x06 | OPC_SPECIAL3,
373 OPC_DINS = 0x07 | OPC_SPECIAL3,
374 OPC_FORK = 0x08 | OPC_SPECIAL3,
375 OPC_YIELD = 0x09 | OPC_SPECIAL3,
376 OPC_BSHFL = 0x20 | OPC_SPECIAL3,
377 OPC_DBSHFL = 0x24 | OPC_SPECIAL3,
378 OPC_RDHWR = 0x3B | OPC_SPECIAL3,
379 OPC_GINV = 0x3D | OPC_SPECIAL3,
381 /* Loongson 2E */
382 OPC_MULT_G_2E = 0x18 | OPC_SPECIAL3,
383 OPC_MULTU_G_2E = 0x19 | OPC_SPECIAL3,
384 OPC_DIV_G_2E = 0x1A | OPC_SPECIAL3,
385 OPC_DIVU_G_2E = 0x1B | OPC_SPECIAL3,
386 OPC_DMULT_G_2E = 0x1C | OPC_SPECIAL3,
387 OPC_DMULTU_G_2E = 0x1D | OPC_SPECIAL3,
388 OPC_DDIV_G_2E = 0x1E | OPC_SPECIAL3,
389 OPC_DDIVU_G_2E = 0x1F | OPC_SPECIAL3,
390 OPC_MOD_G_2E = 0x22 | OPC_SPECIAL3,
391 OPC_MODU_G_2E = 0x23 | OPC_SPECIAL3,
392 OPC_DMOD_G_2E = 0x26 | OPC_SPECIAL3,
393 OPC_DMODU_G_2E = 0x27 | OPC_SPECIAL3,
395 /* MIPS DSP Load */
396 OPC_LX_DSP = 0x0A | OPC_SPECIAL3,
397 /* MIPS DSP Arithmetic */
398 OPC_ADDU_QB_DSP = 0x10 | OPC_SPECIAL3,
399 OPC_ADDU_OB_DSP = 0x14 | OPC_SPECIAL3,
400 OPC_ABSQ_S_PH_DSP = 0x12 | OPC_SPECIAL3,
401 OPC_ABSQ_S_QH_DSP = 0x16 | OPC_SPECIAL3,
402 /* OPC_ADDUH_QB_DSP is same as OPC_MULT_G_2E. */
403 /* OPC_ADDUH_QB_DSP = 0x18 | OPC_SPECIAL3, */
404 OPC_CMPU_EQ_QB_DSP = 0x11 | OPC_SPECIAL3,
405 OPC_CMPU_EQ_OB_DSP = 0x15 | OPC_SPECIAL3,
406 /* MIPS DSP GPR-Based Shift Sub-class */
407 OPC_SHLL_QB_DSP = 0x13 | OPC_SPECIAL3,
408 OPC_SHLL_OB_DSP = 0x17 | OPC_SPECIAL3,
409 /* MIPS DSP Multiply Sub-class insns */
410 /* OPC_MUL_PH_DSP is same as OPC_ADDUH_QB_DSP. */
411 /* OPC_MUL_PH_DSP = 0x18 | OPC_SPECIAL3, */
412 OPC_DPA_W_PH_DSP = 0x30 | OPC_SPECIAL3,
413 OPC_DPAQ_W_QH_DSP = 0x34 | OPC_SPECIAL3,
414 /* DSP Bit/Manipulation Sub-class */
415 OPC_INSV_DSP = 0x0C | OPC_SPECIAL3,
416 OPC_DINSV_DSP = 0x0D | OPC_SPECIAL3,
417 /* MIPS DSP Append Sub-class */
418 OPC_APPEND_DSP = 0x31 | OPC_SPECIAL3,
419 OPC_DAPPEND_DSP = 0x35 | OPC_SPECIAL3,
420 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
421 OPC_EXTR_W_DSP = 0x38 | OPC_SPECIAL3,
422 OPC_DEXTR_W_DSP = 0x3C | OPC_SPECIAL3,
424 /* EVA */
425 OPC_LWLE = 0x19 | OPC_SPECIAL3,
426 OPC_LWRE = 0x1A | OPC_SPECIAL3,
427 OPC_CACHEE = 0x1B | OPC_SPECIAL3,
428 OPC_SBE = 0x1C | OPC_SPECIAL3,
429 OPC_SHE = 0x1D | OPC_SPECIAL3,
430 OPC_SCE = 0x1E | OPC_SPECIAL3,
431 OPC_SWE = 0x1F | OPC_SPECIAL3,
432 OPC_SWLE = 0x21 | OPC_SPECIAL3,
433 OPC_SWRE = 0x22 | OPC_SPECIAL3,
434 OPC_PREFE = 0x23 | OPC_SPECIAL3,
435 OPC_LBUE = 0x28 | OPC_SPECIAL3,
436 OPC_LHUE = 0x29 | OPC_SPECIAL3,
437 OPC_LBE = 0x2C | OPC_SPECIAL3,
438 OPC_LHE = 0x2D | OPC_SPECIAL3,
439 OPC_LLE = 0x2E | OPC_SPECIAL3,
440 OPC_LWE = 0x2F | OPC_SPECIAL3,
442 /* R6 */
443 R6_OPC_PREF = 0x35 | OPC_SPECIAL3,
444 R6_OPC_CACHE = 0x25 | OPC_SPECIAL3,
445 R6_OPC_LL = 0x36 | OPC_SPECIAL3,
446 R6_OPC_SC = 0x26 | OPC_SPECIAL3,
447 R6_OPC_LLD = 0x37 | OPC_SPECIAL3,
448 R6_OPC_SCD = 0x27 | OPC_SPECIAL3,
451 /* Loongson EXT load/store quad word opcodes */
452 #define MASK_LOONGSON_GSLSQ(op) (MASK_OP_MAJOR(op) | (op & 0x8020))
453 enum {
454 OPC_GSLQ = 0x0020 | OPC_LWC2,
455 OPC_GSLQC1 = 0x8020 | OPC_LWC2,
456 OPC_GSSHFL = OPC_LWC2,
457 OPC_GSSQ = 0x0020 | OPC_SWC2,
458 OPC_GSSQC1 = 0x8020 | OPC_SWC2,
459 OPC_GSSHFS = OPC_SWC2,
462 /* Loongson EXT shifted load/store opcodes */
463 #define MASK_LOONGSON_GSSHFLS(op) (MASK_OP_MAJOR(op) | (op & 0xc03f))
464 enum {
465 OPC_GSLWLC1 = 0x4 | OPC_GSSHFL,
466 OPC_GSLWRC1 = 0x5 | OPC_GSSHFL,
467 OPC_GSLDLC1 = 0x6 | OPC_GSSHFL,
468 OPC_GSLDRC1 = 0x7 | OPC_GSSHFL,
469 OPC_GSSWLC1 = 0x4 | OPC_GSSHFS,
470 OPC_GSSWRC1 = 0x5 | OPC_GSSHFS,
471 OPC_GSSDLC1 = 0x6 | OPC_GSSHFS,
472 OPC_GSSDRC1 = 0x7 | OPC_GSSHFS,
475 /* Loongson EXT LDC2/SDC2 opcodes */
476 #define MASK_LOONGSON_LSDC2(op) (MASK_OP_MAJOR(op) | (op & 0x7))
478 enum {
479 OPC_GSLBX = 0x0 | OPC_LDC2,
480 OPC_GSLHX = 0x1 | OPC_LDC2,
481 OPC_GSLWX = 0x2 | OPC_LDC2,
482 OPC_GSLDX = 0x3 | OPC_LDC2,
483 OPC_GSLWXC1 = 0x6 | OPC_LDC2,
484 OPC_GSLDXC1 = 0x7 | OPC_LDC2,
485 OPC_GSSBX = 0x0 | OPC_SDC2,
486 OPC_GSSHX = 0x1 | OPC_SDC2,
487 OPC_GSSWX = 0x2 | OPC_SDC2,
488 OPC_GSSDX = 0x3 | OPC_SDC2,
489 OPC_GSSWXC1 = 0x6 | OPC_SDC2,
490 OPC_GSSDXC1 = 0x7 | OPC_SDC2,
493 /* BSHFL opcodes */
494 #define MASK_BSHFL(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
496 enum {
497 OPC_WSBH = (0x02 << 6) | OPC_BSHFL,
498 OPC_SEB = (0x10 << 6) | OPC_BSHFL,
499 OPC_SEH = (0x18 << 6) | OPC_BSHFL,
500 OPC_ALIGN = (0x08 << 6) | OPC_BSHFL, /* 010.bp (010.00 to 010.11) */
501 OPC_ALIGN_1 = (0x09 << 6) | OPC_BSHFL,
502 OPC_ALIGN_2 = (0x0A << 6) | OPC_BSHFL,
503 OPC_ALIGN_3 = (0x0B << 6) | OPC_BSHFL,
504 OPC_BITSWAP = (0x00 << 6) | OPC_BSHFL /* 00000 */
507 /* DBSHFL opcodes */
508 #define MASK_DBSHFL(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
510 enum {
511 OPC_DSBH = (0x02 << 6) | OPC_DBSHFL,
512 OPC_DSHD = (0x05 << 6) | OPC_DBSHFL,
513 OPC_DALIGN = (0x08 << 6) | OPC_DBSHFL, /* 01.bp (01.000 to 01.111) */
514 OPC_DALIGN_1 = (0x09 << 6) | OPC_DBSHFL,
515 OPC_DALIGN_2 = (0x0A << 6) | OPC_DBSHFL,
516 OPC_DALIGN_3 = (0x0B << 6) | OPC_DBSHFL,
517 OPC_DALIGN_4 = (0x0C << 6) | OPC_DBSHFL,
518 OPC_DALIGN_5 = (0x0D << 6) | OPC_DBSHFL,
519 OPC_DALIGN_6 = (0x0E << 6) | OPC_DBSHFL,
520 OPC_DALIGN_7 = (0x0F << 6) | OPC_DBSHFL,
521 OPC_DBITSWAP = (0x00 << 6) | OPC_DBSHFL, /* 00000 */
524 /* MIPS DSP REGIMM opcodes */
525 enum {
526 OPC_BPOSGE32 = (0x1C << 16) | OPC_REGIMM,
527 OPC_BPOSGE64 = (0x1D << 16) | OPC_REGIMM,
530 #define MASK_LX(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
531 /* MIPS DSP Load */
532 enum {
533 OPC_LBUX = (0x06 << 6) | OPC_LX_DSP,
534 OPC_LHX = (0x04 << 6) | OPC_LX_DSP,
535 OPC_LWX = (0x00 << 6) | OPC_LX_DSP,
536 OPC_LDX = (0x08 << 6) | OPC_LX_DSP,
539 #define MASK_ADDU_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
540 enum {
541 /* MIPS DSP Arithmetic Sub-class */
542 OPC_ADDQ_PH = (0x0A << 6) | OPC_ADDU_QB_DSP,
543 OPC_ADDQ_S_PH = (0x0E << 6) | OPC_ADDU_QB_DSP,
544 OPC_ADDQ_S_W = (0x16 << 6) | OPC_ADDU_QB_DSP,
545 OPC_ADDU_QB = (0x00 << 6) | OPC_ADDU_QB_DSP,
546 OPC_ADDU_S_QB = (0x04 << 6) | OPC_ADDU_QB_DSP,
547 OPC_ADDU_PH = (0x08 << 6) | OPC_ADDU_QB_DSP,
548 OPC_ADDU_S_PH = (0x0C << 6) | OPC_ADDU_QB_DSP,
549 OPC_SUBQ_PH = (0x0B << 6) | OPC_ADDU_QB_DSP,
550 OPC_SUBQ_S_PH = (0x0F << 6) | OPC_ADDU_QB_DSP,
551 OPC_SUBQ_S_W = (0x17 << 6) | OPC_ADDU_QB_DSP,
552 OPC_SUBU_QB = (0x01 << 6) | OPC_ADDU_QB_DSP,
553 OPC_SUBU_S_QB = (0x05 << 6) | OPC_ADDU_QB_DSP,
554 OPC_SUBU_PH = (0x09 << 6) | OPC_ADDU_QB_DSP,
555 OPC_SUBU_S_PH = (0x0D << 6) | OPC_ADDU_QB_DSP,
556 OPC_ADDSC = (0x10 << 6) | OPC_ADDU_QB_DSP,
557 OPC_ADDWC = (0x11 << 6) | OPC_ADDU_QB_DSP,
558 OPC_MODSUB = (0x12 << 6) | OPC_ADDU_QB_DSP,
559 OPC_RADDU_W_QB = (0x14 << 6) | OPC_ADDU_QB_DSP,
560 /* MIPS DSP Multiply Sub-class insns */
561 OPC_MULEU_S_PH_QBL = (0x06 << 6) | OPC_ADDU_QB_DSP,
562 OPC_MULEU_S_PH_QBR = (0x07 << 6) | OPC_ADDU_QB_DSP,
563 OPC_MULQ_RS_PH = (0x1F << 6) | OPC_ADDU_QB_DSP,
564 OPC_MULEQ_S_W_PHL = (0x1C << 6) | OPC_ADDU_QB_DSP,
565 OPC_MULEQ_S_W_PHR = (0x1D << 6) | OPC_ADDU_QB_DSP,
566 OPC_MULQ_S_PH = (0x1E << 6) | OPC_ADDU_QB_DSP,
569 #define OPC_ADDUH_QB_DSP OPC_MULT_G_2E
570 #define MASK_ADDUH_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
571 enum {
572 /* MIPS DSP Arithmetic Sub-class */
573 OPC_ADDUH_QB = (0x00 << 6) | OPC_ADDUH_QB_DSP,
574 OPC_ADDUH_R_QB = (0x02 << 6) | OPC_ADDUH_QB_DSP,
575 OPC_ADDQH_PH = (0x08 << 6) | OPC_ADDUH_QB_DSP,
576 OPC_ADDQH_R_PH = (0x0A << 6) | OPC_ADDUH_QB_DSP,
577 OPC_ADDQH_W = (0x10 << 6) | OPC_ADDUH_QB_DSP,
578 OPC_ADDQH_R_W = (0x12 << 6) | OPC_ADDUH_QB_DSP,
579 OPC_SUBUH_QB = (0x01 << 6) | OPC_ADDUH_QB_DSP,
580 OPC_SUBUH_R_QB = (0x03 << 6) | OPC_ADDUH_QB_DSP,
581 OPC_SUBQH_PH = (0x09 << 6) | OPC_ADDUH_QB_DSP,
582 OPC_SUBQH_R_PH = (0x0B << 6) | OPC_ADDUH_QB_DSP,
583 OPC_SUBQH_W = (0x11 << 6) | OPC_ADDUH_QB_DSP,
584 OPC_SUBQH_R_W = (0x13 << 6) | OPC_ADDUH_QB_DSP,
585 /* MIPS DSP Multiply Sub-class insns */
586 OPC_MUL_PH = (0x0C << 6) | OPC_ADDUH_QB_DSP,
587 OPC_MUL_S_PH = (0x0E << 6) | OPC_ADDUH_QB_DSP,
588 OPC_MULQ_S_W = (0x16 << 6) | OPC_ADDUH_QB_DSP,
589 OPC_MULQ_RS_W = (0x17 << 6) | OPC_ADDUH_QB_DSP,
592 #define MASK_ABSQ_S_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
593 enum {
594 /* MIPS DSP Arithmetic Sub-class */
595 OPC_ABSQ_S_QB = (0x01 << 6) | OPC_ABSQ_S_PH_DSP,
596 OPC_ABSQ_S_PH = (0x09 << 6) | OPC_ABSQ_S_PH_DSP,
597 OPC_ABSQ_S_W = (0x11 << 6) | OPC_ABSQ_S_PH_DSP,
598 OPC_PRECEQ_W_PHL = (0x0C << 6) | OPC_ABSQ_S_PH_DSP,
599 OPC_PRECEQ_W_PHR = (0x0D << 6) | OPC_ABSQ_S_PH_DSP,
600 OPC_PRECEQU_PH_QBL = (0x04 << 6) | OPC_ABSQ_S_PH_DSP,
601 OPC_PRECEQU_PH_QBR = (0x05 << 6) | OPC_ABSQ_S_PH_DSP,
602 OPC_PRECEQU_PH_QBLA = (0x06 << 6) | OPC_ABSQ_S_PH_DSP,
603 OPC_PRECEQU_PH_QBRA = (0x07 << 6) | OPC_ABSQ_S_PH_DSP,
604 OPC_PRECEU_PH_QBL = (0x1C << 6) | OPC_ABSQ_S_PH_DSP,
605 OPC_PRECEU_PH_QBR = (0x1D << 6) | OPC_ABSQ_S_PH_DSP,
606 OPC_PRECEU_PH_QBLA = (0x1E << 6) | OPC_ABSQ_S_PH_DSP,
607 OPC_PRECEU_PH_QBRA = (0x1F << 6) | OPC_ABSQ_S_PH_DSP,
608 /* DSP Bit/Manipulation Sub-class */
609 OPC_BITREV = (0x1B << 6) | OPC_ABSQ_S_PH_DSP,
610 OPC_REPL_QB = (0x02 << 6) | OPC_ABSQ_S_PH_DSP,
611 OPC_REPLV_QB = (0x03 << 6) | OPC_ABSQ_S_PH_DSP,
612 OPC_REPL_PH = (0x0A << 6) | OPC_ABSQ_S_PH_DSP,
613 OPC_REPLV_PH = (0x0B << 6) | OPC_ABSQ_S_PH_DSP,
616 #define MASK_CMPU_EQ_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
617 enum {
618 /* MIPS DSP Arithmetic Sub-class */
619 OPC_PRECR_QB_PH = (0x0D << 6) | OPC_CMPU_EQ_QB_DSP,
620 OPC_PRECRQ_QB_PH = (0x0C << 6) | OPC_CMPU_EQ_QB_DSP,
621 OPC_PRECR_SRA_PH_W = (0x1E << 6) | OPC_CMPU_EQ_QB_DSP,
622 OPC_PRECR_SRA_R_PH_W = (0x1F << 6) | OPC_CMPU_EQ_QB_DSP,
623 OPC_PRECRQ_PH_W = (0x14 << 6) | OPC_CMPU_EQ_QB_DSP,
624 OPC_PRECRQ_RS_PH_W = (0x15 << 6) | OPC_CMPU_EQ_QB_DSP,
625 OPC_PRECRQU_S_QB_PH = (0x0F << 6) | OPC_CMPU_EQ_QB_DSP,
626 /* DSP Compare-Pick Sub-class */
627 OPC_CMPU_EQ_QB = (0x00 << 6) | OPC_CMPU_EQ_QB_DSP,
628 OPC_CMPU_LT_QB = (0x01 << 6) | OPC_CMPU_EQ_QB_DSP,
629 OPC_CMPU_LE_QB = (0x02 << 6) | OPC_CMPU_EQ_QB_DSP,
630 OPC_CMPGU_EQ_QB = (0x04 << 6) | OPC_CMPU_EQ_QB_DSP,
631 OPC_CMPGU_LT_QB = (0x05 << 6) | OPC_CMPU_EQ_QB_DSP,
632 OPC_CMPGU_LE_QB = (0x06 << 6) | OPC_CMPU_EQ_QB_DSP,
633 OPC_CMPGDU_EQ_QB = (0x18 << 6) | OPC_CMPU_EQ_QB_DSP,
634 OPC_CMPGDU_LT_QB = (0x19 << 6) | OPC_CMPU_EQ_QB_DSP,
635 OPC_CMPGDU_LE_QB = (0x1A << 6) | OPC_CMPU_EQ_QB_DSP,
636 OPC_CMP_EQ_PH = (0x08 << 6) | OPC_CMPU_EQ_QB_DSP,
637 OPC_CMP_LT_PH = (0x09 << 6) | OPC_CMPU_EQ_QB_DSP,
638 OPC_CMP_LE_PH = (0x0A << 6) | OPC_CMPU_EQ_QB_DSP,
639 OPC_PICK_QB = (0x03 << 6) | OPC_CMPU_EQ_QB_DSP,
640 OPC_PICK_PH = (0x0B << 6) | OPC_CMPU_EQ_QB_DSP,
641 OPC_PACKRL_PH = (0x0E << 6) | OPC_CMPU_EQ_QB_DSP,
644 #define MASK_SHLL_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
645 enum {
646 /* MIPS DSP GPR-Based Shift Sub-class */
647 OPC_SHLL_QB = (0x00 << 6) | OPC_SHLL_QB_DSP,
648 OPC_SHLLV_QB = (0x02 << 6) | OPC_SHLL_QB_DSP,
649 OPC_SHLL_PH = (0x08 << 6) | OPC_SHLL_QB_DSP,
650 OPC_SHLLV_PH = (0x0A << 6) | OPC_SHLL_QB_DSP,
651 OPC_SHLL_S_PH = (0x0C << 6) | OPC_SHLL_QB_DSP,
652 OPC_SHLLV_S_PH = (0x0E << 6) | OPC_SHLL_QB_DSP,
653 OPC_SHLL_S_W = (0x14 << 6) | OPC_SHLL_QB_DSP,
654 OPC_SHLLV_S_W = (0x16 << 6) | OPC_SHLL_QB_DSP,
655 OPC_SHRL_QB = (0x01 << 6) | OPC_SHLL_QB_DSP,
656 OPC_SHRLV_QB = (0x03 << 6) | OPC_SHLL_QB_DSP,
657 OPC_SHRL_PH = (0x19 << 6) | OPC_SHLL_QB_DSP,
658 OPC_SHRLV_PH = (0x1B << 6) | OPC_SHLL_QB_DSP,
659 OPC_SHRA_QB = (0x04 << 6) | OPC_SHLL_QB_DSP,
660 OPC_SHRA_R_QB = (0x05 << 6) | OPC_SHLL_QB_DSP,
661 OPC_SHRAV_QB = (0x06 << 6) | OPC_SHLL_QB_DSP,
662 OPC_SHRAV_R_QB = (0x07 << 6) | OPC_SHLL_QB_DSP,
663 OPC_SHRA_PH = (0x09 << 6) | OPC_SHLL_QB_DSP,
664 OPC_SHRAV_PH = (0x0B << 6) | OPC_SHLL_QB_DSP,
665 OPC_SHRA_R_PH = (0x0D << 6) | OPC_SHLL_QB_DSP,
666 OPC_SHRAV_R_PH = (0x0F << 6) | OPC_SHLL_QB_DSP,
667 OPC_SHRA_R_W = (0x15 << 6) | OPC_SHLL_QB_DSP,
668 OPC_SHRAV_R_W = (0x17 << 6) | OPC_SHLL_QB_DSP,
671 #define MASK_DPA_W_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
672 enum {
673 /* MIPS DSP Multiply Sub-class insns */
674 OPC_DPAU_H_QBL = (0x03 << 6) | OPC_DPA_W_PH_DSP,
675 OPC_DPAU_H_QBR = (0x07 << 6) | OPC_DPA_W_PH_DSP,
676 OPC_DPSU_H_QBL = (0x0B << 6) | OPC_DPA_W_PH_DSP,
677 OPC_DPSU_H_QBR = (0x0F << 6) | OPC_DPA_W_PH_DSP,
678 OPC_DPA_W_PH = (0x00 << 6) | OPC_DPA_W_PH_DSP,
679 OPC_DPAX_W_PH = (0x08 << 6) | OPC_DPA_W_PH_DSP,
680 OPC_DPAQ_S_W_PH = (0x04 << 6) | OPC_DPA_W_PH_DSP,
681 OPC_DPAQX_S_W_PH = (0x18 << 6) | OPC_DPA_W_PH_DSP,
682 OPC_DPAQX_SA_W_PH = (0x1A << 6) | OPC_DPA_W_PH_DSP,
683 OPC_DPS_W_PH = (0x01 << 6) | OPC_DPA_W_PH_DSP,
684 OPC_DPSX_W_PH = (0x09 << 6) | OPC_DPA_W_PH_DSP,
685 OPC_DPSQ_S_W_PH = (0x05 << 6) | OPC_DPA_W_PH_DSP,
686 OPC_DPSQX_S_W_PH = (0x19 << 6) | OPC_DPA_W_PH_DSP,
687 OPC_DPSQX_SA_W_PH = (0x1B << 6) | OPC_DPA_W_PH_DSP,
688 OPC_MULSAQ_S_W_PH = (0x06 << 6) | OPC_DPA_W_PH_DSP,
689 OPC_DPAQ_SA_L_W = (0x0C << 6) | OPC_DPA_W_PH_DSP,
690 OPC_DPSQ_SA_L_W = (0x0D << 6) | OPC_DPA_W_PH_DSP,
691 OPC_MAQ_S_W_PHL = (0x14 << 6) | OPC_DPA_W_PH_DSP,
692 OPC_MAQ_S_W_PHR = (0x16 << 6) | OPC_DPA_W_PH_DSP,
693 OPC_MAQ_SA_W_PHL = (0x10 << 6) | OPC_DPA_W_PH_DSP,
694 OPC_MAQ_SA_W_PHR = (0x12 << 6) | OPC_DPA_W_PH_DSP,
695 OPC_MULSA_W_PH = (0x02 << 6) | OPC_DPA_W_PH_DSP,
698 #define MASK_INSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
699 enum {
700 /* DSP Bit/Manipulation Sub-class */
701 OPC_INSV = (0x00 << 6) | OPC_INSV_DSP,
704 #define MASK_APPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
705 enum {
706 /* MIPS DSP Append Sub-class */
707 OPC_APPEND = (0x00 << 6) | OPC_APPEND_DSP,
708 OPC_PREPEND = (0x01 << 6) | OPC_APPEND_DSP,
709 OPC_BALIGN = (0x10 << 6) | OPC_APPEND_DSP,
712 #define MASK_EXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
713 enum {
714 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
715 OPC_EXTR_W = (0x00 << 6) | OPC_EXTR_W_DSP,
716 OPC_EXTR_R_W = (0x04 << 6) | OPC_EXTR_W_DSP,
717 OPC_EXTR_RS_W = (0x06 << 6) | OPC_EXTR_W_DSP,
718 OPC_EXTR_S_H = (0x0E << 6) | OPC_EXTR_W_DSP,
719 OPC_EXTRV_S_H = (0x0F << 6) | OPC_EXTR_W_DSP,
720 OPC_EXTRV_W = (0x01 << 6) | OPC_EXTR_W_DSP,
721 OPC_EXTRV_R_W = (0x05 << 6) | OPC_EXTR_W_DSP,
722 OPC_EXTRV_RS_W = (0x07 << 6) | OPC_EXTR_W_DSP,
723 OPC_EXTP = (0x02 << 6) | OPC_EXTR_W_DSP,
724 OPC_EXTPV = (0x03 << 6) | OPC_EXTR_W_DSP,
725 OPC_EXTPDP = (0x0A << 6) | OPC_EXTR_W_DSP,
726 OPC_EXTPDPV = (0x0B << 6) | OPC_EXTR_W_DSP,
727 OPC_SHILO = (0x1A << 6) | OPC_EXTR_W_DSP,
728 OPC_SHILOV = (0x1B << 6) | OPC_EXTR_W_DSP,
729 OPC_MTHLIP = (0x1F << 6) | OPC_EXTR_W_DSP,
730 OPC_WRDSP = (0x13 << 6) | OPC_EXTR_W_DSP,
731 OPC_RDDSP = (0x12 << 6) | OPC_EXTR_W_DSP,
734 #define MASK_ABSQ_S_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
735 enum {
736 /* MIPS DSP Arithmetic Sub-class */
737 OPC_PRECEQ_L_PWL = (0x14 << 6) | OPC_ABSQ_S_QH_DSP,
738 OPC_PRECEQ_L_PWR = (0x15 << 6) | OPC_ABSQ_S_QH_DSP,
739 OPC_PRECEQ_PW_QHL = (0x0C << 6) | OPC_ABSQ_S_QH_DSP,
740 OPC_PRECEQ_PW_QHR = (0x0D << 6) | OPC_ABSQ_S_QH_DSP,
741 OPC_PRECEQ_PW_QHLA = (0x0E << 6) | OPC_ABSQ_S_QH_DSP,
742 OPC_PRECEQ_PW_QHRA = (0x0F << 6) | OPC_ABSQ_S_QH_DSP,
743 OPC_PRECEQU_QH_OBL = (0x04 << 6) | OPC_ABSQ_S_QH_DSP,
744 OPC_PRECEQU_QH_OBR = (0x05 << 6) | OPC_ABSQ_S_QH_DSP,
745 OPC_PRECEQU_QH_OBLA = (0x06 << 6) | OPC_ABSQ_S_QH_DSP,
746 OPC_PRECEQU_QH_OBRA = (0x07 << 6) | OPC_ABSQ_S_QH_DSP,
747 OPC_PRECEU_QH_OBL = (0x1C << 6) | OPC_ABSQ_S_QH_DSP,
748 OPC_PRECEU_QH_OBR = (0x1D << 6) | OPC_ABSQ_S_QH_DSP,
749 OPC_PRECEU_QH_OBLA = (0x1E << 6) | OPC_ABSQ_S_QH_DSP,
750 OPC_PRECEU_QH_OBRA = (0x1F << 6) | OPC_ABSQ_S_QH_DSP,
751 OPC_ABSQ_S_OB = (0x01 << 6) | OPC_ABSQ_S_QH_DSP,
752 OPC_ABSQ_S_PW = (0x11 << 6) | OPC_ABSQ_S_QH_DSP,
753 OPC_ABSQ_S_QH = (0x09 << 6) | OPC_ABSQ_S_QH_DSP,
754 /* DSP Bit/Manipulation Sub-class */
755 OPC_REPL_OB = (0x02 << 6) | OPC_ABSQ_S_QH_DSP,
756 OPC_REPL_PW = (0x12 << 6) | OPC_ABSQ_S_QH_DSP,
757 OPC_REPL_QH = (0x0A << 6) | OPC_ABSQ_S_QH_DSP,
758 OPC_REPLV_OB = (0x03 << 6) | OPC_ABSQ_S_QH_DSP,
759 OPC_REPLV_PW = (0x13 << 6) | OPC_ABSQ_S_QH_DSP,
760 OPC_REPLV_QH = (0x0B << 6) | OPC_ABSQ_S_QH_DSP,
763 #define MASK_ADDU_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
764 enum {
765 /* MIPS DSP Multiply Sub-class insns */
766 OPC_MULEQ_S_PW_QHL = (0x1C << 6) | OPC_ADDU_OB_DSP,
767 OPC_MULEQ_S_PW_QHR = (0x1D << 6) | OPC_ADDU_OB_DSP,
768 OPC_MULEU_S_QH_OBL = (0x06 << 6) | OPC_ADDU_OB_DSP,
769 OPC_MULEU_S_QH_OBR = (0x07 << 6) | OPC_ADDU_OB_DSP,
770 OPC_MULQ_RS_QH = (0x1F << 6) | OPC_ADDU_OB_DSP,
771 /* MIPS DSP Arithmetic Sub-class */
772 OPC_RADDU_L_OB = (0x14 << 6) | OPC_ADDU_OB_DSP,
773 OPC_SUBQ_PW = (0x13 << 6) | OPC_ADDU_OB_DSP,
774 OPC_SUBQ_S_PW = (0x17 << 6) | OPC_ADDU_OB_DSP,
775 OPC_SUBQ_QH = (0x0B << 6) | OPC_ADDU_OB_DSP,
776 OPC_SUBQ_S_QH = (0x0F << 6) | OPC_ADDU_OB_DSP,
777 OPC_SUBU_OB = (0x01 << 6) | OPC_ADDU_OB_DSP,
778 OPC_SUBU_S_OB = (0x05 << 6) | OPC_ADDU_OB_DSP,
779 OPC_SUBU_QH = (0x09 << 6) | OPC_ADDU_OB_DSP,
780 OPC_SUBU_S_QH = (0x0D << 6) | OPC_ADDU_OB_DSP,
781 OPC_SUBUH_OB = (0x19 << 6) | OPC_ADDU_OB_DSP,
782 OPC_SUBUH_R_OB = (0x1B << 6) | OPC_ADDU_OB_DSP,
783 OPC_ADDQ_PW = (0x12 << 6) | OPC_ADDU_OB_DSP,
784 OPC_ADDQ_S_PW = (0x16 << 6) | OPC_ADDU_OB_DSP,
785 OPC_ADDQ_QH = (0x0A << 6) | OPC_ADDU_OB_DSP,
786 OPC_ADDQ_S_QH = (0x0E << 6) | OPC_ADDU_OB_DSP,
787 OPC_ADDU_OB = (0x00 << 6) | OPC_ADDU_OB_DSP,
788 OPC_ADDU_S_OB = (0x04 << 6) | OPC_ADDU_OB_DSP,
789 OPC_ADDU_QH = (0x08 << 6) | OPC_ADDU_OB_DSP,
790 OPC_ADDU_S_QH = (0x0C << 6) | OPC_ADDU_OB_DSP,
791 OPC_ADDUH_OB = (0x18 << 6) | OPC_ADDU_OB_DSP,
792 OPC_ADDUH_R_OB = (0x1A << 6) | OPC_ADDU_OB_DSP,
795 #define MASK_CMPU_EQ_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
796 enum {
797 /* DSP Compare-Pick Sub-class */
798 OPC_CMP_EQ_PW = (0x10 << 6) | OPC_CMPU_EQ_OB_DSP,
799 OPC_CMP_LT_PW = (0x11 << 6) | OPC_CMPU_EQ_OB_DSP,
800 OPC_CMP_LE_PW = (0x12 << 6) | OPC_CMPU_EQ_OB_DSP,
801 OPC_CMP_EQ_QH = (0x08 << 6) | OPC_CMPU_EQ_OB_DSP,
802 OPC_CMP_LT_QH = (0x09 << 6) | OPC_CMPU_EQ_OB_DSP,
803 OPC_CMP_LE_QH = (0x0A << 6) | OPC_CMPU_EQ_OB_DSP,
804 OPC_CMPGDU_EQ_OB = (0x18 << 6) | OPC_CMPU_EQ_OB_DSP,
805 OPC_CMPGDU_LT_OB = (0x19 << 6) | OPC_CMPU_EQ_OB_DSP,
806 OPC_CMPGDU_LE_OB = (0x1A << 6) | OPC_CMPU_EQ_OB_DSP,
807 OPC_CMPGU_EQ_OB = (0x04 << 6) | OPC_CMPU_EQ_OB_DSP,
808 OPC_CMPGU_LT_OB = (0x05 << 6) | OPC_CMPU_EQ_OB_DSP,
809 OPC_CMPGU_LE_OB = (0x06 << 6) | OPC_CMPU_EQ_OB_DSP,
810 OPC_CMPU_EQ_OB = (0x00 << 6) | OPC_CMPU_EQ_OB_DSP,
811 OPC_CMPU_LT_OB = (0x01 << 6) | OPC_CMPU_EQ_OB_DSP,
812 OPC_CMPU_LE_OB = (0x02 << 6) | OPC_CMPU_EQ_OB_DSP,
813 OPC_PACKRL_PW = (0x0E << 6) | OPC_CMPU_EQ_OB_DSP,
814 OPC_PICK_OB = (0x03 << 6) | OPC_CMPU_EQ_OB_DSP,
815 OPC_PICK_PW = (0x13 << 6) | OPC_CMPU_EQ_OB_DSP,
816 OPC_PICK_QH = (0x0B << 6) | OPC_CMPU_EQ_OB_DSP,
817 /* MIPS DSP Arithmetic Sub-class */
818 OPC_PRECR_OB_QH = (0x0D << 6) | OPC_CMPU_EQ_OB_DSP,
819 OPC_PRECR_SRA_QH_PW = (0x1E << 6) | OPC_CMPU_EQ_OB_DSP,
820 OPC_PRECR_SRA_R_QH_PW = (0x1F << 6) | OPC_CMPU_EQ_OB_DSP,
821 OPC_PRECRQ_OB_QH = (0x0C << 6) | OPC_CMPU_EQ_OB_DSP,
822 OPC_PRECRQ_PW_L = (0x1C << 6) | OPC_CMPU_EQ_OB_DSP,
823 OPC_PRECRQ_QH_PW = (0x14 << 6) | OPC_CMPU_EQ_OB_DSP,
824 OPC_PRECRQ_RS_QH_PW = (0x15 << 6) | OPC_CMPU_EQ_OB_DSP,
825 OPC_PRECRQU_S_OB_QH = (0x0F << 6) | OPC_CMPU_EQ_OB_DSP,
828 #define MASK_DAPPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
829 enum {
830 /* DSP Append Sub-class */
831 OPC_DAPPEND = (0x00 << 6) | OPC_DAPPEND_DSP,
832 OPC_PREPENDD = (0x03 << 6) | OPC_DAPPEND_DSP,
833 OPC_PREPENDW = (0x01 << 6) | OPC_DAPPEND_DSP,
834 OPC_DBALIGN = (0x10 << 6) | OPC_DAPPEND_DSP,
837 #define MASK_DEXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
838 enum {
839 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
840 OPC_DMTHLIP = (0x1F << 6) | OPC_DEXTR_W_DSP,
841 OPC_DSHILO = (0x1A << 6) | OPC_DEXTR_W_DSP,
842 OPC_DEXTP = (0x02 << 6) | OPC_DEXTR_W_DSP,
843 OPC_DEXTPDP = (0x0A << 6) | OPC_DEXTR_W_DSP,
844 OPC_DEXTPDPV = (0x0B << 6) | OPC_DEXTR_W_DSP,
845 OPC_DEXTPV = (0x03 << 6) | OPC_DEXTR_W_DSP,
846 OPC_DEXTR_L = (0x10 << 6) | OPC_DEXTR_W_DSP,
847 OPC_DEXTR_R_L = (0x14 << 6) | OPC_DEXTR_W_DSP,
848 OPC_DEXTR_RS_L = (0x16 << 6) | OPC_DEXTR_W_DSP,
849 OPC_DEXTR_W = (0x00 << 6) | OPC_DEXTR_W_DSP,
850 OPC_DEXTR_R_W = (0x04 << 6) | OPC_DEXTR_W_DSP,
851 OPC_DEXTR_RS_W = (0x06 << 6) | OPC_DEXTR_W_DSP,
852 OPC_DEXTR_S_H = (0x0E << 6) | OPC_DEXTR_W_DSP,
853 OPC_DEXTRV_L = (0x11 << 6) | OPC_DEXTR_W_DSP,
854 OPC_DEXTRV_R_L = (0x15 << 6) | OPC_DEXTR_W_DSP,
855 OPC_DEXTRV_RS_L = (0x17 << 6) | OPC_DEXTR_W_DSP,
856 OPC_DEXTRV_S_H = (0x0F << 6) | OPC_DEXTR_W_DSP,
857 OPC_DEXTRV_W = (0x01 << 6) | OPC_DEXTR_W_DSP,
858 OPC_DEXTRV_R_W = (0x05 << 6) | OPC_DEXTR_W_DSP,
859 OPC_DEXTRV_RS_W = (0x07 << 6) | OPC_DEXTR_W_DSP,
860 OPC_DSHILOV = (0x1B << 6) | OPC_DEXTR_W_DSP,
863 #define MASK_DINSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
864 enum {
865 /* DSP Bit/Manipulation Sub-class */
866 OPC_DINSV = (0x00 << 6) | OPC_DINSV_DSP,
869 #define MASK_DPAQ_W_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
870 enum {
871 /* MIPS DSP Multiply Sub-class insns */
872 OPC_DMADD = (0x19 << 6) | OPC_DPAQ_W_QH_DSP,
873 OPC_DMADDU = (0x1D << 6) | OPC_DPAQ_W_QH_DSP,
874 OPC_DMSUB = (0x1B << 6) | OPC_DPAQ_W_QH_DSP,
875 OPC_DMSUBU = (0x1F << 6) | OPC_DPAQ_W_QH_DSP,
876 OPC_DPA_W_QH = (0x00 << 6) | OPC_DPAQ_W_QH_DSP,
877 OPC_DPAQ_S_W_QH = (0x04 << 6) | OPC_DPAQ_W_QH_DSP,
878 OPC_DPAQ_SA_L_PW = (0x0C << 6) | OPC_DPAQ_W_QH_DSP,
879 OPC_DPAU_H_OBL = (0x03 << 6) | OPC_DPAQ_W_QH_DSP,
880 OPC_DPAU_H_OBR = (0x07 << 6) | OPC_DPAQ_W_QH_DSP,
881 OPC_DPS_W_QH = (0x01 << 6) | OPC_DPAQ_W_QH_DSP,
882 OPC_DPSQ_S_W_QH = (0x05 << 6) | OPC_DPAQ_W_QH_DSP,
883 OPC_DPSQ_SA_L_PW = (0x0D << 6) | OPC_DPAQ_W_QH_DSP,
884 OPC_DPSU_H_OBL = (0x0B << 6) | OPC_DPAQ_W_QH_DSP,
885 OPC_DPSU_H_OBR = (0x0F << 6) | OPC_DPAQ_W_QH_DSP,
886 OPC_MAQ_S_L_PWL = (0x1C << 6) | OPC_DPAQ_W_QH_DSP,
887 OPC_MAQ_S_L_PWR = (0x1E << 6) | OPC_DPAQ_W_QH_DSP,
888 OPC_MAQ_S_W_QHLL = (0x14 << 6) | OPC_DPAQ_W_QH_DSP,
889 OPC_MAQ_SA_W_QHLL = (0x10 << 6) | OPC_DPAQ_W_QH_DSP,
890 OPC_MAQ_S_W_QHLR = (0x15 << 6) | OPC_DPAQ_W_QH_DSP,
891 OPC_MAQ_SA_W_QHLR = (0x11 << 6) | OPC_DPAQ_W_QH_DSP,
892 OPC_MAQ_S_W_QHRL = (0x16 << 6) | OPC_DPAQ_W_QH_DSP,
893 OPC_MAQ_SA_W_QHRL = (0x12 << 6) | OPC_DPAQ_W_QH_DSP,
894 OPC_MAQ_S_W_QHRR = (0x17 << 6) | OPC_DPAQ_W_QH_DSP,
895 OPC_MAQ_SA_W_QHRR = (0x13 << 6) | OPC_DPAQ_W_QH_DSP,
896 OPC_MULSAQ_S_L_PW = (0x0E << 6) | OPC_DPAQ_W_QH_DSP,
897 OPC_MULSAQ_S_W_QH = (0x06 << 6) | OPC_DPAQ_W_QH_DSP,
900 #define MASK_SHLL_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
901 enum {
902 /* MIPS DSP GPR-Based Shift Sub-class */
903 OPC_SHLL_PW = (0x10 << 6) | OPC_SHLL_OB_DSP,
904 OPC_SHLL_S_PW = (0x14 << 6) | OPC_SHLL_OB_DSP,
905 OPC_SHLLV_OB = (0x02 << 6) | OPC_SHLL_OB_DSP,
906 OPC_SHLLV_PW = (0x12 << 6) | OPC_SHLL_OB_DSP,
907 OPC_SHLLV_S_PW = (0x16 << 6) | OPC_SHLL_OB_DSP,
908 OPC_SHLLV_QH = (0x0A << 6) | OPC_SHLL_OB_DSP,
909 OPC_SHLLV_S_QH = (0x0E << 6) | OPC_SHLL_OB_DSP,
910 OPC_SHRA_PW = (0x11 << 6) | OPC_SHLL_OB_DSP,
911 OPC_SHRA_R_PW = (0x15 << 6) | OPC_SHLL_OB_DSP,
912 OPC_SHRAV_OB = (0x06 << 6) | OPC_SHLL_OB_DSP,
913 OPC_SHRAV_R_OB = (0x07 << 6) | OPC_SHLL_OB_DSP,
914 OPC_SHRAV_PW = (0x13 << 6) | OPC_SHLL_OB_DSP,
915 OPC_SHRAV_R_PW = (0x17 << 6) | OPC_SHLL_OB_DSP,
916 OPC_SHRAV_QH = (0x0B << 6) | OPC_SHLL_OB_DSP,
917 OPC_SHRAV_R_QH = (0x0F << 6) | OPC_SHLL_OB_DSP,
918 OPC_SHRLV_OB = (0x03 << 6) | OPC_SHLL_OB_DSP,
919 OPC_SHRLV_QH = (0x1B << 6) | OPC_SHLL_OB_DSP,
920 OPC_SHLL_OB = (0x00 << 6) | OPC_SHLL_OB_DSP,
921 OPC_SHLL_QH = (0x08 << 6) | OPC_SHLL_OB_DSP,
922 OPC_SHLL_S_QH = (0x0C << 6) | OPC_SHLL_OB_DSP,
923 OPC_SHRA_OB = (0x04 << 6) | OPC_SHLL_OB_DSP,
924 OPC_SHRA_R_OB = (0x05 << 6) | OPC_SHLL_OB_DSP,
925 OPC_SHRA_QH = (0x09 << 6) | OPC_SHLL_OB_DSP,
926 OPC_SHRA_R_QH = (0x0D << 6) | OPC_SHLL_OB_DSP,
927 OPC_SHRL_OB = (0x01 << 6) | OPC_SHLL_OB_DSP,
928 OPC_SHRL_QH = (0x19 << 6) | OPC_SHLL_OB_DSP,
931 /* Coprocessor 0 (rs field) */
932 #define MASK_CP0(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)))
934 enum {
935 OPC_MFC0 = (0x00 << 21) | OPC_CP0,
936 OPC_DMFC0 = (0x01 << 21) | OPC_CP0,
937 OPC_MFHC0 = (0x02 << 21) | OPC_CP0,
938 OPC_MTC0 = (0x04 << 21) | OPC_CP0,
939 OPC_DMTC0 = (0x05 << 21) | OPC_CP0,
940 OPC_MTHC0 = (0x06 << 21) | OPC_CP0,
941 OPC_MFTR = (0x08 << 21) | OPC_CP0,
942 OPC_RDPGPR = (0x0A << 21) | OPC_CP0,
943 OPC_MFMC0 = (0x0B << 21) | OPC_CP0,
944 OPC_MTTR = (0x0C << 21) | OPC_CP0,
945 OPC_WRPGPR = (0x0E << 21) | OPC_CP0,
946 OPC_C0 = (0x10 << 21) | OPC_CP0,
947 OPC_C0_1 = (0x11 << 21) | OPC_CP0,
948 OPC_C0_2 = (0x12 << 21) | OPC_CP0,
949 OPC_C0_3 = (0x13 << 21) | OPC_CP0,
950 OPC_C0_4 = (0x14 << 21) | OPC_CP0,
951 OPC_C0_5 = (0x15 << 21) | OPC_CP0,
952 OPC_C0_6 = (0x16 << 21) | OPC_CP0,
953 OPC_C0_7 = (0x17 << 21) | OPC_CP0,
954 OPC_C0_8 = (0x18 << 21) | OPC_CP0,
955 OPC_C0_9 = (0x19 << 21) | OPC_CP0,
956 OPC_C0_A = (0x1A << 21) | OPC_CP0,
957 OPC_C0_B = (0x1B << 21) | OPC_CP0,
958 OPC_C0_C = (0x1C << 21) | OPC_CP0,
959 OPC_C0_D = (0x1D << 21) | OPC_CP0,
960 OPC_C0_E = (0x1E << 21) | OPC_CP0,
961 OPC_C0_F = (0x1F << 21) | OPC_CP0,
964 /* MFMC0 opcodes */
965 #define MASK_MFMC0(op) (MASK_CP0(op) | (op & 0xFFFF))
967 enum {
968 OPC_DMT = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
969 OPC_EMT = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
970 OPC_DVPE = 0x01 | (0 << 5) | OPC_MFMC0,
971 OPC_EVPE = 0x01 | (1 << 5) | OPC_MFMC0,
972 OPC_DI = (0 << 5) | (0x0C << 11) | OPC_MFMC0,
973 OPC_EI = (1 << 5) | (0x0C << 11) | OPC_MFMC0,
974 OPC_DVP = 0x04 | (0 << 3) | (1 << 5) | (0 << 11) | OPC_MFMC0,
975 OPC_EVP = 0x04 | (0 << 3) | (0 << 5) | (0 << 11) | OPC_MFMC0,
978 /* Coprocessor 0 (with rs == C0) */
979 #define MASK_C0(op) (MASK_CP0(op) | (op & 0x3F))
981 enum {
982 OPC_TLBR = 0x01 | OPC_C0,
983 OPC_TLBWI = 0x02 | OPC_C0,
984 OPC_TLBINV = 0x03 | OPC_C0,
985 OPC_TLBINVF = 0x04 | OPC_C0,
986 OPC_TLBWR = 0x06 | OPC_C0,
987 OPC_TLBP = 0x08 | OPC_C0,
988 OPC_RFE = 0x10 | OPC_C0,
989 OPC_ERET = 0x18 | OPC_C0,
990 OPC_DERET = 0x1F | OPC_C0,
991 OPC_WAIT = 0x20 | OPC_C0,
994 #define MASK_CP2(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)))
996 enum {
997 OPC_MFC2 = (0x00 << 21) | OPC_CP2,
998 OPC_DMFC2 = (0x01 << 21) | OPC_CP2,
999 OPC_CFC2 = (0x02 << 21) | OPC_CP2,
1000 OPC_MFHC2 = (0x03 << 21) | OPC_CP2,
1001 OPC_MTC2 = (0x04 << 21) | OPC_CP2,
1002 OPC_DMTC2 = (0x05 << 21) | OPC_CP2,
1003 OPC_CTC2 = (0x06 << 21) | OPC_CP2,
1004 OPC_MTHC2 = (0x07 << 21) | OPC_CP2,
1005 OPC_BC2 = (0x08 << 21) | OPC_CP2,
1006 OPC_BC2EQZ = (0x09 << 21) | OPC_CP2,
1007 OPC_BC2NEZ = (0x0D << 21) | OPC_CP2,
1010 #define MASK_LMMI(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)) | (op & 0x1F))
1012 enum {
1013 OPC_PADDSH = (24 << 21) | (0x00) | OPC_CP2,
1014 OPC_PADDUSH = (25 << 21) | (0x00) | OPC_CP2,
1015 OPC_PADDH = (26 << 21) | (0x00) | OPC_CP2,
1016 OPC_PADDW = (27 << 21) | (0x00) | OPC_CP2,
1017 OPC_PADDSB = (28 << 21) | (0x00) | OPC_CP2,
1018 OPC_PADDUSB = (29 << 21) | (0x00) | OPC_CP2,
1019 OPC_PADDB = (30 << 21) | (0x00) | OPC_CP2,
1020 OPC_PADDD = (31 << 21) | (0x00) | OPC_CP2,
1022 OPC_PSUBSH = (24 << 21) | (0x01) | OPC_CP2,
1023 OPC_PSUBUSH = (25 << 21) | (0x01) | OPC_CP2,
1024 OPC_PSUBH = (26 << 21) | (0x01) | OPC_CP2,
1025 OPC_PSUBW = (27 << 21) | (0x01) | OPC_CP2,
1026 OPC_PSUBSB = (28 << 21) | (0x01) | OPC_CP2,
1027 OPC_PSUBUSB = (29 << 21) | (0x01) | OPC_CP2,
1028 OPC_PSUBB = (30 << 21) | (0x01) | OPC_CP2,
1029 OPC_PSUBD = (31 << 21) | (0x01) | OPC_CP2,
1031 OPC_PSHUFH = (24 << 21) | (0x02) | OPC_CP2,
1032 OPC_PACKSSWH = (25 << 21) | (0x02) | OPC_CP2,
1033 OPC_PACKSSHB = (26 << 21) | (0x02) | OPC_CP2,
1034 OPC_PACKUSHB = (27 << 21) | (0x02) | OPC_CP2,
1035 OPC_XOR_CP2 = (28 << 21) | (0x02) | OPC_CP2,
1036 OPC_NOR_CP2 = (29 << 21) | (0x02) | OPC_CP2,
1037 OPC_AND_CP2 = (30 << 21) | (0x02) | OPC_CP2,
1038 OPC_PANDN = (31 << 21) | (0x02) | OPC_CP2,
1040 OPC_PUNPCKLHW = (24 << 21) | (0x03) | OPC_CP2,
1041 OPC_PUNPCKHHW = (25 << 21) | (0x03) | OPC_CP2,
1042 OPC_PUNPCKLBH = (26 << 21) | (0x03) | OPC_CP2,
1043 OPC_PUNPCKHBH = (27 << 21) | (0x03) | OPC_CP2,
1044 OPC_PINSRH_0 = (28 << 21) | (0x03) | OPC_CP2,
1045 OPC_PINSRH_1 = (29 << 21) | (0x03) | OPC_CP2,
1046 OPC_PINSRH_2 = (30 << 21) | (0x03) | OPC_CP2,
1047 OPC_PINSRH_3 = (31 << 21) | (0x03) | OPC_CP2,
1049 OPC_PAVGH = (24 << 21) | (0x08) | OPC_CP2,
1050 OPC_PAVGB = (25 << 21) | (0x08) | OPC_CP2,
1051 OPC_PMAXSH = (26 << 21) | (0x08) | OPC_CP2,
1052 OPC_PMINSH = (27 << 21) | (0x08) | OPC_CP2,
1053 OPC_PMAXUB = (28 << 21) | (0x08) | OPC_CP2,
1054 OPC_PMINUB = (29 << 21) | (0x08) | OPC_CP2,
1056 OPC_PCMPEQW = (24 << 21) | (0x09) | OPC_CP2,
1057 OPC_PCMPGTW = (25 << 21) | (0x09) | OPC_CP2,
1058 OPC_PCMPEQH = (26 << 21) | (0x09) | OPC_CP2,
1059 OPC_PCMPGTH = (27 << 21) | (0x09) | OPC_CP2,
1060 OPC_PCMPEQB = (28 << 21) | (0x09) | OPC_CP2,
1061 OPC_PCMPGTB = (29 << 21) | (0x09) | OPC_CP2,
1063 OPC_PSLLW = (24 << 21) | (0x0A) | OPC_CP2,
1064 OPC_PSLLH = (25 << 21) | (0x0A) | OPC_CP2,
1065 OPC_PMULLH = (26 << 21) | (0x0A) | OPC_CP2,
1066 OPC_PMULHH = (27 << 21) | (0x0A) | OPC_CP2,
1067 OPC_PMULUW = (28 << 21) | (0x0A) | OPC_CP2,
1068 OPC_PMULHUH = (29 << 21) | (0x0A) | OPC_CP2,
1070 OPC_PSRLW = (24 << 21) | (0x0B) | OPC_CP2,
1071 OPC_PSRLH = (25 << 21) | (0x0B) | OPC_CP2,
1072 OPC_PSRAW = (26 << 21) | (0x0B) | OPC_CP2,
1073 OPC_PSRAH = (27 << 21) | (0x0B) | OPC_CP2,
1074 OPC_PUNPCKLWD = (28 << 21) | (0x0B) | OPC_CP2,
1075 OPC_PUNPCKHWD = (29 << 21) | (0x0B) | OPC_CP2,
1077 OPC_ADDU_CP2 = (24 << 21) | (0x0C) | OPC_CP2,
1078 OPC_OR_CP2 = (25 << 21) | (0x0C) | OPC_CP2,
1079 OPC_ADD_CP2 = (26 << 21) | (0x0C) | OPC_CP2,
1080 OPC_DADD_CP2 = (27 << 21) | (0x0C) | OPC_CP2,
1081 OPC_SEQU_CP2 = (28 << 21) | (0x0C) | OPC_CP2,
1082 OPC_SEQ_CP2 = (29 << 21) | (0x0C) | OPC_CP2,
1084 OPC_SUBU_CP2 = (24 << 21) | (0x0D) | OPC_CP2,
1085 OPC_PASUBUB = (25 << 21) | (0x0D) | OPC_CP2,
1086 OPC_SUB_CP2 = (26 << 21) | (0x0D) | OPC_CP2,
1087 OPC_DSUB_CP2 = (27 << 21) | (0x0D) | OPC_CP2,
1088 OPC_SLTU_CP2 = (28 << 21) | (0x0D) | OPC_CP2,
1089 OPC_SLT_CP2 = (29 << 21) | (0x0D) | OPC_CP2,
1091 OPC_SLL_CP2 = (24 << 21) | (0x0E) | OPC_CP2,
1092 OPC_DSLL_CP2 = (25 << 21) | (0x0E) | OPC_CP2,
1093 OPC_PEXTRH = (26 << 21) | (0x0E) | OPC_CP2,
1094 OPC_PMADDHW = (27 << 21) | (0x0E) | OPC_CP2,
1095 OPC_SLEU_CP2 = (28 << 21) | (0x0E) | OPC_CP2,
1096 OPC_SLE_CP2 = (29 << 21) | (0x0E) | OPC_CP2,
1098 OPC_SRL_CP2 = (24 << 21) | (0x0F) | OPC_CP2,
1099 OPC_DSRL_CP2 = (25 << 21) | (0x0F) | OPC_CP2,
1100 OPC_SRA_CP2 = (26 << 21) | (0x0F) | OPC_CP2,
1101 OPC_DSRA_CP2 = (27 << 21) | (0x0F) | OPC_CP2,
1102 OPC_BIADD = (28 << 21) | (0x0F) | OPC_CP2,
1103 OPC_PMOVMSKB = (29 << 21) | (0x0F) | OPC_CP2,
1107 #define MASK_CP3(op) (MASK_OP_MAJOR(op) | (op & 0x3F))
1109 enum {
1110 OPC_LWXC1 = 0x00 | OPC_CP3,
1111 OPC_LDXC1 = 0x01 | OPC_CP3,
1112 OPC_LUXC1 = 0x05 | OPC_CP3,
1113 OPC_SWXC1 = 0x08 | OPC_CP3,
1114 OPC_SDXC1 = 0x09 | OPC_CP3,
1115 OPC_SUXC1 = 0x0D | OPC_CP3,
1116 OPC_PREFX = 0x0F | OPC_CP3,
1117 OPC_ALNV_PS = 0x1E | OPC_CP3,
1118 OPC_MADD_S = 0x20 | OPC_CP3,
1119 OPC_MADD_D = 0x21 | OPC_CP3,
1120 OPC_MADD_PS = 0x26 | OPC_CP3,
1121 OPC_MSUB_S = 0x28 | OPC_CP3,
1122 OPC_MSUB_D = 0x29 | OPC_CP3,
1123 OPC_MSUB_PS = 0x2E | OPC_CP3,
1124 OPC_NMADD_S = 0x30 | OPC_CP3,
1125 OPC_NMADD_D = 0x31 | OPC_CP3,
1126 OPC_NMADD_PS = 0x36 | OPC_CP3,
1127 OPC_NMSUB_S = 0x38 | OPC_CP3,
1128 OPC_NMSUB_D = 0x39 | OPC_CP3,
1129 OPC_NMSUB_PS = 0x3E | OPC_CP3,
1134 * AN OVERVIEW OF MXU EXTENSION INSTRUCTION SET
1135 * ============================================
1138 * MXU (full name: MIPS eXtension/enhanced Unit) is a SIMD extension of MIPS32
1139 * instructions set. It is designed to fit the needs of signal, graphical and
1140 * video processing applications. MXU instruction set is used in Xburst family
1141 * of microprocessors by Ingenic.
1143 * MXU unit contains 17 registers called X0-X16. X0 is always zero, and X16 is
1144 * the control register.
1147 * The notation used in MXU assembler mnemonics
1148 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1150 * Register operands:
1152 * XRa, XRb, XRc, XRd - MXU registers
1153 * Rb, Rc, Rd, Rs, Rt - general purpose MIPS registers
1155 * Non-register operands:
1157 * aptn1 - 1-bit accumulate add/subtract pattern
1158 * aptn2 - 2-bit accumulate add/subtract pattern
1159 * eptn2 - 2-bit execute add/subtract pattern
1160 * optn2 - 2-bit operand pattern
1161 * optn3 - 3-bit operand pattern
1162 * sft4 - 4-bit shift amount
1163 * strd2 - 2-bit stride amount
1165 * Prefixes:
1167 * Level of parallelism: Operand size:
1168 * S - single operation at a time 32 - word
1169 * D - two operations in parallel 16 - half word
1170 * Q - four operations in parallel 8 - byte
1172 * Operations:
1174 * ADD - Add or subtract
1175 * ADDC - Add with carry-in
1176 * ACC - Accumulate
1177 * ASUM - Sum together then accumulate (add or subtract)
1178 * ASUMC - Sum together then accumulate (add or subtract) with carry-in
1179 * AVG - Average between 2 operands
1180 * ABD - Absolute difference
1181 * ALN - Align data
1182 * AND - Logical bitwise 'and' operation
1183 * CPS - Copy sign
1184 * EXTR - Extract bits
1185 * I2M - Move from GPR register to MXU register
1186 * LDD - Load data from memory to XRF
1187 * LDI - Load data from memory to XRF (and increase the address base)
1188 * LUI - Load unsigned immediate
1189 * MUL - Multiply
1190 * MULU - Unsigned multiply
1191 * MADD - 64-bit operand add 32x32 product
1192 * MSUB - 64-bit operand subtract 32x32 product
1193 * MAC - Multiply and accumulate (add or subtract)
1194 * MAD - Multiply and add or subtract
1195 * MAX - Maximum between 2 operands
1196 * MIN - Minimum between 2 operands
1197 * M2I - Move from MXU register to GPR register
1198 * MOVZ - Move if zero
1199 * MOVN - Move if non-zero
1200 * NOR - Logical bitwise 'nor' operation
1201 * OR - Logical bitwise 'or' operation
1202 * STD - Store data from XRF to memory
1203 * SDI - Store data from XRF to memory (and increase the address base)
1204 * SLT - Set of less than comparison
1205 * SAD - Sum of absolute differences
1206 * SLL - Logical shift left
1207 * SLR - Logical shift right
1208 * SAR - Arithmetic shift right
1209 * SAT - Saturation
1210 * SFL - Shuffle
1211 * SCOP - Calculate x’s scope (-1, means x<0; 0, means x==0; 1, means x>0)
1212 * XOR - Logical bitwise 'exclusive or' operation
1214 * Suffixes:
1216 * E - Expand results
1217 * F - Fixed point multiplication
1218 * L - Low part result
1219 * R - Doing rounding
1220 * V - Variable instead of immediate
1221 * W - Combine above L and V
1224 * The list of MXU instructions grouped by functionality
1225 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1227 * Load/Store instructions Multiplication instructions
1228 * ----------------------- ---------------------------
1230 * S32LDD XRa, Rb, s12 S32MADD XRa, XRd, Rs, Rt
1231 * S32STD XRa, Rb, s12 S32MADDU XRa, XRd, Rs, Rt
1232 * S32LDDV XRa, Rb, rc, strd2 S32MSUB XRa, XRd, Rs, Rt
1233 * S32STDV XRa, Rb, rc, strd2 S32MSUBU XRa, XRd, Rs, Rt
1234 * S32LDI XRa, Rb, s12 S32MUL XRa, XRd, Rs, Rt
1235 * S32SDI XRa, Rb, s12 S32MULU XRa, XRd, Rs, Rt
1236 * S32LDIV XRa, Rb, rc, strd2 D16MUL XRa, XRb, XRc, XRd, optn2
1237 * S32SDIV XRa, Rb, rc, strd2 D16MULE XRa, XRb, XRc, optn2
1238 * S32LDDR XRa, Rb, s12 D16MULF XRa, XRb, XRc, optn2
1239 * S32STDR XRa, Rb, s12 D16MAC XRa, XRb, XRc, XRd, aptn2, optn2
1240 * S32LDDVR XRa, Rb, rc, strd2 D16MACE XRa, XRb, XRc, XRd, aptn2, optn2
1241 * S32STDVR XRa, Rb, rc, strd2 D16MACF XRa, XRb, XRc, XRd, aptn2, optn2
1242 * S32LDIR XRa, Rb, s12 D16MADL XRa, XRb, XRc, XRd, aptn2, optn2
1243 * S32SDIR XRa, Rb, s12 S16MAD XRa, XRb, XRc, XRd, aptn1, optn2
1244 * S32LDIVR XRa, Rb, rc, strd2 Q8MUL XRa, XRb, XRc, XRd
1245 * S32SDIVR XRa, Rb, rc, strd2 Q8MULSU XRa, XRb, XRc, XRd
1246 * S16LDD XRa, Rb, s10, eptn2 Q8MAC XRa, XRb, XRc, XRd, aptn2
1247 * S16STD XRa, Rb, s10, eptn2 Q8MACSU XRa, XRb, XRc, XRd, aptn2
1248 * S16LDI XRa, Rb, s10, eptn2 Q8MADL XRa, XRb, XRc, XRd, aptn2
1249 * S16SDI XRa, Rb, s10, eptn2
1250 * S8LDD XRa, Rb, s8, eptn3
1251 * S8STD XRa, Rb, s8, eptn3 Addition and subtraction instructions
1252 * S8LDI XRa, Rb, s8, eptn3 -------------------------------------
1253 * S8SDI XRa, Rb, s8, eptn3
1254 * LXW Rd, Rs, Rt, strd2 D32ADD XRa, XRb, XRc, XRd, eptn2
1255 * LXH Rd, Rs, Rt, strd2 D32ADDC XRa, XRb, XRc, XRd
1256 * LXHU Rd, Rs, Rt, strd2 D32ACC XRa, XRb, XRc, XRd, eptn2
1257 * LXB Rd, Rs, Rt, strd2 D32ACCM XRa, XRb, XRc, XRd, eptn2
1258 * LXBU Rd, Rs, Rt, strd2 D32ASUM XRa, XRb, XRc, XRd, eptn2
1259 * S32CPS XRa, XRb, XRc
1260 * Q16ADD XRa, XRb, XRc, XRd, eptn2, optn2
1261 * Comparison instructions Q16ACC XRa, XRb, XRc, XRd, eptn2
1262 * ----------------------- Q16ACCM XRa, XRb, XRc, XRd, eptn2
1263 * D16ASUM XRa, XRb, XRc, XRd, eptn2
1264 * S32MAX XRa, XRb, XRc D16CPS XRa, XRb,
1265 * S32MIN XRa, XRb, XRc D16AVG XRa, XRb, XRc
1266 * S32SLT XRa, XRb, XRc D16AVGR XRa, XRb, XRc
1267 * S32MOVZ XRa, XRb, XRc Q8ADD XRa, XRb, XRc, eptn2
1268 * S32MOVN XRa, XRb, XRc Q8ADDE XRa, XRb, XRc, XRd, eptn2
1269 * D16MAX XRa, XRb, XRc Q8ACCE XRa, XRb, XRc, XRd, eptn2
1270 * D16MIN XRa, XRb, XRc Q8ABD XRa, XRb, XRc
1271 * D16SLT XRa, XRb, XRc Q8SAD XRa, XRb, XRc, XRd
1272 * D16MOVZ XRa, XRb, XRc Q8AVG XRa, XRb, XRc
1273 * D16MOVN XRa, XRb, XRc Q8AVGR XRa, XRb, XRc
1274 * Q8MAX XRa, XRb, XRc D8SUM XRa, XRb, XRc, XRd
1275 * Q8MIN XRa, XRb, XRc D8SUMC XRa, XRb, XRc, XRd
1276 * Q8SLT XRa, XRb, XRc
1277 * Q8SLTU XRa, XRb, XRc
1278 * Q8MOVZ XRa, XRb, XRc Shift instructions
1279 * Q8MOVN XRa, XRb, XRc ------------------
1281 * D32SLL XRa, XRb, XRc, XRd, sft4
1282 * Bitwise instructions D32SLR XRa, XRb, XRc, XRd, sft4
1283 * -------------------- D32SAR XRa, XRb, XRc, XRd, sft4
1284 * D32SARL XRa, XRb, XRc, sft4
1285 * S32NOR XRa, XRb, XRc D32SLLV XRa, XRb, Rb
1286 * S32AND XRa, XRb, XRc D32SLRV XRa, XRb, Rb
1287 * S32XOR XRa, XRb, XRc D32SARV XRa, XRb, Rb
1288 * S32OR XRa, XRb, XRc D32SARW XRa, XRb, XRc, Rb
1289 * Q16SLL XRa, XRb, XRc, XRd, sft4
1290 * Q16SLR XRa, XRb, XRc, XRd, sft4
1291 * Miscellaneous instructions Q16SAR XRa, XRb, XRc, XRd, sft4
1292 * ------------------------- Q16SLLV XRa, XRb, Rb
1293 * Q16SLRV XRa, XRb, Rb
1294 * S32SFL XRa, XRb, XRc, XRd, optn2 Q16SARV XRa, XRb, Rb
1295 * S32ALN XRa, XRb, XRc, Rb
1296 * S32ALNI XRa, XRb, XRc, s3
1297 * S32LUI XRa, s8, optn3 Move instructions
1298 * S32EXTR XRa, XRb, Rb, bits5 -----------------
1299 * S32EXTRV XRa, XRb, Rs, Rt
1300 * Q16SCOP XRa, XRb, XRc, XRd S32M2I XRa, Rb
1301 * Q16SAT XRa, XRb, XRc S32I2M XRa, Rb
1304 * The opcode organization of MXU instructions
1305 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1307 * The bits 31..26 of all MXU instructions are equal to 0x1C (also referred
1308 * as opcode SPECIAL2 in the base MIPS ISA). The organization and meaning of
1309 * other bits up to the instruction level is as follows:
1311 * bits
1312 * 05..00
1314 * ┌─ 000000 ─ OPC_MXU_S32MADD
1315 * ├─ 000001 ─ OPC_MXU_S32MADDU
1316 * ├─ 000010 ─ <not assigned> (non-MXU OPC_MUL)
1317 * │
1318 * │ 20..18
1319 * ├─ 000011 ─ OPC_MXU__POOL00 ─┬─ 000 ─ OPC_MXU_S32MAX
1320 * │ ├─ 001 ─ OPC_MXU_S32MIN
1321 * │ ├─ 010 ─ OPC_MXU_D16MAX
1322 * │ ├─ 011 ─ OPC_MXU_D16MIN
1323 * │ ├─ 100 ─ OPC_MXU_Q8MAX
1324 * │ ├─ 101 ─ OPC_MXU_Q8MIN
1325 * │ ├─ 110 ─ OPC_MXU_Q8SLT
1326 * │ └─ 111 ─ OPC_MXU_Q8SLTU
1327 * ├─ 000100 ─ OPC_MXU_S32MSUB
1328 * ├─ 000101 ─ OPC_MXU_S32MSUBU 20..18
1329 * ├─ 000110 ─ OPC_MXU__POOL01 ─┬─ 000 ─ OPC_MXU_S32SLT
1330 * │ ├─ 001 ─ OPC_MXU_D16SLT
1331 * │ ├─ 010 ─ OPC_MXU_D16AVG
1332 * │ ├─ 011 ─ OPC_MXU_D16AVGR
1333 * │ ├─ 100 ─ OPC_MXU_Q8AVG
1334 * │ ├─ 101 ─ OPC_MXU_Q8AVGR
1335 * │ └─ 111 ─ OPC_MXU_Q8ADD
1336 * │
1337 * │ 20..18
1338 * ├─ 000111 ─ OPC_MXU__POOL02 ─┬─ 000 ─ OPC_MXU_S32CPS
1339 * │ ├─ 010 ─ OPC_MXU_D16CPS
1340 * │ ├─ 100 ─ OPC_MXU_Q8ABD
1341 * │ └─ 110 ─ OPC_MXU_Q16SAT
1342 * ├─ 001000 ─ OPC_MXU_D16MUL
1343 * │ 25..24
1344 * ├─ 001001 ─ OPC_MXU__POOL03 ─┬─ 00 ─ OPC_MXU_D16MULF
1345 * │ └─ 01 ─ OPC_MXU_D16MULE
1346 * ├─ 001010 ─ OPC_MXU_D16MAC
1347 * ├─ 001011 ─ OPC_MXU_D16MACF
1348 * ├─ 001100 ─ OPC_MXU_D16MADL
1349 * ├─ 001101 ─ OPC_MXU_S16MAD
1350 * ├─ 001110 ─ OPC_MXU_Q16ADD
1351 * ├─ 001111 ─ OPC_MXU_D16MACE 23
1352 * │ ┌─ 0 ─ OPC_MXU_S32LDD
1353 * ├─ 010000 ─ OPC_MXU__POOL04 ─┴─ 1 ─ OPC_MXU_S32LDDR
1354 * │
1355 * │ 23
1356 * ├─ 010001 ─ OPC_MXU__POOL05 ─┬─ 0 ─ OPC_MXU_S32STD
1357 * │ └─ 1 ─ OPC_MXU_S32STDR
1358 * │
1359 * │ 13..10
1360 * ├─ 010010 ─ OPC_MXU__POOL06 ─┬─ 0000 ─ OPC_MXU_S32LDDV
1361 * │ └─ 0001 ─ OPC_MXU_S32LDDVR
1362 * │
1363 * │ 13..10
1364 * ├─ 010011 ─ OPC_MXU__POOL07 ─┬─ 0000 ─ OPC_MXU_S32STDV
1365 * │ └─ 0001 ─ OPC_MXU_S32STDVR
1366 * │
1367 * │ 23
1368 * ├─ 010100 ─ OPC_MXU__POOL08 ─┬─ 0 ─ OPC_MXU_S32LDI
1369 * │ └─ 1 ─ OPC_MXU_S32LDIR
1370 * │
1371 * │ 23
1372 * ├─ 010101 ─ OPC_MXU__POOL09 ─┬─ 0 ─ OPC_MXU_S32SDI
1373 * │ └─ 1 ─ OPC_MXU_S32SDIR
1374 * │
1375 * │ 13..10
1376 * ├─ 010110 ─ OPC_MXU__POOL10 ─┬─ 0000 ─ OPC_MXU_S32LDIV
1377 * │ └─ 0001 ─ OPC_MXU_S32LDIVR
1378 * │
1379 * │ 13..10
1380 * ├─ 010111 ─ OPC_MXU__POOL11 ─┬─ 0000 ─ OPC_MXU_S32SDIV
1381 * │ └─ 0001 ─ OPC_MXU_S32SDIVR
1382 * ├─ 011000 ─ OPC_MXU_D32ADD
1383 * │ 23..22
1384 * MXU ├─ 011001 ─ OPC_MXU__POOL12 ─┬─ 00 ─ OPC_MXU_D32ACC
1385 * opcodes ─┤ ├─ 01 ─ OPC_MXU_D32ACCM
1386 * │ └─ 10 ─ OPC_MXU_D32ASUM
1387 * ├─ 011010 ─ <not assigned>
1388 * │ 23..22
1389 * ├─ 011011 ─ OPC_MXU__POOL13 ─┬─ 00 ─ OPC_MXU_Q16ACC
1390 * │ ├─ 01 ─ OPC_MXU_Q16ACCM
1391 * │ └─ 10 ─ OPC_MXU_Q16ASUM
1392 * │
1393 * │ 23..22
1394 * ├─ 011100 ─ OPC_MXU__POOL14 ─┬─ 00 ─ OPC_MXU_Q8ADDE
1395 * │ ├─ 01 ─ OPC_MXU_D8SUM
1396 * ├─ 011101 ─ OPC_MXU_Q8ACCE └─ 10 ─ OPC_MXU_D8SUMC
1397 * ├─ 011110 ─ <not assigned>
1398 * ├─ 011111 ─ <not assigned>
1399 * ├─ 100000 ─ <not assigned> (overlaps with CLZ)
1400 * ├─ 100001 ─ <not assigned> (overlaps with CLO)
1401 * ├─ 100010 ─ OPC_MXU_S8LDD
1402 * ├─ 100011 ─ OPC_MXU_S8STD 15..14
1403 * ├─ 100100 ─ OPC_MXU_S8LDI ┌─ 00 ─ OPC_MXU_S32MUL
1404 * ├─ 100101 ─ OPC_MXU_S8SDI ├─ 00 ─ OPC_MXU_S32MULU
1405 * │ ├─ 00 ─ OPC_MXU_S32EXTR
1406 * ├─ 100110 ─ OPC_MXU__POOL15 ─┴─ 00 ─ OPC_MXU_S32EXTRV
1407 * │
1408 * │ 20..18
1409 * ├─ 100111 ─ OPC_MXU__POOL16 ─┬─ 000 ─ OPC_MXU_D32SARW
1410 * │ ├─ 001 ─ OPC_MXU_S32ALN
1411 * │ ├─ 010 ─ OPC_MXU_S32ALNI
1412 * │ ├─ 011 ─ OPC_MXU_S32LUI
1413 * │ ├─ 100 ─ OPC_MXU_S32NOR
1414 * │ ├─ 101 ─ OPC_MXU_S32AND
1415 * │ ├─ 110 ─ OPC_MXU_S32OR
1416 * │ └─ 111 ─ OPC_MXU_S32XOR
1417 * │
1418 * │ 7..5
1419 * ├─ 101000 ─ OPC_MXU__POOL17 ─┬─ 000 ─ OPC_MXU_LXB
1420 * │ ├─ 001 ─ OPC_MXU_LXH
1421 * ├─ 101001 ─ <not assigned> ├─ 011 ─ OPC_MXU_LXW
1422 * ├─ 101010 ─ OPC_MXU_S16LDD ├─ 100 ─ OPC_MXU_LXBU
1423 * ├─ 101011 ─ OPC_MXU_S16STD └─ 101 ─ OPC_MXU_LXHU
1424 * ├─ 101100 ─ OPC_MXU_S16LDI
1425 * ├─ 101101 ─ OPC_MXU_S16SDI
1426 * ├─ 101110 ─ OPC_MXU_S32M2I
1427 * ├─ 101111 ─ OPC_MXU_S32I2M
1428 * ├─ 110000 ─ OPC_MXU_D32SLL
1429 * ├─ 110001 ─ OPC_MXU_D32SLR 20..18
1430 * ├─ 110010 ─ OPC_MXU_D32SARL ┌─ 000 ─ OPC_MXU_D32SLLV
1431 * ├─ 110011 ─ OPC_MXU_D32SAR ├─ 001 ─ OPC_MXU_D32SLRV
1432 * ├─ 110100 ─ OPC_MXU_Q16SLL ├─ 010 ─ OPC_MXU_D32SARV
1433 * ├─ 110101 ─ OPC_MXU_Q16SLR ├─ 011 ─ OPC_MXU_Q16SLLV
1434 * │ ├─ 100 ─ OPC_MXU_Q16SLRV
1435 * ├─ 110110 ─ OPC_MXU__POOL18 ─┴─ 101 ─ OPC_MXU_Q16SARV
1436 * │
1437 * ├─ 110111 ─ OPC_MXU_Q16SAR
1438 * │ 23..22
1439 * ├─ 111000 ─ OPC_MXU__POOL19 ─┬─ 00 ─ OPC_MXU_Q8MUL
1440 * │ └─ 01 ─ OPC_MXU_Q8MULSU
1441 * │
1442 * │ 20..18
1443 * ├─ 111001 ─ OPC_MXU__POOL20 ─┬─ 000 ─ OPC_MXU_Q8MOVZ
1444 * │ ├─ 001 ─ OPC_MXU_Q8MOVN
1445 * │ ├─ 010 ─ OPC_MXU_D16MOVZ
1446 * │ ├─ 011 ─ OPC_MXU_D16MOVN
1447 * │ ├─ 100 ─ OPC_MXU_S32MOVZ
1448 * │ └─ 101 ─ OPC_MXU_S32MOVN
1449 * │
1450 * │ 23..22
1451 * ├─ 111010 ─ OPC_MXU__POOL21 ─┬─ 00 ─ OPC_MXU_Q8MAC
1452 * │ └─ 10 ─ OPC_MXU_Q8MACSU
1453 * ├─ 111011 ─ OPC_MXU_Q16SCOP
1454 * ├─ 111100 ─ OPC_MXU_Q8MADL
1455 * ├─ 111101 ─ OPC_MXU_S32SFL
1456 * ├─ 111110 ─ OPC_MXU_Q8SAD
1457 * └─ 111111 ─ <not assigned> (overlaps with SDBBP)
1460 * Compiled after:
1462 * "XBurst® Instruction Set Architecture MIPS eXtension/enhanced Unit
1463 * Programming Manual", Ingenic Semiconductor Co, Ltd., revision June 2, 2017
1466 enum {
1467 OPC_MXU__POOL00 = 0x03,
1468 OPC_MXU_D16MUL = 0x08,
1469 OPC_MXU_D16MAC = 0x0A,
1470 OPC_MXU__POOL04 = 0x10,
1471 OPC_MXU_S8LDD = 0x22,
1472 OPC_MXU__POOL16 = 0x27,
1473 OPC_MXU_S32M2I = 0x2E,
1474 OPC_MXU_S32I2M = 0x2F,
1475 OPC_MXU__POOL19 = 0x38,
1480 * MXU pool 00
1482 enum {
1483 OPC_MXU_S32MAX = 0x00,
1484 OPC_MXU_S32MIN = 0x01,
1485 OPC_MXU_D16MAX = 0x02,
1486 OPC_MXU_D16MIN = 0x03,
1487 OPC_MXU_Q8MAX = 0x04,
1488 OPC_MXU_Q8MIN = 0x05,
1492 * MXU pool 04
1494 enum {
1495 OPC_MXU_S32LDD = 0x00,
1496 OPC_MXU_S32LDDR = 0x01,
1500 * MXU pool 16
1502 enum {
1503 OPC_MXU_S32ALNI = 0x02,
1504 OPC_MXU_S32NOR = 0x04,
1505 OPC_MXU_S32AND = 0x05,
1506 OPC_MXU_S32OR = 0x06,
1507 OPC_MXU_S32XOR = 0x07,
1511 * MXU pool 19
1513 enum {
1514 OPC_MXU_Q8MUL = 0x00,
1515 OPC_MXU_Q8MULSU = 0x01,
1519 * Overview of the TX79-specific instruction set
1520 * =============================================
1522 * The R5900 and the C790 have 128-bit wide GPRs, where the upper 64 bits
1523 * are only used by the specific quadword (128-bit) LQ/SQ load/store
1524 * instructions and certain multimedia instructions (MMIs). These MMIs
1525 * configure the 128-bit data path as two 64-bit, four 32-bit, eight 16-bit
1526 * or sixteen 8-bit paths.
1528 * Reference:
1530 * The Toshiba TX System RISC TX79 Core Architecture manual,
1531 * https://wiki.qemu.org/File:C790.pdf
1533 * Three-Operand Multiply and Multiply-Add (4 instructions)
1534 * --------------------------------------------------------
1535 * MADD [rd,] rs, rt Multiply/Add
1536 * MADDU [rd,] rs, rt Multiply/Add Unsigned
1537 * MULT [rd,] rs, rt Multiply (3-operand)
1538 * MULTU [rd,] rs, rt Multiply Unsigned (3-operand)
1540 * Multiply Instructions for Pipeline 1 (10 instructions)
1541 * ------------------------------------------------------
1542 * MULT1 [rd,] rs, rt Multiply Pipeline 1
1543 * MULTU1 [rd,] rs, rt Multiply Unsigned Pipeline 1
1544 * DIV1 rs, rt Divide Pipeline 1
1545 * DIVU1 rs, rt Divide Unsigned Pipeline 1
1546 * MADD1 [rd,] rs, rt Multiply-Add Pipeline 1
1547 * MADDU1 [rd,] rs, rt Multiply-Add Unsigned Pipeline 1
1548 * MFHI1 rd Move From HI1 Register
1549 * MFLO1 rd Move From LO1 Register
1550 * MTHI1 rs Move To HI1 Register
1551 * MTLO1 rs Move To LO1 Register
1553 * Arithmetic (19 instructions)
1554 * ----------------------------
1555 * PADDB rd, rs, rt Parallel Add Byte
1556 * PSUBB rd, rs, rt Parallel Subtract Byte
1557 * PADDH rd, rs, rt Parallel Add Halfword
1558 * PSUBH rd, rs, rt Parallel Subtract Halfword
1559 * PADDW rd, rs, rt Parallel Add Word
1560 * PSUBW rd, rs, rt Parallel Subtract Word
1561 * PADSBH rd, rs, rt Parallel Add/Subtract Halfword
1562 * PADDSB rd, rs, rt Parallel Add with Signed Saturation Byte
1563 * PSUBSB rd, rs, rt Parallel Subtract with Signed Saturation Byte
1564 * PADDSH rd, rs, rt Parallel Add with Signed Saturation Halfword
1565 * PSUBSH rd, rs, rt Parallel Subtract with Signed Saturation Halfword
1566 * PADDSW rd, rs, rt Parallel Add with Signed Saturation Word
1567 * PSUBSW rd, rs, rt Parallel Subtract with Signed Saturation Word
1568 * PADDUB rd, rs, rt Parallel Add with Unsigned saturation Byte
1569 * PSUBUB rd, rs, rt Parallel Subtract with Unsigned saturation Byte
1570 * PADDUH rd, rs, rt Parallel Add with Unsigned saturation Halfword
1571 * PSUBUH rd, rs, rt Parallel Subtract with Unsigned saturation Halfword
1572 * PADDUW rd, rs, rt Parallel Add with Unsigned saturation Word
1573 * PSUBUW rd, rs, rt Parallel Subtract with Unsigned saturation Word
1575 * Min/Max (4 instructions)
1576 * ------------------------
1577 * PMAXH rd, rs, rt Parallel Maximum Halfword
1578 * PMINH rd, rs, rt Parallel Minimum Halfword
1579 * PMAXW rd, rs, rt Parallel Maximum Word
1580 * PMINW rd, rs, rt Parallel Minimum Word
1582 * Absolute (2 instructions)
1583 * -------------------------
1584 * PABSH rd, rt Parallel Absolute Halfword
1585 * PABSW rd, rt Parallel Absolute Word
1587 * Logical (4 instructions)
1588 * ------------------------
1589 * PAND rd, rs, rt Parallel AND
1590 * POR rd, rs, rt Parallel OR
1591 * PXOR rd, rs, rt Parallel XOR
1592 * PNOR rd, rs, rt Parallel NOR
1594 * Shift (9 instructions)
1595 * ----------------------
1596 * PSLLH rd, rt, sa Parallel Shift Left Logical Halfword
1597 * PSRLH rd, rt, sa Parallel Shift Right Logical Halfword
1598 * PSRAH rd, rt, sa Parallel Shift Right Arithmetic Halfword
1599 * PSLLW rd, rt, sa Parallel Shift Left Logical Word
1600 * PSRLW rd, rt, sa Parallel Shift Right Logical Word
1601 * PSRAW rd, rt, sa Parallel Shift Right Arithmetic Word
1602 * PSLLVW rd, rt, rs Parallel Shift Left Logical Variable Word
1603 * PSRLVW rd, rt, rs Parallel Shift Right Logical Variable Word
1604 * PSRAVW rd, rt, rs Parallel Shift Right Arithmetic Variable Word
1606 * Compare (6 instructions)
1607 * ------------------------
1608 * PCGTB rd, rs, rt Parallel Compare for Greater Than Byte
1609 * PCEQB rd, rs, rt Parallel Compare for Equal Byte
1610 * PCGTH rd, rs, rt Parallel Compare for Greater Than Halfword
1611 * PCEQH rd, rs, rt Parallel Compare for Equal Halfword
1612 * PCGTW rd, rs, rt Parallel Compare for Greater Than Word
1613 * PCEQW rd, rs, rt Parallel Compare for Equal Word
1615 * LZC (1 instruction)
1616 * -------------------
1617 * PLZCW rd, rs Parallel Leading Zero or One Count Word
1619 * Quadword Load and Store (2 instructions)
1620 * ----------------------------------------
1621 * LQ rt, offset(base) Load Quadword
1622 * SQ rt, offset(base) Store Quadword
1624 * Multiply and Divide (19 instructions)
1625 * -------------------------------------
1626 * PMULTW rd, rs, rt Parallel Multiply Word
1627 * PMULTUW rd, rs, rt Parallel Multiply Unsigned Word
1628 * PDIVW rs, rt Parallel Divide Word
1629 * PDIVUW rs, rt Parallel Divide Unsigned Word
1630 * PMADDW rd, rs, rt Parallel Multiply-Add Word
1631 * PMADDUW rd, rs, rt Parallel Multiply-Add Unsigned Word
1632 * PMSUBW rd, rs, rt Parallel Multiply-Subtract Word
1633 * PMULTH rd, rs, rt Parallel Multiply Halfword
1634 * PMADDH rd, rs, rt Parallel Multiply-Add Halfword
1635 * PMSUBH rd, rs, rt Parallel Multiply-Subtract Halfword
1636 * PHMADH rd, rs, rt Parallel Horizontal Multiply-Add Halfword
1637 * PHMSBH rd, rs, rt Parallel Horizontal Multiply-Subtract Halfword
1638 * PDIVBW rs, rt Parallel Divide Broadcast Word
1639 * PMFHI rd Parallel Move From HI Register
1640 * PMFLO rd Parallel Move From LO Register
1641 * PMTHI rs Parallel Move To HI Register
1642 * PMTLO rs Parallel Move To LO Register
1643 * PMFHL rd Parallel Move From HI/LO Register
1644 * PMTHL rs Parallel Move To HI/LO Register
1646 * Pack/Extend (11 instructions)
1647 * -----------------------------
1648 * PPAC5 rd, rt Parallel Pack to 5 bits
1649 * PPACB rd, rs, rt Parallel Pack to Byte
1650 * PPACH rd, rs, rt Parallel Pack to Halfword
1651 * PPACW rd, rs, rt Parallel Pack to Word
1652 * PEXT5 rd, rt Parallel Extend Upper from 5 bits
1653 * PEXTUB rd, rs, rt Parallel Extend Upper from Byte
1654 * PEXTLB rd, rs, rt Parallel Extend Lower from Byte
1655 * PEXTUH rd, rs, rt Parallel Extend Upper from Halfword
1656 * PEXTLH rd, rs, rt Parallel Extend Lower from Halfword
1657 * PEXTUW rd, rs, rt Parallel Extend Upper from Word
1658 * PEXTLW rd, rs, rt Parallel Extend Lower from Word
1660 * Others (16 instructions)
1661 * ------------------------
1662 * PCPYH rd, rt Parallel Copy Halfword
1663 * PCPYLD rd, rs, rt Parallel Copy Lower Doubleword
1664 * PCPYUD rd, rs, rt Parallel Copy Upper Doubleword
1665 * PREVH rd, rt Parallel Reverse Halfword
1666 * PINTH rd, rs, rt Parallel Interleave Halfword
1667 * PINTEH rd, rs, rt Parallel Interleave Even Halfword
1668 * PEXEH rd, rt Parallel Exchange Even Halfword
1669 * PEXCH rd, rt Parallel Exchange Center Halfword
1670 * PEXEW rd, rt Parallel Exchange Even Word
1671 * PEXCW rd, rt Parallel Exchange Center Word
1672 * QFSRV rd, rs, rt Quadword Funnel Shift Right Variable
1673 * MFSA rd Move from Shift Amount Register
1674 * MTSA rs Move to Shift Amount Register
1675 * MTSAB rs, immediate Move Byte Count to Shift Amount Register
1676 * MTSAH rs, immediate Move Halfword Count to Shift Amount Register
1677 * PROT3W rd, rt Parallel Rotate 3 Words
1679 * MMI (MultiMedia Instruction) encodings
1680 * ======================================
1682 * MMI instructions encoding table keys:
1684 * * This code is reserved for future use. An attempt to execute it
1685 * causes a Reserved Instruction exception.
1686 * % This code indicates an instruction class. The instruction word
1687 * must be further decoded by examining additional tables that show
1688 * the values for other instruction fields.
1689 * # This code is reserved for the unsupported instructions DMULT,
1690 * DMULTU, DDIV, DDIVU, LL, LLD, SC, SCD, LWC2 and SWC2. An attempt
1691 * to execute it causes a Reserved Instruction exception.
1693 * MMI instructions encoded by opcode field (MMI, LQ, SQ):
1695 * 31 26 0
1696 * +--------+----------------------------------------+
1697 * | opcode | |
1698 * +--------+----------------------------------------+
1700 * opcode bits 28..26
1701 * bits | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7
1702 * 31..29 | 000 | 001 | 010 | 011 | 100 | 101 | 110 | 111
1703 * -------+-------+-------+-------+-------+-------+-------+-------+-------
1704 * 0 000 |SPECIAL| REGIMM| J | JAL | BEQ | BNE | BLEZ | BGTZ
1705 * 1 001 | ADDI | ADDIU | SLTI | SLTIU | ANDI | ORI | XORI | LUI
1706 * 2 010 | COP0 | COP1 | * | * | BEQL | BNEL | BLEZL | BGTZL
1707 * 3 011 | DADDI | DADDIU| LDL | LDR | MMI% | * | LQ | SQ
1708 * 4 100 | LB | LH | LWL | LW | LBU | LHU | LWR | LWU
1709 * 5 101 | SB | SH | SWL | SW | SDL | SDR | SWR | CACHE
1710 * 6 110 | # | LWC1 | # | PREF | # | LDC1 | # | LD
1711 * 7 111 | # | SWC1 | # | * | # | SDC1 | # | SD
1714 enum {
1715 MMI_OPC_CLASS_MMI = 0x1C << 26, /* Same as OPC_SPECIAL2 */
1716 MMI_OPC_LQ = 0x1E << 26, /* Same as OPC_MSA */
1717 MMI_OPC_SQ = 0x1F << 26, /* Same as OPC_SPECIAL3 */
1721 * MMI instructions with opcode field = MMI:
1723 * 31 26 5 0
1724 * +--------+-------------------------------+--------+
1725 * | MMI | |function|
1726 * +--------+-------------------------------+--------+
1728 * function bits 2..0
1729 * bits | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7
1730 * 5..3 | 000 | 001 | 010 | 011 | 100 | 101 | 110 | 111
1731 * -------+-------+-------+-------+-------+-------+-------+-------+-------
1732 * 0 000 | MADD | MADDU | * | * | PLZCW | * | * | *
1733 * 1 001 | MMI0% | MMI2% | * | * | * | * | * | *
1734 * 2 010 | MFHI1 | MTHI1 | MFLO1 | MTLO1 | * | * | * | *
1735 * 3 011 | MULT1 | MULTU1| DIV1 | DIVU1 | * | * | * | *
1736 * 4 100 | MADD1 | MADDU1| * | * | * | * | * | *
1737 * 5 101 | MMI1% | MMI3% | * | * | * | * | * | *
1738 * 6 110 | PMFHL | PMTHL | * | * | PSLLH | * | PSRLH | PSRAH
1739 * 7 111 | * | * | * | * | PSLLW | * | PSRLW | PSRAW
1742 #define MASK_MMI(op) (MASK_OP_MAJOR(op) | ((op) & 0x3F))
1743 enum {
1744 MMI_OPC_MADD = 0x00 | MMI_OPC_CLASS_MMI, /* Same as OPC_MADD */
1745 MMI_OPC_MADDU = 0x01 | MMI_OPC_CLASS_MMI, /* Same as OPC_MADDU */
1746 MMI_OPC_PLZCW = 0x04 | MMI_OPC_CLASS_MMI,
1747 MMI_OPC_CLASS_MMI0 = 0x08 | MMI_OPC_CLASS_MMI,
1748 MMI_OPC_CLASS_MMI2 = 0x09 | MMI_OPC_CLASS_MMI,
1749 MMI_OPC_MFHI1 = 0x10 | MMI_OPC_CLASS_MMI, /* Same minor as OPC_MFHI */
1750 MMI_OPC_MTHI1 = 0x11 | MMI_OPC_CLASS_MMI, /* Same minor as OPC_MTHI */
1751 MMI_OPC_MFLO1 = 0x12 | MMI_OPC_CLASS_MMI, /* Same minor as OPC_MFLO */
1752 MMI_OPC_MTLO1 = 0x13 | MMI_OPC_CLASS_MMI, /* Same minor as OPC_MTLO */
1753 MMI_OPC_MULT1 = 0x18 | MMI_OPC_CLASS_MMI, /* Same minor as OPC_MULT */
1754 MMI_OPC_MULTU1 = 0x19 | MMI_OPC_CLASS_MMI, /* Same min. as OPC_MULTU */
1755 MMI_OPC_DIV1 = 0x1A | MMI_OPC_CLASS_MMI, /* Same minor as OPC_DIV */
1756 MMI_OPC_DIVU1 = 0x1B | MMI_OPC_CLASS_MMI, /* Same minor as OPC_DIVU */
1757 MMI_OPC_MADD1 = 0x20 | MMI_OPC_CLASS_MMI,
1758 MMI_OPC_MADDU1 = 0x21 | MMI_OPC_CLASS_MMI,
1759 MMI_OPC_CLASS_MMI1 = 0x28 | MMI_OPC_CLASS_MMI,
1760 MMI_OPC_CLASS_MMI3 = 0x29 | MMI_OPC_CLASS_MMI,
1761 MMI_OPC_PMFHL = 0x30 | MMI_OPC_CLASS_MMI,
1762 MMI_OPC_PMTHL = 0x31 | MMI_OPC_CLASS_MMI,
1763 MMI_OPC_PSLLH = 0x34 | MMI_OPC_CLASS_MMI,
1764 MMI_OPC_PSRLH = 0x36 | MMI_OPC_CLASS_MMI,
1765 MMI_OPC_PSRAH = 0x37 | MMI_OPC_CLASS_MMI,
1766 MMI_OPC_PSLLW = 0x3C | MMI_OPC_CLASS_MMI,
1767 MMI_OPC_PSRLW = 0x3E | MMI_OPC_CLASS_MMI,
1768 MMI_OPC_PSRAW = 0x3F | MMI_OPC_CLASS_MMI,
1772 * MMI instructions with opcode field = MMI and bits 5..0 = MMI0:
1774 * 31 26 10 6 5 0
1775 * +--------+----------------------+--------+--------+
1776 * | MMI | |function| MMI0 |
1777 * +--------+----------------------+--------+--------+
1779 * function bits 7..6
1780 * bits | 0 | 1 | 2 | 3
1781 * 10..8 | 00 | 01 | 10 | 11
1782 * -------+-------+-------+-------+-------
1783 * 0 000 | PADDW | PSUBW | PCGTW | PMAXW
1784 * 1 001 | PADDH | PSUBH | PCGTH | PMAXH
1785 * 2 010 | PADDB | PSUBB | PCGTB | *
1786 * 3 011 | * | * | * | *
1787 * 4 100 | PADDSW| PSUBSW| PEXTLW| PPACW
1788 * 5 101 | PADDSH| PSUBSH| PEXTLH| PPACH
1789 * 6 110 | PADDSB| PSUBSB| PEXTLB| PPACB
1790 * 7 111 | * | * | PEXT5 | PPAC5
1793 #define MASK_MMI0(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
1794 enum {
1795 MMI_OPC_0_PADDW = (0x00 << 6) | MMI_OPC_CLASS_MMI0,
1796 MMI_OPC_0_PSUBW = (0x01 << 6) | MMI_OPC_CLASS_MMI0,
1797 MMI_OPC_0_PCGTW = (0x02 << 6) | MMI_OPC_CLASS_MMI0,
1798 MMI_OPC_0_PMAXW = (0x03 << 6) | MMI_OPC_CLASS_MMI0,
1799 MMI_OPC_0_PADDH = (0x04 << 6) | MMI_OPC_CLASS_MMI0,
1800 MMI_OPC_0_PSUBH = (0x05 << 6) | MMI_OPC_CLASS_MMI0,
1801 MMI_OPC_0_PCGTH = (0x06 << 6) | MMI_OPC_CLASS_MMI0,
1802 MMI_OPC_0_PMAXH = (0x07 << 6) | MMI_OPC_CLASS_MMI0,
1803 MMI_OPC_0_PADDB = (0x08 << 6) | MMI_OPC_CLASS_MMI0,
1804 MMI_OPC_0_PSUBB = (0x09 << 6) | MMI_OPC_CLASS_MMI0,
1805 MMI_OPC_0_PCGTB = (0x0A << 6) | MMI_OPC_CLASS_MMI0,
1806 MMI_OPC_0_PADDSW = (0x10 << 6) | MMI_OPC_CLASS_MMI0,
1807 MMI_OPC_0_PSUBSW = (0x11 << 6) | MMI_OPC_CLASS_MMI0,
1808 MMI_OPC_0_PEXTLW = (0x12 << 6) | MMI_OPC_CLASS_MMI0,
1809 MMI_OPC_0_PPACW = (0x13 << 6) | MMI_OPC_CLASS_MMI0,
1810 MMI_OPC_0_PADDSH = (0x14 << 6) | MMI_OPC_CLASS_MMI0,
1811 MMI_OPC_0_PSUBSH = (0x15 << 6) | MMI_OPC_CLASS_MMI0,
1812 MMI_OPC_0_PEXTLH = (0x16 << 6) | MMI_OPC_CLASS_MMI0,
1813 MMI_OPC_0_PPACH = (0x17 << 6) | MMI_OPC_CLASS_MMI0,
1814 MMI_OPC_0_PADDSB = (0x18 << 6) | MMI_OPC_CLASS_MMI0,
1815 MMI_OPC_0_PSUBSB = (0x19 << 6) | MMI_OPC_CLASS_MMI0,
1816 MMI_OPC_0_PEXTLB = (0x1A << 6) | MMI_OPC_CLASS_MMI0,
1817 MMI_OPC_0_PPACB = (0x1B << 6) | MMI_OPC_CLASS_MMI0,
1818 MMI_OPC_0_PEXT5 = (0x1E << 6) | MMI_OPC_CLASS_MMI0,
1819 MMI_OPC_0_PPAC5 = (0x1F << 6) | MMI_OPC_CLASS_MMI0,
1823 * MMI instructions with opcode field = MMI and bits 5..0 = MMI1:
1825 * 31 26 10 6 5 0
1826 * +--------+----------------------+--------+--------+
1827 * | MMI | |function| MMI1 |
1828 * +--------+----------------------+--------+--------+
1830 * function bits 7..6
1831 * bits | 0 | 1 | 2 | 3
1832 * 10..8 | 00 | 01 | 10 | 11
1833 * -------+-------+-------+-------+-------
1834 * 0 000 | * | PABSW | PCEQW | PMINW
1835 * 1 001 | PADSBH| PABSH | PCEQH | PMINH
1836 * 2 010 | * | * | PCEQB | *
1837 * 3 011 | * | * | * | *
1838 * 4 100 | PADDUW| PSUBUW| PEXTUW| *
1839 * 5 101 | PADDUH| PSUBUH| PEXTUH| *
1840 * 6 110 | PADDUB| PSUBUB| PEXTUB| QFSRV
1841 * 7 111 | * | * | * | *
1844 #define MASK_MMI1(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
1845 enum {
1846 MMI_OPC_1_PABSW = (0x01 << 6) | MMI_OPC_CLASS_MMI1,
1847 MMI_OPC_1_PCEQW = (0x02 << 6) | MMI_OPC_CLASS_MMI1,
1848 MMI_OPC_1_PMINW = (0x03 << 6) | MMI_OPC_CLASS_MMI1,
1849 MMI_OPC_1_PADSBH = (0x04 << 6) | MMI_OPC_CLASS_MMI1,
1850 MMI_OPC_1_PABSH = (0x05 << 6) | MMI_OPC_CLASS_MMI1,
1851 MMI_OPC_1_PCEQH = (0x06 << 6) | MMI_OPC_CLASS_MMI1,
1852 MMI_OPC_1_PMINH = (0x07 << 6) | MMI_OPC_CLASS_MMI1,
1853 MMI_OPC_1_PCEQB = (0x0A << 6) | MMI_OPC_CLASS_MMI1,
1854 MMI_OPC_1_PADDUW = (0x10 << 6) | MMI_OPC_CLASS_MMI1,
1855 MMI_OPC_1_PSUBUW = (0x11 << 6) | MMI_OPC_CLASS_MMI1,
1856 MMI_OPC_1_PEXTUW = (0x12 << 6) | MMI_OPC_CLASS_MMI1,
1857 MMI_OPC_1_PADDUH = (0x14 << 6) | MMI_OPC_CLASS_MMI1,
1858 MMI_OPC_1_PSUBUH = (0x15 << 6) | MMI_OPC_CLASS_MMI1,
1859 MMI_OPC_1_PEXTUH = (0x16 << 6) | MMI_OPC_CLASS_MMI1,
1860 MMI_OPC_1_PADDUB = (0x18 << 6) | MMI_OPC_CLASS_MMI1,
1861 MMI_OPC_1_PSUBUB = (0x19 << 6) | MMI_OPC_CLASS_MMI1,
1862 MMI_OPC_1_PEXTUB = (0x1A << 6) | MMI_OPC_CLASS_MMI1,
1863 MMI_OPC_1_QFSRV = (0x1B << 6) | MMI_OPC_CLASS_MMI1,
1867 * MMI instructions with opcode field = MMI and bits 5..0 = MMI2:
1869 * 31 26 10 6 5 0
1870 * +--------+----------------------+--------+--------+
1871 * | MMI | |function| MMI2 |
1872 * +--------+----------------------+--------+--------+
1874 * function bits 7..6
1875 * bits | 0 | 1 | 2 | 3
1876 * 10..8 | 00 | 01 | 10 | 11
1877 * -------+-------+-------+-------+-------
1878 * 0 000 | PMADDW| * | PSLLVW| PSRLVW
1879 * 1 001 | PMSUBW| * | * | *
1880 * 2 010 | PMFHI | PMFLO | PINTH | *
1881 * 3 011 | PMULTW| PDIVW | PCPYLD| *
1882 * 4 100 | PMADDH| PHMADH| PAND | PXOR
1883 * 5 101 | PMSUBH| PHMSBH| * | *
1884 * 6 110 | * | * | PEXEH | PREVH
1885 * 7 111 | PMULTH| PDIVBW| PEXEW | PROT3W
1888 #define MASK_MMI2(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
1889 enum {
1890 MMI_OPC_2_PMADDW = (0x00 << 6) | MMI_OPC_CLASS_MMI2,
1891 MMI_OPC_2_PSLLVW = (0x02 << 6) | MMI_OPC_CLASS_MMI2,
1892 MMI_OPC_2_PSRLVW = (0x03 << 6) | MMI_OPC_CLASS_MMI2,
1893 MMI_OPC_2_PMSUBW = (0x04 << 6) | MMI_OPC_CLASS_MMI2,
1894 MMI_OPC_2_PMFHI = (0x08 << 6) | MMI_OPC_CLASS_MMI2,
1895 MMI_OPC_2_PMFLO = (0x09 << 6) | MMI_OPC_CLASS_MMI2,
1896 MMI_OPC_2_PINTH = (0x0A << 6) | MMI_OPC_CLASS_MMI2,
1897 MMI_OPC_2_PMULTW = (0x0C << 6) | MMI_OPC_CLASS_MMI2,
1898 MMI_OPC_2_PDIVW = (0x0D << 6) | MMI_OPC_CLASS_MMI2,
1899 MMI_OPC_2_PCPYLD = (0x0E << 6) | MMI_OPC_CLASS_MMI2,
1900 MMI_OPC_2_PMADDH = (0x10 << 6) | MMI_OPC_CLASS_MMI2,
1901 MMI_OPC_2_PHMADH = (0x11 << 6) | MMI_OPC_CLASS_MMI2,
1902 MMI_OPC_2_PAND = (0x12 << 6) | MMI_OPC_CLASS_MMI2,
1903 MMI_OPC_2_PXOR = (0x13 << 6) | MMI_OPC_CLASS_MMI2,
1904 MMI_OPC_2_PMSUBH = (0x14 << 6) | MMI_OPC_CLASS_MMI2,
1905 MMI_OPC_2_PHMSBH = (0x15 << 6) | MMI_OPC_CLASS_MMI2,
1906 MMI_OPC_2_PEXEH = (0x1A << 6) | MMI_OPC_CLASS_MMI2,
1907 MMI_OPC_2_PREVH = (0x1B << 6) | MMI_OPC_CLASS_MMI2,
1908 MMI_OPC_2_PMULTH = (0x1C << 6) | MMI_OPC_CLASS_MMI2,
1909 MMI_OPC_2_PDIVBW = (0x1D << 6) | MMI_OPC_CLASS_MMI2,
1910 MMI_OPC_2_PEXEW = (0x1E << 6) | MMI_OPC_CLASS_MMI2,
1911 MMI_OPC_2_PROT3W = (0x1F << 6) | MMI_OPC_CLASS_MMI2,
1915 * MMI instructions with opcode field = MMI and bits 5..0 = MMI3:
1917 * 31 26 10 6 5 0
1918 * +--------+----------------------+--------+--------+
1919 * | MMI | |function| MMI3 |
1920 * +--------+----------------------+--------+--------+
1922 * function bits 7..6
1923 * bits | 0 | 1 | 2 | 3
1924 * 10..8 | 00 | 01 | 10 | 11
1925 * -------+-------+-------+-------+-------
1926 * 0 000 |PMADDUW| * | * | PSRAVW
1927 * 1 001 | * | * | * | *
1928 * 2 010 | PMTHI | PMTLO | PINTEH| *
1929 * 3 011 |PMULTUW| PDIVUW| PCPYUD| *
1930 * 4 100 | * | * | POR | PNOR
1931 * 5 101 | * | * | * | *
1932 * 6 110 | * | * | PEXCH | PCPYH
1933 * 7 111 | * | * | PEXCW | *
1936 #define MASK_MMI3(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
1937 enum {
1938 MMI_OPC_3_PMADDUW = (0x00 << 6) | MMI_OPC_CLASS_MMI3,
1939 MMI_OPC_3_PSRAVW = (0x03 << 6) | MMI_OPC_CLASS_MMI3,
1940 MMI_OPC_3_PMTHI = (0x08 << 6) | MMI_OPC_CLASS_MMI3,
1941 MMI_OPC_3_PMTLO = (0x09 << 6) | MMI_OPC_CLASS_MMI3,
1942 MMI_OPC_3_PINTEH = (0x0A << 6) | MMI_OPC_CLASS_MMI3,
1943 MMI_OPC_3_PMULTUW = (0x0C << 6) | MMI_OPC_CLASS_MMI3,
1944 MMI_OPC_3_PDIVUW = (0x0D << 6) | MMI_OPC_CLASS_MMI3,
1945 MMI_OPC_3_PCPYUD = (0x0E << 6) | MMI_OPC_CLASS_MMI3,
1946 MMI_OPC_3_POR = (0x12 << 6) | MMI_OPC_CLASS_MMI3,
1947 MMI_OPC_3_PNOR = (0x13 << 6) | MMI_OPC_CLASS_MMI3,
1948 MMI_OPC_3_PEXCH = (0x1A << 6) | MMI_OPC_CLASS_MMI3,
1949 MMI_OPC_3_PCPYH = (0x1B << 6) | MMI_OPC_CLASS_MMI3,
1950 MMI_OPC_3_PEXCW = (0x1E << 6) | MMI_OPC_CLASS_MMI3,
1953 /* global register indices */
1954 TCGv cpu_gpr[32], cpu_PC;
1956 * For CPUs using 128-bit GPR registers, we put the lower halves in cpu_gpr[])
1957 * and the upper halves in cpu_gpr_hi[].
1959 TCGv_i64 cpu_gpr_hi[32];
1960 TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC];
1961 static TCGv cpu_dspctrl, btarget;
1962 TCGv bcond;
1963 static TCGv cpu_lladdr, cpu_llval;
1964 static TCGv_i32 hflags;
1965 TCGv_i32 fpu_fcr0, fpu_fcr31;
1966 TCGv_i64 fpu_f64[32];
1968 #if !defined(TARGET_MIPS64)
1969 /* MXU registers */
1970 static TCGv mxu_gpr[NUMBER_OF_MXU_REGISTERS - 1];
1971 static TCGv mxu_CR;
1972 #endif
1974 #include "exec/gen-icount.h"
1976 #define gen_helper_0e0i(name, arg) do { \
1977 TCGv_i32 helper_tmp = tcg_const_i32(arg); \
1978 gen_helper_##name(cpu_env, helper_tmp); \
1979 tcg_temp_free_i32(helper_tmp); \
1980 } while (0)
1982 #define gen_helper_0e1i(name, arg1, arg2) do { \
1983 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
1984 gen_helper_##name(cpu_env, arg1, helper_tmp); \
1985 tcg_temp_free_i32(helper_tmp); \
1986 } while (0)
1988 #define gen_helper_1e0i(name, ret, arg1) do { \
1989 TCGv_i32 helper_tmp = tcg_const_i32(arg1); \
1990 gen_helper_##name(ret, cpu_env, helper_tmp); \
1991 tcg_temp_free_i32(helper_tmp); \
1992 } while (0)
1994 #define gen_helper_1e1i(name, ret, arg1, arg2) do { \
1995 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
1996 gen_helper_##name(ret, cpu_env, arg1, helper_tmp); \
1997 tcg_temp_free_i32(helper_tmp); \
1998 } while (0)
2000 #define gen_helper_0e2i(name, arg1, arg2, arg3) do { \
2001 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
2002 gen_helper_##name(cpu_env, arg1, arg2, helper_tmp); \
2003 tcg_temp_free_i32(helper_tmp); \
2004 } while (0)
2006 #define gen_helper_1e2i(name, ret, arg1, arg2, arg3) do { \
2007 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
2008 gen_helper_##name(ret, cpu_env, arg1, arg2, helper_tmp); \
2009 tcg_temp_free_i32(helper_tmp); \
2010 } while (0)
2012 #define gen_helper_0e3i(name, arg1, arg2, arg3, arg4) do { \
2013 TCGv_i32 helper_tmp = tcg_const_i32(arg4); \
2014 gen_helper_##name(cpu_env, arg1, arg2, arg3, helper_tmp); \
2015 tcg_temp_free_i32(helper_tmp); \
2016 } while (0)
2018 #define DISAS_STOP DISAS_TARGET_0
2019 #define DISAS_EXIT DISAS_TARGET_1
2021 static const char * const regnames[] = {
2022 "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
2023 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
2024 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
2025 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
2028 static const char * const regnames_HI[] = {
2029 "HI0", "HI1", "HI2", "HI3",
2032 static const char * const regnames_LO[] = {
2033 "LO0", "LO1", "LO2", "LO3",
2036 static const char * const fregnames[] = {
2037 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
2038 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
2039 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
2040 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
2043 #if !defined(TARGET_MIPS64)
2044 static const char * const mxuregnames[] = {
2045 "XR1", "XR2", "XR3", "XR4", "XR5", "XR6", "XR7", "XR8",
2046 "XR9", "XR10", "XR11", "XR12", "XR13", "XR14", "XR15", "MXU_CR",
2049 void mxu_translate_init(void)
2051 for (unsigned i = 0; i < NUMBER_OF_MXU_REGISTERS - 1; i++) {
2052 mxu_gpr[i] = tcg_global_mem_new(cpu_env,
2053 offsetof(CPUMIPSState, active_tc.mxu_gpr[i]),
2054 mxuregnames[i]);
2057 mxu_CR = tcg_global_mem_new(cpu_env,
2058 offsetof(CPUMIPSState, active_tc.mxu_cr),
2059 mxuregnames[NUMBER_OF_MXU_REGISTERS - 1]);
2061 #endif /* !TARGET_MIPS64 */
2063 /* General purpose registers moves. */
2064 void gen_load_gpr(TCGv t, int reg)
2066 if (reg == 0) {
2067 tcg_gen_movi_tl(t, 0);
2068 } else {
2069 tcg_gen_mov_tl(t, cpu_gpr[reg]);
2073 void gen_store_gpr(TCGv t, int reg)
2075 if (reg != 0) {
2076 tcg_gen_mov_tl(cpu_gpr[reg], t);
2080 #if defined(TARGET_MIPS64)
2081 void gen_load_gpr_hi(TCGv_i64 t, int reg)
2083 if (reg == 0) {
2084 tcg_gen_movi_i64(t, 0);
2085 } else {
2086 tcg_gen_mov_i64(t, cpu_gpr_hi[reg]);
2090 void gen_store_gpr_hi(TCGv_i64 t, int reg)
2092 if (reg != 0) {
2093 tcg_gen_mov_i64(cpu_gpr_hi[reg], t);
2096 #endif /* TARGET_MIPS64 */
2098 /* Moves to/from shadow registers. */
2099 static inline void gen_load_srsgpr(int from, int to)
2101 TCGv t0 = tcg_temp_new();
2103 if (from == 0) {
2104 tcg_gen_movi_tl(t0, 0);
2105 } else {
2106 TCGv_i32 t2 = tcg_temp_new_i32();
2107 TCGv_ptr addr = tcg_temp_new_ptr();
2109 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
2110 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
2111 tcg_gen_andi_i32(t2, t2, 0xf);
2112 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
2113 tcg_gen_ext_i32_ptr(addr, t2);
2114 tcg_gen_add_ptr(addr, cpu_env, addr);
2116 tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from);
2117 tcg_temp_free_ptr(addr);
2118 tcg_temp_free_i32(t2);
2120 gen_store_gpr(t0, to);
2121 tcg_temp_free(t0);
2124 static inline void gen_store_srsgpr(int from, int to)
2126 if (to != 0) {
2127 TCGv t0 = tcg_temp_new();
2128 TCGv_i32 t2 = tcg_temp_new_i32();
2129 TCGv_ptr addr = tcg_temp_new_ptr();
2131 gen_load_gpr(t0, from);
2132 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
2133 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
2134 tcg_gen_andi_i32(t2, t2, 0xf);
2135 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
2136 tcg_gen_ext_i32_ptr(addr, t2);
2137 tcg_gen_add_ptr(addr, cpu_env, addr);
2139 tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to);
2140 tcg_temp_free_ptr(addr);
2141 tcg_temp_free_i32(t2);
2142 tcg_temp_free(t0);
2146 #if !defined(TARGET_MIPS64)
2147 /* MXU General purpose registers moves. */
2148 static inline void gen_load_mxu_gpr(TCGv t, unsigned int reg)
2150 if (reg == 0) {
2151 tcg_gen_movi_tl(t, 0);
2152 } else if (reg <= 15) {
2153 tcg_gen_mov_tl(t, mxu_gpr[reg - 1]);
2157 static inline void gen_store_mxu_gpr(TCGv t, unsigned int reg)
2159 if (reg > 0 && reg <= 15) {
2160 tcg_gen_mov_tl(mxu_gpr[reg - 1], t);
2164 /* MXU control register moves. */
2165 static inline void gen_load_mxu_cr(TCGv t)
2167 tcg_gen_mov_tl(t, mxu_CR);
2170 static inline void gen_store_mxu_cr(TCGv t)
2172 /* TODO: Add handling of RW rules for MXU_CR. */
2173 tcg_gen_mov_tl(mxu_CR, t);
2175 #endif
2178 /* Tests */
2179 static inline void gen_save_pc(target_ulong pc)
2181 tcg_gen_movi_tl(cpu_PC, pc);
2184 static inline void save_cpu_state(DisasContext *ctx, int do_save_pc)
2186 LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
2187 if (do_save_pc && ctx->base.pc_next != ctx->saved_pc) {
2188 gen_save_pc(ctx->base.pc_next);
2189 ctx->saved_pc = ctx->base.pc_next;
2191 if (ctx->hflags != ctx->saved_hflags) {
2192 tcg_gen_movi_i32(hflags, ctx->hflags);
2193 ctx->saved_hflags = ctx->hflags;
2194 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
2195 case MIPS_HFLAG_BR:
2196 break;
2197 case MIPS_HFLAG_BC:
2198 case MIPS_HFLAG_BL:
2199 case MIPS_HFLAG_B:
2200 tcg_gen_movi_tl(btarget, ctx->btarget);
2201 break;
2206 static inline void restore_cpu_state(CPUMIPSState *env, DisasContext *ctx)
2208 ctx->saved_hflags = ctx->hflags;
2209 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
2210 case MIPS_HFLAG_BR:
2211 break;
2212 case MIPS_HFLAG_BC:
2213 case MIPS_HFLAG_BL:
2214 case MIPS_HFLAG_B:
2215 ctx->btarget = env->btarget;
2216 break;
2220 void generate_exception_err(DisasContext *ctx, int excp, int err)
2222 TCGv_i32 texcp = tcg_const_i32(excp);
2223 TCGv_i32 terr = tcg_const_i32(err);
2224 save_cpu_state(ctx, 1);
2225 gen_helper_raise_exception_err(cpu_env, texcp, terr);
2226 tcg_temp_free_i32(terr);
2227 tcg_temp_free_i32(texcp);
2228 ctx->base.is_jmp = DISAS_NORETURN;
2231 void generate_exception(DisasContext *ctx, int excp)
2233 gen_helper_0e0i(raise_exception, excp);
2236 void generate_exception_end(DisasContext *ctx, int excp)
2238 generate_exception_err(ctx, excp, 0);
2241 void gen_reserved_instruction(DisasContext *ctx)
2243 generate_exception_end(ctx, EXCP_RI);
2246 /* Floating point register moves. */
2247 void gen_load_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
2249 if (ctx->hflags & MIPS_HFLAG_FRE) {
2250 generate_exception(ctx, EXCP_RI);
2252 tcg_gen_extrl_i64_i32(t, fpu_f64[reg]);
2255 void gen_store_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
2257 TCGv_i64 t64;
2258 if (ctx->hflags & MIPS_HFLAG_FRE) {
2259 generate_exception(ctx, EXCP_RI);
2261 t64 = tcg_temp_new_i64();
2262 tcg_gen_extu_i32_i64(t64, t);
2263 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 0, 32);
2264 tcg_temp_free_i64(t64);
2267 static void gen_load_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
2269 if (ctx->hflags & MIPS_HFLAG_F64) {
2270 tcg_gen_extrh_i64_i32(t, fpu_f64[reg]);
2271 } else {
2272 gen_load_fpr32(ctx, t, reg | 1);
2276 static void gen_store_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
2278 if (ctx->hflags & MIPS_HFLAG_F64) {
2279 TCGv_i64 t64 = tcg_temp_new_i64();
2280 tcg_gen_extu_i32_i64(t64, t);
2281 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 32, 32);
2282 tcg_temp_free_i64(t64);
2283 } else {
2284 gen_store_fpr32(ctx, t, reg | 1);
2288 void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
2290 if (ctx->hflags & MIPS_HFLAG_F64) {
2291 tcg_gen_mov_i64(t, fpu_f64[reg]);
2292 } else {
2293 tcg_gen_concat32_i64(t, fpu_f64[reg & ~1], fpu_f64[reg | 1]);
2297 void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
2299 if (ctx->hflags & MIPS_HFLAG_F64) {
2300 tcg_gen_mov_i64(fpu_f64[reg], t);
2301 } else {
2302 TCGv_i64 t0;
2303 tcg_gen_deposit_i64(fpu_f64[reg & ~1], fpu_f64[reg & ~1], t, 0, 32);
2304 t0 = tcg_temp_new_i64();
2305 tcg_gen_shri_i64(t0, t, 32);
2306 tcg_gen_deposit_i64(fpu_f64[reg | 1], fpu_f64[reg | 1], t0, 0, 32);
2307 tcg_temp_free_i64(t0);
2311 int get_fp_bit(int cc)
2313 if (cc) {
2314 return 24 + cc;
2315 } else {
2316 return 23;
2320 /* Addresses computation */
2321 void gen_op_addr_add(DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1)
2323 tcg_gen_add_tl(ret, arg0, arg1);
2325 #if defined(TARGET_MIPS64)
2326 if (ctx->hflags & MIPS_HFLAG_AWRAP) {
2327 tcg_gen_ext32s_i64(ret, ret);
2329 #endif
2332 static inline void gen_op_addr_addi(DisasContext *ctx, TCGv ret, TCGv base,
2333 target_long ofs)
2335 tcg_gen_addi_tl(ret, base, ofs);
2337 #if defined(TARGET_MIPS64)
2338 if (ctx->hflags & MIPS_HFLAG_AWRAP) {
2339 tcg_gen_ext32s_i64(ret, ret);
2341 #endif
2344 /* Addresses computation (translation time) */
2345 static target_long addr_add(DisasContext *ctx, target_long base,
2346 target_long offset)
2348 target_long sum = base + offset;
2350 #if defined(TARGET_MIPS64)
2351 if (ctx->hflags & MIPS_HFLAG_AWRAP) {
2352 sum = (int32_t)sum;
2354 #endif
2355 return sum;
2358 /* Sign-extract the low 32-bits to a target_long. */
2359 void gen_move_low32(TCGv ret, TCGv_i64 arg)
2361 #if defined(TARGET_MIPS64)
2362 tcg_gen_ext32s_i64(ret, arg);
2363 #else
2364 tcg_gen_extrl_i64_i32(ret, arg);
2365 #endif
2368 /* Sign-extract the high 32-bits to a target_long. */
2369 void gen_move_high32(TCGv ret, TCGv_i64 arg)
2371 #if defined(TARGET_MIPS64)
2372 tcg_gen_sari_i64(ret, arg, 32);
2373 #else
2374 tcg_gen_extrh_i64_i32(ret, arg);
2375 #endif
2378 void check_cp0_enabled(DisasContext *ctx)
2380 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0))) {
2381 generate_exception_end(ctx, EXCP_CpU);
2385 void check_cp1_enabled(DisasContext *ctx)
2387 if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU))) {
2388 generate_exception_err(ctx, EXCP_CpU, 1);
2393 * Verify that the processor is running with COP1X instructions enabled.
2394 * This is associated with the nabla symbol in the MIPS32 and MIPS64
2395 * opcode tables.
2397 void check_cop1x(DisasContext *ctx)
2399 if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X))) {
2400 gen_reserved_instruction(ctx);
2405 * Verify that the processor is running with 64-bit floating-point
2406 * operations enabled.
2408 void check_cp1_64bitmode(DisasContext *ctx)
2410 if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X))) {
2411 gen_reserved_instruction(ctx);
2416 * Verify if floating point register is valid; an operation is not defined
2417 * if bit 0 of any register specification is set and the FR bit in the
2418 * Status register equals zero, since the register numbers specify an
2419 * even-odd pair of adjacent coprocessor general registers. When the FR bit
2420 * in the Status register equals one, both even and odd register numbers
2421 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
2423 * Multiple 64 bit wide registers can be checked by calling
2424 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
2426 void check_cp1_registers(DisasContext *ctx, int regs)
2428 if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1))) {
2429 gen_reserved_instruction(ctx);
2434 * Verify that the processor is running with DSP instructions enabled.
2435 * This is enabled by CP0 Status register MX(24) bit.
2437 static inline void check_dsp(DisasContext *ctx)
2439 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP))) {
2440 if (ctx->insn_flags & ASE_DSP) {
2441 generate_exception_end(ctx, EXCP_DSPDIS);
2442 } else {
2443 gen_reserved_instruction(ctx);
2448 static inline void check_dsp_r2(DisasContext *ctx)
2450 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP_R2))) {
2451 if (ctx->insn_flags & ASE_DSP) {
2452 generate_exception_end(ctx, EXCP_DSPDIS);
2453 } else {
2454 gen_reserved_instruction(ctx);
2459 static inline void check_dsp_r3(DisasContext *ctx)
2461 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP_R3))) {
2462 if (ctx->insn_flags & ASE_DSP) {
2463 generate_exception_end(ctx, EXCP_DSPDIS);
2464 } else {
2465 gen_reserved_instruction(ctx);
2471 * This code generates a "reserved instruction" exception if the
2472 * CPU does not support the instruction set corresponding to flags.
2474 void check_insn(DisasContext *ctx, uint64_t flags)
2476 if (unlikely(!(ctx->insn_flags & flags))) {
2477 gen_reserved_instruction(ctx);
2482 * This code generates a "reserved instruction" exception if the
2483 * CPU has corresponding flag set which indicates that the instruction
2484 * has been removed.
2486 static inline void check_insn_opc_removed(DisasContext *ctx, uint64_t flags)
2488 if (unlikely(ctx->insn_flags & flags)) {
2489 gen_reserved_instruction(ctx);
2494 * The Linux kernel traps certain reserved instruction exceptions to
2495 * emulate the corresponding instructions. QEMU is the kernel in user
2496 * mode, so those traps are emulated by accepting the instructions.
2498 * A reserved instruction exception is generated for flagged CPUs if
2499 * QEMU runs in system mode.
2501 static inline void check_insn_opc_user_only(DisasContext *ctx, uint64_t flags)
2503 #ifndef CONFIG_USER_ONLY
2504 check_insn_opc_removed(ctx, flags);
2505 #endif
2509 * This code generates a "reserved instruction" exception if the
2510 * CPU does not support 64-bit paired-single (PS) floating point data type.
2512 static inline void check_ps(DisasContext *ctx)
2514 if (unlikely(!ctx->ps)) {
2515 generate_exception(ctx, EXCP_RI);
2517 check_cp1_64bitmode(ctx);
2521 * This code generates a "reserved instruction" exception if cpu is not
2522 * 64-bit or 64-bit instructions are not enabled.
2524 void check_mips_64(DisasContext *ctx)
2526 if (unlikely((TARGET_LONG_BITS != 64) || !(ctx->hflags & MIPS_HFLAG_64))) {
2527 gen_reserved_instruction(ctx);
2531 #ifndef CONFIG_USER_ONLY
2532 static inline void check_mvh(DisasContext *ctx)
2534 if (unlikely(!ctx->mvh)) {
2535 generate_exception(ctx, EXCP_RI);
2538 #endif
2541 * This code generates a "reserved instruction" exception if the
2542 * Config5 XNP bit is set.
2544 static inline void check_xnp(DisasContext *ctx)
2546 if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_XNP))) {
2547 gen_reserved_instruction(ctx);
2551 #ifndef CONFIG_USER_ONLY
2553 * This code generates a "reserved instruction" exception if the
2554 * Config3 PW bit is NOT set.
2556 static inline void check_pw(DisasContext *ctx)
2558 if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_PW)))) {
2559 gen_reserved_instruction(ctx);
2562 #endif
2565 * This code generates a "reserved instruction" exception if the
2566 * Config3 MT bit is NOT set.
2568 static inline void check_mt(DisasContext *ctx)
2570 if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_MT)))) {
2571 gen_reserved_instruction(ctx);
2575 #ifndef CONFIG_USER_ONLY
2577 * This code generates a "coprocessor unusable" exception if CP0 is not
2578 * available, and, if that is not the case, generates a "reserved instruction"
2579 * exception if the Config5 MT bit is NOT set. This is needed for availability
2580 * control of some of MT ASE instructions.
2582 static inline void check_cp0_mt(DisasContext *ctx)
2584 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0))) {
2585 generate_exception_end(ctx, EXCP_CpU);
2586 } else {
2587 if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_MT)))) {
2588 gen_reserved_instruction(ctx);
2592 #endif
2595 * This code generates a "reserved instruction" exception if the
2596 * Config5 NMS bit is set.
2598 static inline void check_nms(DisasContext *ctx)
2600 if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_NMS))) {
2601 gen_reserved_instruction(ctx);
2606 * This code generates a "reserved instruction" exception if the
2607 * Config5 NMS bit is set, and Config1 DL, Config1 IL, Config2 SL,
2608 * Config2 TL, and Config5 L2C are unset.
2610 static inline void check_nms_dl_il_sl_tl_l2c(DisasContext *ctx)
2612 if (unlikely((ctx->CP0_Config5 & (1 << CP0C5_NMS)) &&
2613 !(ctx->CP0_Config1 & (1 << CP0C1_DL)) &&
2614 !(ctx->CP0_Config1 & (1 << CP0C1_IL)) &&
2615 !(ctx->CP0_Config2 & (1 << CP0C2_SL)) &&
2616 !(ctx->CP0_Config2 & (1 << CP0C2_TL)) &&
2617 !(ctx->CP0_Config5 & (1 << CP0C5_L2C)))) {
2618 gen_reserved_instruction(ctx);
2623 * This code generates a "reserved instruction" exception if the
2624 * Config5 EVA bit is NOT set.
2626 static inline void check_eva(DisasContext *ctx)
2628 if (unlikely(!(ctx->CP0_Config5 & (1 << CP0C5_EVA)))) {
2629 gen_reserved_instruction(ctx);
2635 * Define small wrappers for gen_load_fpr* so that we have a uniform
2636 * calling interface for 32 and 64-bit FPRs. No sense in changing
2637 * all callers for gen_load_fpr32 when we need the CTX parameter for
2638 * this one use.
2640 #define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(ctx, x, y)
2641 #define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
2642 #define FOP_CONDS(type, abs, fmt, ifmt, bits) \
2643 static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \
2644 int ft, int fs, int cc) \
2646 TCGv_i##bits fp0 = tcg_temp_new_i##bits(); \
2647 TCGv_i##bits fp1 = tcg_temp_new_i##bits(); \
2648 switch (ifmt) { \
2649 case FMT_PS: \
2650 check_ps(ctx); \
2651 break; \
2652 case FMT_D: \
2653 if (abs) { \
2654 check_cop1x(ctx); \
2656 check_cp1_registers(ctx, fs | ft); \
2657 break; \
2658 case FMT_S: \
2659 if (abs) { \
2660 check_cop1x(ctx); \
2662 break; \
2664 gen_ldcmp_fpr##bits(ctx, fp0, fs); \
2665 gen_ldcmp_fpr##bits(ctx, fp1, ft); \
2666 switch (n) { \
2667 case 0: \
2668 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc); \
2669 break; \
2670 case 1: \
2671 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc); \
2672 break; \
2673 case 2: \
2674 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc); \
2675 break; \
2676 case 3: \
2677 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc); \
2678 break; \
2679 case 4: \
2680 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc); \
2681 break; \
2682 case 5: \
2683 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc); \
2684 break; \
2685 case 6: \
2686 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc); \
2687 break; \
2688 case 7: \
2689 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc); \
2690 break; \
2691 case 8: \
2692 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc); \
2693 break; \
2694 case 9: \
2695 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); \
2696 break; \
2697 case 10: \
2698 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc); \
2699 break; \
2700 case 11: \
2701 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc); \
2702 break; \
2703 case 12: \
2704 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc); \
2705 break; \
2706 case 13: \
2707 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc); \
2708 break; \
2709 case 14: \
2710 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc); \
2711 break; \
2712 case 15: \
2713 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc); \
2714 break; \
2715 default: \
2716 abort(); \
2718 tcg_temp_free_i##bits(fp0); \
2719 tcg_temp_free_i##bits(fp1); \
2722 FOP_CONDS(, 0, d, FMT_D, 64)
2723 FOP_CONDS(abs, 1, d, FMT_D, 64)
2724 FOP_CONDS(, 0, s, FMT_S, 32)
2725 FOP_CONDS(abs, 1, s, FMT_S, 32)
2726 FOP_CONDS(, 0, ps, FMT_PS, 64)
2727 FOP_CONDS(abs, 1, ps, FMT_PS, 64)
2728 #undef FOP_CONDS
2730 #define FOP_CONDNS(fmt, ifmt, bits, STORE) \
2731 static inline void gen_r6_cmp_ ## fmt(DisasContext *ctx, int n, \
2732 int ft, int fs, int fd) \
2734 TCGv_i ## bits fp0 = tcg_temp_new_i ## bits(); \
2735 TCGv_i ## bits fp1 = tcg_temp_new_i ## bits(); \
2736 if (ifmt == FMT_D) { \
2737 check_cp1_registers(ctx, fs | ft | fd); \
2739 gen_ldcmp_fpr ## bits(ctx, fp0, fs); \
2740 gen_ldcmp_fpr ## bits(ctx, fp1, ft); \
2741 switch (n) { \
2742 case 0: \
2743 gen_helper_r6_cmp_ ## fmt ## _af(fp0, cpu_env, fp0, fp1); \
2744 break; \
2745 case 1: \
2746 gen_helper_r6_cmp_ ## fmt ## _un(fp0, cpu_env, fp0, fp1); \
2747 break; \
2748 case 2: \
2749 gen_helper_r6_cmp_ ## fmt ## _eq(fp0, cpu_env, fp0, fp1); \
2750 break; \
2751 case 3: \
2752 gen_helper_r6_cmp_ ## fmt ## _ueq(fp0, cpu_env, fp0, fp1); \
2753 break; \
2754 case 4: \
2755 gen_helper_r6_cmp_ ## fmt ## _lt(fp0, cpu_env, fp0, fp1); \
2756 break; \
2757 case 5: \
2758 gen_helper_r6_cmp_ ## fmt ## _ult(fp0, cpu_env, fp0, fp1); \
2759 break; \
2760 case 6: \
2761 gen_helper_r6_cmp_ ## fmt ## _le(fp0, cpu_env, fp0, fp1); \
2762 break; \
2763 case 7: \
2764 gen_helper_r6_cmp_ ## fmt ## _ule(fp0, cpu_env, fp0, fp1); \
2765 break; \
2766 case 8: \
2767 gen_helper_r6_cmp_ ## fmt ## _saf(fp0, cpu_env, fp0, fp1); \
2768 break; \
2769 case 9: \
2770 gen_helper_r6_cmp_ ## fmt ## _sun(fp0, cpu_env, fp0, fp1); \
2771 break; \
2772 case 10: \
2773 gen_helper_r6_cmp_ ## fmt ## _seq(fp0, cpu_env, fp0, fp1); \
2774 break; \
2775 case 11: \
2776 gen_helper_r6_cmp_ ## fmt ## _sueq(fp0, cpu_env, fp0, fp1); \
2777 break; \
2778 case 12: \
2779 gen_helper_r6_cmp_ ## fmt ## _slt(fp0, cpu_env, fp0, fp1); \
2780 break; \
2781 case 13: \
2782 gen_helper_r6_cmp_ ## fmt ## _sult(fp0, cpu_env, fp0, fp1); \
2783 break; \
2784 case 14: \
2785 gen_helper_r6_cmp_ ## fmt ## _sle(fp0, cpu_env, fp0, fp1); \
2786 break; \
2787 case 15: \
2788 gen_helper_r6_cmp_ ## fmt ## _sule(fp0, cpu_env, fp0, fp1); \
2789 break; \
2790 case 17: \
2791 gen_helper_r6_cmp_ ## fmt ## _or(fp0, cpu_env, fp0, fp1); \
2792 break; \
2793 case 18: \
2794 gen_helper_r6_cmp_ ## fmt ## _une(fp0, cpu_env, fp0, fp1); \
2795 break; \
2796 case 19: \
2797 gen_helper_r6_cmp_ ## fmt ## _ne(fp0, cpu_env, fp0, fp1); \
2798 break; \
2799 case 25: \
2800 gen_helper_r6_cmp_ ## fmt ## _sor(fp0, cpu_env, fp0, fp1); \
2801 break; \
2802 case 26: \
2803 gen_helper_r6_cmp_ ## fmt ## _sune(fp0, cpu_env, fp0, fp1); \
2804 break; \
2805 case 27: \
2806 gen_helper_r6_cmp_ ## fmt ## _sne(fp0, cpu_env, fp0, fp1); \
2807 break; \
2808 default: \
2809 abort(); \
2811 STORE; \
2812 tcg_temp_free_i ## bits(fp0); \
2813 tcg_temp_free_i ## bits(fp1); \
2816 FOP_CONDNS(d, FMT_D, 64, gen_store_fpr64(ctx, fp0, fd))
2817 FOP_CONDNS(s, FMT_S, 32, gen_store_fpr32(ctx, fp0, fd))
2818 #undef FOP_CONDNS
2819 #undef gen_ldcmp_fpr32
2820 #undef gen_ldcmp_fpr64
2822 /* load/store instructions. */
2823 #ifdef CONFIG_USER_ONLY
2824 #define OP_LD_ATOMIC(insn, fname) \
2825 static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx, \
2826 DisasContext *ctx) \
2828 TCGv t0 = tcg_temp_new(); \
2829 tcg_gen_mov_tl(t0, arg1); \
2830 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
2831 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
2832 tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval)); \
2833 tcg_temp_free(t0); \
2835 #else
2836 #define OP_LD_ATOMIC(insn, fname) \
2837 static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx, \
2838 DisasContext *ctx) \
2840 gen_helper_1e1i(insn, ret, arg1, mem_idx); \
2842 #endif
2843 OP_LD_ATOMIC(ll, ld32s);
2844 #if defined(TARGET_MIPS64)
2845 OP_LD_ATOMIC(lld, ld64);
2846 #endif
2847 #undef OP_LD_ATOMIC
2849 void gen_base_offset_addr(DisasContext *ctx, TCGv addr, int base, int offset)
2851 if (base == 0) {
2852 tcg_gen_movi_tl(addr, offset);
2853 } else if (offset == 0) {
2854 gen_load_gpr(addr, base);
2855 } else {
2856 tcg_gen_movi_tl(addr, offset);
2857 gen_op_addr_add(ctx, addr, cpu_gpr[base], addr);
2861 static target_ulong pc_relative_pc(DisasContext *ctx)
2863 target_ulong pc = ctx->base.pc_next;
2865 if (ctx->hflags & MIPS_HFLAG_BMASK) {
2866 int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
2868 pc -= branch_bytes;
2871 pc &= ~(target_ulong)3;
2872 return pc;
2875 /* Load */
2876 static void gen_ld(DisasContext *ctx, uint32_t opc,
2877 int rt, int base, int offset)
2879 TCGv t0, t1, t2;
2880 int mem_idx = ctx->mem_idx;
2882 if (rt == 0 && ctx->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F |
2883 INSN_LOONGSON3A)) {
2885 * Loongson CPU uses a load to zero register for prefetch.
2886 * We emulate it as a NOP. On other CPU we must perform the
2887 * actual memory access.
2889 return;
2892 t0 = tcg_temp_new();
2893 gen_base_offset_addr(ctx, t0, base, offset);
2895 switch (opc) {
2896 #if defined(TARGET_MIPS64)
2897 case OPC_LWU:
2898 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL |
2899 ctx->default_tcg_memop_mask);
2900 gen_store_gpr(t0, rt);
2901 break;
2902 case OPC_LD:
2903 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ |
2904 ctx->default_tcg_memop_mask);
2905 gen_store_gpr(t0, rt);
2906 break;
2907 case OPC_LLD:
2908 case R6_OPC_LLD:
2909 op_ld_lld(t0, t0, mem_idx, ctx);
2910 gen_store_gpr(t0, rt);
2911 break;
2912 case OPC_LDL:
2913 t1 = tcg_temp_new();
2915 * Do a byte access to possibly trigger a page
2916 * fault with the unaligned address.
2918 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
2919 tcg_gen_andi_tl(t1, t0, 7);
2920 #ifndef TARGET_WORDS_BIGENDIAN
2921 tcg_gen_xori_tl(t1, t1, 7);
2922 #endif
2923 tcg_gen_shli_tl(t1, t1, 3);
2924 tcg_gen_andi_tl(t0, t0, ~7);
2925 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
2926 tcg_gen_shl_tl(t0, t0, t1);
2927 t2 = tcg_const_tl(-1);
2928 tcg_gen_shl_tl(t2, t2, t1);
2929 gen_load_gpr(t1, rt);
2930 tcg_gen_andc_tl(t1, t1, t2);
2931 tcg_temp_free(t2);
2932 tcg_gen_or_tl(t0, t0, t1);
2933 tcg_temp_free(t1);
2934 gen_store_gpr(t0, rt);
2935 break;
2936 case OPC_LDR:
2937 t1 = tcg_temp_new();
2939 * Do a byte access to possibly trigger a page
2940 * fault with the unaligned address.
2942 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
2943 tcg_gen_andi_tl(t1, t0, 7);
2944 #ifdef TARGET_WORDS_BIGENDIAN
2945 tcg_gen_xori_tl(t1, t1, 7);
2946 #endif
2947 tcg_gen_shli_tl(t1, t1, 3);
2948 tcg_gen_andi_tl(t0, t0, ~7);
2949 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
2950 tcg_gen_shr_tl(t0, t0, t1);
2951 tcg_gen_xori_tl(t1, t1, 63);
2952 t2 = tcg_const_tl(0xfffffffffffffffeull);
2953 tcg_gen_shl_tl(t2, t2, t1);
2954 gen_load_gpr(t1, rt);
2955 tcg_gen_and_tl(t1, t1, t2);
2956 tcg_temp_free(t2);
2957 tcg_gen_or_tl(t0, t0, t1);
2958 tcg_temp_free(t1);
2959 gen_store_gpr(t0, rt);
2960 break;
2961 case OPC_LDPC:
2962 t1 = tcg_const_tl(pc_relative_pc(ctx));
2963 gen_op_addr_add(ctx, t0, t0, t1);
2964 tcg_temp_free(t1);
2965 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
2966 gen_store_gpr(t0, rt);
2967 break;
2968 #endif
2969 case OPC_LWPC:
2970 t1 = tcg_const_tl(pc_relative_pc(ctx));
2971 gen_op_addr_add(ctx, t0, t0, t1);
2972 tcg_temp_free(t1);
2973 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESL);
2974 gen_store_gpr(t0, rt);
2975 break;
2976 case OPC_LWE:
2977 mem_idx = MIPS_HFLAG_UM;
2978 /* fall through */
2979 case OPC_LW:
2980 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESL |
2981 ctx->default_tcg_memop_mask);
2982 gen_store_gpr(t0, rt);
2983 break;
2984 case OPC_LHE:
2985 mem_idx = MIPS_HFLAG_UM;
2986 /* fall through */
2987 case OPC_LH:
2988 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESW |
2989 ctx->default_tcg_memop_mask);
2990 gen_store_gpr(t0, rt);
2991 break;
2992 case OPC_LHUE:
2993 mem_idx = MIPS_HFLAG_UM;
2994 /* fall through */
2995 case OPC_LHU:
2996 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUW |
2997 ctx->default_tcg_memop_mask);
2998 gen_store_gpr(t0, rt);
2999 break;
3000 case OPC_LBE:
3001 mem_idx = MIPS_HFLAG_UM;
3002 /* fall through */
3003 case OPC_LB:
3004 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_SB);
3005 gen_store_gpr(t0, rt);
3006 break;
3007 case OPC_LBUE:
3008 mem_idx = MIPS_HFLAG_UM;
3009 /* fall through */
3010 case OPC_LBU:
3011 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_UB);
3012 gen_store_gpr(t0, rt);
3013 break;
3014 case OPC_LWLE:
3015 mem_idx = MIPS_HFLAG_UM;
3016 /* fall through */
3017 case OPC_LWL:
3018 t1 = tcg_temp_new();
3020 * Do a byte access to possibly trigger a page
3021 * fault with the unaligned address.
3023 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
3024 tcg_gen_andi_tl(t1, t0, 3);
3025 #ifndef TARGET_WORDS_BIGENDIAN
3026 tcg_gen_xori_tl(t1, t1, 3);
3027 #endif
3028 tcg_gen_shli_tl(t1, t1, 3);
3029 tcg_gen_andi_tl(t0, t0, ~3);
3030 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL);
3031 tcg_gen_shl_tl(t0, t0, t1);
3032 t2 = tcg_const_tl(-1);
3033 tcg_gen_shl_tl(t2, t2, t1);
3034 gen_load_gpr(t1, rt);
3035 tcg_gen_andc_tl(t1, t1, t2);
3036 tcg_temp_free(t2);
3037 tcg_gen_or_tl(t0, t0, t1);
3038 tcg_temp_free(t1);
3039 tcg_gen_ext32s_tl(t0, t0);
3040 gen_store_gpr(t0, rt);
3041 break;
3042 case OPC_LWRE:
3043 mem_idx = MIPS_HFLAG_UM;
3044 /* fall through */
3045 case OPC_LWR:
3046 t1 = tcg_temp_new();
3048 * Do a byte access to possibly trigger a page
3049 * fault with the unaligned address.
3051 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
3052 tcg_gen_andi_tl(t1, t0, 3);
3053 #ifdef TARGET_WORDS_BIGENDIAN
3054 tcg_gen_xori_tl(t1, t1, 3);
3055 #endif
3056 tcg_gen_shli_tl(t1, t1, 3);
3057 tcg_gen_andi_tl(t0, t0, ~3);
3058 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL);
3059 tcg_gen_shr_tl(t0, t0, t1);
3060 tcg_gen_xori_tl(t1, t1, 31);
3061 t2 = tcg_const_tl(0xfffffffeull);
3062 tcg_gen_shl_tl(t2, t2, t1);
3063 gen_load_gpr(t1, rt);
3064 tcg_gen_and_tl(t1, t1, t2);
3065 tcg_temp_free(t2);
3066 tcg_gen_or_tl(t0, t0, t1);
3067 tcg_temp_free(t1);
3068 tcg_gen_ext32s_tl(t0, t0);
3069 gen_store_gpr(t0, rt);
3070 break;
3071 case OPC_LLE:
3072 mem_idx = MIPS_HFLAG_UM;
3073 /* fall through */
3074 case OPC_LL:
3075 case R6_OPC_LL:
3076 op_ld_ll(t0, t0, mem_idx, ctx);
3077 gen_store_gpr(t0, rt);
3078 break;
3080 tcg_temp_free(t0);
3083 static void gen_llwp(DisasContext *ctx, uint32_t base, int16_t offset,
3084 uint32_t reg1, uint32_t reg2)
3086 TCGv taddr = tcg_temp_new();
3087 TCGv_i64 tval = tcg_temp_new_i64();
3088 TCGv tmp1 = tcg_temp_new();
3089 TCGv tmp2 = tcg_temp_new();
3091 gen_base_offset_addr(ctx, taddr, base, offset);
3092 tcg_gen_qemu_ld64(tval, taddr, ctx->mem_idx);
3093 #ifdef TARGET_WORDS_BIGENDIAN
3094 tcg_gen_extr_i64_tl(tmp2, tmp1, tval);
3095 #else
3096 tcg_gen_extr_i64_tl(tmp1, tmp2, tval);
3097 #endif
3098 gen_store_gpr(tmp1, reg1);
3099 tcg_temp_free(tmp1);
3100 gen_store_gpr(tmp2, reg2);
3101 tcg_temp_free(tmp2);
3102 tcg_gen_st_i64(tval, cpu_env, offsetof(CPUMIPSState, llval_wp));
3103 tcg_temp_free_i64(tval);
3104 tcg_gen_st_tl(taddr, cpu_env, offsetof(CPUMIPSState, lladdr));
3105 tcg_temp_free(taddr);
3108 /* Store */
3109 static void gen_st(DisasContext *ctx, uint32_t opc, int rt,
3110 int base, int offset)
3112 TCGv t0 = tcg_temp_new();
3113 TCGv t1 = tcg_temp_new();
3114 int mem_idx = ctx->mem_idx;
3116 gen_base_offset_addr(ctx, t0, base, offset);
3117 gen_load_gpr(t1, rt);
3118 switch (opc) {
3119 #if defined(TARGET_MIPS64)
3120 case OPC_SD:
3121 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEQ |
3122 ctx->default_tcg_memop_mask);
3123 break;
3124 case OPC_SDL:
3125 gen_helper_0e2i(sdl, t1, t0, mem_idx);
3126 break;
3127 case OPC_SDR:
3128 gen_helper_0e2i(sdr, t1, t0, mem_idx);
3129 break;
3130 #endif
3131 case OPC_SWE:
3132 mem_idx = MIPS_HFLAG_UM;
3133 /* fall through */
3134 case OPC_SW:
3135 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUL |
3136 ctx->default_tcg_memop_mask);
3137 break;
3138 case OPC_SHE:
3139 mem_idx = MIPS_HFLAG_UM;
3140 /* fall through */
3141 case OPC_SH:
3142 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUW |
3143 ctx->default_tcg_memop_mask);
3144 break;
3145 case OPC_SBE:
3146 mem_idx = MIPS_HFLAG_UM;
3147 /* fall through */
3148 case OPC_SB:
3149 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_8);
3150 break;
3151 case OPC_SWLE:
3152 mem_idx = MIPS_HFLAG_UM;
3153 /* fall through */
3154 case OPC_SWL:
3155 gen_helper_0e2i(swl, t1, t0, mem_idx);
3156 break;
3157 case OPC_SWRE:
3158 mem_idx = MIPS_HFLAG_UM;
3159 /* fall through */
3160 case OPC_SWR:
3161 gen_helper_0e2i(swr, t1, t0, mem_idx);
3162 break;
3164 tcg_temp_free(t0);
3165 tcg_temp_free(t1);
3169 /* Store conditional */
3170 static void gen_st_cond(DisasContext *ctx, int rt, int base, int offset,
3171 MemOp tcg_mo, bool eva)
3173 TCGv addr, t0, val;
3174 TCGLabel *l1 = gen_new_label();
3175 TCGLabel *done = gen_new_label();
3177 t0 = tcg_temp_new();
3178 addr = tcg_temp_new();
3179 /* compare the address against that of the preceding LL */
3180 gen_base_offset_addr(ctx, addr, base, offset);
3181 tcg_gen_brcond_tl(TCG_COND_EQ, addr, cpu_lladdr, l1);
3182 tcg_temp_free(addr);
3183 tcg_gen_movi_tl(t0, 0);
3184 gen_store_gpr(t0, rt);
3185 tcg_gen_br(done);
3187 gen_set_label(l1);
3188 /* generate cmpxchg */
3189 val = tcg_temp_new();
3190 gen_load_gpr(val, rt);
3191 tcg_gen_atomic_cmpxchg_tl(t0, cpu_lladdr, cpu_llval, val,
3192 eva ? MIPS_HFLAG_UM : ctx->mem_idx, tcg_mo);
3193 tcg_gen_setcond_tl(TCG_COND_EQ, t0, t0, cpu_llval);
3194 gen_store_gpr(t0, rt);
3195 tcg_temp_free(val);
3197 gen_set_label(done);
3198 tcg_temp_free(t0);
3202 static void gen_scwp(DisasContext *ctx, uint32_t base, int16_t offset,
3203 uint32_t reg1, uint32_t reg2, bool eva)
3205 TCGv taddr = tcg_temp_local_new();
3206 TCGv lladdr = tcg_temp_local_new();
3207 TCGv_i64 tval = tcg_temp_new_i64();
3208 TCGv_i64 llval = tcg_temp_new_i64();
3209 TCGv_i64 val = tcg_temp_new_i64();
3210 TCGv tmp1 = tcg_temp_new();
3211 TCGv tmp2 = tcg_temp_new();
3212 TCGLabel *lab_fail = gen_new_label();
3213 TCGLabel *lab_done = gen_new_label();
3215 gen_base_offset_addr(ctx, taddr, base, offset);
3217 tcg_gen_ld_tl(lladdr, cpu_env, offsetof(CPUMIPSState, lladdr));
3218 tcg_gen_brcond_tl(TCG_COND_NE, taddr, lladdr, lab_fail);
3220 gen_load_gpr(tmp1, reg1);
3221 gen_load_gpr(tmp2, reg2);
3223 #ifdef TARGET_WORDS_BIGENDIAN
3224 tcg_gen_concat_tl_i64(tval, tmp2, tmp1);
3225 #else
3226 tcg_gen_concat_tl_i64(tval, tmp1, tmp2);
3227 #endif
3229 tcg_gen_ld_i64(llval, cpu_env, offsetof(CPUMIPSState, llval_wp));
3230 tcg_gen_atomic_cmpxchg_i64(val, taddr, llval, tval,
3231 eva ? MIPS_HFLAG_UM : ctx->mem_idx, MO_64);
3232 if (reg1 != 0) {
3233 tcg_gen_movi_tl(cpu_gpr[reg1], 1);
3235 tcg_gen_brcond_i64(TCG_COND_EQ, val, llval, lab_done);
3237 gen_set_label(lab_fail);
3239 if (reg1 != 0) {
3240 tcg_gen_movi_tl(cpu_gpr[reg1], 0);
3242 gen_set_label(lab_done);
3243 tcg_gen_movi_tl(lladdr, -1);
3244 tcg_gen_st_tl(lladdr, cpu_env, offsetof(CPUMIPSState, lladdr));
3247 /* Load and store */
3248 static void gen_flt_ldst(DisasContext *ctx, uint32_t opc, int ft,
3249 TCGv t0)
3252 * Don't do NOP if destination is zero: we must perform the actual
3253 * memory access.
3255 switch (opc) {
3256 case OPC_LWC1:
3258 TCGv_i32 fp0 = tcg_temp_new_i32();
3259 tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, MO_TESL |
3260 ctx->default_tcg_memop_mask);
3261 gen_store_fpr32(ctx, fp0, ft);
3262 tcg_temp_free_i32(fp0);
3264 break;
3265 case OPC_SWC1:
3267 TCGv_i32 fp0 = tcg_temp_new_i32();
3268 gen_load_fpr32(ctx, fp0, ft);
3269 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL |
3270 ctx->default_tcg_memop_mask);
3271 tcg_temp_free_i32(fp0);
3273 break;
3274 case OPC_LDC1:
3276 TCGv_i64 fp0 = tcg_temp_new_i64();
3277 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ |
3278 ctx->default_tcg_memop_mask);
3279 gen_store_fpr64(ctx, fp0, ft);
3280 tcg_temp_free_i64(fp0);
3282 break;
3283 case OPC_SDC1:
3285 TCGv_i64 fp0 = tcg_temp_new_i64();
3286 gen_load_fpr64(ctx, fp0, ft);
3287 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ |
3288 ctx->default_tcg_memop_mask);
3289 tcg_temp_free_i64(fp0);
3291 break;
3292 default:
3293 MIPS_INVAL("flt_ldst");
3294 gen_reserved_instruction(ctx);
3295 break;
3299 static void gen_cop1_ldst(DisasContext *ctx, uint32_t op, int rt,
3300 int rs, int16_t imm)
3302 TCGv t0 = tcg_temp_new();
3304 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
3305 check_cp1_enabled(ctx);
3306 switch (op) {
3307 case OPC_LDC1:
3308 case OPC_SDC1:
3309 check_insn(ctx, ISA_MIPS2);
3310 /* Fallthrough */
3311 default:
3312 gen_base_offset_addr(ctx, t0, rs, imm);
3313 gen_flt_ldst(ctx, op, rt, t0);
3315 } else {
3316 generate_exception_err(ctx, EXCP_CpU, 1);
3318 tcg_temp_free(t0);
3321 /* Arithmetic with immediate operand */
3322 static void gen_arith_imm(DisasContext *ctx, uint32_t opc,
3323 int rt, int rs, int imm)
3325 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
3327 if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
3329 * If no destination, treat it as a NOP.
3330 * For addi, we must generate the overflow exception when needed.
3332 return;
3334 switch (opc) {
3335 case OPC_ADDI:
3337 TCGv t0 = tcg_temp_local_new();
3338 TCGv t1 = tcg_temp_new();
3339 TCGv t2 = tcg_temp_new();
3340 TCGLabel *l1 = gen_new_label();
3342 gen_load_gpr(t1, rs);
3343 tcg_gen_addi_tl(t0, t1, uimm);
3344 tcg_gen_ext32s_tl(t0, t0);
3346 tcg_gen_xori_tl(t1, t1, ~uimm);
3347 tcg_gen_xori_tl(t2, t0, uimm);
3348 tcg_gen_and_tl(t1, t1, t2);
3349 tcg_temp_free(t2);
3350 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
3351 tcg_temp_free(t1);
3352 /* operands of same sign, result different sign */
3353 generate_exception(ctx, EXCP_OVERFLOW);
3354 gen_set_label(l1);
3355 tcg_gen_ext32s_tl(t0, t0);
3356 gen_store_gpr(t0, rt);
3357 tcg_temp_free(t0);
3359 break;
3360 case OPC_ADDIU:
3361 if (rs != 0) {
3362 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3363 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
3364 } else {
3365 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
3367 break;
3368 #if defined(TARGET_MIPS64)
3369 case OPC_DADDI:
3371 TCGv t0 = tcg_temp_local_new();
3372 TCGv t1 = tcg_temp_new();
3373 TCGv t2 = tcg_temp_new();
3374 TCGLabel *l1 = gen_new_label();
3376 gen_load_gpr(t1, rs);
3377 tcg_gen_addi_tl(t0, t1, uimm);
3379 tcg_gen_xori_tl(t1, t1, ~uimm);
3380 tcg_gen_xori_tl(t2, t0, uimm);
3381 tcg_gen_and_tl(t1, t1, t2);
3382 tcg_temp_free(t2);
3383 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
3384 tcg_temp_free(t1);
3385 /* operands of same sign, result different sign */
3386 generate_exception(ctx, EXCP_OVERFLOW);
3387 gen_set_label(l1);
3388 gen_store_gpr(t0, rt);
3389 tcg_temp_free(t0);
3391 break;
3392 case OPC_DADDIU:
3393 if (rs != 0) {
3394 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3395 } else {
3396 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
3398 break;
3399 #endif
3403 /* Logic with immediate operand */
3404 static void gen_logic_imm(DisasContext *ctx, uint32_t opc,
3405 int rt, int rs, int16_t imm)
3407 target_ulong uimm;
3409 if (rt == 0) {
3410 /* If no destination, treat it as a NOP. */
3411 return;
3413 uimm = (uint16_t)imm;
3414 switch (opc) {
3415 case OPC_ANDI:
3416 if (likely(rs != 0)) {
3417 tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3418 } else {
3419 tcg_gen_movi_tl(cpu_gpr[rt], 0);
3421 break;
3422 case OPC_ORI:
3423 if (rs != 0) {
3424 tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3425 } else {
3426 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
3428 break;
3429 case OPC_XORI:
3430 if (likely(rs != 0)) {
3431 tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3432 } else {
3433 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
3435 break;
3436 case OPC_LUI:
3437 if (rs != 0 && (ctx->insn_flags & ISA_MIPS_R6)) {
3438 /* OPC_AUI */
3439 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm << 16);
3440 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
3441 } else {
3442 tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
3444 break;
3446 default:
3447 break;
3451 /* Set on less than with immediate operand */
3452 static void gen_slt_imm(DisasContext *ctx, uint32_t opc,
3453 int rt, int rs, int16_t imm)
3455 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
3456 TCGv t0;
3458 if (rt == 0) {
3459 /* If no destination, treat it as a NOP. */
3460 return;
3462 t0 = tcg_temp_new();
3463 gen_load_gpr(t0, rs);
3464 switch (opc) {
3465 case OPC_SLTI:
3466 tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
3467 break;
3468 case OPC_SLTIU:
3469 tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
3470 break;
3472 tcg_temp_free(t0);
3475 /* Shifts with immediate operand */
3476 static void gen_shift_imm(DisasContext *ctx, uint32_t opc,
3477 int rt, int rs, int16_t imm)
3479 target_ulong uimm = ((uint16_t)imm) & 0x1f;
3480 TCGv t0;
3482 if (rt == 0) {
3483 /* If no destination, treat it as a NOP. */
3484 return;
3487 t0 = tcg_temp_new();
3488 gen_load_gpr(t0, rs);
3489 switch (opc) {
3490 case OPC_SLL:
3491 tcg_gen_shli_tl(t0, t0, uimm);
3492 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
3493 break;
3494 case OPC_SRA:
3495 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
3496 break;
3497 case OPC_SRL:
3498 if (uimm != 0) {
3499 tcg_gen_ext32u_tl(t0, t0);
3500 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
3501 } else {
3502 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
3504 break;
3505 case OPC_ROTR:
3506 if (uimm != 0) {
3507 TCGv_i32 t1 = tcg_temp_new_i32();
3509 tcg_gen_trunc_tl_i32(t1, t0);
3510 tcg_gen_rotri_i32(t1, t1, uimm);
3511 tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
3512 tcg_temp_free_i32(t1);
3513 } else {
3514 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
3516 break;
3517 #if defined(TARGET_MIPS64)
3518 case OPC_DSLL:
3519 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
3520 break;
3521 case OPC_DSRA:
3522 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
3523 break;
3524 case OPC_DSRL:
3525 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
3526 break;
3527 case OPC_DROTR:
3528 if (uimm != 0) {
3529 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
3530 } else {
3531 tcg_gen_mov_tl(cpu_gpr[rt], t0);
3533 break;
3534 case OPC_DSLL32:
3535 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
3536 break;
3537 case OPC_DSRA32:
3538 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
3539 break;
3540 case OPC_DSRL32:
3541 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
3542 break;
3543 case OPC_DROTR32:
3544 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
3545 break;
3546 #endif
3548 tcg_temp_free(t0);
3551 /* Arithmetic */
3552 static void gen_arith(DisasContext *ctx, uint32_t opc,
3553 int rd, int rs, int rt)
3555 if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
3556 && opc != OPC_DADD && opc != OPC_DSUB) {
3558 * If no destination, treat it as a NOP.
3559 * For add & sub, we must generate the overflow exception when needed.
3561 return;
3564 switch (opc) {
3565 case OPC_ADD:
3567 TCGv t0 = tcg_temp_local_new();
3568 TCGv t1 = tcg_temp_new();
3569 TCGv t2 = tcg_temp_new();
3570 TCGLabel *l1 = gen_new_label();
3572 gen_load_gpr(t1, rs);
3573 gen_load_gpr(t2, rt);
3574 tcg_gen_add_tl(t0, t1, t2);
3575 tcg_gen_ext32s_tl(t0, t0);
3576 tcg_gen_xor_tl(t1, t1, t2);
3577 tcg_gen_xor_tl(t2, t0, t2);
3578 tcg_gen_andc_tl(t1, t2, t1);
3579 tcg_temp_free(t2);
3580 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
3581 tcg_temp_free(t1);
3582 /* operands of same sign, result different sign */
3583 generate_exception(ctx, EXCP_OVERFLOW);
3584 gen_set_label(l1);
3585 gen_store_gpr(t0, rd);
3586 tcg_temp_free(t0);
3588 break;
3589 case OPC_ADDU:
3590 if (rs != 0 && rt != 0) {
3591 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
3592 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3593 } else if (rs == 0 && rt != 0) {
3594 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
3595 } else if (rs != 0 && rt == 0) {
3596 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
3597 } else {
3598 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3600 break;
3601 case OPC_SUB:
3603 TCGv t0 = tcg_temp_local_new();
3604 TCGv t1 = tcg_temp_new();
3605 TCGv t2 = tcg_temp_new();
3606 TCGLabel *l1 = gen_new_label();
3608 gen_load_gpr(t1, rs);
3609 gen_load_gpr(t2, rt);
3610 tcg_gen_sub_tl(t0, t1, t2);
3611 tcg_gen_ext32s_tl(t0, t0);
3612 tcg_gen_xor_tl(t2, t1, t2);
3613 tcg_gen_xor_tl(t1, t0, t1);
3614 tcg_gen_and_tl(t1, t1, t2);
3615 tcg_temp_free(t2);
3616 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
3617 tcg_temp_free(t1);
3619 * operands of different sign, first operand and the result
3620 * of different sign
3622 generate_exception(ctx, EXCP_OVERFLOW);
3623 gen_set_label(l1);
3624 gen_store_gpr(t0, rd);
3625 tcg_temp_free(t0);
3627 break;
3628 case OPC_SUBU:
3629 if (rs != 0 && rt != 0) {
3630 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
3631 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3632 } else if (rs == 0 && rt != 0) {
3633 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
3634 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3635 } else if (rs != 0 && rt == 0) {
3636 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
3637 } else {
3638 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3640 break;
3641 #if defined(TARGET_MIPS64)
3642 case OPC_DADD:
3644 TCGv t0 = tcg_temp_local_new();
3645 TCGv t1 = tcg_temp_new();
3646 TCGv t2 = tcg_temp_new();
3647 TCGLabel *l1 = gen_new_label();
3649 gen_load_gpr(t1, rs);
3650 gen_load_gpr(t2, rt);
3651 tcg_gen_add_tl(t0, t1, t2);
3652 tcg_gen_xor_tl(t1, t1, t2);
3653 tcg_gen_xor_tl(t2, t0, t2);
3654 tcg_gen_andc_tl(t1, t2, t1);
3655 tcg_temp_free(t2);
3656 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
3657 tcg_temp_free(t1);
3658 /* operands of same sign, result different sign */
3659 generate_exception(ctx, EXCP_OVERFLOW);
3660 gen_set_label(l1);
3661 gen_store_gpr(t0, rd);
3662 tcg_temp_free(t0);
3664 break;
3665 case OPC_DADDU:
3666 if (rs != 0 && rt != 0) {
3667 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
3668 } else if (rs == 0 && rt != 0) {
3669 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
3670 } else if (rs != 0 && rt == 0) {
3671 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
3672 } else {
3673 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3675 break;
3676 case OPC_DSUB:
3678 TCGv t0 = tcg_temp_local_new();
3679 TCGv t1 = tcg_temp_new();