]> Git Repo - qemu.git/blame - target/mips/translate.c
target/mips: MXU: Add missing opcodes/decoding for LX* instructions
[qemu.git] / target / mips / translate.c
CommitLineData
6af0bf9c 1/*
ab99e0e4 2 * MIPS emulation for QEMU - main translation routines
5fafdf24 3 *
6af0bf9c 4 * Copyright (c) 2004-2005 Jocelyn Mayer
6ea83fed 5 * Copyright (c) 2006 Marius Groeger (FPU operations)
bb8a53ad 6 * Copyright (c) 2006 Thiemo Seufer (MIPS32R2 support)
3c824109 7 * Copyright (c) 2009 CodeSourcery (MIPS16 and microMIPS support)
4133498f 8 * Copyright (c) 2012 Jia Liu & Dongxue Zhang (MIPS ASE DSP support)
6af0bf9c
FB
9 *
10 * This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public
12 * License as published by the Free Software Foundation; either
13 * version 2 of the License, or (at your option) any later version.
14 *
15 * This library is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Lesser General Public License for more details.
19 *
20 * You should have received a copy of the GNU Lesser General Public
8167ee88 21 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
6af0bf9c
FB
22 */
23
c684822a 24#include "qemu/osdep.h"
6af0bf9c 25#include "cpu.h"
26aa3d9a 26#include "internal.h"
76cad711 27#include "disas/disas.h"
63c91552 28#include "exec/exec-all.h"
57fec1fe 29#include "tcg-op.h"
f08b6170 30#include "exec/cpu_ldst.h"
d3d93c6c 31#include "hw/mips/cpudevs.h"
6af0bf9c 32
2ef6175a
RH
33#include "exec/helper-proto.h"
34#include "exec/helper-gen.h"
3b3c1694 35#include "exec/semihost.h"
a7812ae4 36
b44a7fb1 37#include "target/mips/trace.h"
a7e30d84 38#include "trace-tcg.h"
b28425ba 39#include "exec/translator.h"
508127e2 40#include "exec/log.h"
a7e30d84 41
fb7729e2 42#define MIPS_DEBUG_DISAS 0
6af0bf9c 43
7a387fff
TS
44/* MIPS major opcodes */
45#define MASK_OP_MAJOR(op) (op & (0x3F << 26))
e37e863f
FB
46
47enum {
48 /* indirect opcode tables */
7a387fff
TS
49 OPC_SPECIAL = (0x00 << 26),
50 OPC_REGIMM = (0x01 << 26),
51 OPC_CP0 = (0x10 << 26),
52 OPC_CP1 = (0x11 << 26),
53 OPC_CP2 = (0x12 << 26),
54 OPC_CP3 = (0x13 << 26),
55 OPC_SPECIAL2 = (0x1C << 26),
56 OPC_SPECIAL3 = (0x1F << 26),
e37e863f 57 /* arithmetic with immediate */
7a387fff
TS
58 OPC_ADDI = (0x08 << 26),
59 OPC_ADDIU = (0x09 << 26),
60 OPC_SLTI = (0x0A << 26),
61 OPC_SLTIU = (0x0B << 26),
324d9e32 62 /* logic with immediate */
7a387fff
TS
63 OPC_ANDI = (0x0C << 26),
64 OPC_ORI = (0x0D << 26),
65 OPC_XORI = (0x0E << 26),
66 OPC_LUI = (0x0F << 26),
324d9e32 67 /* arithmetic with immediate */
7a387fff
TS
68 OPC_DADDI = (0x18 << 26),
69 OPC_DADDIU = (0x19 << 26),
e37e863f 70 /* Jump and branches */
7a387fff
TS
71 OPC_J = (0x02 << 26),
72 OPC_JAL = (0x03 << 26),
73 OPC_BEQ = (0x04 << 26), /* Unconditional if rs = rt = 0 (B) */
74 OPC_BEQL = (0x14 << 26),
75 OPC_BNE = (0x05 << 26),
76 OPC_BNEL = (0x15 << 26),
77 OPC_BLEZ = (0x06 << 26),
78 OPC_BLEZL = (0x16 << 26),
79 OPC_BGTZ = (0x07 << 26),
80 OPC_BGTZL = (0x17 << 26),
b231c103 81 OPC_JALX = (0x1D << 26),
d4ea6acd 82 OPC_DAUI = (0x1D << 26),
e37e863f 83 /* Load and stores */
7a387fff
TS
84 OPC_LDL = (0x1A << 26),
85 OPC_LDR = (0x1B << 26),
86 OPC_LB = (0x20 << 26),
87 OPC_LH = (0x21 << 26),
88 OPC_LWL = (0x22 << 26),
89 OPC_LW = (0x23 << 26),
364d4831 90 OPC_LWPC = OPC_LW | 0x5,
7a387fff
TS
91 OPC_LBU = (0x24 << 26),
92 OPC_LHU = (0x25 << 26),
93 OPC_LWR = (0x26 << 26),
94 OPC_LWU = (0x27 << 26),
95 OPC_SB = (0x28 << 26),
96 OPC_SH = (0x29 << 26),
97 OPC_SWL = (0x2A << 26),
98 OPC_SW = (0x2B << 26),
99 OPC_SDL = (0x2C << 26),
100 OPC_SDR = (0x2D << 26),
101 OPC_SWR = (0x2E << 26),
102 OPC_LL = (0x30 << 26),
103 OPC_LLD = (0x34 << 26),
104 OPC_LD = (0x37 << 26),
364d4831 105 OPC_LDPC = OPC_LD | 0x5,
7a387fff
TS
106 OPC_SC = (0x38 << 26),
107 OPC_SCD = (0x3C << 26),
108 OPC_SD = (0x3F << 26),
e37e863f 109 /* Floating point load/store */
7a387fff
TS
110 OPC_LWC1 = (0x31 << 26),
111 OPC_LWC2 = (0x32 << 26),
112 OPC_LDC1 = (0x35 << 26),
113 OPC_LDC2 = (0x36 << 26),
114 OPC_SWC1 = (0x39 << 26),
115 OPC_SWC2 = (0x3A << 26),
116 OPC_SDC1 = (0x3D << 26),
117 OPC_SDC2 = (0x3E << 26),
31837be3
YK
118 /* Compact Branches */
119 OPC_BLEZALC = (0x06 << 26),
120 OPC_BGEZALC = (0x06 << 26),
121 OPC_BGEUC = (0x06 << 26),
122 OPC_BGTZALC = (0x07 << 26),
123 OPC_BLTZALC = (0x07 << 26),
124 OPC_BLTUC = (0x07 << 26),
125 OPC_BOVC = (0x08 << 26),
126 OPC_BEQZALC = (0x08 << 26),
127 OPC_BEQC = (0x08 << 26),
128 OPC_BLEZC = (0x16 << 26),
129 OPC_BGEZC = (0x16 << 26),
130 OPC_BGEC = (0x16 << 26),
131 OPC_BGTZC = (0x17 << 26),
132 OPC_BLTZC = (0x17 << 26),
133 OPC_BLTC = (0x17 << 26),
134 OPC_BNVC = (0x18 << 26),
135 OPC_BNEZALC = (0x18 << 26),
136 OPC_BNEC = (0x18 << 26),
137 OPC_BC = (0x32 << 26),
138 OPC_BEQZC = (0x36 << 26),
139 OPC_JIC = (0x36 << 26),
140 OPC_BALC = (0x3A << 26),
141 OPC_BNEZC = (0x3E << 26),
142 OPC_JIALC = (0x3E << 26),
7a387fff
TS
143 /* MDMX ASE specific */
144 OPC_MDMX = (0x1E << 26),
239dfebe
YK
145 /* MSA ASE, same as MDMX */
146 OPC_MSA = OPC_MDMX,
e37e863f 147 /* Cache and prefetch */
7a387fff
TS
148 OPC_CACHE = (0x2F << 26),
149 OPC_PREF = (0x33 << 26),
d4ea6acd
LA
150 /* PC-relative address computation / loads */
151 OPC_PCREL = (0x3B << 26),
152};
153
154/* PC-relative address computation / loads */
155#define MASK_OPC_PCREL_TOP2BITS(op) (MASK_OP_MAJOR(op) | (op & (3 << 19)))
156#define MASK_OPC_PCREL_TOP5BITS(op) (MASK_OP_MAJOR(op) | (op & (0x1f << 16)))
157enum {
158 /* Instructions determined by bits 19 and 20 */
159 OPC_ADDIUPC = OPC_PCREL | (0 << 19),
160 R6_OPC_LWPC = OPC_PCREL | (1 << 19),
161 OPC_LWUPC = OPC_PCREL | (2 << 19),
162
163 /* Instructions determined by bits 16 ... 20 */
164 OPC_AUIPC = OPC_PCREL | (0x1e << 16),
165 OPC_ALUIPC = OPC_PCREL | (0x1f << 16),
166
167 /* Other */
168 R6_OPC_LDPC = OPC_PCREL | (6 << 18),
e37e863f
FB
169};
170
171/* MIPS special opcodes */
7a387fff
TS
172#define MASK_SPECIAL(op) MASK_OP_MAJOR(op) | (op & 0x3F)
173
e37e863f
FB
174enum {
175 /* Shifts */
7a387fff 176 OPC_SLL = 0x00 | OPC_SPECIAL,
e37e863f
FB
177 /* NOP is SLL r0, r0, 0 */
178 /* SSNOP is SLL r0, r0, 1 */
7a387fff
TS
179 /* EHB is SLL r0, r0, 3 */
180 OPC_SRL = 0x02 | OPC_SPECIAL, /* also ROTR */
ea63e2c3 181 OPC_ROTR = OPC_SRL | (1 << 21),
7a387fff
TS
182 OPC_SRA = 0x03 | OPC_SPECIAL,
183 OPC_SLLV = 0x04 | OPC_SPECIAL,
e189e748 184 OPC_SRLV = 0x06 | OPC_SPECIAL, /* also ROTRV */
ea63e2c3 185 OPC_ROTRV = OPC_SRLV | (1 << 6),
7a387fff
TS
186 OPC_SRAV = 0x07 | OPC_SPECIAL,
187 OPC_DSLLV = 0x14 | OPC_SPECIAL,
188 OPC_DSRLV = 0x16 | OPC_SPECIAL, /* also DROTRV */
ea63e2c3 189 OPC_DROTRV = OPC_DSRLV | (1 << 6),
7a387fff
TS
190 OPC_DSRAV = 0x17 | OPC_SPECIAL,
191 OPC_DSLL = 0x38 | OPC_SPECIAL,
192 OPC_DSRL = 0x3A | OPC_SPECIAL, /* also DROTR */
ea63e2c3 193 OPC_DROTR = OPC_DSRL | (1 << 21),
7a387fff
TS
194 OPC_DSRA = 0x3B | OPC_SPECIAL,
195 OPC_DSLL32 = 0x3C | OPC_SPECIAL,
196 OPC_DSRL32 = 0x3E | OPC_SPECIAL, /* also DROTR32 */
ea63e2c3 197 OPC_DROTR32 = OPC_DSRL32 | (1 << 21),
7a387fff 198 OPC_DSRA32 = 0x3F | OPC_SPECIAL,
e37e863f 199 /* Multiplication / division */
7a387fff
TS
200 OPC_MULT = 0x18 | OPC_SPECIAL,
201 OPC_MULTU = 0x19 | OPC_SPECIAL,
202 OPC_DIV = 0x1A | OPC_SPECIAL,
203 OPC_DIVU = 0x1B | OPC_SPECIAL,
204 OPC_DMULT = 0x1C | OPC_SPECIAL,
205 OPC_DMULTU = 0x1D | OPC_SPECIAL,
206 OPC_DDIV = 0x1E | OPC_SPECIAL,
207 OPC_DDIVU = 0x1F | OPC_SPECIAL,
b42ee5e1 208
e37e863f 209 /* 2 registers arithmetic / logic */
7a387fff
TS
210 OPC_ADD = 0x20 | OPC_SPECIAL,
211 OPC_ADDU = 0x21 | OPC_SPECIAL,
212 OPC_SUB = 0x22 | OPC_SPECIAL,
213 OPC_SUBU = 0x23 | OPC_SPECIAL,
214 OPC_AND = 0x24 | OPC_SPECIAL,
215 OPC_OR = 0x25 | OPC_SPECIAL,
216 OPC_XOR = 0x26 | OPC_SPECIAL,
217 OPC_NOR = 0x27 | OPC_SPECIAL,
218 OPC_SLT = 0x2A | OPC_SPECIAL,
219 OPC_SLTU = 0x2B | OPC_SPECIAL,
220 OPC_DADD = 0x2C | OPC_SPECIAL,
221 OPC_DADDU = 0x2D | OPC_SPECIAL,
222 OPC_DSUB = 0x2E | OPC_SPECIAL,
223 OPC_DSUBU = 0x2F | OPC_SPECIAL,
e37e863f 224 /* Jumps */
7a387fff
TS
225 OPC_JR = 0x08 | OPC_SPECIAL, /* Also JR.HB */
226 OPC_JALR = 0x09 | OPC_SPECIAL, /* Also JALR.HB */
e37e863f 227 /* Traps */
7a387fff
TS
228 OPC_TGE = 0x30 | OPC_SPECIAL,
229 OPC_TGEU = 0x31 | OPC_SPECIAL,
230 OPC_TLT = 0x32 | OPC_SPECIAL,
231 OPC_TLTU = 0x33 | OPC_SPECIAL,
232 OPC_TEQ = 0x34 | OPC_SPECIAL,
233 OPC_TNE = 0x36 | OPC_SPECIAL,
e37e863f 234 /* HI / LO registers load & stores */
7a387fff
TS
235 OPC_MFHI = 0x10 | OPC_SPECIAL,
236 OPC_MTHI = 0x11 | OPC_SPECIAL,
237 OPC_MFLO = 0x12 | OPC_SPECIAL,
238 OPC_MTLO = 0x13 | OPC_SPECIAL,
e37e863f 239 /* Conditional moves */
7a387fff
TS
240 OPC_MOVZ = 0x0A | OPC_SPECIAL,
241 OPC_MOVN = 0x0B | OPC_SPECIAL,
e37e863f 242
b691d9d2
LA
243 OPC_SELEQZ = 0x35 | OPC_SPECIAL,
244 OPC_SELNEZ = 0x37 | OPC_SPECIAL,
245
7a387fff 246 OPC_MOVCI = 0x01 | OPC_SPECIAL,
e37e863f
FB
247
248 /* Special */
a0d700e4 249 OPC_PMON = 0x05 | OPC_SPECIAL, /* unofficial */
7a387fff
TS
250 OPC_SYSCALL = 0x0C | OPC_SPECIAL,
251 OPC_BREAK = 0x0D | OPC_SPECIAL,
a0d700e4 252 OPC_SPIM = 0x0E | OPC_SPECIAL, /* unofficial */
7a387fff
TS
253 OPC_SYNC = 0x0F | OPC_SPECIAL,
254
7a387fff
TS
255 OPC_SPECIAL28_RESERVED = 0x28 | OPC_SPECIAL,
256 OPC_SPECIAL29_RESERVED = 0x29 | OPC_SPECIAL,
7a387fff
TS
257 OPC_SPECIAL39_RESERVED = 0x39 | OPC_SPECIAL,
258 OPC_SPECIAL3D_RESERVED = 0x3D | OPC_SPECIAL,
259};
260
b42ee5e1
LA
261/* R6 Multiply and Divide instructions have the same Opcode
262 and function field as legacy OPC_MULT[U]/OPC_DIV[U] */
263#define MASK_R6_MULDIV(op) (MASK_SPECIAL(op) | (op & (0x7ff)))
264
265enum {
266 R6_OPC_MUL = OPC_MULT | (2 << 6),
267 R6_OPC_MUH = OPC_MULT | (3 << 6),
268 R6_OPC_MULU = OPC_MULTU | (2 << 6),
269 R6_OPC_MUHU = OPC_MULTU | (3 << 6),
270 R6_OPC_DIV = OPC_DIV | (2 << 6),
271 R6_OPC_MOD = OPC_DIV | (3 << 6),
272 R6_OPC_DIVU = OPC_DIVU | (2 << 6),
273 R6_OPC_MODU = OPC_DIVU | (3 << 6),
274
275 R6_OPC_DMUL = OPC_DMULT | (2 << 6),
276 R6_OPC_DMUH = OPC_DMULT | (3 << 6),
277 R6_OPC_DMULU = OPC_DMULTU | (2 << 6),
278 R6_OPC_DMUHU = OPC_DMULTU | (3 << 6),
279 R6_OPC_DDIV = OPC_DDIV | (2 << 6),
280 R6_OPC_DMOD = OPC_DDIV | (3 << 6),
281 R6_OPC_DDIVU = OPC_DDIVU | (2 << 6),
282 R6_OPC_DMODU = OPC_DDIVU | (3 << 6),
4267d3e6
LA
283
284 R6_OPC_CLZ = 0x10 | OPC_SPECIAL,
285 R6_OPC_CLO = 0x11 | OPC_SPECIAL,
286 R6_OPC_DCLZ = 0x12 | OPC_SPECIAL,
287 R6_OPC_DCLO = 0x13 | OPC_SPECIAL,
288 R6_OPC_SDBBP = 0x0e | OPC_SPECIAL,
d4ea6acd
LA
289
290 OPC_LSA = 0x05 | OPC_SPECIAL,
291 OPC_DLSA = 0x15 | OPC_SPECIAL,
b42ee5e1
LA
292};
293
e9c71dd1
TS
294/* Multiplication variants of the vr54xx. */
295#define MASK_MUL_VR54XX(op) MASK_SPECIAL(op) | (op & (0x1F << 6))
296
297enum {
298 OPC_VR54XX_MULS = (0x03 << 6) | OPC_MULT,
299 OPC_VR54XX_MULSU = (0x03 << 6) | OPC_MULTU,
300 OPC_VR54XX_MACC = (0x05 << 6) | OPC_MULT,
301 OPC_VR54XX_MACCU = (0x05 << 6) | OPC_MULTU,
302 OPC_VR54XX_MSAC = (0x07 << 6) | OPC_MULT,
303 OPC_VR54XX_MSACU = (0x07 << 6) | OPC_MULTU,
304 OPC_VR54XX_MULHI = (0x09 << 6) | OPC_MULT,
305 OPC_VR54XX_MULHIU = (0x09 << 6) | OPC_MULTU,
306 OPC_VR54XX_MULSHI = (0x0B << 6) | OPC_MULT,
307 OPC_VR54XX_MULSHIU = (0x0B << 6) | OPC_MULTU,
308 OPC_VR54XX_MACCHI = (0x0D << 6) | OPC_MULT,
309 OPC_VR54XX_MACCHIU = (0x0D << 6) | OPC_MULTU,
310 OPC_VR54XX_MSACHI = (0x0F << 6) | OPC_MULT,
311 OPC_VR54XX_MSACHIU = (0x0F << 6) | OPC_MULTU,
312};
313
7a387fff
TS
314/* REGIMM (rt field) opcodes */
315#define MASK_REGIMM(op) MASK_OP_MAJOR(op) | (op & (0x1F << 16))
316
317enum {
318 OPC_BLTZ = (0x00 << 16) | OPC_REGIMM,
319 OPC_BLTZL = (0x02 << 16) | OPC_REGIMM,
320 OPC_BGEZ = (0x01 << 16) | OPC_REGIMM,
321 OPC_BGEZL = (0x03 << 16) | OPC_REGIMM,
322 OPC_BLTZAL = (0x10 << 16) | OPC_REGIMM,
323 OPC_BLTZALL = (0x12 << 16) | OPC_REGIMM,
324 OPC_BGEZAL = (0x11 << 16) | OPC_REGIMM,
325 OPC_BGEZALL = (0x13 << 16) | OPC_REGIMM,
326 OPC_TGEI = (0x08 << 16) | OPC_REGIMM,
327 OPC_TGEIU = (0x09 << 16) | OPC_REGIMM,
328 OPC_TLTI = (0x0A << 16) | OPC_REGIMM,
329 OPC_TLTIU = (0x0B << 16) | OPC_REGIMM,
330 OPC_TEQI = (0x0C << 16) | OPC_REGIMM,
331 OPC_TNEI = (0x0E << 16) | OPC_REGIMM,
bb238210 332 OPC_SIGRIE = (0x17 << 16) | OPC_REGIMM,
7a387fff 333 OPC_SYNCI = (0x1F << 16) | OPC_REGIMM,
d4ea6acd
LA
334
335 OPC_DAHI = (0x06 << 16) | OPC_REGIMM,
336 OPC_DATI = (0x1e << 16) | OPC_REGIMM,
e37e863f
FB
337};
338
7a387fff
TS
339/* Special2 opcodes */
340#define MASK_SPECIAL2(op) MASK_OP_MAJOR(op) | (op & 0x3F)
341
e37e863f 342enum {
7a387fff
TS
343 /* Multiply & xxx operations */
344 OPC_MADD = 0x00 | OPC_SPECIAL2,
345 OPC_MADDU = 0x01 | OPC_SPECIAL2,
346 OPC_MUL = 0x02 | OPC_SPECIAL2,
347 OPC_MSUB = 0x04 | OPC_SPECIAL2,
348 OPC_MSUBU = 0x05 | OPC_SPECIAL2,
161f85e6
AJ
349 /* Loongson 2F */
350 OPC_MULT_G_2F = 0x10 | OPC_SPECIAL2,
351 OPC_DMULT_G_2F = 0x11 | OPC_SPECIAL2,
352 OPC_MULTU_G_2F = 0x12 | OPC_SPECIAL2,
353 OPC_DMULTU_G_2F = 0x13 | OPC_SPECIAL2,
354 OPC_DIV_G_2F = 0x14 | OPC_SPECIAL2,
355 OPC_DDIV_G_2F = 0x15 | OPC_SPECIAL2,
356 OPC_DIVU_G_2F = 0x16 | OPC_SPECIAL2,
357 OPC_DDIVU_G_2F = 0x17 | OPC_SPECIAL2,
358 OPC_MOD_G_2F = 0x1c | OPC_SPECIAL2,
359 OPC_DMOD_G_2F = 0x1d | OPC_SPECIAL2,
360 OPC_MODU_G_2F = 0x1e | OPC_SPECIAL2,
361 OPC_DMODU_G_2F = 0x1f | OPC_SPECIAL2,
e37e863f 362 /* Misc */
7a387fff
TS
363 OPC_CLZ = 0x20 | OPC_SPECIAL2,
364 OPC_CLO = 0x21 | OPC_SPECIAL2,
365 OPC_DCLZ = 0x24 | OPC_SPECIAL2,
366 OPC_DCLO = 0x25 | OPC_SPECIAL2,
e37e863f 367 /* Special */
7a387fff
TS
368 OPC_SDBBP = 0x3F | OPC_SPECIAL2,
369};
370
371/* Special3 opcodes */
372#define MASK_SPECIAL3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
373
374enum {
375 OPC_EXT = 0x00 | OPC_SPECIAL3,
376 OPC_DEXTM = 0x01 | OPC_SPECIAL3,
377 OPC_DEXTU = 0x02 | OPC_SPECIAL3,
378 OPC_DEXT = 0x03 | OPC_SPECIAL3,
379 OPC_INS = 0x04 | OPC_SPECIAL3,
380 OPC_DINSM = 0x05 | OPC_SPECIAL3,
381 OPC_DINSU = 0x06 | OPC_SPECIAL3,
382 OPC_DINS = 0x07 | OPC_SPECIAL3,
ead9360e
TS
383 OPC_FORK = 0x08 | OPC_SPECIAL3,
384 OPC_YIELD = 0x09 | OPC_SPECIAL3,
7a387fff
TS
385 OPC_BSHFL = 0x20 | OPC_SPECIAL3,
386 OPC_DBSHFL = 0x24 | OPC_SPECIAL3,
387 OPC_RDHWR = 0x3B | OPC_SPECIAL3,
161f85e6
AJ
388
389 /* Loongson 2E */
390 OPC_MULT_G_2E = 0x18 | OPC_SPECIAL3,
391 OPC_MULTU_G_2E = 0x19 | OPC_SPECIAL3,
392 OPC_DIV_G_2E = 0x1A | OPC_SPECIAL3,
393 OPC_DIVU_G_2E = 0x1B | OPC_SPECIAL3,
394 OPC_DMULT_G_2E = 0x1C | OPC_SPECIAL3,
395 OPC_DMULTU_G_2E = 0x1D | OPC_SPECIAL3,
396 OPC_DDIV_G_2E = 0x1E | OPC_SPECIAL3,
397 OPC_DDIVU_G_2E = 0x1F | OPC_SPECIAL3,
398 OPC_MOD_G_2E = 0x22 | OPC_SPECIAL3,
399 OPC_MODU_G_2E = 0x23 | OPC_SPECIAL3,
400 OPC_DMOD_G_2E = 0x26 | OPC_SPECIAL3,
401 OPC_DMODU_G_2E = 0x27 | OPC_SPECIAL3,
9b1a1d68
JL
402
403 /* MIPS DSP Load */
404 OPC_LX_DSP = 0x0A | OPC_SPECIAL3,
461c08df
JL
405 /* MIPS DSP Arithmetic */
406 OPC_ADDU_QB_DSP = 0x10 | OPC_SPECIAL3,
461c08df 407 OPC_ADDU_OB_DSP = 0x14 | OPC_SPECIAL3,
461c08df 408 OPC_ABSQ_S_PH_DSP = 0x12 | OPC_SPECIAL3,
461c08df 409 OPC_ABSQ_S_QH_DSP = 0x16 | OPC_SPECIAL3,
461c08df
JL
410 /* OPC_ADDUH_QB_DSP is same as OPC_MULT_G_2E. */
411 /* OPC_ADDUH_QB_DSP = 0x18 | OPC_SPECIAL3, */
412 OPC_CMPU_EQ_QB_DSP = 0x11 | OPC_SPECIAL3,
461c08df 413 OPC_CMPU_EQ_OB_DSP = 0x15 | OPC_SPECIAL3,
77c5fa8b
JL
414 /* MIPS DSP GPR-Based Shift Sub-class */
415 OPC_SHLL_QB_DSP = 0x13 | OPC_SPECIAL3,
77c5fa8b 416 OPC_SHLL_OB_DSP = 0x17 | OPC_SPECIAL3,
77c5fa8b
JL
417 /* MIPS DSP Multiply Sub-class insns */
418 /* OPC_MUL_PH_DSP is same as OPC_ADDUH_QB_DSP. */
419 /* OPC_MUL_PH_DSP = 0x18 | OPC_SPECIAL3, */
420 OPC_DPA_W_PH_DSP = 0x30 | OPC_SPECIAL3,
77c5fa8b 421 OPC_DPAQ_W_QH_DSP = 0x34 | OPC_SPECIAL3,
1cb6686c
JL
422 /* DSP Bit/Manipulation Sub-class */
423 OPC_INSV_DSP = 0x0C | OPC_SPECIAL3,
1cb6686c 424 OPC_DINSV_DSP = 0x0D | OPC_SPECIAL3,
df6126a7 425 /* MIPS DSP Append Sub-class */
26690560 426 OPC_APPEND_DSP = 0x31 | OPC_SPECIAL3,
26690560 427 OPC_DAPPEND_DSP = 0x35 | OPC_SPECIAL3,
b53371ed
JL
428 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
429 OPC_EXTR_W_DSP = 0x38 | OPC_SPECIAL3,
b53371ed 430 OPC_DEXTR_W_DSP = 0x3C | OPC_SPECIAL3,
4368b29a 431
76964147
JH
432 /* EVA */
433 OPC_LWLE = 0x19 | OPC_SPECIAL3,
434 OPC_LWRE = 0x1A | OPC_SPECIAL3,
435 OPC_CACHEE = 0x1B | OPC_SPECIAL3,
436 OPC_SBE = 0x1C | OPC_SPECIAL3,
437 OPC_SHE = 0x1D | OPC_SPECIAL3,
438 OPC_SCE = 0x1E | OPC_SPECIAL3,
439 OPC_SWE = 0x1F | OPC_SPECIAL3,
440 OPC_SWLE = 0x21 | OPC_SPECIAL3,
441 OPC_SWRE = 0x22 | OPC_SPECIAL3,
442 OPC_PREFE = 0x23 | OPC_SPECIAL3,
443 OPC_LBUE = 0x28 | OPC_SPECIAL3,
444 OPC_LHUE = 0x29 | OPC_SPECIAL3,
445 OPC_LBE = 0x2C | OPC_SPECIAL3,
446 OPC_LHE = 0x2D | OPC_SPECIAL3,
447 OPC_LLE = 0x2E | OPC_SPECIAL3,
448 OPC_LWE = 0x2F | OPC_SPECIAL3,
449
4368b29a 450 /* R6 */
bf7910c6
LA
451 R6_OPC_PREF = 0x35 | OPC_SPECIAL3,
452 R6_OPC_CACHE = 0x25 | OPC_SPECIAL3,
4368b29a
LA
453 R6_OPC_LL = 0x36 | OPC_SPECIAL3,
454 R6_OPC_SC = 0x26 | OPC_SPECIAL3,
bf7910c6
LA
455 R6_OPC_LLD = 0x37 | OPC_SPECIAL3,
456 R6_OPC_SCD = 0x27 | OPC_SPECIAL3,
e37e863f
FB
457};
458
7a387fff
TS
459/* BSHFL opcodes */
460#define MASK_BSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
461
e37e863f 462enum {
15eacb9b
YK
463 OPC_WSBH = (0x02 << 6) | OPC_BSHFL,
464 OPC_SEB = (0x10 << 6) | OPC_BSHFL,
465 OPC_SEH = (0x18 << 6) | OPC_BSHFL,
373ecd38
AM
466 OPC_ALIGN = (0x08 << 6) | OPC_BSHFL, /* 010.bp (010.00 to 010.11) */
467 OPC_ALIGN_1 = (0x09 << 6) | OPC_BSHFL,
468 OPC_ALIGN_2 = (0x0A << 6) | OPC_BSHFL,
469 OPC_ALIGN_3 = (0x0B << 6) | OPC_BSHFL,
15eacb9b 470 OPC_BITSWAP = (0x00 << 6) | OPC_BSHFL /* 00000 */
e37e863f
FB
471};
472
7a387fff
TS
473/* DBSHFL opcodes */
474#define MASK_DBSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
475
e37e863f 476enum {
15eacb9b
YK
477 OPC_DSBH = (0x02 << 6) | OPC_DBSHFL,
478 OPC_DSHD = (0x05 << 6) | OPC_DBSHFL,
373ecd38
AM
479 OPC_DALIGN = (0x08 << 6) | OPC_DBSHFL, /* 01.bp (01.000 to 01.111) */
480 OPC_DALIGN_1 = (0x09 << 6) | OPC_DBSHFL,
481 OPC_DALIGN_2 = (0x0A << 6) | OPC_DBSHFL,
482 OPC_DALIGN_3 = (0x0B << 6) | OPC_DBSHFL,
483 OPC_DALIGN_4 = (0x0C << 6) | OPC_DBSHFL,
484 OPC_DALIGN_5 = (0x0D << 6) | OPC_DBSHFL,
485 OPC_DALIGN_6 = (0x0E << 6) | OPC_DBSHFL,
486 OPC_DALIGN_7 = (0x0F << 6) | OPC_DBSHFL,
15eacb9b 487 OPC_DBITSWAP = (0x00 << 6) | OPC_DBSHFL, /* 00000 */
e37e863f
FB
488};
489
e45a93e2
JL
490/* MIPS DSP REGIMM opcodes */
491enum {
492 OPC_BPOSGE32 = (0x1C << 16) | OPC_REGIMM,
e45a93e2 493 OPC_BPOSGE64 = (0x1D << 16) | OPC_REGIMM,
e45a93e2
JL
494};
495
9b1a1d68
JL
496#define MASK_LX(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
497/* MIPS DSP Load */
498enum {
499 OPC_LBUX = (0x06 << 6) | OPC_LX_DSP,
500 OPC_LHX = (0x04 << 6) | OPC_LX_DSP,
501 OPC_LWX = (0x00 << 6) | OPC_LX_DSP,
9b1a1d68 502 OPC_LDX = (0x08 << 6) | OPC_LX_DSP,
9b1a1d68
JL
503};
504
461c08df
JL
505#define MASK_ADDU_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
506enum {
507 /* MIPS DSP Arithmetic Sub-class */
508 OPC_ADDQ_PH = (0x0A << 6) | OPC_ADDU_QB_DSP,
509 OPC_ADDQ_S_PH = (0x0E << 6) | OPC_ADDU_QB_DSP,
510 OPC_ADDQ_S_W = (0x16 << 6) | OPC_ADDU_QB_DSP,
511 OPC_ADDU_QB = (0x00 << 6) | OPC_ADDU_QB_DSP,
512 OPC_ADDU_S_QB = (0x04 << 6) | OPC_ADDU_QB_DSP,
513 OPC_ADDU_PH = (0x08 << 6) | OPC_ADDU_QB_DSP,
514 OPC_ADDU_S_PH = (0x0C << 6) | OPC_ADDU_QB_DSP,
515 OPC_SUBQ_PH = (0x0B << 6) | OPC_ADDU_QB_DSP,
516 OPC_SUBQ_S_PH = (0x0F << 6) | OPC_ADDU_QB_DSP,
517 OPC_SUBQ_S_W = (0x17 << 6) | OPC_ADDU_QB_DSP,
518 OPC_SUBU_QB = (0x01 << 6) | OPC_ADDU_QB_DSP,
519 OPC_SUBU_S_QB = (0x05 << 6) | OPC_ADDU_QB_DSP,
520 OPC_SUBU_PH = (0x09 << 6) | OPC_ADDU_QB_DSP,
521 OPC_SUBU_S_PH = (0x0D << 6) | OPC_ADDU_QB_DSP,
522 OPC_ADDSC = (0x10 << 6) | OPC_ADDU_QB_DSP,
523 OPC_ADDWC = (0x11 << 6) | OPC_ADDU_QB_DSP,
524 OPC_MODSUB = (0x12 << 6) | OPC_ADDU_QB_DSP,
525 OPC_RADDU_W_QB = (0x14 << 6) | OPC_ADDU_QB_DSP,
a22260ae
JL
526 /* MIPS DSP Multiply Sub-class insns */
527 OPC_MULEU_S_PH_QBL = (0x06 << 6) | OPC_ADDU_QB_DSP,
528 OPC_MULEU_S_PH_QBR = (0x07 << 6) | OPC_ADDU_QB_DSP,
529 OPC_MULQ_RS_PH = (0x1F << 6) | OPC_ADDU_QB_DSP,
530 OPC_MULEQ_S_W_PHL = (0x1C << 6) | OPC_ADDU_QB_DSP,
531 OPC_MULEQ_S_W_PHR = (0x1D << 6) | OPC_ADDU_QB_DSP,
532 OPC_MULQ_S_PH = (0x1E << 6) | OPC_ADDU_QB_DSP,
461c08df
JL
533};
534
535#define OPC_ADDUH_QB_DSP OPC_MULT_G_2E
536#define MASK_ADDUH_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
537enum {
538 /* MIPS DSP Arithmetic Sub-class */
539 OPC_ADDUH_QB = (0x00 << 6) | OPC_ADDUH_QB_DSP,
540 OPC_ADDUH_R_QB = (0x02 << 6) | OPC_ADDUH_QB_DSP,
541 OPC_ADDQH_PH = (0x08 << 6) | OPC_ADDUH_QB_DSP,
542 OPC_ADDQH_R_PH = (0x0A << 6) | OPC_ADDUH_QB_DSP,
543 OPC_ADDQH_W = (0x10 << 6) | OPC_ADDUH_QB_DSP,
544 OPC_ADDQH_R_W = (0x12 << 6) | OPC_ADDUH_QB_DSP,
545 OPC_SUBUH_QB = (0x01 << 6) | OPC_ADDUH_QB_DSP,
546 OPC_SUBUH_R_QB = (0x03 << 6) | OPC_ADDUH_QB_DSP,
547 OPC_SUBQH_PH = (0x09 << 6) | OPC_ADDUH_QB_DSP,
548 OPC_SUBQH_R_PH = (0x0B << 6) | OPC_ADDUH_QB_DSP,
549 OPC_SUBQH_W = (0x11 << 6) | OPC_ADDUH_QB_DSP,
550 OPC_SUBQH_R_W = (0x13 << 6) | OPC_ADDUH_QB_DSP,
a22260ae
JL
551 /* MIPS DSP Multiply Sub-class insns */
552 OPC_MUL_PH = (0x0C << 6) | OPC_ADDUH_QB_DSP,
553 OPC_MUL_S_PH = (0x0E << 6) | OPC_ADDUH_QB_DSP,
554 OPC_MULQ_S_W = (0x16 << 6) | OPC_ADDUH_QB_DSP,
555 OPC_MULQ_RS_W = (0x17 << 6) | OPC_ADDUH_QB_DSP,
461c08df
JL
556};
557
558#define MASK_ABSQ_S_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
559enum {
560 /* MIPS DSP Arithmetic Sub-class */
561 OPC_ABSQ_S_QB = (0x01 << 6) | OPC_ABSQ_S_PH_DSP,
562 OPC_ABSQ_S_PH = (0x09 << 6) | OPC_ABSQ_S_PH_DSP,
563 OPC_ABSQ_S_W = (0x11 << 6) | OPC_ABSQ_S_PH_DSP,
564 OPC_PRECEQ_W_PHL = (0x0C << 6) | OPC_ABSQ_S_PH_DSP,
565 OPC_PRECEQ_W_PHR = (0x0D << 6) | OPC_ABSQ_S_PH_DSP,
566 OPC_PRECEQU_PH_QBL = (0x04 << 6) | OPC_ABSQ_S_PH_DSP,
567 OPC_PRECEQU_PH_QBR = (0x05 << 6) | OPC_ABSQ_S_PH_DSP,
568 OPC_PRECEQU_PH_QBLA = (0x06 << 6) | OPC_ABSQ_S_PH_DSP,
569 OPC_PRECEQU_PH_QBRA = (0x07 << 6) | OPC_ABSQ_S_PH_DSP,
570 OPC_PRECEU_PH_QBL = (0x1C << 6) | OPC_ABSQ_S_PH_DSP,
571 OPC_PRECEU_PH_QBR = (0x1D << 6) | OPC_ABSQ_S_PH_DSP,
572 OPC_PRECEU_PH_QBLA = (0x1E << 6) | OPC_ABSQ_S_PH_DSP,
573 OPC_PRECEU_PH_QBRA = (0x1F << 6) | OPC_ABSQ_S_PH_DSP,
1cb6686c
JL
574 /* DSP Bit/Manipulation Sub-class */
575 OPC_BITREV = (0x1B << 6) | OPC_ABSQ_S_PH_DSP,
576 OPC_REPL_QB = (0x02 << 6) | OPC_ABSQ_S_PH_DSP,
577 OPC_REPLV_QB = (0x03 << 6) | OPC_ABSQ_S_PH_DSP,
578 OPC_REPL_PH = (0x0A << 6) | OPC_ABSQ_S_PH_DSP,
579 OPC_REPLV_PH = (0x0B << 6) | OPC_ABSQ_S_PH_DSP,
461c08df
JL
580};
581
582#define MASK_CMPU_EQ_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
583enum {
584 /* MIPS DSP Arithmetic Sub-class */
585 OPC_PRECR_QB_PH = (0x0D << 6) | OPC_CMPU_EQ_QB_DSP,
586 OPC_PRECRQ_QB_PH = (0x0C << 6) | OPC_CMPU_EQ_QB_DSP,
587 OPC_PRECR_SRA_PH_W = (0x1E << 6) | OPC_CMPU_EQ_QB_DSP,
588 OPC_PRECR_SRA_R_PH_W = (0x1F << 6) | OPC_CMPU_EQ_QB_DSP,
589 OPC_PRECRQ_PH_W = (0x14 << 6) | OPC_CMPU_EQ_QB_DSP,
590 OPC_PRECRQ_RS_PH_W = (0x15 << 6) | OPC_CMPU_EQ_QB_DSP,
591 OPC_PRECRQU_S_QB_PH = (0x0F << 6) | OPC_CMPU_EQ_QB_DSP,
26690560
JL
592 /* DSP Compare-Pick Sub-class */
593 OPC_CMPU_EQ_QB = (0x00 << 6) | OPC_CMPU_EQ_QB_DSP,
594 OPC_CMPU_LT_QB = (0x01 << 6) | OPC_CMPU_EQ_QB_DSP,
595 OPC_CMPU_LE_QB = (0x02 << 6) | OPC_CMPU_EQ_QB_DSP,
596 OPC_CMPGU_EQ_QB = (0x04 << 6) | OPC_CMPU_EQ_QB_DSP,
597 OPC_CMPGU_LT_QB = (0x05 << 6) | OPC_CMPU_EQ_QB_DSP,
598 OPC_CMPGU_LE_QB = (0x06 << 6) | OPC_CMPU_EQ_QB_DSP,
599 OPC_CMPGDU_EQ_QB = (0x18 << 6) | OPC_CMPU_EQ_QB_DSP,
600 OPC_CMPGDU_LT_QB = (0x19 << 6) | OPC_CMPU_EQ_QB_DSP,
601 OPC_CMPGDU_LE_QB = (0x1A << 6) | OPC_CMPU_EQ_QB_DSP,
602 OPC_CMP_EQ_PH = (0x08 << 6) | OPC_CMPU_EQ_QB_DSP,
603 OPC_CMP_LT_PH = (0x09 << 6) | OPC_CMPU_EQ_QB_DSP,
604 OPC_CMP_LE_PH = (0x0A << 6) | OPC_CMPU_EQ_QB_DSP,
605 OPC_PICK_QB = (0x03 << 6) | OPC_CMPU_EQ_QB_DSP,
606 OPC_PICK_PH = (0x0B << 6) | OPC_CMPU_EQ_QB_DSP,
607 OPC_PACKRL_PH = (0x0E << 6) | OPC_CMPU_EQ_QB_DSP,
461c08df 608};
a22260ae 609
77c5fa8b
JL
610#define MASK_SHLL_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
611enum {
612 /* MIPS DSP GPR-Based Shift Sub-class */
613 OPC_SHLL_QB = (0x00 << 6) | OPC_SHLL_QB_DSP,
614 OPC_SHLLV_QB = (0x02 << 6) | OPC_SHLL_QB_DSP,
615 OPC_SHLL_PH = (0x08 << 6) | OPC_SHLL_QB_DSP,
616 OPC_SHLLV_PH = (0x0A << 6) | OPC_SHLL_QB_DSP,
617 OPC_SHLL_S_PH = (0x0C << 6) | OPC_SHLL_QB_DSP,
618 OPC_SHLLV_S_PH = (0x0E << 6) | OPC_SHLL_QB_DSP,
619 OPC_SHLL_S_W = (0x14 << 6) | OPC_SHLL_QB_DSP,
620 OPC_SHLLV_S_W = (0x16 << 6) | OPC_SHLL_QB_DSP,
621 OPC_SHRL_QB = (0x01 << 6) | OPC_SHLL_QB_DSP,
622 OPC_SHRLV_QB = (0x03 << 6) | OPC_SHLL_QB_DSP,
623 OPC_SHRL_PH = (0x19 << 6) | OPC_SHLL_QB_DSP,
624 OPC_SHRLV_PH = (0x1B << 6) | OPC_SHLL_QB_DSP,
625 OPC_SHRA_QB = (0x04 << 6) | OPC_SHLL_QB_DSP,
626 OPC_SHRA_R_QB = (0x05 << 6) | OPC_SHLL_QB_DSP,
627 OPC_SHRAV_QB = (0x06 << 6) | OPC_SHLL_QB_DSP,
628 OPC_SHRAV_R_QB = (0x07 << 6) | OPC_SHLL_QB_DSP,
629 OPC_SHRA_PH = (0x09 << 6) | OPC_SHLL_QB_DSP,
630 OPC_SHRAV_PH = (0x0B << 6) | OPC_SHLL_QB_DSP,
631 OPC_SHRA_R_PH = (0x0D << 6) | OPC_SHLL_QB_DSP,
632 OPC_SHRAV_R_PH = (0x0F << 6) | OPC_SHLL_QB_DSP,
633 OPC_SHRA_R_W = (0x15 << 6) | OPC_SHLL_QB_DSP,
634 OPC_SHRAV_R_W = (0x17 << 6) | OPC_SHLL_QB_DSP,
635};
461c08df 636
a22260ae
JL
637#define MASK_DPA_W_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
638enum {
639 /* MIPS DSP Multiply Sub-class insns */
640 OPC_DPAU_H_QBL = (0x03 << 6) | OPC_DPA_W_PH_DSP,
641 OPC_DPAU_H_QBR = (0x07 << 6) | OPC_DPA_W_PH_DSP,
642 OPC_DPSU_H_QBL = (0x0B << 6) | OPC_DPA_W_PH_DSP,
643 OPC_DPSU_H_QBR = (0x0F << 6) | OPC_DPA_W_PH_DSP,
644 OPC_DPA_W_PH = (0x00 << 6) | OPC_DPA_W_PH_DSP,
645 OPC_DPAX_W_PH = (0x08 << 6) | OPC_DPA_W_PH_DSP,
646 OPC_DPAQ_S_W_PH = (0x04 << 6) | OPC_DPA_W_PH_DSP,
647 OPC_DPAQX_S_W_PH = (0x18 << 6) | OPC_DPA_W_PH_DSP,
648 OPC_DPAQX_SA_W_PH = (0x1A << 6) | OPC_DPA_W_PH_DSP,
649 OPC_DPS_W_PH = (0x01 << 6) | OPC_DPA_W_PH_DSP,
650 OPC_DPSX_W_PH = (0x09 << 6) | OPC_DPA_W_PH_DSP,
651 OPC_DPSQ_S_W_PH = (0x05 << 6) | OPC_DPA_W_PH_DSP,
652 OPC_DPSQX_S_W_PH = (0x19 << 6) | OPC_DPA_W_PH_DSP,
653 OPC_DPSQX_SA_W_PH = (0x1B << 6) | OPC_DPA_W_PH_DSP,
654 OPC_MULSAQ_S_W_PH = (0x06 << 6) | OPC_DPA_W_PH_DSP,
655 OPC_DPAQ_SA_L_W = (0x0C << 6) | OPC_DPA_W_PH_DSP,
656 OPC_DPSQ_SA_L_W = (0x0D << 6) | OPC_DPA_W_PH_DSP,
657 OPC_MAQ_S_W_PHL = (0x14 << 6) | OPC_DPA_W_PH_DSP,
658 OPC_MAQ_S_W_PHR = (0x16 << 6) | OPC_DPA_W_PH_DSP,
659 OPC_MAQ_SA_W_PHL = (0x10 << 6) | OPC_DPA_W_PH_DSP,
660 OPC_MAQ_SA_W_PHR = (0x12 << 6) | OPC_DPA_W_PH_DSP,
661 OPC_MULSA_W_PH = (0x02 << 6) | OPC_DPA_W_PH_DSP,
662};
663
1cb6686c
JL
664#define MASK_INSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
665enum {
666 /* DSP Bit/Manipulation Sub-class */
667 OPC_INSV = (0x00 << 6) | OPC_INSV_DSP,
668};
669
26690560
JL
670#define MASK_APPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
671enum {
df6126a7 672 /* MIPS DSP Append Sub-class */
26690560
JL
673 OPC_APPEND = (0x00 << 6) | OPC_APPEND_DSP,
674 OPC_PREPEND = (0x01 << 6) | OPC_APPEND_DSP,
675 OPC_BALIGN = (0x10 << 6) | OPC_APPEND_DSP,
676};
677
b53371ed
JL
678#define MASK_EXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
679enum {
680 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
681 OPC_EXTR_W = (0x00 << 6) | OPC_EXTR_W_DSP,
682 OPC_EXTR_R_W = (0x04 << 6) | OPC_EXTR_W_DSP,
683 OPC_EXTR_RS_W = (0x06 << 6) | OPC_EXTR_W_DSP,
684 OPC_EXTR_S_H = (0x0E << 6) | OPC_EXTR_W_DSP,
685 OPC_EXTRV_S_H = (0x0F << 6) | OPC_EXTR_W_DSP,
686 OPC_EXTRV_W = (0x01 << 6) | OPC_EXTR_W_DSP,
687 OPC_EXTRV_R_W = (0x05 << 6) | OPC_EXTR_W_DSP,
688 OPC_EXTRV_RS_W = (0x07 << 6) | OPC_EXTR_W_DSP,
689 OPC_EXTP = (0x02 << 6) | OPC_EXTR_W_DSP,
690 OPC_EXTPV = (0x03 << 6) | OPC_EXTR_W_DSP,
691 OPC_EXTPDP = (0x0A << 6) | OPC_EXTR_W_DSP,
692 OPC_EXTPDPV = (0x0B << 6) | OPC_EXTR_W_DSP,
693 OPC_SHILO = (0x1A << 6) | OPC_EXTR_W_DSP,
694 OPC_SHILOV = (0x1B << 6) | OPC_EXTR_W_DSP,
695 OPC_MTHLIP = (0x1F << 6) | OPC_EXTR_W_DSP,
696 OPC_WRDSP = (0x13 << 6) | OPC_EXTR_W_DSP,
697 OPC_RDDSP = (0x12 << 6) | OPC_EXTR_W_DSP,
698};
699
461c08df
JL
700#define MASK_ABSQ_S_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
701enum {
702 /* MIPS DSP Arithmetic Sub-class */
703 OPC_PRECEQ_L_PWL = (0x14 << 6) | OPC_ABSQ_S_QH_DSP,
704 OPC_PRECEQ_L_PWR = (0x15 << 6) | OPC_ABSQ_S_QH_DSP,
705 OPC_PRECEQ_PW_QHL = (0x0C << 6) | OPC_ABSQ_S_QH_DSP,
706 OPC_PRECEQ_PW_QHR = (0x0D << 6) | OPC_ABSQ_S_QH_DSP,
707 OPC_PRECEQ_PW_QHLA = (0x0E << 6) | OPC_ABSQ_S_QH_DSP,
708 OPC_PRECEQ_PW_QHRA = (0x0F << 6) | OPC_ABSQ_S_QH_DSP,
709 OPC_PRECEQU_QH_OBL = (0x04 << 6) | OPC_ABSQ_S_QH_DSP,
710 OPC_PRECEQU_QH_OBR = (0x05 << 6) | OPC_ABSQ_S_QH_DSP,
711 OPC_PRECEQU_QH_OBLA = (0x06 << 6) | OPC_ABSQ_S_QH_DSP,
712 OPC_PRECEQU_QH_OBRA = (0x07 << 6) | OPC_ABSQ_S_QH_DSP,
713 OPC_PRECEU_QH_OBL = (0x1C << 6) | OPC_ABSQ_S_QH_DSP,
714 OPC_PRECEU_QH_OBR = (0x1D << 6) | OPC_ABSQ_S_QH_DSP,
715 OPC_PRECEU_QH_OBLA = (0x1E << 6) | OPC_ABSQ_S_QH_DSP,
716 OPC_PRECEU_QH_OBRA = (0x1F << 6) | OPC_ABSQ_S_QH_DSP,
717 OPC_ABSQ_S_OB = (0x01 << 6) | OPC_ABSQ_S_QH_DSP,
718 OPC_ABSQ_S_PW = (0x11 << 6) | OPC_ABSQ_S_QH_DSP,
719 OPC_ABSQ_S_QH = (0x09 << 6) | OPC_ABSQ_S_QH_DSP,
1cb6686c
JL
720 /* DSP Bit/Manipulation Sub-class */
721 OPC_REPL_OB = (0x02 << 6) | OPC_ABSQ_S_QH_DSP,
722 OPC_REPL_PW = (0x12 << 6) | OPC_ABSQ_S_QH_DSP,
723 OPC_REPL_QH = (0x0A << 6) | OPC_ABSQ_S_QH_DSP,
724 OPC_REPLV_OB = (0x03 << 6) | OPC_ABSQ_S_QH_DSP,
725 OPC_REPLV_PW = (0x13 << 6) | OPC_ABSQ_S_QH_DSP,
726 OPC_REPLV_QH = (0x0B << 6) | OPC_ABSQ_S_QH_DSP,
461c08df 727};
461c08df 728
461c08df
JL
729#define MASK_ADDU_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
730enum {
a22260ae
JL
731 /* MIPS DSP Multiply Sub-class insns */
732 OPC_MULEQ_S_PW_QHL = (0x1C << 6) | OPC_ADDU_OB_DSP,
733 OPC_MULEQ_S_PW_QHR = (0x1D << 6) | OPC_ADDU_OB_DSP,
734 OPC_MULEU_S_QH_OBL = (0x06 << 6) | OPC_ADDU_OB_DSP,
735 OPC_MULEU_S_QH_OBR = (0x07 << 6) | OPC_ADDU_OB_DSP,
736 OPC_MULQ_RS_QH = (0x1F << 6) | OPC_ADDU_OB_DSP,
461c08df
JL
737 /* MIPS DSP Arithmetic Sub-class */
738 OPC_RADDU_L_OB = (0x14 << 6) | OPC_ADDU_OB_DSP,
739 OPC_SUBQ_PW = (0x13 << 6) | OPC_ADDU_OB_DSP,
740 OPC_SUBQ_S_PW = (0x17 << 6) | OPC_ADDU_OB_DSP,
741 OPC_SUBQ_QH = (0x0B << 6) | OPC_ADDU_OB_DSP,
742 OPC_SUBQ_S_QH = (0x0F << 6) | OPC_ADDU_OB_DSP,
743 OPC_SUBU_OB = (0x01 << 6) | OPC_ADDU_OB_DSP,
744 OPC_SUBU_S_OB = (0x05 << 6) | OPC_ADDU_OB_DSP,
745 OPC_SUBU_QH = (0x09 << 6) | OPC_ADDU_OB_DSP,
746 OPC_SUBU_S_QH = (0x0D << 6) | OPC_ADDU_OB_DSP,
747 OPC_SUBUH_OB = (0x19 << 6) | OPC_ADDU_OB_DSP,
748 OPC_SUBUH_R_OB = (0x1B << 6) | OPC_ADDU_OB_DSP,
749 OPC_ADDQ_PW = (0x12 << 6) | OPC_ADDU_OB_DSP,
750 OPC_ADDQ_S_PW = (0x16 << 6) | OPC_ADDU_OB_DSP,
751 OPC_ADDQ_QH = (0x0A << 6) | OPC_ADDU_OB_DSP,
752 OPC_ADDQ_S_QH = (0x0E << 6) | OPC_ADDU_OB_DSP,
753 OPC_ADDU_OB = (0x00 << 6) | OPC_ADDU_OB_DSP,
754 OPC_ADDU_S_OB = (0x04 << 6) | OPC_ADDU_OB_DSP,
755 OPC_ADDU_QH = (0x08 << 6) | OPC_ADDU_OB_DSP,
756 OPC_ADDU_S_QH = (0x0C << 6) | OPC_ADDU_OB_DSP,
757 OPC_ADDUH_OB = (0x18 << 6) | OPC_ADDU_OB_DSP,
758 OPC_ADDUH_R_OB = (0x1A << 6) | OPC_ADDU_OB_DSP,
759};
461c08df 760
461c08df
JL
761#define MASK_CMPU_EQ_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
762enum {
26690560
JL
763 /* DSP Compare-Pick Sub-class */
764 OPC_CMP_EQ_PW = (0x10 << 6) | OPC_CMPU_EQ_OB_DSP,
765 OPC_CMP_LT_PW = (0x11 << 6) | OPC_CMPU_EQ_OB_DSP,
766 OPC_CMP_LE_PW = (0x12 << 6) | OPC_CMPU_EQ_OB_DSP,
767 OPC_CMP_EQ_QH = (0x08 << 6) | OPC_CMPU_EQ_OB_DSP,
768 OPC_CMP_LT_QH = (0x09 << 6) | OPC_CMPU_EQ_OB_DSP,
769 OPC_CMP_LE_QH = (0x0A << 6) | OPC_CMPU_EQ_OB_DSP,
770 OPC_CMPGDU_EQ_OB = (0x18 << 6) | OPC_CMPU_EQ_OB_DSP,
771 OPC_CMPGDU_LT_OB = (0x19 << 6) | OPC_CMPU_EQ_OB_DSP,
772 OPC_CMPGDU_LE_OB = (0x1A << 6) | OPC_CMPU_EQ_OB_DSP,
773 OPC_CMPGU_EQ_OB = (0x04 << 6) | OPC_CMPU_EQ_OB_DSP,
774 OPC_CMPGU_LT_OB = (0x05 << 6) | OPC_CMPU_EQ_OB_DSP,
775 OPC_CMPGU_LE_OB = (0x06 << 6) | OPC_CMPU_EQ_OB_DSP,
776 OPC_CMPU_EQ_OB = (0x00 << 6) | OPC_CMPU_EQ_OB_DSP,
777 OPC_CMPU_LT_OB = (0x01 << 6) | OPC_CMPU_EQ_OB_DSP,
778 OPC_CMPU_LE_OB = (0x02 << 6) | OPC_CMPU_EQ_OB_DSP,
779 OPC_PACKRL_PW = (0x0E << 6) | OPC_CMPU_EQ_OB_DSP,
780 OPC_PICK_OB = (0x03 << 6) | OPC_CMPU_EQ_OB_DSP,
781 OPC_PICK_PW = (0x13 << 6) | OPC_CMPU_EQ_OB_DSP,
782 OPC_PICK_QH = (0x0B << 6) | OPC_CMPU_EQ_OB_DSP,
461c08df
JL
783 /* MIPS DSP Arithmetic Sub-class */
784 OPC_PRECR_OB_QH = (0x0D << 6) | OPC_CMPU_EQ_OB_DSP,
785 OPC_PRECR_SRA_QH_PW = (0x1E << 6) | OPC_CMPU_EQ_OB_DSP,
786 OPC_PRECR_SRA_R_QH_PW = (0x1F << 6) | OPC_CMPU_EQ_OB_DSP,
787 OPC_PRECRQ_OB_QH = (0x0C << 6) | OPC_CMPU_EQ_OB_DSP,
788 OPC_PRECRQ_PW_L = (0x1C << 6) | OPC_CMPU_EQ_OB_DSP,
789 OPC_PRECRQ_QH_PW = (0x14 << 6) | OPC_CMPU_EQ_OB_DSP,
790 OPC_PRECRQ_RS_QH_PW = (0x15 << 6) | OPC_CMPU_EQ_OB_DSP,
791 OPC_PRECRQU_S_OB_QH = (0x0F << 6) | OPC_CMPU_EQ_OB_DSP,
792};
461c08df 793
26690560
JL
794#define MASK_DAPPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
795enum {
df6126a7 796 /* DSP Append Sub-class */
26690560
JL
797 OPC_DAPPEND = (0x00 << 6) | OPC_DAPPEND_DSP,
798 OPC_PREPENDD = (0x03 << 6) | OPC_DAPPEND_DSP,
799 OPC_PREPENDW = (0x01 << 6) | OPC_DAPPEND_DSP,
800 OPC_DBALIGN = (0x10 << 6) | OPC_DAPPEND_DSP,
801};
26690560 802
b53371ed
JL
803#define MASK_DEXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
804enum {
805 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
806 OPC_DMTHLIP = (0x1F << 6) | OPC_DEXTR_W_DSP,
807 OPC_DSHILO = (0x1A << 6) | OPC_DEXTR_W_DSP,
808 OPC_DEXTP = (0x02 << 6) | OPC_DEXTR_W_DSP,
809 OPC_DEXTPDP = (0x0A << 6) | OPC_DEXTR_W_DSP,
810 OPC_DEXTPDPV = (0x0B << 6) | OPC_DEXTR_W_DSP,
811 OPC_DEXTPV = (0x03 << 6) | OPC_DEXTR_W_DSP,
812 OPC_DEXTR_L = (0x10 << 6) | OPC_DEXTR_W_DSP,
813 OPC_DEXTR_R_L = (0x14 << 6) | OPC_DEXTR_W_DSP,
814 OPC_DEXTR_RS_L = (0x16 << 6) | OPC_DEXTR_W_DSP,
815 OPC_DEXTR_W = (0x00 << 6) | OPC_DEXTR_W_DSP,
816 OPC_DEXTR_R_W = (0x04 << 6) | OPC_DEXTR_W_DSP,
817 OPC_DEXTR_RS_W = (0x06 << 6) | OPC_DEXTR_W_DSP,
818 OPC_DEXTR_S_H = (0x0E << 6) | OPC_DEXTR_W_DSP,
819 OPC_DEXTRV_L = (0x11 << 6) | OPC_DEXTR_W_DSP,
820 OPC_DEXTRV_R_L = (0x15 << 6) | OPC_DEXTR_W_DSP,
821 OPC_DEXTRV_RS_L = (0x17 << 6) | OPC_DEXTR_W_DSP,
822 OPC_DEXTRV_S_H = (0x0F << 6) | OPC_DEXTR_W_DSP,
823 OPC_DEXTRV_W = (0x01 << 6) | OPC_DEXTR_W_DSP,
824 OPC_DEXTRV_R_W = (0x05 << 6) | OPC_DEXTR_W_DSP,
825 OPC_DEXTRV_RS_W = (0x07 << 6) | OPC_DEXTR_W_DSP,
826 OPC_DSHILOV = (0x1B << 6) | OPC_DEXTR_W_DSP,
827};
828
1cb6686c
JL
829#define MASK_DINSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
830enum {
831 /* DSP Bit/Manipulation Sub-class */
832 OPC_DINSV = (0x00 << 6) | OPC_DINSV_DSP,
833};
1cb6686c 834
a22260ae
JL
835#define MASK_DPAQ_W_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
836enum {
837 /* MIPS DSP Multiply Sub-class insns */
838 OPC_DMADD = (0x19 << 6) | OPC_DPAQ_W_QH_DSP,
839 OPC_DMADDU = (0x1D << 6) | OPC_DPAQ_W_QH_DSP,
840 OPC_DMSUB = (0x1B << 6) | OPC_DPAQ_W_QH_DSP,
841 OPC_DMSUBU = (0x1F << 6) | OPC_DPAQ_W_QH_DSP,
842 OPC_DPA_W_QH = (0x00 << 6) | OPC_DPAQ_W_QH_DSP,
843 OPC_DPAQ_S_W_QH = (0x04 << 6) | OPC_DPAQ_W_QH_DSP,
844 OPC_DPAQ_SA_L_PW = (0x0C << 6) | OPC_DPAQ_W_QH_DSP,
845 OPC_DPAU_H_OBL = (0x03 << 6) | OPC_DPAQ_W_QH_DSP,
846 OPC_DPAU_H_OBR = (0x07 << 6) | OPC_DPAQ_W_QH_DSP,
847 OPC_DPS_W_QH = (0x01 << 6) | OPC_DPAQ_W_QH_DSP,
848 OPC_DPSQ_S_W_QH = (0x05 << 6) | OPC_DPAQ_W_QH_DSP,
849 OPC_DPSQ_SA_L_PW = (0x0D << 6) | OPC_DPAQ_W_QH_DSP,
850 OPC_DPSU_H_OBL = (0x0B << 6) | OPC_DPAQ_W_QH_DSP,
851 OPC_DPSU_H_OBR = (0x0F << 6) | OPC_DPAQ_W_QH_DSP,
852 OPC_MAQ_S_L_PWL = (0x1C << 6) | OPC_DPAQ_W_QH_DSP,
853 OPC_MAQ_S_L_PWR = (0x1E << 6) | OPC_DPAQ_W_QH_DSP,
854 OPC_MAQ_S_W_QHLL = (0x14 << 6) | OPC_DPAQ_W_QH_DSP,
855 OPC_MAQ_SA_W_QHLL = (0x10 << 6) | OPC_DPAQ_W_QH_DSP,
856 OPC_MAQ_S_W_QHLR = (0x15 << 6) | OPC_DPAQ_W_QH_DSP,
857 OPC_MAQ_SA_W_QHLR = (0x11 << 6) | OPC_DPAQ_W_QH_DSP,
858 OPC_MAQ_S_W_QHRL = (0x16 << 6) | OPC_DPAQ_W_QH_DSP,
859 OPC_MAQ_SA_W_QHRL = (0x12 << 6) | OPC_DPAQ_W_QH_DSP,
860 OPC_MAQ_S_W_QHRR = (0x17 << 6) | OPC_DPAQ_W_QH_DSP,
861 OPC_MAQ_SA_W_QHRR = (0x13 << 6) | OPC_DPAQ_W_QH_DSP,
862 OPC_MULSAQ_S_L_PW = (0x0E << 6) | OPC_DPAQ_W_QH_DSP,
863 OPC_MULSAQ_S_W_QH = (0x06 << 6) | OPC_DPAQ_W_QH_DSP,
864};
a22260ae 865
77c5fa8b
JL
866#define MASK_SHLL_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
867enum {
868 /* MIPS DSP GPR-Based Shift Sub-class */
869 OPC_SHLL_PW = (0x10 << 6) | OPC_SHLL_OB_DSP,
870 OPC_SHLL_S_PW = (0x14 << 6) | OPC_SHLL_OB_DSP,
871 OPC_SHLLV_OB = (0x02 << 6) | OPC_SHLL_OB_DSP,
872 OPC_SHLLV_PW = (0x12 << 6) | OPC_SHLL_OB_DSP,
873 OPC_SHLLV_S_PW = (0x16 << 6) | OPC_SHLL_OB_DSP,
874 OPC_SHLLV_QH = (0x0A << 6) | OPC_SHLL_OB_DSP,
875 OPC_SHLLV_S_QH = (0x0E << 6) | OPC_SHLL_OB_DSP,
876 OPC_SHRA_PW = (0x11 << 6) | OPC_SHLL_OB_DSP,
877 OPC_SHRA_R_PW = (0x15 << 6) | OPC_SHLL_OB_DSP,
878 OPC_SHRAV_OB = (0x06 << 6) | OPC_SHLL_OB_DSP,
879 OPC_SHRAV_R_OB = (0x07 << 6) | OPC_SHLL_OB_DSP,
880 OPC_SHRAV_PW = (0x13 << 6) | OPC_SHLL_OB_DSP,
881 OPC_SHRAV_R_PW = (0x17 << 6) | OPC_SHLL_OB_DSP,
882 OPC_SHRAV_QH = (0x0B << 6) | OPC_SHLL_OB_DSP,
883 OPC_SHRAV_R_QH = (0x0F << 6) | OPC_SHLL_OB_DSP,
884 OPC_SHRLV_OB = (0x03 << 6) | OPC_SHLL_OB_DSP,
885 OPC_SHRLV_QH = (0x1B << 6) | OPC_SHLL_OB_DSP,
886 OPC_SHLL_OB = (0x00 << 6) | OPC_SHLL_OB_DSP,
887 OPC_SHLL_QH = (0x08 << 6) | OPC_SHLL_OB_DSP,
888 OPC_SHLL_S_QH = (0x0C << 6) | OPC_SHLL_OB_DSP,
889 OPC_SHRA_OB = (0x04 << 6) | OPC_SHLL_OB_DSP,
890 OPC_SHRA_R_OB = (0x05 << 6) | OPC_SHLL_OB_DSP,
891 OPC_SHRA_QH = (0x09 << 6) | OPC_SHLL_OB_DSP,
892 OPC_SHRA_R_QH = (0x0D << 6) | OPC_SHLL_OB_DSP,
893 OPC_SHRL_OB = (0x01 << 6) | OPC_SHLL_OB_DSP,
894 OPC_SHRL_QH = (0x19 << 6) | OPC_SHLL_OB_DSP,
895};
77c5fa8b 896
7a387fff
TS
897/* Coprocessor 0 (rs field) */
898#define MASK_CP0(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
899
6ea83fed 900enum {
7a387fff
TS
901 OPC_MFC0 = (0x00 << 21) | OPC_CP0,
902 OPC_DMFC0 = (0x01 << 21) | OPC_CP0,
5204ea79 903 OPC_MFHC0 = (0x02 << 21) | OPC_CP0,
7a387fff
TS
904 OPC_MTC0 = (0x04 << 21) | OPC_CP0,
905 OPC_DMTC0 = (0x05 << 21) | OPC_CP0,
5204ea79 906 OPC_MTHC0 = (0x06 << 21) | OPC_CP0,
ead9360e 907 OPC_MFTR = (0x08 << 21) | OPC_CP0,
7a387fff
TS
908 OPC_RDPGPR = (0x0A << 21) | OPC_CP0,
909 OPC_MFMC0 = (0x0B << 21) | OPC_CP0,
ead9360e 910 OPC_MTTR = (0x0C << 21) | OPC_CP0,
7a387fff
TS
911 OPC_WRPGPR = (0x0E << 21) | OPC_CP0,
912 OPC_C0 = (0x10 << 21) | OPC_CP0,
c38a1d52
AR
913 OPC_C0_1 = (0x11 << 21) | OPC_CP0,
914 OPC_C0_2 = (0x12 << 21) | OPC_CP0,
915 OPC_C0_3 = (0x13 << 21) | OPC_CP0,
916 OPC_C0_4 = (0x14 << 21) | OPC_CP0,
917 OPC_C0_5 = (0x15 << 21) | OPC_CP0,
918 OPC_C0_6 = (0x16 << 21) | OPC_CP0,
919 OPC_C0_7 = (0x17 << 21) | OPC_CP0,
920 OPC_C0_8 = (0x18 << 21) | OPC_CP0,
921 OPC_C0_9 = (0x19 << 21) | OPC_CP0,
922 OPC_C0_A = (0x1A << 21) | OPC_CP0,
923 OPC_C0_B = (0x1B << 21) | OPC_CP0,
924 OPC_C0_C = (0x1C << 21) | OPC_CP0,
925 OPC_C0_D = (0x1D << 21) | OPC_CP0,
926 OPC_C0_E = (0x1E << 21) | OPC_CP0,
927 OPC_C0_F = (0x1F << 21) | OPC_CP0,
6ea83fed 928};
7a387fff
TS
929
930/* MFMC0 opcodes */
b48cfdff 931#define MASK_MFMC0(op) MASK_CP0(op) | (op & 0xFFFF)
7a387fff
TS
932
933enum {
ead9360e
TS
934 OPC_DMT = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
935 OPC_EMT = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
936 OPC_DVPE = 0x01 | (0 << 5) | OPC_MFMC0,
937 OPC_EVPE = 0x01 | (1 << 5) | OPC_MFMC0,
7a387fff
TS
938 OPC_DI = (0 << 5) | (0x0C << 11) | OPC_MFMC0,
939 OPC_EI = (1 << 5) | (0x0C << 11) | OPC_MFMC0,
01bc435b
YK
940 OPC_DVP = 0x04 | (0 << 3) | (1 << 5) | (0 << 11) | OPC_MFMC0,
941 OPC_EVP = 0x04 | (0 << 3) | (0 << 5) | (0 << 11) | OPC_MFMC0,
7a387fff
TS
942};
943
944/* Coprocessor 0 (with rs == C0) */
945#define MASK_C0(op) MASK_CP0(op) | (op & 0x3F)
946
947enum {
948 OPC_TLBR = 0x01 | OPC_C0,
949 OPC_TLBWI = 0x02 | OPC_C0,
9456c2fb
LA
950 OPC_TLBINV = 0x03 | OPC_C0,
951 OPC_TLBINVF = 0x04 | OPC_C0,
7a387fff
TS
952 OPC_TLBWR = 0x06 | OPC_C0,
953 OPC_TLBP = 0x08 | OPC_C0,
954 OPC_RFE = 0x10 | OPC_C0,
955 OPC_ERET = 0x18 | OPC_C0,
956 OPC_DERET = 0x1F | OPC_C0,
957 OPC_WAIT = 0x20 | OPC_C0,
958};
959
960/* Coprocessor 1 (rs field) */
961#define MASK_CP1(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
962
bf4120ad
NF
963/* Values for the fmt field in FP instructions */
964enum {
965 /* 0 - 15 are reserved */
e459440a
AJ
966 FMT_S = 16, /* single fp */
967 FMT_D = 17, /* double fp */
968 FMT_E = 18, /* extended fp */
969 FMT_Q = 19, /* quad fp */
970 FMT_W = 20, /* 32-bit fixed */
971 FMT_L = 21, /* 64-bit fixed */
972 FMT_PS = 22, /* paired single fp */
bf4120ad
NF
973 /* 23 - 31 are reserved */
974};
975
7a387fff
TS
976enum {
977 OPC_MFC1 = (0x00 << 21) | OPC_CP1,
978 OPC_DMFC1 = (0x01 << 21) | OPC_CP1,
979 OPC_CFC1 = (0x02 << 21) | OPC_CP1,
5a5012ec 980 OPC_MFHC1 = (0x03 << 21) | OPC_CP1,
7a387fff
TS
981 OPC_MTC1 = (0x04 << 21) | OPC_CP1,
982 OPC_DMTC1 = (0x05 << 21) | OPC_CP1,
983 OPC_CTC1 = (0x06 << 21) | OPC_CP1,
5a5012ec 984 OPC_MTHC1 = (0x07 << 21) | OPC_CP1,
7a387fff 985 OPC_BC1 = (0x08 << 21) | OPC_CP1, /* bc */
5a5012ec
TS
986 OPC_BC1ANY2 = (0x09 << 21) | OPC_CP1,
987 OPC_BC1ANY4 = (0x0A << 21) | OPC_CP1,
239dfebe
YK
988 OPC_BZ_V = (0x0B << 21) | OPC_CP1,
989 OPC_BNZ_V = (0x0F << 21) | OPC_CP1,
e459440a
AJ
990 OPC_S_FMT = (FMT_S << 21) | OPC_CP1,
991 OPC_D_FMT = (FMT_D << 21) | OPC_CP1,
992 OPC_E_FMT = (FMT_E << 21) | OPC_CP1,
993 OPC_Q_FMT = (FMT_Q << 21) | OPC_CP1,
994 OPC_W_FMT = (FMT_W << 21) | OPC_CP1,
995 OPC_L_FMT = (FMT_L << 21) | OPC_CP1,
996 OPC_PS_FMT = (FMT_PS << 21) | OPC_CP1,
31837be3
YK
997 OPC_BC1EQZ = (0x09 << 21) | OPC_CP1,
998 OPC_BC1NEZ = (0x0D << 21) | OPC_CP1,
239dfebe
YK
999 OPC_BZ_B = (0x18 << 21) | OPC_CP1,
1000 OPC_BZ_H = (0x19 << 21) | OPC_CP1,
1001 OPC_BZ_W = (0x1A << 21) | OPC_CP1,
1002 OPC_BZ_D = (0x1B << 21) | OPC_CP1,
1003 OPC_BNZ_B = (0x1C << 21) | OPC_CP1,
1004 OPC_BNZ_H = (0x1D << 21) | OPC_CP1,
1005 OPC_BNZ_W = (0x1E << 21) | OPC_CP1,
1006 OPC_BNZ_D = (0x1F << 21) | OPC_CP1,
7a387fff
TS
1007};
1008
5a5012ec
TS
1009#define MASK_CP1_FUNC(op) MASK_CP1(op) | (op & 0x3F)
1010#define MASK_BC1(op) MASK_CP1(op) | (op & (0x3 << 16))
1011
7a387fff
TS
1012enum {
1013 OPC_BC1F = (0x00 << 16) | OPC_BC1,
1014 OPC_BC1T = (0x01 << 16) | OPC_BC1,
1015 OPC_BC1FL = (0x02 << 16) | OPC_BC1,
1016 OPC_BC1TL = (0x03 << 16) | OPC_BC1,
1017};
1018
5a5012ec
TS
1019enum {
1020 OPC_BC1FANY2 = (0x00 << 16) | OPC_BC1ANY2,
1021 OPC_BC1TANY2 = (0x01 << 16) | OPC_BC1ANY2,
1022};
1023
1024enum {
1025 OPC_BC1FANY4 = (0x00 << 16) | OPC_BC1ANY4,
1026 OPC_BC1TANY4 = (0x01 << 16) | OPC_BC1ANY4,
1027};
7a387fff
TS
1028
1029#define MASK_CP2(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
e0c84da7
TS
1030
1031enum {
1032 OPC_MFC2 = (0x00 << 21) | OPC_CP2,
1033 OPC_DMFC2 = (0x01 << 21) | OPC_CP2,
1034 OPC_CFC2 = (0x02 << 21) | OPC_CP2,
1035 OPC_MFHC2 = (0x03 << 21) | OPC_CP2,
1036 OPC_MTC2 = (0x04 << 21) | OPC_CP2,
1037 OPC_DMTC2 = (0x05 << 21) | OPC_CP2,
1038 OPC_CTC2 = (0x06 << 21) | OPC_CP2,
1039 OPC_MTHC2 = (0x07 << 21) | OPC_CP2,
1040 OPC_BC2 = (0x08 << 21) | OPC_CP2,
31837be3
YK
1041 OPC_BC2EQZ = (0x09 << 21) | OPC_CP2,
1042 OPC_BC2NEZ = (0x0D << 21) | OPC_CP2,
e0c84da7
TS
1043};
1044
bd277fa1
RH
1045#define MASK_LMI(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)) | (op & 0x1F))
1046
1047enum {
1048 OPC_PADDSH = (24 << 21) | (0x00) | OPC_CP2,
1049 OPC_PADDUSH = (25 << 21) | (0x00) | OPC_CP2,
1050 OPC_PADDH = (26 << 21) | (0x00) | OPC_CP2,
1051 OPC_PADDW = (27 << 21) | (0x00) | OPC_CP2,
1052 OPC_PADDSB = (28 << 21) | (0x00) | OPC_CP2,
1053 OPC_PADDUSB = (29 << 21) | (0x00) | OPC_CP2,
1054 OPC_PADDB = (30 << 21) | (0x00) | OPC_CP2,
1055 OPC_PADDD = (31 << 21) | (0x00) | OPC_CP2,
1056
1057 OPC_PSUBSH = (24 << 21) | (0x01) | OPC_CP2,
1058 OPC_PSUBUSH = (25 << 21) | (0x01) | OPC_CP2,
1059 OPC_PSUBH = (26 << 21) | (0x01) | OPC_CP2,
1060 OPC_PSUBW = (27 << 21) | (0x01) | OPC_CP2,
1061 OPC_PSUBSB = (28 << 21) | (0x01) | OPC_CP2,
1062 OPC_PSUBUSB = (29 << 21) | (0x01) | OPC_CP2,
1063 OPC_PSUBB = (30 << 21) | (0x01) | OPC_CP2,
1064 OPC_PSUBD = (31 << 21) | (0x01) | OPC_CP2,
1065
1066 OPC_PSHUFH = (24 << 21) | (0x02) | OPC_CP2,
1067 OPC_PACKSSWH = (25 << 21) | (0x02) | OPC_CP2,
1068 OPC_PACKSSHB = (26 << 21) | (0x02) | OPC_CP2,
1069 OPC_PACKUSHB = (27 << 21) | (0x02) | OPC_CP2,
1070 OPC_XOR_CP2 = (28 << 21) | (0x02) | OPC_CP2,
1071 OPC_NOR_CP2 = (29 << 21) | (0x02) | OPC_CP2,
1072 OPC_AND_CP2 = (30 << 21) | (0x02) | OPC_CP2,
1073 OPC_PANDN = (31 << 21) | (0x02) | OPC_CP2,
1074
1075 OPC_PUNPCKLHW = (24 << 21) | (0x03) | OPC_CP2,
1076 OPC_PUNPCKHHW = (25 << 21) | (0x03) | OPC_CP2,
1077 OPC_PUNPCKLBH = (26 << 21) | (0x03) | OPC_CP2,
1078 OPC_PUNPCKHBH = (27 << 21) | (0x03) | OPC_CP2,
1079 OPC_PINSRH_0 = (28 << 21) | (0x03) | OPC_CP2,
1080 OPC_PINSRH_1 = (29 << 21) | (0x03) | OPC_CP2,
1081 OPC_PINSRH_2 = (30 << 21) | (0x03) | OPC_CP2,
1082 OPC_PINSRH_3 = (31 << 21) | (0x03) | OPC_CP2,
1083
1084 OPC_PAVGH = (24 << 21) | (0x08) | OPC_CP2,
1085 OPC_PAVGB = (25 << 21) | (0x08) | OPC_CP2,
1086 OPC_PMAXSH = (26 << 21) | (0x08) | OPC_CP2,
1087 OPC_PMINSH = (27 << 21) | (0x08) | OPC_CP2,
1088 OPC_PMAXUB = (28 << 21) | (0x08) | OPC_CP2,
1089 OPC_PMINUB = (29 << 21) | (0x08) | OPC_CP2,
1090
1091 OPC_PCMPEQW = (24 << 21) | (0x09) | OPC_CP2,
1092 OPC_PCMPGTW = (25 << 21) | (0x09) | OPC_CP2,
1093 OPC_PCMPEQH = (26 << 21) | (0x09) | OPC_CP2,
1094 OPC_PCMPGTH = (27 << 21) | (0x09) | OPC_CP2,
1095 OPC_PCMPEQB = (28 << 21) | (0x09) | OPC_CP2,
1096 OPC_PCMPGTB = (29 << 21) | (0x09) | OPC_CP2,
1097
1098 OPC_PSLLW = (24 << 21) | (0x0A) | OPC_CP2,
1099 OPC_PSLLH = (25 << 21) | (0x0A) | OPC_CP2,
1100 OPC_PMULLH = (26 << 21) | (0x0A) | OPC_CP2,
1101 OPC_PMULHH = (27 << 21) | (0x0A) | OPC_CP2,
1102 OPC_PMULUW = (28 << 21) | (0x0A) | OPC_CP2,
1103 OPC_PMULHUH = (29 << 21) | (0x0A) | OPC_CP2,
1104
1105 OPC_PSRLW = (24 << 21) | (0x0B) | OPC_CP2,
1106 OPC_PSRLH = (25 << 21) | (0x0B) | OPC_CP2,
1107 OPC_PSRAW = (26 << 21) | (0x0B) | OPC_CP2,
1108 OPC_PSRAH = (27 << 21) | (0x0B) | OPC_CP2,
1109 OPC_PUNPCKLWD = (28 << 21) | (0x0B) | OPC_CP2,
1110 OPC_PUNPCKHWD = (29 << 21) | (0x0B) | OPC_CP2,
1111
1112 OPC_ADDU_CP2 = (24 << 21) | (0x0C) | OPC_CP2,
1113 OPC_OR_CP2 = (25 << 21) | (0x0C) | OPC_CP2,
1114 OPC_ADD_CP2 = (26 << 21) | (0x0C) | OPC_CP2,
1115 OPC_DADD_CP2 = (27 << 21) | (0x0C) | OPC_CP2,
1116 OPC_SEQU_CP2 = (28 << 21) | (0x0C) | OPC_CP2,
1117 OPC_SEQ_CP2 = (29 << 21) | (0x0C) | OPC_CP2,
1118
1119 OPC_SUBU_CP2 = (24 << 21) | (0x0D) | OPC_CP2,
1120 OPC_PASUBUB = (25 << 21) | (0x0D) | OPC_CP2,
1121 OPC_SUB_CP2 = (26 << 21) | (0x0D) | OPC_CP2,
1122 OPC_DSUB_CP2 = (27 << 21) | (0x0D) | OPC_CP2,
1123 OPC_SLTU_CP2 = (28 << 21) | (0x0D) | OPC_CP2,
1124 OPC_SLT_CP2 = (29 << 21) | (0x0D) | OPC_CP2,
1125
1126 OPC_SLL_CP2 = (24 << 21) | (0x0E) | OPC_CP2,
1127 OPC_DSLL_CP2 = (25 << 21) | (0x0E) | OPC_CP2,
1128 OPC_PEXTRH = (26 << 21) | (0x0E) | OPC_CP2,
1129 OPC_PMADDHW = (27 << 21) | (0x0E) | OPC_CP2,
1130 OPC_SLEU_CP2 = (28 << 21) | (0x0E) | OPC_CP2,
1131 OPC_SLE_CP2 = (29 << 21) | (0x0E) | OPC_CP2,
1132
1133 OPC_SRL_CP2 = (24 << 21) | (0x0F) | OPC_CP2,
1134 OPC_DSRL_CP2 = (25 << 21) | (0x0F) | OPC_CP2,
1135 OPC_SRA_CP2 = (26 << 21) | (0x0F) | OPC_CP2,
1136 OPC_DSRA_CP2 = (27 << 21) | (0x0F) | OPC_CP2,
1137 OPC_BIADD = (28 << 21) | (0x0F) | OPC_CP2,
1138 OPC_PMOVMSKB = (29 << 21) | (0x0F) | OPC_CP2,
1139};
1140
1141
e0c84da7
TS
1142#define MASK_CP3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
1143
1144enum {
1145 OPC_LWXC1 = 0x00 | OPC_CP3,
1146 OPC_LDXC1 = 0x01 | OPC_CP3,
1147 OPC_LUXC1 = 0x05 | OPC_CP3,
1148 OPC_SWXC1 = 0x08 | OPC_CP3,
1149 OPC_SDXC1 = 0x09 | OPC_CP3,
1150 OPC_SUXC1 = 0x0D | OPC_CP3,
1151 OPC_PREFX = 0x0F | OPC_CP3,
1152 OPC_ALNV_PS = 0x1E | OPC_CP3,
1153 OPC_MADD_S = 0x20 | OPC_CP3,
1154 OPC_MADD_D = 0x21 | OPC_CP3,
1155 OPC_MADD_PS = 0x26 | OPC_CP3,
1156 OPC_MSUB_S = 0x28 | OPC_CP3,
1157 OPC_MSUB_D = 0x29 | OPC_CP3,
1158 OPC_MSUB_PS = 0x2E | OPC_CP3,
1159 OPC_NMADD_S = 0x30 | OPC_CP3,
fbcc6828 1160 OPC_NMADD_D = 0x31 | OPC_CP3,
e0c84da7
TS
1161 OPC_NMADD_PS= 0x36 | OPC_CP3,
1162 OPC_NMSUB_S = 0x38 | OPC_CP3,
1163 OPC_NMSUB_D = 0x39 | OPC_CP3,
1164 OPC_NMSUB_PS= 0x3E | OPC_CP3,
1165};
1166
239dfebe
YK
1167/* MSA Opcodes */
1168#define MASK_MSA_MINOR(op) (MASK_OP_MAJOR(op) | (op & 0x3F))
1169enum {
1170 OPC_MSA_I8_00 = 0x00 | OPC_MSA,
1171 OPC_MSA_I8_01 = 0x01 | OPC_MSA,
1172 OPC_MSA_I8_02 = 0x02 | OPC_MSA,
1173 OPC_MSA_I5_06 = 0x06 | OPC_MSA,
1174 OPC_MSA_I5_07 = 0x07 | OPC_MSA,
1175 OPC_MSA_BIT_09 = 0x09 | OPC_MSA,
1176 OPC_MSA_BIT_0A = 0x0A | OPC_MSA,
1177 OPC_MSA_3R_0D = 0x0D | OPC_MSA,
1178 OPC_MSA_3R_0E = 0x0E | OPC_MSA,
1179 OPC_MSA_3R_0F = 0x0F | OPC_MSA,
1180 OPC_MSA_3R_10 = 0x10 | OPC_MSA,
1181 OPC_MSA_3R_11 = 0x11 | OPC_MSA,
1182 OPC_MSA_3R_12 = 0x12 | OPC_MSA,
1183 OPC_MSA_3R_13 = 0x13 | OPC_MSA,
1184 OPC_MSA_3R_14 = 0x14 | OPC_MSA,
1185 OPC_MSA_3R_15 = 0x15 | OPC_MSA,
1186 OPC_MSA_ELM = 0x19 | OPC_MSA,
1187 OPC_MSA_3RF_1A = 0x1A | OPC_MSA,
1188 OPC_MSA_3RF_1B = 0x1B | OPC_MSA,
1189 OPC_MSA_3RF_1C = 0x1C | OPC_MSA,
1190 OPC_MSA_VEC = 0x1E | OPC_MSA,
1191
1192 /* MI10 instruction */
1193 OPC_LD_B = (0x20) | OPC_MSA,
1194 OPC_LD_H = (0x21) | OPC_MSA,
1195 OPC_LD_W = (0x22) | OPC_MSA,
1196 OPC_LD_D = (0x23) | OPC_MSA,
1197 OPC_ST_B = (0x24) | OPC_MSA,
1198 OPC_ST_H = (0x25) | OPC_MSA,
1199 OPC_ST_W = (0x26) | OPC_MSA,
1200 OPC_ST_D = (0x27) | OPC_MSA,
1201};
1202
1203enum {
1204 /* I5 instruction df(bits 22..21) = _b, _h, _w, _d */
1205 OPC_ADDVI_df = (0x0 << 23) | OPC_MSA_I5_06,
1206 OPC_CEQI_df = (0x0 << 23) | OPC_MSA_I5_07,
1207 OPC_SUBVI_df = (0x1 << 23) | OPC_MSA_I5_06,
1208 OPC_MAXI_S_df = (0x2 << 23) | OPC_MSA_I5_06,
1209 OPC_CLTI_S_df = (0x2 << 23) | OPC_MSA_I5_07,
1210 OPC_MAXI_U_df = (0x3 << 23) | OPC_MSA_I5_06,
1211 OPC_CLTI_U_df = (0x3 << 23) | OPC_MSA_I5_07,
1212 OPC_MINI_S_df = (0x4 << 23) | OPC_MSA_I5_06,
1213 OPC_CLEI_S_df = (0x4 << 23) | OPC_MSA_I5_07,
1214 OPC_MINI_U_df = (0x5 << 23) | OPC_MSA_I5_06,
1215 OPC_CLEI_U_df = (0x5 << 23) | OPC_MSA_I5_07,
1216 OPC_LDI_df = (0x6 << 23) | OPC_MSA_I5_07,
1217
1218 /* I8 instruction */
1219 OPC_ANDI_B = (0x0 << 24) | OPC_MSA_I8_00,
1220 OPC_BMNZI_B = (0x0 << 24) | OPC_MSA_I8_01,
1221 OPC_SHF_B = (0x0 << 24) | OPC_MSA_I8_02,
1222 OPC_ORI_B = (0x1 << 24) | OPC_MSA_I8_00,
1223 OPC_BMZI_B = (0x1 << 24) | OPC_MSA_I8_01,
1224 OPC_SHF_H = (0x1 << 24) | OPC_MSA_I8_02,
1225 OPC_NORI_B = (0x2 << 24) | OPC_MSA_I8_00,
1226 OPC_BSELI_B = (0x2 << 24) | OPC_MSA_I8_01,
1227 OPC_SHF_W = (0x2 << 24) | OPC_MSA_I8_02,
1228 OPC_XORI_B = (0x3 << 24) | OPC_MSA_I8_00,
1229
1230 /* VEC/2R/2RF instruction */
1231 OPC_AND_V = (0x00 << 21) | OPC_MSA_VEC,
1232 OPC_OR_V = (0x01 << 21) | OPC_MSA_VEC,
1233 OPC_NOR_V = (0x02 << 21) | OPC_MSA_VEC,
1234 OPC_XOR_V = (0x03 << 21) | OPC_MSA_VEC,
1235 OPC_BMNZ_V = (0x04 << 21) | OPC_MSA_VEC,
1236 OPC_BMZ_V = (0x05 << 21) | OPC_MSA_VEC,
1237 OPC_BSEL_V = (0x06 << 21) | OPC_MSA_VEC,
1238
1239 OPC_MSA_2R = (0x18 << 21) | OPC_MSA_VEC,
1240 OPC_MSA_2RF = (0x19 << 21) | OPC_MSA_VEC,
1241
1242 /* 2R instruction df(bits 17..16) = _b, _h, _w, _d */
1243 OPC_FILL_df = (0x00 << 18) | OPC_MSA_2R,
1244 OPC_PCNT_df = (0x01 << 18) | OPC_MSA_2R,
1245 OPC_NLOC_df = (0x02 << 18) | OPC_MSA_2R,
1246 OPC_NLZC_df = (0x03 << 18) | OPC_MSA_2R,
1247
1248 /* 2RF instruction df(bit 16) = _w, _d */
1249 OPC_FCLASS_df = (0x00 << 17) | OPC_MSA_2RF,
1250 OPC_FTRUNC_S_df = (0x01 << 17) | OPC_MSA_2RF,
1251 OPC_FTRUNC_U_df = (0x02 << 17) | OPC_MSA_2RF,
1252 OPC_FSQRT_df = (0x03 << 17) | OPC_MSA_2RF,
1253 OPC_FRSQRT_df = (0x04 << 17) | OPC_MSA_2RF,
1254 OPC_FRCP_df = (0x05 << 17) | OPC_MSA_2RF,
1255 OPC_FRINT_df = (0x06 << 17) | OPC_MSA_2RF,
1256 OPC_FLOG2_df = (0x07 << 17) | OPC_MSA_2RF,
1257 OPC_FEXUPL_df = (0x08 << 17) | OPC_MSA_2RF,
1258 OPC_FEXUPR_df = (0x09 << 17) | OPC_MSA_2RF,
1259 OPC_FFQL_df = (0x0A << 17) | OPC_MSA_2RF,
1260 OPC_FFQR_df = (0x0B << 17) | OPC_MSA_2RF,
1261 OPC_FTINT_S_df = (0x0C << 17) | OPC_MSA_2RF,
1262 OPC_FTINT_U_df = (0x0D << 17) | OPC_MSA_2RF,
1263 OPC_FFINT_S_df = (0x0E << 17) | OPC_MSA_2RF,
1264 OPC_FFINT_U_df = (0x0F << 17) | OPC_MSA_2RF,
1265
1266 /* 3R instruction df(bits 22..21) = _b, _h, _w, d */
1267 OPC_SLL_df = (0x0 << 23) | OPC_MSA_3R_0D,
1268 OPC_ADDV_df = (0x0 << 23) | OPC_MSA_3R_0E,
1269 OPC_CEQ_df = (0x0 << 23) | OPC_MSA_3R_0F,
1270 OPC_ADD_A_df = (0x0 << 23) | OPC_MSA_3R_10,
1271 OPC_SUBS_S_df = (0x0 << 23) | OPC_MSA_3R_11,
1272 OPC_MULV_df = (0x0 << 23) | OPC_MSA_3R_12,
1273 OPC_DOTP_S_df = (0x0 << 23) | OPC_MSA_3R_13,
1274 OPC_SLD_df = (0x0 << 23) | OPC_MSA_3R_14,
1275 OPC_VSHF_df = (0x0 << 23) | OPC_MSA_3R_15,
1276 OPC_SRA_df = (0x1 << 23) | OPC_MSA_3R_0D,
1277 OPC_SUBV_df = (0x1 << 23) | OPC_MSA_3R_0E,
1278 OPC_ADDS_A_df = (0x1 << 23) | OPC_MSA_3R_10,
1279 OPC_SUBS_U_df = (0x1 << 23) | OPC_MSA_3R_11,
1280 OPC_MADDV_df = (0x1 << 23) | OPC_MSA_3R_12,
1281 OPC_DOTP_U_df = (0x1 << 23) | OPC_MSA_3R_13,
1282 OPC_SPLAT_df = (0x1 << 23) | OPC_MSA_3R_14,
1283 OPC_SRAR_df = (0x1 << 23) | OPC_MSA_3R_15,
1284 OPC_SRL_df = (0x2 << 23) | OPC_MSA_3R_0D,
1285 OPC_MAX_S_df = (0x2 << 23) | OPC_MSA_3R_0E,
1286 OPC_CLT_S_df = (0x2 << 23) | OPC_MSA_3R_0F,
1287 OPC_ADDS_S_df = (0x2 << 23) | OPC_MSA_3R_10,
1288 OPC_SUBSUS_U_df = (0x2 << 23) | OPC_MSA_3R_11,
1289 OPC_MSUBV_df = (0x2 << 23) | OPC_MSA_3R_12,
1290 OPC_DPADD_S_df = (0x2 << 23) | OPC_MSA_3R_13,
1291 OPC_PCKEV_df = (0x2 << 23) | OPC_MSA_3R_14,
1292 OPC_SRLR_df = (0x2 << 23) | OPC_MSA_3R_15,
1293 OPC_BCLR_df = (0x3 << 23) | OPC_MSA_3R_0D,
1294 OPC_MAX_U_df = (0x3 << 23) | OPC_MSA_3R_0E,
1295 OPC_CLT_U_df = (0x3 << 23) | OPC_MSA_3R_0F,
1296 OPC_ADDS_U_df = (0x3 << 23) | OPC_MSA_3R_10,
1297 OPC_SUBSUU_S_df = (0x3 << 23) | OPC_MSA_3R_11,
1298 OPC_DPADD_U_df = (0x3 << 23) | OPC_MSA_3R_13,
1299 OPC_PCKOD_df = (0x3 << 23) | OPC_MSA_3R_14,
1300 OPC_BSET_df = (0x4 << 23) | OPC_MSA_3R_0D,
1301 OPC_MIN_S_df = (0x4 << 23) | OPC_MSA_3R_0E,
1302 OPC_CLE_S_df = (0x4 << 23) | OPC_MSA_3R_0F,
1303 OPC_AVE_S_df = (0x4 << 23) | OPC_MSA_3R_10,
1304 OPC_ASUB_S_df = (0x4 << 23) | OPC_MSA_3R_11,
1305 OPC_DIV_S_df = (0x4 << 23) | OPC_MSA_3R_12,
1306 OPC_DPSUB_S_df = (0x4 << 23) | OPC_MSA_3R_13,
1307 OPC_ILVL_df = (0x4 << 23) | OPC_MSA_3R_14,
1308 OPC_HADD_S_df = (0x4 << 23) | OPC_MSA_3R_15,
1309 OPC_BNEG_df = (0x5 << 23) | OPC_MSA_3R_0D,
1310 OPC_MIN_U_df = (0x5 << 23) | OPC_MSA_3R_0E,
1311 OPC_CLE_U_df = (0x5 << 23) | OPC_MSA_3R_0F,
1312 OPC_AVE_U_df = (0x5 << 23) | OPC_MSA_3R_10,
1313 OPC_ASUB_U_df = (0x5 << 23) | OPC_MSA_3R_11,
1314 OPC_DIV_U_df = (0x5 << 23) | OPC_MSA_3R_12,
1315 OPC_DPSUB_U_df = (0x5 << 23) | OPC_MSA_3R_13,
1316 OPC_ILVR_df = (0x5 << 23) | OPC_MSA_3R_14,
1317 OPC_HADD_U_df = (0x5 << 23) | OPC_MSA_3R_15,
1318 OPC_BINSL_df = (0x6 << 23) | OPC_MSA_3R_0D,
1319 OPC_MAX_A_df = (0x6 << 23) | OPC_MSA_3R_0E,
1320 OPC_AVER_S_df = (0x6 << 23) | OPC_MSA_3R_10,
1321 OPC_MOD_S_df = (0x6 << 23) | OPC_MSA_3R_12,
1322 OPC_ILVEV_df = (0x6 << 23) | OPC_MSA_3R_14,
1323 OPC_HSUB_S_df = (0x6 << 23) | OPC_MSA_3R_15,
1324 OPC_BINSR_df = (0x7 << 23) | OPC_MSA_3R_0D,
1325 OPC_MIN_A_df = (0x7 << 23) | OPC_MSA_3R_0E,
1326 OPC_AVER_U_df = (0x7 << 23) | OPC_MSA_3R_10,
1327 OPC_MOD_U_df = (0x7 << 23) | OPC_MSA_3R_12,
1328 OPC_ILVOD_df = (0x7 << 23) | OPC_MSA_3R_14,
1329 OPC_HSUB_U_df = (0x7 << 23) | OPC_MSA_3R_15,
1330
1331 /* ELM instructions df(bits 21..16) = _b, _h, _w, _d */
1332 OPC_SLDI_df = (0x0 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1333 OPC_CTCMSA = (0x0 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1334 OPC_SPLATI_df = (0x1 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1335 OPC_CFCMSA = (0x1 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1336 OPC_COPY_S_df = (0x2 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1337 OPC_MOVE_V = (0x2 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1338 OPC_COPY_U_df = (0x3 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1339 OPC_INSERT_df = (0x4 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1340 OPC_INSVE_df = (0x5 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1341
1342 /* 3RF instruction _df(bit 21) = _w, _d */
1343 OPC_FCAF_df = (0x0 << 22) | OPC_MSA_3RF_1A,
1344 OPC_FADD_df = (0x0 << 22) | OPC_MSA_3RF_1B,
1345 OPC_FCUN_df = (0x1 << 22) | OPC_MSA_3RF_1A,
1346 OPC_FSUB_df = (0x1 << 22) | OPC_MSA_3RF_1B,
1347 OPC_FCOR_df = (0x1 << 22) | OPC_MSA_3RF_1C,
1348 OPC_FCEQ_df = (0x2 << 22) | OPC_MSA_3RF_1A,
1349 OPC_FMUL_df = (0x2 << 22) | OPC_MSA_3RF_1B,
1350 OPC_FCUNE_df = (0x2 << 22) | OPC_MSA_3RF_1C,
1351 OPC_FCUEQ_df = (0x3 << 22) | OPC_MSA_3RF_1A,
1352 OPC_FDIV_df = (0x3 << 22) | OPC_MSA_3RF_1B,
1353 OPC_FCNE_df = (0x3 << 22) | OPC_MSA_3RF_1C,
1354 OPC_FCLT_df = (0x4 << 22) | OPC_MSA_3RF_1A,
1355 OPC_FMADD_df = (0x4 << 22) | OPC_MSA_3RF_1B,
1356 OPC_MUL_Q_df = (0x4 << 22) | OPC_MSA_3RF_1C,
1357 OPC_FCULT_df = (0x5 << 22) | OPC_MSA_3RF_1A,
1358 OPC_FMSUB_df = (0x5 << 22) | OPC_MSA_3RF_1B,
1359 OPC_MADD_Q_df = (0x5 << 22) | OPC_MSA_3RF_1C,
1360 OPC_FCLE_df = (0x6 << 22) | OPC_MSA_3RF_1A,
1361 OPC_MSUB_Q_df = (0x6 << 22) | OPC_MSA_3RF_1C,
1362 OPC_FCULE_df = (0x7 << 22) | OPC_MSA_3RF_1A,
1363 OPC_FEXP2_df = (0x7 << 22) | OPC_MSA_3RF_1B,
1364 OPC_FSAF_df = (0x8 << 22) | OPC_MSA_3RF_1A,
1365 OPC_FEXDO_df = (0x8 << 22) | OPC_MSA_3RF_1B,
1366 OPC_FSUN_df = (0x9 << 22) | OPC_MSA_3RF_1A,
1367 OPC_FSOR_df = (0x9 << 22) | OPC_MSA_3RF_1C,
1368 OPC_FSEQ_df = (0xA << 22) | OPC_MSA_3RF_1A,
1369 OPC_FTQ_df = (0xA << 22) | OPC_MSA_3RF_1B,
1370 OPC_FSUNE_df = (0xA << 22) | OPC_MSA_3RF_1C,
1371 OPC_FSUEQ_df = (0xB << 22) | OPC_MSA_3RF_1A,
1372 OPC_FSNE_df = (0xB << 22) | OPC_MSA_3RF_1C,
1373 OPC_FSLT_df = (0xC << 22) | OPC_MSA_3RF_1A,
1374 OPC_FMIN_df = (0xC << 22) | OPC_MSA_3RF_1B,
1375 OPC_MULR_Q_df = (0xC << 22) | OPC_MSA_3RF_1C,
1376 OPC_FSULT_df = (0xD << 22) | OPC_MSA_3RF_1A,
1377 OPC_FMIN_A_df = (0xD << 22) | OPC_MSA_3RF_1B,
1378 OPC_MADDR_Q_df = (0xD << 22) | OPC_MSA_3RF_1C,
1379 OPC_FSLE_df = (0xE << 22) | OPC_MSA_3RF_1A,
1380 OPC_FMAX_df = (0xE << 22) | OPC_MSA_3RF_1B,
1381 OPC_MSUBR_Q_df = (0xE << 22) | OPC_MSA_3RF_1C,
1382 OPC_FSULE_df = (0xF << 22) | OPC_MSA_3RF_1A,
1383 OPC_FMAX_A_df = (0xF << 22) | OPC_MSA_3RF_1B,
1384
1385 /* BIT instruction df(bits 22..16) = _B _H _W _D */
1386 OPC_SLLI_df = (0x0 << 23) | OPC_MSA_BIT_09,
1387 OPC_SAT_S_df = (0x0 << 23) | OPC_MSA_BIT_0A,
1388 OPC_SRAI_df = (0x1 << 23) | OPC_MSA_BIT_09,
1389 OPC_SAT_U_df = (0x1 << 23) | OPC_MSA_BIT_0A,
1390 OPC_SRLI_df = (0x2 << 23) | OPC_MSA_BIT_09,
1391 OPC_SRARI_df = (0x2 << 23) | OPC_MSA_BIT_0A,
1392 OPC_BCLRI_df = (0x3 << 23) | OPC_MSA_BIT_09,
1393 OPC_SRLRI_df = (0x3 << 23) | OPC_MSA_BIT_0A,
1394 OPC_BSETI_df = (0x4 << 23) | OPC_MSA_BIT_09,
1395 OPC_BNEGI_df = (0x5 << 23) | OPC_MSA_BIT_09,
1396 OPC_BINSLI_df = (0x6 << 23) | OPC_MSA_BIT_09,
1397 OPC_BINSRI_df = (0x7 << 23) | OPC_MSA_BIT_09,
1398};
1399
b158d449
AM
1400
1401/*
1402 * AN OVERVIEW OF MXU EXTENSION INSTRUCTION SET
1403 * ============================================
1404 *
1405 * MXU (full name: MIPS eXtension/enhanced Unit) is an SIMD extension of MIPS32
1406 * instructions set. It is designed to fit the needs of signal, graphical and
1407 * video processing applications. MXU instruction set is used in Xburst family
1408 * of microprocessors by Ingenic.
1409 *
1410 * MXU unit contains 17 registers called X0-X16. X0 is always zero, and X16 is
1411 * the control register.
1412 *
093ade12
AM
1413 * The notation used in MXU assembler mnemonics
1414 * --------------------------------------------
1415 *
1416 * Registers:
1d0e663c
AM
1417 *
1418 * XRa, XRb, XRc, XRd - MXU registers
1419 * Rb, Rc, Rd, Rs, Rt - general purpose MIPS registers
093ade12
AM
1420 *
1421 * Subfields:
1422 *
1423 * aptn1 - 1-bit accumulate add/subtract pattern
1424 * aptn2 - 2-bit accumulate add/subtract pattern
1425 * eptn2 - 2-bit execute add/subtract pattern
1426 * optn2 - 2-bit operand pattern
1427 * optn3 - 3-bit operand pattern
1428 * sft4 - 4-bit shift amount
1429 * strd2 - 2-bit stride amount
1430 *
1431 * Prefixes:
1432 *
1433 * <Operation parallel level><Operand size>
1434 * S 32
1435 * D 16
1436 * Q 8
1437 *
1438 * Suffixes:
1439 *
1440 * E - Expand results
1441 * F - Fixed point multiplication
1442 * L - Low part result
1443 * R - Doing rounding
1444 * V - Variable instead of immediate
1445 * W - Combine above L and V
1446 *
1447 * Operations:
1448 *
1449 * ADD - Add or subtract
1450 * ADDC - Add with carry-in
1451 * ACC - Accumulate
1452 * ASUM - Sum together then accumulate (add or subtract)
1453 * ASUMC - Sum together then accumulate (add or subtract) with carry-in
1454 * AVG - Average between 2 operands
1455 * ABD - Absolute difference
1456 * ALN - Align data
1457 * AND - Logical bitwise 'and' operation
1458 * CPS - Copy sign
1459 * EXTR - Extract bits
1460 * I2M - Move from GPR register to MXU register
1461 * LDD - Load data from memory to XRF
1462 * LDI - Load data from memory to XRF (and increase the address base)
1463 * LUI - Load unsigned immediate
1464 * MUL - Multiply
1465 * MULU - Unsigned multiply
1466 * MADD - 64-bit operand add 32x32 product
1467 * MSUB - 64-bit operand subtract 32x32 product
1468 * MAC - Multiply and accumulate (add or subtract)
1469 * MAD - Multiply and add or subtract
1470 * MAX - Maximum between 2 operands
1471 * MIN - Minimum between 2 operands
1472 * M2I - Move from MXU register to GPR register
1473 * MOVZ - Move if zero
1474 * MOVN - Move if non-zero
1475 * NOR - Logical bitwise 'nor' operation
1476 * OR - Logical bitwise 'or' operation
1477 * STD - Store data from XRF to memory
1478 * SDI - Store data from XRF to memory (and increase the address base)
1479 * SLT - Set of less than comparison
1480 * SAD - Sum of absolute differences
1481 * SLL - Logical shift left
1482 * SLR - Logical shift right
1483 * SAR - Arithmetic shift right
1484 * SAT - Saturation
1485 * SFL - Shuffle
1486 * SCOP - Calculate x’s scope (-1, means x<0; 0, means x==0; 1, means x>0)
1487 * XOR - Logical bitwise 'exclusive or' operation
1d0e663c
AM
1488 *
1489 * Load/Store instructions Multiplication instructions
1490 * ----------------------- ---------------------------
1491 *
1492 * S32LDD XRa, Rb, s12 S32MADD XRa, XRd, Rs, Rt
1493 * S32STD XRa, Rb, s12 S32MADDU XRa, XRd, Rs, Rt
093ade12
AM
1494 * S32LDDV XRa, Rb, rc, strd2 S32MSUB XRa, XRd, Rs, Rt
1495 * S32STDV XRa, Rb, rc, strd2 S32MSUBU XRa, XRd, Rs, Rt
1d0e663c
AM
1496 * S32LDI XRa, Rb, s12 S32MUL XRa, XRd, Rs, Rt
1497 * S32SDI XRa, Rb, s12 S32MULU XRa, XRd, Rs, Rt
1498 * S32LDIV XRa, Rb, rc, strd2 D16MUL XRa, XRb, XRc, XRd, optn2
1499 * S32SDIV XRa, Rb, rc, strd2 D16MULE XRa, XRb, XRc, optn2
1500 * S32LDDR XRa, Rb, s12 D16MULF XRa, XRb, XRc, optn2
1501 * S32STDR XRa, Rb, s12 D16MAC XRa, XRb, XRc, XRd, aptn2, optn2
1502 * S32LDDVR XRa, Rb, rc, strd2 D16MACE XRa, XRb, XRc, XRd, aptn2, optn2
1503 * S32STDVR XRa, Rb, rc, strd2 D16MACF XRa, XRb, XRc, XRd, aptn2, optn2
1504 * S32LDIR XRa, Rb, s12 D16MADL XRa, XRb, XRc, XRd, aptn2, optn2
1505 * S32SDIR XRa, Rb, s12 S16MAD XRa, XRb, XRc, XRd, aptn1, optn2
1506 * S32LDIVR XRa, Rb, rc, strd2 Q8MUL XRa, XRb, XRc, XRd
1507 * S32SDIVR XRa, Rb, rc, strd2 Q8MULSU XRa, XRb, XRc, XRd
1508 * S16LDD XRa, Rb, s10, eptn2 Q8MAC XRa, XRb, XRc, XRd, aptn2
1509 * S16STD XRa, Rb, s10, eptn2 Q8MACSU XRa, XRb, XRc, XRd, aptn2
1510 * S16LDI XRa, Rb, s10, eptn2 Q8MADL XRa, XRb, XRc, XRd, aptn2
1511 * S16SDI XRa, Rb, s10, eptn2
1512 * S8LDD XRa, Rb, s8, eptn3
1513 * S8STD XRa, Rb, s8, eptn3 Addition and subtraction instructions
1514 * S8LDI XRa, Rb, s8, eptn3 -------------------------------------
1515 * S8SDI XRa, Rb, s8, eptn3
1516 * LXW Rd, Rs, Rt, strd2 D32ADD XRa, XRb, XRc, XRd, eptn2
1517 * LXH Rd, Rs, Rt, strd2 D32ADDC XRa, XRb, XRc, XRd
1518 * LXHU Rd, Rs, Rt, strd2 D32ACC XRa, XRb, XRc, XRd, eptn2
1519 * LXB Rd, Rs, Rt, strd2 D32ACCM XRa, XRb, XRc, XRd, eptn2
1520 * LXBU Rd, Rs, Rt, strd2 D32ASUM XRa, XRb, XRc, XRd, eptn2
1521 * S32CPS XRa, XRb, XRc
1522 * Q16ADD XRa, XRb, XRc, XRd, eptn2, optn2
1523 * Comparison instructions Q16ACC XRa, XRb, XRc, XRd, eptn2
1524 * ----------------------- Q16ACCM XRa, XRb, XRc, XRd, eptn2
1525 * D16ASUM XRa, XRb, XRc, XRd, eptn2
1526 * S32MAX XRa, XRb, XRc D16CPS XRa, XRb,
1527 * S32MIN XRa, XRb, XRc D16AVG XRa, XRb, XRc
1528 * S32SLT XRa, XRb, XRc D16AVGR XRa, XRb, XRc
1529 * S32MOVZ XRa, XRb, XRc Q8ADD XRa, XRb, XRc, eptn2
1530 * S32MOVN XRa, XRb, XRc Q8ADDE XRa, XRb, XRc, XRd, eptn2
1531 * D16MAX XRa, XRb, XRc Q8ACCE XRa, XRb, XRc, XRd, eptn2
1532 * D16MIN XRa, XRb, XRc Q8ABD XRa, XRb, XRc
1533 * D16SLT XRa, XRb, XRc Q8SAD XRa, XRb, XRc, XRd
1534 * D16MOVZ XRa, XRb, XRc Q8AVG XRa, XRb, XRc
1535 * D16MOVN XRa, XRb, XRc Q8AVGR XRa, XRb, XRc
1536 * Q8MAX XRa, XRb, XRc D8SUM XRa, XRb, XRc, XRd
1537 * Q8MIN XRa, XRb, XRc D8SUMC XRa, XRb, XRc, XRd
1538 * Q8SLT XRa, XRb, XRc
1539 * Q8SLTU XRa, XRb, XRc
1540 * Q8MOVZ XRa, XRb, XRc Shift instructions
1541 * Q8MOVN XRa, XRb, XRc ------------------
1542 *
1543 * D32SLL XRa, XRb, XRc, XRd, sft4
1544 * Bitwise instructions D32SLR XRa, XRb, XRc, XRd, sft4
1545 * -------------------- D32SAR XRa, XRb, XRc, XRd, sft4
1546 * D32SARL XRa, XRb, XRc, sft4
1547 * S32NOR XRa, XRb, XRc D32SLLV XRa, XRb, Rb
1548 * S32AND XRa, XRb, XRc D32SLRV XRa, XRb, Rb
1549 * S32XOR XRa, XRb, XRc D32SARV XRa, XRb, Rb
1550 * S32OR XRa, XRb, XRc D32SARW XRa, XRb, XRc, Rb
1551 * Q16SLL XRa, XRb, XRc, XRd, sft4
1552 * Q16SLR XRa, XRb, XRc, XRd, sft4
eab0bdb0 1553 * Miscellaneous instructions Q16SAR XRa, XRb, XRc, XRd, sft4
1d0e663c
AM
1554 * ------------------------- Q16SLLV XRa, XRb, Rb
1555 * Q16SLRV XRa, XRb, Rb
1556 * S32SFL XRa, XRb, XRc, XRd, optn2 Q16SARV XRa, XRb, Rb
1557 * S32ALN XRa, XRb, XRc, Rb
1558 * S32ALNI XRa, XRb, XRc, s3
1559 * S32LUI XRa, s8, optn3 Move instructions
1560 * S32EXTR XRa, XRb, Rb, bits5 -----------------
1561 * S32EXTRV XRa, XRb, Rs, Rt
1562 * Q16SCOP XRa, XRb, XRc, XRd S32M2I XRa, Rb
1563 * Q16SAT XRa, XRb, XRc S32I2M XRa, Rb
1564 *
9ef5bff9
AM
1565 *
1566 * bits
1567 * 05..00
1568 *
1569 * ┌─ 000000 ─ OPC_MXU_S32MADD
1570 * ├─ 000001 ─ OPC_MXU_S32MADDU
eab0bdb0
AM
1571 * ├─ 000010 ─ <not assigned> (non-MXU OPC_MUL)
1572 * │
9ef5bff9
AM
1573 * │ 20..18
1574 * ├─ 000011 ─ OPC_MXU__POOL00 ─┬─ 000 ─ OPC_MXU_S32MAX
1575 * │ ├─ 001 ─ OPC_MXU_S32MIN
1576 * │ ├─ 010 ─ OPC_MXU_D16MAX
1577 * │ ├─ 011 ─ OPC_MXU_D16MIN
1578 * │ ├─ 100 ─ OPC_MXU_Q8MAX
1579 * │ ├─ 101 ─ OPC_MXU_Q8MIN
1580 * │ ├─ 110 ─ OPC_MXU_Q8SLT
1581 * │ └─ 111 ─ OPC_MXU_Q8SLTU
1582 * ├─ 000100 ─ OPC_MXU_S32MSUB
1583 * ├─ 000101 ─ OPC_MXU_S32MSUBU 20..18
1584 * ├─ 000110 ─ OPC_MXU__POOL01 ─┬─ 000 ─ OPC_MXU_S32SLT
1585 * │ ├─ 001 ─ OPC_MXU_D16SLT
1586 * │ ├─ 010 ─ OPC_MXU_D16AVG
1587 * │ ├─ 011 ─ OPC_MXU_D16AVGR
1588 * │ ├─ 100 ─ OPC_MXU_Q8AVG
1589 * │ ├─ 101 ─ OPC_MXU_Q8AVGR
1590 * │ └─ 111 ─ OPC_MXU_Q8ADD
1591 * │
1592 * │ 20..18
1593 * ├─ 000111 ─ OPC_MXU__POOL02 ─┬─ 000 ─ OPC_MXU_S32CPS
1594 * │ ├─ 010 ─ OPC_MXU_D16CPS
1595 * │ ├─ 100 ─ OPC_MXU_Q8ABD
1596 * │ └─ 110 ─ OPC_MXU_Q16SAT
1597 * ├─ 001000 ─ OPC_MXU_D16MUL
1598 * │ 25..24
1599 * ├─ 001001 ─ OPC_MXU__POOL03 ─┬─ 00 ─ OPC_MXU_D16MULF
1600 * │ └─ 01 ─ OPC_MXU_D16MULE
1601 * ├─ 001010 ─ OPC_MXU_D16MAC
1602 * ├─ 001011 ─ OPC_MXU_D16MACF
1603 * ├─ 001100 ─ OPC_MXU_D16MADL
eab0bdb0 1604 * ├─ 001101 ─ OPC_MXU_S16MAD
9ef5bff9 1605 * ├─ 001110 ─ OPC_MXU_Q16ADD
eab0bdb0
AM
1606 * ├─ 001111 ─ OPC_MXU_D16MACE 23
1607 * │ ┌─ 0 ─ OPC_MXU_S32LDD
1608 * ├─ 010000 ─ OPC_MXU__POOL04 ─┴─ 1 ─ OPC_MXU_S32LDDR
9ef5bff9
AM
1609 * │
1610 * │ 23
eab0bdb0 1611 * ├─ 010001 ─ OPC_MXU__POOL05 ─┬─ 0 ─ OPC_MXU_S32STD
9ef5bff9
AM
1612 * │ └─ 1 ─ OPC_MXU_S32STDR
1613 * │
1614 * │ 13..10
eab0bdb0 1615 * ├─ 010010 ─ OPC_MXU__POOL06 ─┬─ 0000 ─ OPC_MXU_S32LDDV
9ef5bff9
AM
1616 * │ └─ 0001 ─ OPC_MXU_S32LDDVR
1617 * │
1618 * │ 13..10
eab0bdb0 1619 * ├─ 010011 ─ OPC_MXU__POOL07 ─┬─ 0000 ─ OPC_MXU_S32STDV
9ef5bff9
AM
1620 * │ └─ 0001 ─ OPC_MXU_S32STDVR
1621 * │
1622 * │ 23
eab0bdb0 1623 * ├─ 010100 ─ OPC_MXU__POOL08 ─┬─ 0 ─ OPC_MXU_S32LDI
9ef5bff9
AM
1624 * │ └─ 1 ─ OPC_MXU_S32LDIR
1625 * │
1626 * │ 23
eab0bdb0 1627 * ├─ 010101 ─ OPC_MXU__POOL09 ─┬─ 0 ─ OPC_MXU_S32SDI
9ef5bff9
AM
1628 * │ └─ 1 ─ OPC_MXU_S32SDIR
1629 * │
1630 * │ 13..10
eab0bdb0 1631 * ├─ 010110 ─ OPC_MXU__POOL10 ─┬─ 0000 ─ OPC_MXU_S32LDIV
9ef5bff9
AM
1632 * │ └─ 0001 ─ OPC_MXU_S32LDIVR
1633 * │
1634 * │ 13..10
eab0bdb0 1635 * ├─ 010111 ─ OPC_MXU__POOL11 ─┬─ 0000 ─ OPC_MXU_S32SDIV
9ef5bff9
AM
1636 * │ └─ 0001 ─ OPC_MXU_S32SDIVR
1637 * ├─ 011000 ─ OPC_MXU_D32ADD
1638 * │ 23..22
eab0bdb0 1639 * MXU ├─ 011001 ─ OPC_MXU__POOL12 ─┬─ 00 ─ OPC_MXU_D32ACC
9ef5bff9
AM
1640 * opcodes ─┤ ├─ 01 ─ OPC_MXU_D32ACCM
1641 * │ └─ 10 ─ OPC_MXU_D32ASUM
1642 * ├─ 011010 ─ <not assigned>
1643 * │ 23..22
eab0bdb0 1644 * ├─ 011011 ─ OPC_MXU__POOL13 ─┬─ 00 ─ OPC_MXU_Q16ACC
9ef5bff9
AM
1645 * │ ├─ 01 ─ OPC_MXU_Q16ACCM
1646 * │ └─ 10 ─ OPC_MXU_Q16ASUM
1647 * │
1648 * │ 23..22
eab0bdb0 1649 * ├─ 011100 ─ OPC_MXU__POOL14 ─┬─ 00 ─ OPC_MXU_Q8ADDE
9ef5bff9
AM
1650 * │ ├─ 01 ─ OPC_MXU_D8SUM
1651 * ├─ 011101 ─ OPC_MXU_Q8ACCE └─ 10 ─ OPC_MXU_D8SUMC
1652 * ├─ 011110 ─ <not assigned>
1653 * ├─ 011111 ─ <not assigned>
eab0bdb0
AM
1654 * ├─ 100000 ─ <not assigned> (overlaps with CLZ)
1655 * ├─ 100001 ─ <not assigned> (overlaps with CLO)
9ef5bff9 1656 * ├─ 100010 ─ OPC_MXU_S8LDD
eab0bdb0
AM
1657 * ├─ 100011 ─ OPC_MXU_S8STD 15..14
1658 * ├─ 100100 ─ OPC_MXU_S8LDI ┌─ 00 ─ OPC_MXU_S32MUL
1659 * ├─ 100101 ─ OPC_MXU_S8SDI ├─ 00 ─ OPC_MXU_S32MULU
9ef5bff9 1660 * │ ├─ 00 ─ OPC_MXU_S32EXTR
eab0bdb0 1661 * ├─ 100110 ─ OPC_MXU__POOL15 ─┴─ 00 ─ OPC_MXU_S32EXTRV
9ef5bff9
AM
1662 * │
1663 * │ 20..18
eab0bdb0 1664 * ├─ 100111 ─ OPC_MXU__POOL16 ─┬─ 000 ─ OPC_MXU_D32SARW
9ef5bff9 1665 * │ ├─ 001 ─ OPC_MXU_S32ALN
c233bf07
AM
1666 * │ ├─ 010 ─ OPC_MXU_S32ALNI
1667 * │ ├─ 011 ─ OPC_MXU_S32NOR
1668 * │ ├─ 100 ─ OPC_MXU_S32AND
1669 * │ ├─ 101 ─ OPC_MXU_S32OR
1670 * │ ├─ 110 ─ OPC_MXU_S32XOR
1671 * │ └─ 111 ─ OPC_MXU_S32LUI
1672 * │
1673 * │ 7..5
1674 * ├─ 101000 ─ OPC_MXU__POOL17 ─┬─ 000 ─ OPC_MXU_LXB
1675 * │ ├─ 001 ─ OPC_MXU_LXH
1676 * ├─ 101001 ─ <not assigned> ├─ 011 ─ OPC_MXU_LXW
1677 * ├─ 101010 ─ OPC_MXU_S16LDD ├─ 100 ─ OPC_MXU_LXBU
1678 * ├─ 101011 ─ OPC_MXU_S16STD └─ 101 ─ OPC_MXU_LXHU
1679 * ├─ 101100 ─ OPC_MXU_S16LDI
1680 * ├─ 101101 ─ OPC_MXU_S16SDI
9ef5bff9
AM
1681 * ├─ 101110 ─ OPC_MXU_S32M2I
1682 * ├─ 101111 ─ OPC_MXU_S32I2M
1683 * ├─ 110000 ─ OPC_MXU_D32SLL
eab0bdb0
AM
1684 * ├─ 110001 ─ OPC_MXU_D32SLR 20..18
1685 * ├─ 110010 ─ OPC_MXU_D32SARL ┌─ 000 ─ OPC_MXU_D32SLLV
1686 * ├─ 110011 ─ OPC_MXU_D32SAR ├─ 001 ─ OPC_MXU_D32SLRV
1687 * ├─ 110100 ─ OPC_MXU_Q16SLL ├─ 010 ─ OPC_MXU_D32SARV
1688 * ├─ 110101 ─ OPC_MXU_Q16SLR ├─ 011 ─ OPC_MXU_Q16SLLV
9ef5bff9 1689 * │ ├─ 100 ─ OPC_MXU_Q16SLRV
c233bf07 1690 * ├─ 110110 ─ OPC_MXU__POOL18 ─┴─ 101 ─ OPC_MXU_Q16SARV
eab0bdb0 1691 * │
9ef5bff9
AM
1692 * ├─ 110111 ─ OPC_MXU_Q16SAR
1693 * │ 23..22
c233bf07 1694 * ├─ 111000 ─ OPC_MXU__POOL19 ─┬─ 00 ─ OPC_MXU_Q8MUL
9ef5bff9
AM
1695 * │ └─ 01 ─ OPC_MXU_Q8MULSU
1696 * │
1697 * │ 20..18
c233bf07 1698 * ├─ 111001 ─ OPC_MXU__POOL20 ─┬─ 000 ─ OPC_MXU_Q8MOVZ
9ef5bff9
AM
1699 * │ ├─ 001 ─ OPC_MXU_Q8MOVN
1700 * │ ├─ 010 ─ OPC_MXU_D16MOVZ
1701 * │ ├─ 011 ─ OPC_MXU_D16MOVN
1702 * │ ├─ 100 ─ OPC_MXU_S32MOVZ
1703 * │ └─ 101 ─ OPC_MXU_S32MOV
1704 * │
1705 * │ 23..22
c233bf07 1706 * ├─ 111010 ─ OPC_MXU__POOL21 ─┬─ 00 ─ OPC_MXU_Q8MAC
9ef5bff9
AM
1707 * │ └─ 10 ─ OPC_MXU_Q8MACSU
1708 * ├─ 111011 ─ OPC_MXU_Q16SCOP
1709 * ├─ 111100 ─ OPC_MXU_Q8MADL
1710 * ├─ 111101 ─ OPC_MXU_S32SFL
1711 * ├─ 111110 ─ OPC_MXU_Q8SAD
eab0bdb0 1712 * └─ 111111 ─ <not assigned> (overlaps with SDBBP)
9ef5bff9
AM
1713 *
1714 *
b158d449
AM
1715 * Compiled after:
1716 *
1717 * "XBurst® Instruction Set Architecture MIPS eXtension/enhanced Unit
1718 * Programming Manual", Ingenic Semiconductor Co, Ltd., 2017
1719 */
1720
8bacd1ff
AM
1721enum {
1722 OPC_MXU_S32MADD = 0x00,
1723 OPC_MXU_S32MADDU = 0x01,
11d56f61 1724 OPC__MXU_MUL = 0x02,
8bacd1ff
AM
1725 OPC_MXU__POOL00 = 0x03,
1726 OPC_MXU_S32MSUB = 0x04,
1727 OPC_MXU_S32MSUBU = 0x05,
1728 OPC_MXU__POOL01 = 0x06,
1729 OPC_MXU__POOL02 = 0x07,
1730 OPC_MXU_D16MUL = 0x08,
1731 OPC_MXU__POOL03 = 0x09,
1732 OPC_MXU_D16MAC = 0x0A,
1733 OPC_MXU_D16MACF = 0x0B,
1734 OPC_MXU_D16MADL = 0x0C,
eab0bdb0 1735 OPC_MXU_S16MAD = 0x0D,
8bacd1ff
AM
1736 OPC_MXU_Q16ADD = 0x0E,
1737 OPC_MXU_D16MACE = 0x0F,
eab0bdb0
AM
1738 OPC_MXU__POOL04 = 0x10,
1739 OPC_MXU__POOL05 = 0x11,
1740 OPC_MXU__POOL06 = 0x12,
1741 OPC_MXU__POOL07 = 0x13,
1742 OPC_MXU__POOL08 = 0x14,
1743 OPC_MXU__POOL09 = 0x15,
1744 OPC_MXU__POOL10 = 0x16,
1745 OPC_MXU__POOL11 = 0x17,
8bacd1ff 1746 OPC_MXU_D32ADD = 0x18,
eab0bdb0 1747 OPC_MXU__POOL12 = 0x19,
8bacd1ff 1748 /* not assigned 0x1A */
eab0bdb0
AM
1749 OPC_MXU__POOL13 = 0x1B,
1750 OPC_MXU__POOL14 = 0x1C,
8bacd1ff
AM
1751 OPC_MXU_Q8ACCE = 0x1D,
1752 /* not assigned 0x1E */
1753 /* not assigned 0x1F */
1754 /* not assigned 0x20 */
1755 /* not assigned 0x21 */
1756 OPC_MXU_S8LDD = 0x22,
1757 OPC_MXU_S8STD = 0x23,
1758 OPC_MXU_S8LDI = 0x24,
1759 OPC_MXU_S8SDI = 0x25,
eab0bdb0
AM
1760 OPC_MXU__POOL15 = 0x26,
1761 OPC_MXU__POOL16 = 0x27,
c233bf07 1762 OPC_MXU__POOL17 = 0x28,
8bacd1ff
AM
1763 /* not assigned 0x29 */
1764 OPC_MXU_S16LDD = 0x2A,
1765 OPC_MXU_S16STD = 0x2B,
1766 OPC_MXU_S16LDI = 0x2C,
1767 OPC_MXU_S16SDI = 0x2D,
1768 OPC_MXU_S32M2I = 0x2E,
1769 OPC_MXU_S32I2M = 0x2F,
1770 OPC_MXU_D32SLL = 0x30,
1771 OPC_MXU_D32SLR = 0x31,
1772 OPC_MXU_D32SARL = 0x32,
1773 OPC_MXU_D32SAR = 0x33,
1774 OPC_MXU_Q16SLL = 0x34,
1775 OPC_MXU_Q16SLR = 0x35,
c233bf07 1776 OPC_MXU__POOL18 = 0x36,
8bacd1ff 1777 OPC_MXU_Q16SAR = 0x37,
c233bf07
AM
1778 OPC_MXU__POOL19 = 0x38,
1779 OPC_MXU__POOL20 = 0x39,
1780 OPC_MXU__POOL21 = 0x3A,
8bacd1ff
AM
1781 OPC_MXU_Q16SCOP = 0x3B,
1782 OPC_MXU_Q8MADL = 0x3C,
1783 OPC_MXU_S32SFL = 0x3D,
1784 OPC_MXU_Q8SAD = 0x3E,
1785 /* not assigned 0x3F */
1786};
1787
1788
1789/*
1790 * MXU pool 00
1791 */
1792enum {
1793 OPC_MXU_S32MAX = 0x00,
1794 OPC_MXU_S32MIN = 0x01,
1795 OPC_MXU_D16MAX = 0x02,
1796 OPC_MXU_D16MIN = 0x03,
1797 OPC_MXU_Q8MAX = 0x04,
1798 OPC_MXU_Q8MIN = 0x05,
1799 OPC_MXU_Q8SLT = 0x06,
1800 OPC_MXU_Q8SLTU = 0x07,
1801};
1802
1803/*
1804 * MXU pool 01
1805 */
1806enum {
1807 OPC_MXU_S32SLT = 0x00,
1808 OPC_MXU_D16SLT = 0x01,
1809 OPC_MXU_D16AVG = 0x02,
1810 OPC_MXU_D16AVGR = 0x03,
1811 OPC_MXU_Q8AVG = 0x04,
1812 OPC_MXU_Q8AVGR = 0x05,
1813 OPC_MXU_Q8ADD = 0x07,
1814};
1815
1816/*
1817 * MXU pool 02
1818 */
1819enum {
1820 OPC_MXU_S32CPS = 0x00,
1821 OPC_MXU_D16CPS = 0x02,
1822 OPC_MXU_Q8ABD = 0x04,
1823 OPC_MXU_Q16SAT = 0x06,
1824};
1825
1826/*
1827 * MXU pool 03
1828 */
1829enum {
1830 OPC_MXU_D16MULF = 0x00,
1831 OPC_MXU_D16MULE = 0x01,
1832};
1833
1834/*
1835 * MXU pool 04
1836 */
8bacd1ff
AM
1837enum {
1838 OPC_MXU_S32LDD = 0x00,
1839 OPC_MXU_S32LDDR = 0x01,
1840};
1841
1842/*
eab0bdb0 1843 * MXU pool 05
8bacd1ff
AM
1844 */
1845enum {
1846 OPC_MXU_S32STD = 0x00,
1847 OPC_MXU_S32STDR = 0x01,
1848};
1849
1850/*
eab0bdb0 1851 * MXU pool 06
8bacd1ff
AM
1852 */
1853enum {
1854 OPC_MXU_S32LDDV = 0x00,
1855 OPC_MXU_S32LDDVR = 0x01,
1856};
1857
1858/*
eab0bdb0 1859 * MXU pool 07
8bacd1ff
AM
1860 */
1861enum {
1862 OPC_MXU_S32STDV = 0x00,
1863 OPC_MXU_S32STDVR = 0x01,
1864};
1865
1866/*
eab0bdb0 1867 * MXU pool 08
8bacd1ff
AM
1868 */
1869enum {
1870 OPC_MXU_S32LDI = 0x00,
1871 OPC_MXU_S32LDIR = 0x01,
1872};
1873
1874/*
eab0bdb0 1875 * MXU pool 09
8bacd1ff
AM
1876 */
1877enum {
1878 OPC_MXU_S32SDI = 0x00,
1879 OPC_MXU_S32SDIR = 0x01,
1880};
1881
1882/*
eab0bdb0 1883 * MXU pool 10
8bacd1ff
AM
1884 */
1885enum {
1886 OPC_MXU_S32LDIV = 0x00,
1887 OPC_MXU_S32LDIVR = 0x01,
1888};
1889
1890/*
eab0bdb0 1891 * MXU pool 11
8bacd1ff
AM
1892 */
1893enum {
1894 OPC_MXU_S32SDIV = 0x00,
1895 OPC_MXU_S32SDIVR = 0x01,
1896};
1897
1898/*
eab0bdb0 1899 * MXU pool 12
8bacd1ff
AM
1900 */
1901enum {
1902 OPC_MXU_D32ACC = 0x00,
1903 OPC_MXU_D32ACCM = 0x01,
1904 OPC_MXU_D32ASUM = 0x02,
1905};
1906
1907/*
eab0bdb0 1908 * MXU pool 13
8bacd1ff
AM
1909 */
1910enum {
1911 OPC_MXU_Q16ACC = 0x00,
1912 OPC_MXU_Q16ACCM = 0x01,
1913 OPC_MXU_Q16ASUM = 0x02,
1914};
1915
1916/*
eab0bdb0 1917 * MXU pool 14
8bacd1ff
AM
1918 */
1919enum {
1920 OPC_MXU_Q8ADDE = 0x00,
1921 OPC_MXU_D8SUM = 0x01,
1922 OPC_MXU_D8SUMC = 0x02,
1923};
1924
1925/*
eab0bdb0 1926 * MXU pool 15
8bacd1ff
AM
1927 */
1928enum {
1929 OPC_MXU_S32MUL = 0x00,
1930 OPC_MXU_S32MULU = 0x01,
1931 OPC_MXU_S32EXTR = 0x02,
1932 OPC_MXU_S32EXTRV = 0x03,
1933};
1934
1935/*
eab0bdb0 1936 * MXU pool 16
8bacd1ff
AM
1937 */
1938enum {
1939 OPC_MXU_D32SARW = 0x00,
1940 OPC_MXU_S32ALN = 0x01,
1941 OPC_MXU_S32ALNI = 0x02,
1942 OPC_MXU_S32NOR = 0x03,
1943 OPC_MXU_S32AND = 0x04,
1944 OPC_MXU_S32OR = 0x05,
1945 OPC_MXU_S32XOR = 0x06,
1946 OPC_MXU_S32LUI = 0x07,
1947};
1948
1949/*
eab0bdb0 1950 * MXU pool 17
8bacd1ff 1951 */
c233bf07
AM
1952enum {
1953 OPC_MXU_LXB = 0x00,
1954 OPC_MXU_LXH = 0x01,
1955 OPC_MXU_LXW = 0x03,
1956 OPC_MXU_LXBU = 0x04,
1957 OPC_MXU_LXHU = 0x05,
1958};
1959
1960/*
1961 * MXU pool 18
1962 */
8bacd1ff
AM
1963enum {
1964 OPC_MXU_D32SLLV = 0x00,
1965 OPC_MXU_D32SLRV = 0x01,
1966 OPC_MXU_D32SARV = 0x03,
1967 OPC_MXU_Q16SLLV = 0x04,
1968 OPC_MXU_Q16SLRV = 0x05,
1969 OPC_MXU_Q16SARV = 0x07,
1970};
1971
1972/*
c233bf07 1973 * MXU pool 19
8bacd1ff
AM
1974 */
1975enum {
1976 OPC_MXU_Q8MUL = 0x00,
1977 OPC_MXU_Q8MULSU = 0x01,
1978};
1979
1980/*
c233bf07 1981 * MXU pool 20
8bacd1ff
AM
1982 */
1983enum {
1984 OPC_MXU_Q8MOVZ = 0x00,
1985 OPC_MXU_Q8MOVN = 0x01,
1986 OPC_MXU_D16MOVZ = 0x02,
1987 OPC_MXU_D16MOVN = 0x03,
1988 OPC_MXU_S32MOVZ = 0x04,
1989 OPC_MXU_S32MOVN = 0x05,
1990};
1991
1992/*
c233bf07 1993 * MXU pool 21
8bacd1ff
AM
1994 */
1995enum {
1996 OPC_MXU_Q8MAC = 0x00,
1997 OPC_MXU_Q8MACSU = 0x01,
1998};
1999
497f072b
FN
2000/*
2001 * Overview of the TX79-specific instruction set
2002 * =============================================
2003 *
2004 * The R5900 and the C790 have 128-bit wide GPRs, where the upper 64 bits
2005 * are only used by the specific quadword (128-bit) LQ/SQ load/store
2006 * instructions and certain multimedia instructions (MMIs). These MMIs
2007 * configure the 128-bit data path as two 64-bit, four 32-bit, eight 16-bit
2008 * or sixteen 8-bit paths.
2009 *
2010 * Reference:
2011 *
2012 * The Toshiba TX System RISC TX79 Core Architecture manual,
2013 * https://wiki.qemu.org/File:C790.pdf
2014 *
2015 * Three-Operand Multiply and Multiply-Add (4 instructions)
2016 * --------------------------------------------------------
2017 * MADD [rd,] rs, rt Multiply/Add
2018 * MADDU [rd,] rs, rt Multiply/Add Unsigned
2019 * MULT [rd,] rs, rt Multiply (3-operand)
2020 * MULTU [rd,] rs, rt Multiply Unsigned (3-operand)
2021 *
2022 * Multiply Instructions for Pipeline 1 (10 instructions)
2023 * ------------------------------------------------------
2024 * MULT1 [rd,] rs, rt Multiply Pipeline 1
2025 * MULTU1 [rd,] rs, rt Multiply Unsigned Pipeline 1
2026 * DIV1 rs, rt Divide Pipeline 1
2027 * DIVU1 rs, rt Divide Unsigned Pipeline 1
2028 * MADD1 [rd,] rs, rt Multiply-Add Pipeline 1
2029 * MADDU1 [rd,] rs, rt Multiply-Add Unsigned Pipeline 1
2030 * MFHI1 rd Move From HI1 Register
2031 * MFLO1 rd Move From LO1 Register
2032 * MTHI1 rs Move To HI1 Register
2033 * MTLO1 rs Move To LO1 Register
2034 *
2035 * Arithmetic (19 instructions)
2036 * ----------------------------
2037 * PADDB rd, rs, rt Parallel Add Byte
2038 * PSUBB rd, rs, rt Parallel Subtract Byte
2039 * PADDH rd, rs, rt Parallel Add Halfword
2040 * PSUBH rd, rs, rt Parallel Subtract Halfword
2041 * PADDW rd, rs, rt Parallel Add Word
2042 * PSUBW rd, rs, rt Parallel Subtract Word
2043 * PADSBH rd, rs, rt Parallel Add/Subtract Halfword
2044 * PADDSB rd, rs, rt Parallel Add with Signed Saturation Byte
2045 * PSUBSB rd, rs, rt Parallel Subtract with Signed Saturation Byte
2046 * PADDSH rd, rs, rt Parallel Add with Signed Saturation Halfword
2047 * PSUBSH rd, rs, rt Parallel Subtract with Signed Saturation Halfword
2048 * PADDSW rd, rs, rt Parallel Add with Signed Saturation Word
2049 * PSUBSW rd, rs, rt Parallel Subtract with Signed Saturation Word
2050 * PADDUB rd, rs, rt Parallel Add with Unsigned saturation Byte
2051 * PSUBUB rd, rs, rt Parallel Subtract with Unsigned saturation Byte
2052 * PADDUH rd, rs, rt Parallel Add with Unsigned saturation Halfword
2053 * PSUBUH rd, rs, rt Parallel Subtract with Unsigned saturation Halfword
2054 * PADDUW rd, rs, rt Parallel Add with Unsigned saturation Word
2055 * PSUBUW rd, rs, rt Parallel Subtract with Unsigned saturation Word
2056 *
2057 * Min/Max (4 instructions)
2058 * ------------------------
2059 * PMAXH rd, rs, rt Parallel Maximum Halfword
2060 * PMINH rd, rs, rt Parallel Minimum Halfword
2061 * PMAXW rd, rs, rt Parallel Maximum Word
2062 * PMINW rd, rs, rt Parallel Minimum Word
2063 *
2064 * Absolute (2 instructions)
2065 * -------------------------
2066 * PABSH rd, rt Parallel Absolute Halfword
2067 * PABSW rd, rt Parallel Absolute Word
2068 *
2069 * Logical (4 instructions)
2070 * ------------------------
2071 * PAND rd, rs, rt Parallel AND
2072 * POR rd, rs, rt Parallel OR
2073 * PXOR rd, rs, rt Parallel XOR
2074 * PNOR rd, rs, rt Parallel NOR
2075 *
2076 * Shift (9 instructions)
2077 * ----------------------
2078 * PSLLH rd, rt, sa Parallel Shift Left Logical Halfword
2079 * PSRLH rd, rt, sa Parallel Shift Right Logical Halfword
2080 * PSRAH rd, rt, sa Parallel Shift Right Arithmetic Halfword
2081 * PSLLW rd, rt, sa Parallel Shift Left Logical Word
2082 * PSRLW rd, rt, sa Parallel Shift Right Logical Word
2083 * PSRAW rd, rt, sa Parallel Shift Right Arithmetic Word
2084 * PSLLVW rd, rt, rs Parallel Shift Left Logical Variable Word
2085 * PSRLVW rd, rt, rs Parallel Shift Right Logical Variable Word
2086 * PSRAVW rd, rt, rs Parallel Shift Right Arithmetic Variable Word
2087 *
2088 * Compare (6 instructions)
2089 * ------------------------
2090 * PCGTB rd, rs, rt Parallel Compare for Greater Than Byte
2091 * PCEQB rd, rs, rt Parallel Compare for Equal Byte
2092 * PCGTH rd, rs, rt Parallel Compare for Greater Than Halfword
2093 * PCEQH rd, rs, rt Parallel Compare for Equal Halfword
2094 * PCGTW rd, rs, rt Parallel Compare for Greater Than Word
2095 * PCEQW rd, rs, rt Parallel Compare for Equal Word
2096 *
2097 * LZC (1 instruction)
2098 * -------------------
2099 * PLZCW rd, rs Parallel Leading Zero or One Count Word
2100 *
2101 * Quadword Load and Store (2 instructions)
2102 * ----------------------------------------
2103 * LQ rt, offset(base) Load Quadword
2104 * SQ rt, offset(base) Store Quadword
2105 *
2106 * Multiply and Divide (19 instructions)
2107 * -------------------------------------
2108 * PMULTW rd, rs, rt Parallel Multiply Word
2109 * PMULTUW rd, rs, rt Parallel Multiply Unsigned Word
2110 * PDIVW rs, rt Parallel Divide Word
2111 * PDIVUW rs, rt Parallel Divide Unsigned Word
2112 * PMADDW rd, rs, rt Parallel Multiply-Add Word
2113 * PMADDUW rd, rs, rt Parallel Multiply-Add Unsigned Word
2114 * PMSUBW rd, rs, rt Parallel Multiply-Subtract Word
2115 * PMULTH rd, rs, rt Parallel Multiply Halfword
2116 * PMADDH rd, rs, rt Parallel Multiply-Add Halfword
2117 * PMSUBH rd, rs, rt Parallel Multiply-Subtract Halfword
2118 * PHMADH rd, rs, rt Parallel Horizontal Multiply-Add Halfword
2119 * PHMSBH rd, rs, rt Parallel Horizontal Multiply-Subtract Halfword
2120 * PDIVBW rs, rt Parallel Divide Broadcast Word
2121 * PMFHI rd Parallel Move From HI Register
2122 * PMFLO rd Parallel Move From LO Register
2123 * PMTHI rs Parallel Move To HI Register
2124 * PMTLO rs Parallel Move To LO Register
2125 * PMFHL rd Parallel Move From HI/LO Register
2126 * PMTHL rs Parallel Move To HI/LO Register
2127 *
2128 * Pack/Extend (11 instructions)
2129 * -----------------------------
2130 * PPAC5 rd, rt Parallel Pack to 5 bits
2131 * PPACB rd, rs, rt Parallel Pack to Byte
2132 * PPACH rd, rs, rt Parallel Pack to Halfword
2133 * PPACW rd, rs, rt Parallel Pack to Word
2134 * PEXT5 rd, rt Parallel Extend Upper from 5 bits
2135 * PEXTUB rd, rs, rt Parallel Extend Upper from Byte
2136 * PEXTLB rd, rs, rt Parallel Extend Lower from Byte
2137 * PEXTUH rd, rs, rt Parallel Extend Upper from Halfword
2138 * PEXTLH rd, rs, rt Parallel Extend Lower from Halfword
2139 * PEXTUW rd, rs, rt Parallel Extend Upper from Word
2140 * PEXTLW rd, rs, rt Parallel Extend Lower from Word
2141 *
2142 * Others (16 instructions)
2143 * ------------------------
2144 * PCPYH rd, rt Parallel Copy Halfword
2145 * PCPYLD rd, rs, rt Parallel Copy Lower Doubleword
2146 * PCPYUD rd, rs, rt Parallel Copy Upper Doubleword
2147 * PREVH rd, rt Parallel Reverse Halfword
2148 * PINTH rd, rs, rt Parallel Interleave Halfword
2149 * PINTEH rd, rs, rt Parallel Interleave Even Halfword
2150 * PEXEH rd, rt Parallel Exchange Even Halfword
2151 * PEXCH rd, rt Parallel Exchange Center Halfword
2152 * PEXEW rd, rt Parallel Exchange Even Word
2153 * PEXCW rd, rt Parallel Exchange Center Word
2154 * QFSRV rd, rs, rt Quadword Funnel Shift Right Variable
2155 * MFSA rd Move from Shift Amount Register
2156 * MTSA rs Move to Shift Amount Register
2157 * MTSAB rs, immediate Move Byte Count to Shift Amount Register
2158 * MTSAH rs, immediate Move Halfword Count to Shift Amount Register
2159 * PROT3W rd, rt Parallel Rotate 3 Words
f99c0d6d 2160 *
baa609db
AM
2161 * MMI (MultiMedia Instruction) encodings
2162 * ======================================
f99c0d6d 2163 *
baa609db 2164 * MMI instructions encoding table keys:
f99c0d6d
FN
2165 *
2166 * * This code is reserved for future use. An attempt to execute it
2167 * causes a Reserved Instruction exception.
2168 * % This code indicates an instruction class. The instruction word
2169 * must be further decoded by examining additional tables that show
2170 * the values for other instruction fields.
2171 * # This code is reserved for the unsupported instructions DMULT,
2172 * DMULTU, DDIV, DDIVU, LL, LLD, SC, SCD, LWC2 and SWC2. An attempt
2173 * to execute it causes a Reserved Instruction exception.
2174 *
baa609db 2175 * MMI instructions encoded by opcode field (MMI, LQ, SQ):
f99c0d6d
FN
2176 *
2177 * 31 26 0
2178 * +--------+----------------------------------------+
2179 * | opcode | |
2180 * +--------+----------------------------------------+
2181 *
2182 * opcode bits 28..26
2183 * bits | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7
2184 * 31..29 | 000 | 001 | 010 | 011 | 100 | 101 | 110 | 111
2185 * -------+-------+-------+-------+-------+-------+-------+-------+-------
2186 * 0 000 |SPECIAL| REGIMM| J | JAL | BEQ | BNE | BLEZ | BGTZ
2187 * 1 001 | ADDI | ADDIU | SLTI | SLTIU | ANDI | ORI | XORI | LUI
2188 * 2 010 | COP0 | COP1 | * | * | BEQL | BNEL | BLEZL | BGTZL
2189 * 3 011 | DADDI | DADDIU| LDL | LDR | MMI% | * | LQ | SQ
2190 * 4 100 | LB | LH | LWL | LW | LBU | LHU | LWR | LWU
2191 * 5 101 | SB | SH | SWL | SW | SDL | SDR | SWR | CACHE
2192 * 6 110 | # | LWC1 | # | PREF | # | LDC1 | # | LD
2193 * 7 111 | # | SWC1 | # | * | # | SDC1 | # | SD
497f072b 2194 */
b158d449 2195
f99c0d6d 2196enum {
baa609db
AM
2197 MMI_OPC_CLASS_MMI = 0x1C << 26, /* Same as OPC_SPECIAL2 */
2198 MMI_OPC_LQ = 0x1E << 26, /* Same as OPC_MSA */
2199 MMI_OPC_SQ = 0x1F << 26, /* Same as OPC_SPECIAL3 */
f99c0d6d
FN
2200};
2201
d3297211 2202/*
baa609db 2203 * MMI instructions with opcode field = MMI:
d3297211
FN
2204 *
2205 * 31 26 5 0
2206 * +--------+-------------------------------+--------+
2207 * | MMI | |function|
2208 * +--------+-------------------------------+--------+
2209 *
2210 * function bits 2..0
2211 * bits | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7
2212 * 5..3 | 000 | 001 | 010 | 011 | 100 | 101 | 110 | 111
2213 * -------+-------+-------+-------+-------+-------+-------+-------+-------
2214 * 0 000 | MADD | MADDU | * | * | PLZCW | * | * | *
2215 * 1 001 | MMI0% | MMI2% | * | * | * | * | * | *
2216 * 2 010 | MFHI1 | MTHI1 | MFLO1 | MTLO1 | * | * | * | *
2217 * 3 011 | MULT1 | MULTU1| DIV1 | DIVU1 | * | * | * | *
2218 * 4 100 | MADD1 | MADDU1| * | * | * | * | * | *
2219 * 5 101 | MMI1% | MMI3% | * | * | * | * | * | *
2220 * 6 110 | PMFHL | PMTHL | * | * | PSLLH | * | PSRLH | PSRAH
2221 * 7 111 | * | * | * | * | PSLLW | * | PSRLW | PSRAW
2222 */
2223
c8341e00 2224#define MASK_MMI(op) (MASK_OP_MAJOR(op) | ((op) & 0x3F))
d3297211 2225enum {
baa609db
AM
2226 MMI_OPC_MADD = 0x00 | MMI_OPC_CLASS_MMI, /* Same as OPC_MADD */
2227 MMI_OPC_MADDU = 0x01 | MMI_OPC_CLASS_MMI, /* Same as OPC_MADDU */
2228 MMI_OPC_PLZCW = 0x04 | MMI_OPC_CLASS_MMI,
2229 MMI_OPC_CLASS_MMI0 = 0x08 | MMI_OPC_CLASS_MMI,
2230 MMI_OPC_CLASS_MMI2 = 0x09 | MMI_OPC_CLASS_MMI,
2231 MMI_OPC_MFHI1 = 0x10 | MMI_OPC_CLASS_MMI, /* Same minor as OPC_MFHI */
2232 MMI_OPC_MTHI1 = 0x11 | MMI_OPC_CLASS_MMI, /* Same minor as OPC_MTHI */
2233 MMI_OPC_MFLO1 = 0x12 | MMI_OPC_CLASS_MMI, /* Same minor as OPC_MFLO */
2234 MMI_OPC_MTLO1 = 0x13 | MMI_OPC_CLASS_MMI, /* Same minor as OPC_MTLO */
2235 MMI_OPC_MULT1 = 0x18 | MMI_OPC_CLASS_MMI, /* Same minor as OPC_MULT */
2236 MMI_OPC_MULTU1 = 0x19 | MMI_OPC_CLASS_MMI, /* Same min. as OPC_MULTU */
2237 MMI_OPC_DIV1 = 0x1A | MMI_OPC_CLASS_MMI, /* Same minor as OPC_DIV */
2238 MMI_OPC_DIVU1 = 0x1B | MMI_OPC_CLASS_MMI, /* Same minor as OPC_DIVU */
2239 MMI_OPC_MADD1 = 0x20 | MMI_OPC_CLASS_MMI,
2240 MMI_OPC_MADDU1 = 0x21 | MMI_OPC_CLASS_MMI,
2241 MMI_OPC_CLASS_MMI1 = 0x28 | MMI_OPC_CLASS_MMI,
2242 MMI_OPC_CLASS_MMI3 = 0x29 | MMI_OPC_CLASS_MMI,
2243 MMI_OPC_PMFHL = 0x30 | MMI_OPC_CLASS_MMI,
2244 MMI_OPC_PMTHL = 0x31 | MMI_OPC_CLASS_MMI,
2245 MMI_OPC_PSLLH = 0x34 | MMI_OPC_CLASS_MMI,
2246 MMI_OPC_PSRLH = 0x36 | MMI_OPC_CLASS_MMI,
2247 MMI_OPC_PSRAH = 0x37 | MMI_OPC_CLASS_MMI,
2248 MMI_OPC_PSLLW = 0x3C | MMI_OPC_CLASS_MMI,
2249 MMI_OPC_PSRLW = 0x3E | MMI_OPC_CLASS_MMI,
2250 MMI_OPC_PSRAW = 0x3F | MMI_OPC_CLASS_MMI,
d3297211
FN
2251};
2252
3ef65697 2253/*
baa609db 2254 * MMI instructions with opcode field = MMI and bits 5..0 = MMI0:
3ef65697
FN
2255 *
2256 * 31 26 10 6 5 0
2257 * +--------+----------------------+--------+--------+
2258 * | MMI | |function| MMI0 |
2259 * +--------+----------------------+--------+--------+
2260 *
2261 * function bits 7..6
2262 * bits | 0 | 1 | 2 | 3
2263 * 10..8 | 00 | 01 | 10 | 11
2264 * -------+-------+-------+-------+-------
2265 * 0 000 | PADDW | PSUBW | PCGTW | PMAXW
2266 * 1 001 | PADDH | PSUBH | PCGTH | PMAXH
2267 * 2 010 | PADDB | PSUBB | PCGTB | *
2268 * 3 011 | * | * | * | *
2269 * 4 100 | PADDSW| PSUBSW| PEXTLW| PPACW
2270 * 5 101 | PADDSH| PSUBSH| PEXTLH| PPACH
2271 * 6 110 | PADDSB| PSUBSB| PEXTLB| PPACB
2272 * 7 111 | * | * | PEXT5 | PPAC5
2273 */
2274
c8341e00 2275#define MASK_MMI0(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
3ef65697 2276enum {
baa609db
AM
2277 MMI_OPC_0_PADDW = (0x00 << 6) | MMI_OPC_CLASS_MMI0,
2278 MMI_OPC_0_PSUBW = (0x01 << 6) | MMI_OPC_CLASS_MMI0,
2279 MMI_OPC_0_PCGTW = (0x02 << 6) | MMI_OPC_CLASS_MMI0,
2280 MMI_OPC_0_PMAXW = (0x03 << 6) | MMI_OPC_CLASS_MMI0,
2281 MMI_OPC_0_PADDH = (0x04 << 6) | MMI_OPC_CLASS_MMI0,
2282 MMI_OPC_0_PSUBH = (0x05 << 6) | MMI_OPC_CLASS_MMI0,
2283 MMI_OPC_0_PCGTH = (0x06 << 6) | MMI_OPC_CLASS_MMI0,
2284 MMI_OPC_0_PMAXH = (0x07 << 6) | MMI_OPC_CLASS_MMI0,
2285 MMI_OPC_0_PADDB = (0x08 << 6) | MMI_OPC_CLASS_MMI0,
2286 MMI_OPC_0_PSUBB = (0x09 << 6) | MMI_OPC_CLASS_MMI0,
2287 MMI_OPC_0_PCGTB = (0x0A << 6) | MMI_OPC_CLASS_MMI0,
2288 MMI_OPC_0_PADDSW = (0x10 << 6) | MMI_OPC_CLASS_MMI0,
2289 MMI_OPC_0_PSUBSW = (0x11 << 6) | MMI_OPC_CLASS_MMI0,
2290 MMI_OPC_0_PEXTLW = (0x12 << 6) | MMI_OPC_CLASS_MMI0,
2291 MMI_OPC_0_PPACW = (0x13 << 6) | MMI_OPC_CLASS_MMI0,
2292 MMI_OPC_0_PADDSH = (0x14 << 6) | MMI_OPC_CLASS_MMI0,
2293 MMI_OPC_0_PSUBSH = (0x15 << 6) | MMI_OPC_CLASS_MMI0,
2294 MMI_OPC_0_PEXTLH = (0x16 << 6) | MMI_OPC_CLASS_MMI0,
2295 MMI_OPC_0_PPACH = (0x17 << 6) | MMI_OPC_CLASS_MMI0,
2296 MMI_OPC_0_PADDSB = (0x18 << 6) | MMI_OPC_CLASS_MMI0,
2297 MMI_OPC_0_PSUBSB = (0x19 << 6) | MMI_OPC_CLASS_MMI0,
2298 MMI_OPC_0_PEXTLB = (0x1A << 6) | MMI_OPC_CLASS_MMI0,
2299 MMI_OPC_0_PPACB = (0x1B << 6) | MMI_OPC_CLASS_MMI0,
2300 MMI_OPC_0_PEXT5 = (0x1E << 6) | MMI_OPC_CLASS_MMI0,
2301 MMI_OPC_0_PPAC5 = (0x1F << 6) | MMI_OPC_CLASS_MMI0,
3ef65697
FN
2302};
2303
77596541 2304/*
baa609db 2305 * MMI instructions with opcode field = MMI and bits 5..0 = MMI1:
77596541
FN
2306 *
2307 * 31 26 10 6 5 0
2308 * +--------+----------------------+--------+--------+
2309 * | MMI | |function| MMI1 |
2310 * +--------+----------------------+--------+--------+
2311 *
2312 * function bits 7..6
2313 * bits | 0 | 1 | 2 | 3
2314 * 10..8 | 00 | 01 | 10 | 11
2315 * -------+-------+-------+-------+-------
2316 * 0 000 | * | PABSW | PCEQW | PMINW
2317 * 1 001 | PADSBH| PABSH | PCEQH | PMINH
2318 * 2 010 | * | * | PCEQB | *
2319 * 3 011 | * | * | * | *
2320 * 4 100 | PADDUW| PSUBUW| PEXTUW| *
2321 * 5 101 | PADDUH| PSUBUH| PEXTUH| *
2322 * 6 110 | PADDUB| PSUBUB| PEXTUB| QFSRV
2323 * 7 111 | * | * | * | *
2324 */
2325
c8341e00 2326#define MASK_MMI1(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
77596541 2327enum {
baa609db
AM
2328 MMI_OPC_1_PABSW = (0x01 << 6) | MMI_OPC_CLASS_MMI1,
2329 MMI_OPC_1_PCEQW = (0x02 << 6) | MMI_OPC_CLASS_MMI1,
2330 MMI_OPC_1_PMINW = (0x03 << 6) | MMI_OPC_CLASS_MMI1,
2331 MMI_OPC_1_PADSBH = (0x04 << 6) | MMI_OPC_CLASS_MMI1,
2332 MMI_OPC_1_PABSH = (0x05 << 6) | MMI_OPC_CLASS_MMI1,
2333 MMI_OPC_1_PCEQH = (0x06 << 6) | MMI_OPC_CLASS_MMI1,
2334 MMI_OPC_1_PMINH = (0x07 << 6) | MMI_OPC_CLASS_MMI1,
2335 MMI_OPC_1_PCEQB = (0x0A << 6) | MMI_OPC_CLASS_MMI1,
2336 MMI_OPC_1_PADDUW = (0x10 << 6) | MMI_OPC_CLASS_MMI1,
2337 MMI_OPC_1_PSUBUW = (0x11 << 6) | MMI_OPC_CLASS_MMI1,
2338 MMI_OPC_1_PEXTUW = (0x12 << 6) | MMI_OPC_CLASS_MMI1,
2339 MMI_OPC_1_PADDUH = (0x14 << 6) | MMI_OPC_CLASS_MMI1,
2340 MMI_OPC_1_PSUBUH = (0x15 << 6) | MMI_OPC_CLASS_MMI1,
2341 MMI_OPC_1_PEXTUH = (0x16 << 6) | MMI_OPC_CLASS_MMI1,
2342 MMI_OPC_1_PADDUB = (0x18 << 6) | MMI_OPC_CLASS_MMI1,
2343 MMI_OPC_1_PSUBUB = (0x19 << 6) | MMI_OPC_CLASS_MMI1,
2344 MMI_OPC_1_PEXTUB = (0x1A << 6) | MMI_OPC_CLASS_MMI1,
2345 MMI_OPC_1_QFSRV = (0x1B << 6) | MMI_OPC_CLASS_MMI1,
77596541
FN
2346};
2347
6c03ef6a 2348/*
baa609db 2349 * MMI instructions with opcode field = MMI and bits 5..0 = MMI2:
6c03ef6a
FN
2350 *
2351 * 31 26 10 6 5 0
2352 * +--------+----------------------+--------+--------+
2353 * | MMI | |function| MMI2 |
2354 * +--------+----------------------+--------+--------+
2355 *
2356 * function bits 7..6
2357 * bits | 0 | 1 | 2 | 3
2358 * 10..8 | 00 | 01 | 10 | 11
2359 * -------+-------+-------+-------+-------
2360 * 0 000 | PMADDW| * | PSLLVW| PSRLVW
2361 * 1 001 | PMSUBW| * | * | *
2362 * 2 010 | PMFHI | PMFLO | PINTH | *
2363 * 3 011 | PMULTW| PDIVW | PCPYLD| *
2364 * 4 100 | PMADDH| PHMADH| PAND | PXOR
2365 * 5 101 | PMSUBH| PHMSBH| * | *
2366 * 6 110 | * | * | PEXEH | PREVH
2367 * 7 111 | PMULTH| PDIVBW| PEXEW | PROT3W
2368 */
2369
c8341e00 2370#define MASK_MMI2(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
6c03ef6a 2371enum {
baa609db
AM
2372 MMI_OPC_2_PMADDW = (0x00 << 6) | MMI_OPC_CLASS_MMI2,
2373 MMI_OPC_2_PSLLVW = (0x02 << 6) | MMI_OPC_CLASS_MMI2,
2374 MMI_OPC_2_PSRLVW = (0x03 << 6) | MMI_OPC_CLASS_MMI2,
2375 MMI_OPC_2_PMSUBW = (0x04 << 6) | MMI_OPC_CLASS_MMI2,
2376 MMI_OPC_2_PMFHI = (0x08 << 6) | MMI_OPC_CLASS_MMI2,
2377 MMI_OPC_2_PMFLO = (0x09 << 6) | MMI_OPC_CLASS_MMI2,
2378 MMI_OPC_2_PINTH = (0x0A << 6) | MMI_OPC_CLASS_MMI2,
2379 MMI_OPC_2_PMULTW = (0x0C << 6) | MMI_OPC_CLASS_MMI2,
2380 MMI_OPC_2_PDIVW = (0x0D << 6) | MMI_OPC_CLASS_MMI2,
2381 MMI_OPC_2_PCPYLD = (0x0E << 6) | MMI_OPC_CLASS_MMI2,
2382 MMI_OPC_2_PMADDH = (0x10 << 6) | MMI_OPC_CLASS_MMI2,
2383 MMI_OPC_2_PHMADH = (0x11 << 6) | MMI_OPC_CLASS_MMI2,
2384 MMI_OPC_2_PAND = (0x12 << 6) | MMI_OPC_CLASS_MMI2,
2385 MMI_OPC_2_PXOR = (0x13 << 6) | MMI_OPC_CLASS_MMI2,
2386 MMI_OPC_2_PMSUBH = (0x14 << 6) | MMI_OPC_CLASS_MMI2,
2387 MMI_OPC_2_PHMSBH = (0x15 << 6) | MMI_OPC_CLASS_MMI2,
2388 MMI_OPC_2_PEXEH = (0x1A << 6) | MMI_OPC_CLASS_MMI2,
2389 MMI_OPC_2_PREVH = (0x1B << 6) | MMI_OPC_CLASS_MMI2,
2390 MMI_OPC_2_PMULTH = (0x1C << 6) | MMI_OPC_CLASS_MMI2,
2391 MMI_OPC_2_PDIVBW = (0x1D << 6) | MMI_OPC_CLASS_MMI2,
2392 MMI_OPC_2_PEXEW = (0x1E << 6) | MMI_OPC_CLASS_MMI2,
2393 MMI_OPC_2_PROT3W = (0x1F << 6) | MMI_OPC_CLASS_MMI2,
6c03ef6a
FN
2394};
2395
dd581bf9 2396/*
baa609db 2397 * MMI instructions with opcode field = MMI and bits 5..0 = MMI3:
dd581bf9
FN
2398 *
2399 * 31 26 10 6 5 0
2400 * +--------+----------------------+--------+--------+
2401 * | MMI | |function| MMI3 |
2402 * +--------+----------------------+--------+--------+
2403 *
2404 * function bits 7..6
2405 * bits | 0 | 1 | 2 | 3
2406 * 10..8 | 00 | 01 | 10 | 11
2407 * -------+-------+-------+-------+-------
2408 * 0 000 |PMADDUW| * | * | PSRAVW
2409 * 1 001 | * | * | * | *
2410 * 2 010 | PMTHI | PMTLO | PINTEH| *
2411 * 3 011 |PMULTUW| PDIVUW| PCPYUD| *
2412 * 4 100 | * | * | POR | PNOR
2413 * 5 101 | * | * | * | *
2414 * 6 110 | * | * | PEXCH | PCPYH
2415 * 7 111 | * | * | PEXCW | *
2416 */
2417
c8341e00 2418#define MASK_MMI3(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
dd581bf9 2419enum {
baa609db
AM
2420 MMI_OPC_3_PMADDUW = (0x00 << 6) | MMI_OPC_CLASS_MMI3,
2421 MMI_OPC_3_PSRAVW = (0x03 << 6) | MMI_OPC_CLASS_MMI3,
2422 MMI_OPC_3_PMTHI = (0x08 << 6) | MMI_OPC_CLASS_MMI3,
2423 MMI_OPC_3_PMTLO = (0x09 << 6) | MMI_OPC_CLASS_MMI3,
2424 MMI_OPC_3_PINTEH = (0x0A << 6) | MMI_OPC_CLASS_MMI3,
2425 MMI_OPC_3_PMULTUW = (0x0C << 6) | MMI_OPC_CLASS_MMI3,
2426 MMI_OPC_3_PDIVUW = (0x0D << 6) | MMI_OPC_CLASS_MMI3,
2427 MMI_OPC_3_PCPYUD = (0x0E << 6) | MMI_OPC_CLASS_MMI3,
2428 MMI_OPC_3_POR = (0x12 << 6) | MMI_OPC_CLASS_MMI3,
2429 MMI_OPC_3_PNOR = (0x13 << 6) | MMI_OPC_CLASS_MMI3,
2430 MMI_OPC_3_PEXCH = (0x1A << 6) | MMI_OPC_CLASS_MMI3,
2431 MMI_OPC_3_PCPYH = (0x1B << 6) | MMI_OPC_CLASS_MMI3,
2432 MMI_OPC_3_PEXCW = (0x1E << 6) | MMI_OPC_CLASS_MMI3,
dd581bf9
FN
2433};
2434
39454628 2435/* global register indices */
a7812ae4 2436static TCGv cpu_gpr[32], cpu_PC;
340fff72 2437static TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC];
41db4607
AJ
2438static TCGv cpu_dspctrl, btarget, bcond;
2439static TCGv_i32 hflags;
a7812ae4 2440static TCGv_i32 fpu_fcr0, fpu_fcr31;
d73ee8a2 2441static TCGv_i64 fpu_f64[32];
863f264d 2442static TCGv_i64 msa_wr_d[64];
aa0bf00b 2443
eb5559f6
CJ
2444/* MXU registers */
2445static TCGv mxu_gpr[NUMBER_OF_MXU_REGISTERS - 1];
2446static TCGv mxu_CR;
2447
022c62cb 2448#include "exec/gen-icount.h"
2e70f6ef 2449
895c2d04 2450#define gen_helper_0e0i(name, arg) do { \
a7812ae4 2451 TCGv_i32 helper_tmp = tcg_const_i32(arg); \
895c2d04 2452 gen_helper_##name(cpu_env, helper_tmp); \
a7812ae4
PB
2453 tcg_temp_free_i32(helper_tmp); \
2454 } while(0)
be24bb4f 2455
895c2d04 2456#define gen_helper_0e1i(name, arg1, arg2) do { \
a7812ae4 2457 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
895c2d04 2458 gen_helper_##name(cpu_env, arg1, helper_tmp); \
a7812ae4
PB
2459 tcg_temp_free_i32(helper_tmp); \
2460 } while(0)
be24bb4f 2461
895c2d04
BS
2462#define gen_helper_1e0i(name, ret, arg1) do { \
2463 TCGv_i32 helper_tmp = tcg_const_i32(arg1); \
2464 gen_helper_##name(ret, cpu_env, helper_tmp); \
2465 tcg_temp_free_i32(helper_tmp); \
2466 } while(0)
2467
2468#define gen_helper_1e1i(name, ret, arg1, arg2) do { \
2469 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
2470 gen_helper_##name(ret, cpu_env, arg1, helper_tmp); \
2471 tcg_temp_free_i32(helper_tmp); \
2472 } while(0)
2473
2474#define gen_helper_0e2i(name, arg1, arg2, arg3) do { \
2475 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
2476 gen_helper_##name(cpu_env, arg1, arg2, helper_tmp); \
2477 tcg_temp_free_i32(helper_tmp); \
2478 } while(0)
2479
2480#define gen_helper_1e2i(name, ret, arg1, arg2, arg3) do { \
a7812ae4 2481 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
895c2d04 2482 gen_helper_##name(ret, cpu_env, arg1, arg2, helper_tmp); \
a7812ae4
PB
2483 tcg_temp_free_i32(helper_tmp); \
2484 } while(0)
be24bb4f 2485
895c2d04 2486#define gen_helper_0e3i(name, arg1, arg2, arg3, arg4) do { \
a7812ae4 2487 TCGv_i32 helper_tmp = tcg_const_i32(arg4); \
895c2d04 2488 gen_helper_##name(cpu_env, arg1, arg2, arg3, helper_tmp); \
a7812ae4
PB
2489 tcg_temp_free_i32(helper_tmp); \
2490 } while(0)
c239529e 2491
8e9ade68 2492typedef struct DisasContext {
eeb3bba8
EC
2493 DisasContextBase base;
2494 target_ulong saved_pc;
18f440ed 2495 target_ulong page_start;
8e9ade68 2496 uint32_t opcode;
f9c9cd63 2497 uint64_t insn_flags;
5ab5c041 2498 int32_t CP0_Config1;
49735f76 2499 int32_t CP0_Config2;
ab77fc61
DN
2500 int32_t CP0_Config3;
2501 int32_t CP0_Config5;
8e9ade68
TS
2502 /* Routine used to access memory */
2503 int mem_idx;
be3a8c53 2504 TCGMemOp default_tcg_memop_mask;
8e9ade68 2505 uint32_t hflags, saved_hflags;
8e9ade68 2506 target_ulong btarget;
d279279e 2507 bool ulri;
e98c0d17 2508 int kscrexist;
7207c7f9 2509 bool rxi;
9456c2fb 2510 int ie;
aea14095
LA
2511 bool bi;
2512 bool bp;
5204ea79
LA
2513 uint64_t PAMask;
2514 bool mvh;
76964147 2515 bool eva;
cec56a73 2516 bool sc;
5204ea79 2517 int CP0_LLAddr_shift;
e29c9628 2518 bool ps;
01bc435b 2519 bool vp;
c870e3f5 2520 bool cmgcr;
f6d4dd81 2521 bool mrp;
87552089 2522 bool nan2008;
6be77480 2523 bool abs2008;
8e9ade68
TS
2524} DisasContext;
2525
b28425ba
EC
2526#define DISAS_STOP DISAS_TARGET_0
2527#define DISAS_EXIT DISAS_TARGET_1
8e9ade68 2528
d73ee8a2
RH
2529static const char * const regnames[] = {
2530 "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
2531 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
2532 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
2533 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
2534};
6af0bf9c 2535
d73ee8a2
RH
2536static const char * const regnames_HI[] = {
2537 "HI0", "HI1", "HI2", "HI3",
2538};
4b2eb8d2 2539
d73ee8a2
RH
2540static const char * const regnames_LO[] = {
2541 "LO0", "LO1", "LO2", "LO3",
2542};
4b2eb8d2 2543
d73ee8a2
RH
2544static const char * const fregnames[] = {
2545 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
2546 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
2547 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
2548 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
2549};
958fb4a9 2550
863f264d
YK
2551static const char * const msaregnames[] = {
2552 "w0.d0", "w0.d1", "w1.d0", "w1.d1",
2553 "w2.d0", "w2.d1", "w3.d0", "w3.d1",
2554 "w4.d0", "w4.d1", "w5.d0", "w5.d1",
2555 "w6.d0", "w6.d1", "w7.d0", "w7.d1",
2556 "w8.d0", "w8.d1", "w9.d0", "w9.d1",
2557 "w10.d0", "w10.d1", "w11.d0", "w11.d1",
2558 "w12.d0", "w12.d1", "w13.d0", "w13.d1",
2559 "w14.d0", "w14.d1", "w15.d0", "w15.d1",
2560 "w16.d0", "w16.d1", "w17.d0", "w17.d1",
2561 "w18.d0", "w18.d1", "w19.d0", "w19.d1",
2562 "w20.d0", "w20.d1", "w21.d0", "w21.d1",
2563 "w22.d0", "w22.d1", "w23.d0", "w23.d1",
2564 "w24.d0", "w24.d1", "w25.d0", "w25.d1",
2565 "w26.d0", "w26.d1", "w27.d0", "w27.d1",
2566 "w28.d0", "w28.d1", "w29.d0", "w29.d1",
2567 "w30.d0", "w30.d1", "w31.d0", "w31.d1",
2568};
2569
eb5559f6
CJ
2570static const char * const mxuregnames[] = {
2571 "XR1", "XR2", "XR3", "XR4", "XR5", "XR6", "XR7", "XR8",
2572 "XR9", "XR10", "XR11", "XR12", "XR13", "XR14", "XR15", "MXU_CR",
2573};
2574
9d68ac14 2575#define LOG_DISAS(...) \
fb7729e2
RH
2576 do { \
2577 if (MIPS_DEBUG_DISAS) { \
9d68ac14 2578 qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__); \
fb7729e2
RH
2579 } \
2580 } while (0)
2581
9d68ac14 2582#define MIPS_INVAL(op) \
fb7729e2
RH
2583 do { \
2584 if (MIPS_DEBUG_DISAS) { \
9d68ac14
AJ
2585 qemu_log_mask(CPU_LOG_TB_IN_ASM, \
2586 TARGET_FMT_lx ": %08x Invalid %s %03x %03x %03x\n", \
eeb3bba8
EC
2587 ctx->base.pc_next, ctx->opcode, op, \
2588 ctx->opcode >> 26, ctx->opcode & 0x3F, \
2589 ((ctx->opcode >> 16) & 0x1F)); \
fb7729e2
RH
2590 } \
2591 } while (0)
958fb4a9 2592
8e9ade68
TS
2593/* General purpose registers moves. */
2594static inline void gen_load_gpr (TCGv t, int reg)
aaa9128a 2595{
8e9ade68
TS
2596 if (reg == 0)
2597 tcg_gen_movi_tl(t, 0);
2598 else
4b2eb8d2 2599 tcg_gen_mov_tl(t, cpu_gpr[reg]);
aaa9128a
TS
2600}
2601
8e9ade68 2602static inline void gen_store_gpr (TCGv t, int reg)
aaa9128a 2603{
8e9ade68 2604 if (reg != 0)
4b2eb8d2 2605 tcg_gen_mov_tl(cpu_gpr[reg], t);
aaa9128a
TS
2606}
2607
8e9ade68 2608/* Moves to/from shadow registers. */
be24bb4f 2609static inline void gen_load_srsgpr (int from, int to)
aaa9128a 2610{
d9bea114 2611 TCGv t0 = tcg_temp_new();
be24bb4f
TS
2612
2613 if (from == 0)
d9bea114 2614 tcg_gen_movi_tl(t0, 0);
8e9ade68 2615 else {
d9bea114 2616 TCGv_i32 t2 = tcg_temp_new_i32();
a7812ae4 2617 TCGv_ptr addr = tcg_temp_new_ptr();
aaa9128a 2618
7db13fae 2619 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
d9bea114
AJ
2620 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
2621 tcg_gen_andi_i32(t2, t2, 0xf);
2622 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
2623 tcg_gen_ext_i32_ptr(addr, t2);
a7812ae4 2624 tcg_gen_add_ptr(addr, cpu_env, addr);
aaa9128a 2625
d9bea114 2626 tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from);
a7812ae4 2627 tcg_temp_free_ptr(addr);
d9bea114 2628 tcg_temp_free_i32(t2);
8e9ade68 2629 }
d9bea114
AJ
2630 gen_store_gpr(t0, to);
2631 tcg_temp_free(t0);
aaa9128a
TS
2632}
2633
be24bb4f 2634static inline void gen_store_srsgpr (int from, int to)
aaa9128a 2635{
be24bb4f 2636 if (to != 0) {
d9bea114
AJ
2637 TCGv t0 = tcg_temp_new();
2638 TCGv_i32 t2 = tcg_temp_new_i32();
a7812ae4 2639 TCGv_ptr addr = tcg_temp_new_ptr();
be24bb4f 2640
d9bea114 2641 gen_load_gpr(t0, from);
7db13fae 2642 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
d9bea114
AJ
2643 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
2644 tcg_gen_andi_i32(t2, t2, 0xf);
2645 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
2646 tcg_gen_ext_i32_ptr(addr, t2);
a7812ae4 2647 tcg_gen_add_ptr(addr, cpu_env, addr);
be24bb4f 2648
d9bea114 2649 tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to);
a7812ae4 2650 tcg_temp_free_ptr(addr);
d9bea114
AJ
2651 tcg_temp_free_i32(t2);
2652 tcg_temp_free(t0);
8e9ade68 2653 }
aaa9128a
TS
2654}
2655
96992d1a
CJ
2656/* MXU General purpose registers moves. */
2657static inline void gen_load_mxu_gpr(TCGv t, unsigned int reg)
2658{
2659 if (reg == 0) {
2660 tcg_gen_movi_tl(t, 0);
2661 } else if (reg <= 15) {
2662 tcg_gen_mov_tl(t, mxu_gpr[reg - 1]);
2663 }
2664}
2665
2666static inline void gen_store_mxu_gpr(TCGv t, unsigned int reg)
2667{
2668 if (reg > 0 && reg <= 15) {
2669 tcg_gen_mov_tl(mxu_gpr[reg - 1], t);
2670 }
2671}
2672
2673/* MXU control register moves. */
2674static inline void gen_load_mxu_cr(TCGv t)
2675{
2676 tcg_gen_mov_tl(t, mxu_CR);
2677}
2678
2679static inline void gen_store_mxu_cr(TCGv t)
2680{
2681 /* TODO: Add handling of RW rules for MXU_CR. */
2682 tcg_gen_mov_tl(mxu_CR, t);
2683}
2684
2685
eab9944c
LA
2686/* Tests */
2687static inline void gen_save_pc(target_ulong pc)
2688{
2689 tcg_gen_movi_tl(cpu_PC, pc);
2690}
2691
2692static inline void save_cpu_state(DisasContext *ctx, int do_save_pc)
2693{
2694 LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
eeb3bba8
EC
2695 if (do_save_pc && ctx->base.pc_next != ctx->saved_pc) {
2696 gen_save_pc(ctx->base.pc_next);
2697 ctx->saved_pc = ctx->base.pc_next;
eab9944c
LA
2698 }
2699 if (ctx->hflags != ctx->saved_hflags) {
2700 tcg_gen_movi_i32(hflags, ctx->hflags);
2701 ctx->saved_hflags = ctx->hflags;
2702 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
2703 case MIPS_HFLAG_BR:
2704 break;
2705 case MIPS_HFLAG_BC:
2706 case MIPS_HFLAG_BL:
2707 case MIPS_HFLAG_B:
2708 tcg_gen_movi_tl(btarget, ctx->btarget);
2709 break;
2710 }
2711 }
2712}
2713
2714static inline void restore_cpu_state(CPUMIPSState *env, DisasContext *ctx)
2715{
2716 ctx->saved_hflags = ctx->hflags;
2717 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
2718 case MIPS_HFLAG_BR:
2719 break;
2720 case MIPS_HFLAG_BC:
2721 case MIPS_HFLAG_BL:
2722 case MIPS_HFLAG_B:
2723 ctx->btarget = env->btarget;
2724 break;
2725 }
2726}
2727
2728static inline void generate_exception_err(DisasContext *ctx, int excp, int err)
2729{
2730 TCGv_i32 texcp = tcg_const_i32(excp);
2731 TCGv_i32 terr = tcg_const_i32(err);
2732 save_cpu_state(ctx, 1);
2733 gen_helper_raise_exception_err(cpu_env, texcp, terr);
2734 tcg_temp_free_i32(terr);
2735 tcg_temp_free_i32(texcp);
eeb3bba8 2736 ctx->base.is_jmp = DISAS_NORETURN;
eab9944c
LA
2737}
2738
2739static inline void generate_exception(DisasContext *ctx, int excp)
2740{
eab9944c
LA
2741 gen_helper_0e0i(raise_exception, excp);
2742}
2743
9c708c7f
PD
2744static inline void generate_exception_end(DisasContext *ctx, int excp)
2745{
2746 generate_exception_err(ctx, excp, 0);
2747}
2748
aaa9128a 2749/* Floating point register moves. */
7c979afd 2750static void gen_load_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
aa0bf00b 2751{
7c979afd
LA
2752 if (ctx->hflags & MIPS_HFLAG_FRE) {
2753 generate_exception(ctx, EXCP_RI);
2754 }
ecc7b3aa 2755 tcg_gen_extrl_i64_i32(t, fpu_f64[reg]);
6ea83fed
FB
2756}
2757
7c979afd 2758static void gen_store_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
aa0bf00b 2759{
7c979afd
LA
2760 TCGv_i64 t64;
2761 if (ctx->hflags & MIPS_HFLAG_FRE) {
2762 generate_exception(ctx, EXCP_RI);
2763 }
2764 t64 = tcg_temp_new_i64();
d73ee8a2
RH
2765 tcg_gen_extu_i32_i64(t64, t);
2766 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 0, 32);
2767 tcg_temp_free_i64(t64);
6d066274
AJ
2768}
2769
7f6613ce 2770static void gen_load_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
6d066274 2771{
7f6613ce 2772 if (ctx->hflags & MIPS_HFLAG_F64) {
71f303cd 2773 tcg_gen_extrh_i64_i32(t, fpu_f64[reg]);
7f6613ce 2774 } else {
7c979afd 2775 gen_load_fpr32(ctx, t, reg | 1);
7f6613ce 2776 }
6d066274
AJ
2777}
2778
7f6613ce 2779static void gen_store_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
6d066274 2780{
7f6613ce
PJ
2781 if (ctx->hflags & MIPS_HFLAG_F64) {
2782 TCGv_i64 t64 = tcg_temp_new_i64();
2783 tcg_gen_extu_i32_i64(t64, t);
2784 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 32, 32);
2785 tcg_temp_free_i64(t64);
2786 } else {
7c979afd 2787 gen_store_fpr32(ctx, t, reg | 1);
7f6613ce 2788 }
aa0bf00b 2789}
6ea83fed 2790
d73ee8a2 2791static void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
aa0bf00b 2792{
f364515c 2793 if (ctx->hflags & MIPS_HFLAG_F64) {
d73ee8a2 2794 tcg_gen_mov_i64(t, fpu_f64[reg]);
f364515c 2795 } else {
d73ee8a2 2796 tcg_gen_concat32_i64(t, fpu_f64[reg & ~1], fpu_f64[reg | 1]);
aa0bf00b
TS
2797 }
2798}
6ea83fed 2799
d73ee8a2 2800static void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
aa0bf00b 2801{
f364515c 2802 if (ctx->hflags & MIPS_HFLAG_F64) {
d73ee8a2 2803 tcg_gen_mov_i64(fpu_f64[reg], t);
f364515c 2804 } else {
d73ee8a2
RH
2805 TCGv_i64 t0;
2806 tcg_gen_deposit_i64(fpu_f64[reg & ~1], fpu_f64[reg & ~1], t, 0, 32);
2807 t0 = tcg_temp_new_i64();
6d066274 2808 tcg_gen_shri_i64(t0, t, 32);
d73ee8a2 2809 tcg_gen_deposit_i64(fpu_f64[reg | 1], fpu_f64[reg | 1], t0, 0, 32);
6d066274 2810 tcg_temp_free_i64(t0);
aa0bf00b
TS
2811 }
2812}
6ea83fed 2813
d94536f4 2814static inline int get_fp_bit (int cc)
a16336e4 2815{
d94536f4
AJ
2816 if (cc)
2817 return 24 + cc;
2818 else
2819 return 23;
a16336e4
TS
2820}
2821
48d38ca5 2822/* Addresses computation */
941694d0 2823static inline void gen_op_addr_add (DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1)
4ad40f36 2824{
941694d0 2825 tcg_gen_add_tl(ret, arg0, arg1);
48d38ca5
TS
2826
2827#if defined(TARGET_MIPS64)
01f72885 2828 if (ctx->hflags & MIPS_HFLAG_AWRAP) {
941694d0 2829 tcg_gen_ext32s_i64(ret, ret);
48d38ca5
TS
2830 }
2831#endif
4ad40f36
FB
2832}
2833
bf0718c5
SM
2834static inline void gen_op_addr_addi(DisasContext *ctx, TCGv ret, TCGv base,
2835 target_long ofs)
2836{
2837 tcg_gen_addi_tl(ret, base, ofs);
2838
2839#if defined(TARGET_MIPS64)
2840 if (ctx->hflags & MIPS_HFLAG_AWRAP) {
2841 tcg_gen_ext32s_i64(ret, ret);
2842 }
2843#endif
2844}
2845
31837be3
YK
2846/* Addresses computation (translation time) */
2847static target_long addr_add(DisasContext *ctx, target_long base,
2848 target_long offset)
2849{
2850 target_long sum = base + offset;
2851
2852#if defined(TARGET_MIPS64)
2853 if (ctx->hflags & MIPS_HFLAG_AWRAP) {
2854 sum = (int32_t)sum;
2855 }
2856#endif
2857 return sum;
2858}
2859
71f303cd 2860/* Sign-extract the low 32-bits to a target_long. */
1f1b4c00
YK
2861static inline void gen_move_low32(TCGv ret, TCGv_i64 arg)
2862{
2863#if defined(TARGET_MIPS64)
71f303cd
RH
2864 tcg_gen_ext32s_i64(ret, arg);
2865#else
2866 tcg_gen_extrl_i64_i32(ret, arg);
2867#endif
2868}
2869
2870/* Sign-extract the high 32-bits to a target_long. */
2871static inline void gen_move_high32(TCGv ret, TCGv_i64 arg)
2872{
2873#if defined(TARGET_MIPS64)
2874 tcg_gen_sari_i64(ret, arg, 32);
1f1b4c00 2875#else
71f303cd 2876 tcg_gen_extrh_i64_i32(ret, arg);
1f1b4c00
YK
2877#endif
2878}
2879
356265ae 2880static inline void check_cp0_enabled(DisasContext *ctx)
387a8fe5 2881{
fe253235 2882 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
c2c65dab 2883 generate_exception_err(ctx, EXCP_CpU, 0);
387a8fe5
TS
2884}
2885
356265ae 2886static inline void check_cp1_enabled(DisasContext *ctx)
5e755519 2887{
fe253235 2888 if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
5e755519
TS
2889 generate_exception_err(ctx, EXCP_CpU, 1);
2890}
2891
b8aa4598
TS
2892/* Verify that the processor is running with COP1X instructions enabled.
2893 This is associated with the nabla symbol in the MIPS32 and MIPS64
2894 opcode tables. */
2895
356265ae 2896static inline void check_cop1x(DisasContext *ctx)
b8aa4598
TS
2897{
2898 if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
9c708c7f 2899 generate_exception_end(ctx, EXCP_RI);
b8aa4598
TS
2900}
2901
2902/* Verify that the processor is running with 64-bit floating-point
2903 operations enabled. */
2904
356265ae 2905static inline void check_cp1_64bitmode(DisasContext *ctx)
5e755519 2906{
b8aa4598 2907 if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
9c708c7f 2908 generate_exception_end(ctx, EXCP_RI);
5e755519
TS
2909}
2910
2911/*
2912 * Verify if floating point register is valid; an operation is not defined
2913 * if bit 0 of any register specification is set and the FR bit in the
2914 * Status register equals zero, since the register numbers specify an
2915 * even-odd pair of adjacent coprocessor general registers. When the FR bit
2916 * in the Status register equals one, both even and odd register numbers
2917 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
2918 *
2919 * Multiple 64 bit wide registers can be checked by calling
2920 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
2921 */
356265ae 2922static inline void check_cp1_registers(DisasContext *ctx, int regs)
5e755519 2923{
fe253235 2924 if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)))
9c708c7f 2925 generate_exception_end(ctx, EXCP_RI);
5e755519
TS
2926}
2927
853c3240
JL
2928/* Verify that the processor is running with DSP instructions enabled.
2929 This is enabled by CP0 Status register MX(24) bit.
2930 */
2931
2932static inline void check_dsp(DisasContext *ctx)
2933{
2934 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP))) {
ad153f15 2935 if (ctx->insn_flags & ASE_DSP) {
9c708c7f 2936 generate_exception_end(ctx, EXCP_DSPDIS);
ad153f15 2937 } else {
9c708c7f 2938 generate_exception_end(ctx, EXCP_RI);
ad153f15 2939 }
853c3240
JL
2940 }
2941}
2942
908f6be1 2943static inline void check_dsp_r2(DisasContext *ctx)
853c3240 2944{
908f6be1 2945 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP_R2))) {
ad153f15 2946 if (ctx->insn_flags & ASE_DSP) {
9c708c7f 2947 generate_exception_end(ctx, EXCP_DSPDIS);
ad153f15 2948 } else {
9c708c7f 2949 generate_exception_end(ctx, EXCP_RI);
ad153f15 2950 }
853c3240
JL
2951 }
2952}
2953
908f6be1 2954static inline void check_dsp_r3(DisasContext *ctx)
59e781fb 2955{
908f6be1 2956 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP_R3))) {
59e781fb
SM
2957 if (ctx->insn_flags & ASE_DSP) {
2958 generate_exception_end(ctx, EXCP_DSPDIS);
2959 } else {
2960 generate_exception_end(ctx, EXCP_RI);
2961 }
2962 }
2963}
2964
3a95e3a7 2965/* This code generates a "reserved instruction" exception if the
e189e748 2966 CPU does not support the instruction set corresponding to flags. */
f9c9cd63 2967static inline void check_insn(DisasContext *ctx, uint64_t flags)
3a95e3a7 2968{
d75c135e 2969 if (unlikely(!(ctx->insn_flags & flags))) {
9c708c7f 2970 generate_exception_end(ctx, EXCP_RI);
d75c135e 2971 }
3a95e3a7
TS
2972}
2973
fecd2646
LA
2974/* This code generates a "reserved instruction" exception if the
2975 CPU has corresponding flag set which indicates that the instruction
2976 has been removed. */
f9c9cd63 2977static inline void check_insn_opc_removed(DisasContext *ctx, uint64_t flags)
fecd2646
LA
2978{
2979 if (unlikely(ctx->insn_flags & flags)) {
9c708c7f 2980 generate_exception_end(ctx, EXCP_RI);
fecd2646
LA
2981 }
2982}
2983
96631327
FN
2984/*
2985 * The Linux kernel traps certain reserved instruction exceptions to
2986 * emulate the corresponding instructions. QEMU is the kernel in user
2987 * mode, so those traps are emulated by accepting the instructions.
2988 *
2989 * A reserved instruction exception is generated for flagged CPUs if
2990 * QEMU runs in system mode.
2991 */
2992static inline void check_insn_opc_user_only(DisasContext *ctx, uint64_t flags)
2993{
2994#ifndef CONFIG_USER_ONLY
2995 check_insn_opc_removed(ctx, flags);
2996#endif
2997}
2998
e29c9628
YK
2999/* This code generates a "reserved instruction" exception if the
3000 CPU does not support 64-bit paired-single (PS) floating point data type */
3001static inline void check_ps(DisasContext *ctx)
3002{
3003 if (unlikely(!ctx->ps)) {
3004 generate_exception(ctx, EXCP_RI);
3005 }
3006 check_cp1_64bitmode(ctx);
3007}
3008
c7986fd6 3009#ifdef TARGET_MIPS64
e189e748
TS
3010/* This code generates a "reserved instruction" exception if 64-bit
3011 instructions are not enabled. */
356265ae 3012static inline void check_mips_64(DisasContext *ctx)
e189e748 3013{
fe253235 3014 if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
9c708c7f 3015 generate_exception_end(ctx, EXCP_RI);
e189e748 3016}
c7986fd6 3017#endif
e189e748 3018
5204ea79
LA
3019#ifndef CONFIG_USER_ONLY
3020static inline void check_mvh(DisasContext *ctx)
3021{
3022 if (unlikely(!ctx->mvh)) {
3023 generate_exception(ctx, EXCP_RI);
3024 }
3025}
3026#endif
3027
0b16dcd1
AR
3028/*
3029 * This code generates a "reserved instruction" exception if the
3030 * Config5 XNP bit is set.
3031 */
3032static inline void check_xnp(DisasContext *ctx)
3033{
3034 if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_XNP))) {
3035 generate_exception_end(ctx, EXCP_RI);
3036 }
3037}
3038
5e31fdd5
YK
3039#ifndef CONFIG_USER_ONLY
3040/*
3041 * This code generates a "reserved instruction" exception if the
3042 * Config3 PW bit is NOT set.
3043 */
3044static inline void check_pw(DisasContext *ctx)
3045{
3046 if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_PW)))) {
3047 generate_exception_end(ctx, EXCP_RI);
3048 }
3049}
3050#endif
3051
9affc1c5
AR
3052/*
3053 * This code generates a "reserved instruction" exception if the
3054 * Config3 MT bit is NOT set.
3055 */
3056static inline void check_mt(DisasContext *ctx)
3057{
3058 if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_MT)))) {
3059 generate_exception_end(ctx, EXCP_RI);
3060 }
3061}
3062
3063#ifndef CONFIG_USER_ONLY
3064/*
3065 * This code generates a "coprocessor unusable" exception if CP0 is not
3066 * available, and, if that is not the case, generates a "reserved instruction"
3067 * exception if the Config5 MT bit is NOT set. This is needed for availability
3068 * control of some of MT ASE instructions.
3069 */
3070static inline void check_cp0_mt(DisasContext *ctx)
3071{
3072 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0))) {
3073 generate_exception_err(ctx, EXCP_CpU, 0);
3074 } else {
3075 if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_MT)))) {
3076 generate_exception_err(ctx, EXCP_RI, 0);
3077 }
3078 }
3079}
3080#endif
3081
fb32f8c8
DN
3082/*
3083 * This code generates a "reserved instruction" exception if the
3084 * Config5 NMS bit is set.
3085 */
3086static inline void check_nms(DisasContext *ctx)
3087{
3088 if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_NMS))) {
3089 generate_exception_end(ctx, EXCP_RI);
3090 }
3091}
3092
d046a9ea
DN
3093/*
3094 * This code generates a "reserved instruction" exception if the
3095 * Config5 NMS bit is set, and Config1 DL, Config1 IL, Config2 SL,
3096 * Config2 TL, and Config5 L2C are unset.
3097 */
3098static inline void check_nms_dl_il_sl_tl_l2c(DisasContext *ctx)
3099{
3100 if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_NMS)) &&
3101 !(ctx->CP0_Config1 & (1 << CP0C1_DL)) &&
3102 !(ctx->CP0_Config1 & (1 << CP0C1_IL)) &&
3103 !(ctx->CP0_Config2 & (1 << CP0C2_SL)) &&
3104 !(ctx->CP0_Config2 & (1 << CP0C2_TL)) &&
3105 !(ctx->CP0_Config5 & (1 << CP0C5_L2C)))
3106 {
3107 generate_exception_end(ctx, EXCP_RI);
3108 }
3109}
3110
3111/*
3112 * This code generates a "reserved instruction" exception if the
3113 * Config5 EVA bit is NOT set.
3114 */
3115static inline void check_eva(DisasContext *ctx)
3116{
3117 if (unlikely(!(ctx->CP0_Config5 & (1 << CP0C5_EVA)))) {
3118 generate_exception_end(ctx, EXCP_RI);
3119 }
3120}
3121
0b16dcd1 3122
8153667c
NF
3123/* Define small wrappers for gen_load_fpr* so that we have a uniform
3124 calling interface for 32 and 64-bit FPRs. No sense in changing
3125 all callers for gen_load_fpr32 when we need the CTX parameter for
3126 this one use. */
7c979afd 3127#define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(ctx, x, y)
8153667c
NF
3128#define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
3129#define FOP_CONDS(type, abs, fmt, ifmt, bits) \
3130static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \
3131 int ft, int fs, int cc) \
3132{ \
3133 TCGv_i##bits fp0 = tcg_temp_new_i##bits (); \
3134 TCGv_i##bits fp1 = tcg_temp_new_i##bits (); \
3135 switch (ifmt) { \
3136 case FMT_PS: \
e29c9628 3137 check_ps(ctx); \
8153667c
NF
3138 break; \
3139 case FMT_D: \
3140 if (abs) { \
3141 check_cop1x(ctx); \
3142 } \
3143 check_cp1_registers(ctx, fs | ft); \
3144 break; \
3145 case FMT_S: \
3146 if (abs) { \
3147 check_cop1x(ctx); \
3148 } \
3149 break; \
3150 } \
3151 gen_ldcmp_fpr##bits (ctx, fp0, fs); \
3152 gen_ldcmp_fpr##bits (ctx, fp1, ft); \
3153 switch (n) { \
895c2d04
BS
3154 case 0: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc); break;\
3155 case 1: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc); break;\
3156 case 2: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc); break;\
3157 case 3: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc); break;\
3158 case 4: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc); break;\
3159 case 5: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc); break;\
3160 case 6: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc); break;\
3161 case 7: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc); break;\
3162 case 8: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc); break;\
3163 case 9: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); break;\
3164 case 10: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc); break;\
3165 case 11: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc); break;\
3166 case 12: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc); break;\
3167 case 13: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc); break;\
3168 case 14: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc); break;\
3169 case 15: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc); break;\
8153667c
NF
3170 default: abort(); \
3171 } \
3172 tcg_temp_free_i##bits (fp0); \
3173 tcg_temp_free_i##bits (fp1); \
3174}
3175
3176FOP_CONDS(, 0, d, FMT_D, 64)
3177FOP_CONDS(abs, 1, d, FMT_D, 64)
3178FOP_CONDS(, 0, s, FMT_S, 32)
3179FOP_CONDS(abs, 1, s, FMT_S, 32)
3180FOP_CONDS(, 0, ps, FMT_PS, 64)
3181FOP_CONDS(abs, 1, ps, FMT_PS, 64)
3182#undef FOP_CONDS
3f493883
YK
3183
3184#define FOP_CONDNS(fmt, ifmt, bits, STORE) \
3185static inline void gen_r6_cmp_ ## fmt(DisasContext * ctx, int n, \
3186 int ft, int fs, int fd) \
3187{ \
3188 TCGv_i ## bits fp0 = tcg_temp_new_i ## bits(); \
3189 TCGv_i ## bits fp1 = tcg_temp_new_i ## bits(); \
00fb4a11 3190 if (ifmt == FMT_D) { \
3f493883 3191 check_cp1_registers(ctx, fs | ft | fd); \
3f493883
YK
3192 } \
3193 gen_ldcmp_fpr ## bits(ctx, fp0, fs); \
3194 gen_ldcmp_fpr ## bits(ctx, fp1, ft); \
3195 switch (n) { \
3196 case 0: \
3197 gen_helper_r6_cmp_ ## fmt ## _af(fp0, cpu_env, fp0, fp1); \
3198 break; \
3199 case 1: \
3200 gen_helper_r6_cmp_ ## fmt ## _un(fp0, cpu_env, fp0, fp1); \
3201 break; \
3202 case 2: \
3203 gen_helper_r6_cmp_ ## fmt ## _eq(fp0, cpu_env, fp0, fp1); \
3204 break; \
3205 case 3: \
3206 gen_helper_r6_cmp_ ## fmt ## _ueq(fp0, cpu_env, fp0, fp1); \
3207 break; \
3208 case 4: \
3209 gen_helper_r6_cmp_ ## fmt ## _lt(fp0, cpu_env, fp0, fp1); \
3210 break; \
3211 case 5: \
3212 gen_helper_r6_cmp_ ## fmt ## _ult(fp0, cpu_env, fp0, fp1); \
3213 break; \
3214 case 6: \
3215 gen_helper_r6_cmp_ ## fmt ## _le(fp0, cpu_env, fp0, fp1); \
3216 break; \
3217 case 7: \
3218 gen_helper_r6_cmp_ ## fmt ## _ule(fp0, cpu_env, fp0, fp1); \
3219 break; \
3220 case 8: \
3221 gen_helper_r6_cmp_ ## fmt ## _saf(fp0, cpu_env, fp0, fp1); \
3222 break; \
3223 case 9: \
3224 gen_helper_r6_cmp_ ## fmt ## _sun(fp0, cpu_env, fp0, fp1); \
3225 break; \
3226 case 10: \
3227 gen_helper_r6_cmp_ ## fmt ## _seq(fp0, cpu_env, fp0, fp1); \
3228 break; \
3229 case 11: \
3230 gen_helper_r6_cmp_ ## fmt ## _sueq(fp0, cpu_env, fp0, fp1); \
3231 break; \
3232 case 12: \
3233 gen_helper_r6_cmp_ ## fmt ## _slt(fp0, cpu_env, fp0, fp1); \
3234 break; \
3235 case 13: \
3236 gen_helper_r6_cmp_ ## fmt ## _sult(fp0, cpu_env, fp0, fp1); \
3237 break; \
3238 case 14: \
3239 gen_helper_r6_cmp_ ## fmt ## _sle(fp0, cpu_env, fp0, fp1); \
3240 break; \
3241 case 15: \
3242 gen_helper_r6_cmp_ ## fmt ## _sule(fp0, cpu_env, fp0, fp1); \
3243 break; \
3244 case 17: \
3245 gen_helper_r6_cmp_ ## fmt ## _or(fp0, cpu_env, fp0, fp1); \
3246 break; \
3247 case 18: \
3248 gen_helper_r6_cmp_ ## fmt ## _une(fp0, cpu_env, fp0, fp1); \
3249 break; \
3250 case 19: \
3251 gen_helper_r6_cmp_ ## fmt ## _ne(fp0, cpu_env, fp0, fp1); \
3252 break; \
3253 case 25: \
3254 gen_helper_r6_cmp_ ## fmt ## _sor(fp0, cpu_env, fp0, fp1); \
3255 break; \
3256 case 26: \
3257 gen_helper_r6_cmp_ ## fmt ## _sune(fp0, cpu_env, fp0, fp1); \
3258 break; \
3259 case 27: \
3260 gen_helper_r6_cmp_ ## fmt ## _sne(fp0, cpu_env, fp0, fp1); \
3261 break; \
3262 default: \
3263 abort(); \
3264 } \
3265 STORE; \
3266 tcg_temp_free_i ## bits (fp0); \
3267 tcg_temp_free_i ## bits (fp1); \
3268}
3269
3270FOP_CONDNS(d, FMT_D, 64, gen_store_fpr64(ctx, fp0, fd))
7c979afd 3271FOP_CONDNS(s, FMT_S, 32, gen_store_fpr32(ctx, fp0, fd))
3f493883 3272#undef FOP_CONDNS
8153667c
NF
3273#undef gen_ldcmp_fpr32
3274#undef gen_ldcmp_fpr64
3275
958fb4a9 3276/* load/store instructions. */
e7139c44 3277#ifdef CONFIG_USER_ONLY
d9bea114 3278#define OP_LD_ATOMIC(insn,fname) \
dd4096cd
JH
3279static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx, \
3280 DisasContext *ctx) \
d9bea114
AJ
3281{ \
3282 TCGv t0 = tcg_temp_new(); \
3283 tcg_gen_mov_tl(t0, arg1); \
3284 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
7db13fae
AF
3285 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
3286 tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval)); \
d9bea114 3287 tcg_temp_free(t0); \
aaa9128a 3288}
e7139c44
AJ
3289#else
3290#define OP_LD_ATOMIC(insn,fname) \
dd4096cd
JH
3291static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx, \
3292 DisasContext *ctx) \
e7139c44 3293{ \
dd4096cd 3294 gen_helper_1e1i(insn, ret, arg1, mem_idx); \
e7139c44
AJ
3295}
3296#endif
aaa9128a
TS
3297OP_LD_ATOMIC(ll,ld32s);
3298#if defined(TARGET_MIPS64)
3299OP_LD_ATOMIC(lld,ld64);
3300#endif
3301#undef OP_LD_ATOMIC
3302
590bc601
PB
3303#ifdef CONFIG_USER_ONLY
3304#define OP_ST_ATOMIC(insn,fname,ldname,almask) \
dd4096cd
JH
3305static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, int mem_idx, \
3306 DisasContext *ctx) \
590bc601
PB
3307{ \
3308 TCGv t0 = tcg_temp_new(); \
42a268c2
RH
3309 TCGLabel *l1 = gen_new_label(); \
3310 TCGLabel *l2 = gen_new_label(); \
590bc601
PB
3311 \
3312 tcg_gen_andi_tl(t0, arg2, almask); \
3313 tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1); \
7db13fae 3314 tcg_gen_st_tl(arg2, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr)); \
590bc601
PB
3315 generate_exception(ctx, EXCP_AdES); \
3316 gen_set_label(l1); \
7db13fae 3317 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
590bc601
PB
3318 tcg_gen_brcond_tl(TCG_COND_NE, arg2, t0, l2); \
3319 tcg_gen_movi_tl(t0, rt | ((almask << 3) & 0x20)); \
7db13fae
AF
3320 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, llreg)); \
3321 tcg_gen_st_tl(arg1, cpu_env, offsetof(CPUMIPSState, llnewval)); \
9c708c7f 3322 generate_exception_end(ctx, EXCP_SC); \
590bc601
PB
3323 gen_set_label(l2); \
3324 tcg_gen_movi_tl(t0, 0); \
3325 gen_store_gpr(t0, rt); \
3326 tcg_temp_free(t0); \
3327}
3328#else
3329#define OP_ST_ATOMIC(insn,fname,ldname,almask) \
dd4096cd
JH
3330static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, int mem_idx, \
3331 DisasContext *ctx) \
590bc601
PB
3332{ \
3333 TCGv t0 = tcg_temp_new(); \
dd4096cd 3334 gen_helper_1e2i(insn, t0, arg1, arg2, mem_idx); \
590bc601 3335 gen_store_gpr(t0, rt); \
590bc601
PB
3336 tcg_temp_free(t0); \
3337}
3338#endif
590bc601 3339OP_ST_ATOMIC(sc,st32,ld32s,0x3);
aaa9128a 3340#if defined(TARGET_MIPS64)
590bc601 3341OP_ST_ATOMIC(scd,st64,ld64,0x7);
aaa9128a
TS
3342#endif
3343#undef OP_ST_ATOMIC
3344
662d7485 3345static void gen_base_offset_addr (DisasContext *ctx, TCGv addr,
72e1f16f 3346 int base, int offset)
662d7485
NF
3347{
3348 if (base == 0) {
3349 tcg_gen_movi_tl(addr, offset);
3350 } else if (offset == 0) {
3351 gen_load_gpr(addr, base);
3352 } else {
3353 tcg_gen_movi_tl(addr, offset);
3354 gen_op_addr_add(ctx, addr, cpu_gpr[base], addr);
3355 }
3356}
3357
364d4831
NF
3358static target_ulong pc_relative_pc (DisasContext *ctx)
3359{
eeb3bba8 3360 target_ulong pc = ctx->base.pc_next;
364d4831
NF
3361
3362 if (ctx->hflags & MIPS_HFLAG_BMASK) {
3363 int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
3364
3365 pc -= branch_bytes;
3366 }
3367
3368 pc &= ~(target_ulong)3;
3369 return pc;
3370}
3371
5c13fdfd 3372/* Load */
d75c135e 3373static void gen_ld(DisasContext *ctx, uint32_t opc,
72e1f16f 3374 int rt, int base, int offset)
6af0bf9c 3375{
fc40787a 3376 TCGv t0, t1, t2;
dd4096cd 3377 int mem_idx = ctx->mem_idx;
afa88c3a 3378
d75c135e 3379 if (rt == 0 && ctx->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)) {
afa88c3a
AJ
3380 /* Loongson CPU uses a load to zero register for prefetch.
3381 We emulate it as a NOP. On other CPU we must perform the
3382 actual memory access. */
afa88c3a
AJ
3383 return;
3384 }
6af0bf9c 3385
afa88c3a 3386 t0 = tcg_temp_new();
662d7485 3387 gen_base_offset_addr(ctx, t0, base, offset);
afa88c3a 3388
6af0bf9c 3389 switch (opc) {
d26bc211 3390#if defined(TARGET_MIPS64)
6e473128 3391 case OPC_LWU:
dd4096cd 3392 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL |
be3a8c53 3393 ctx->default_tcg_memop_mask);
78723684 3394 gen_store_gpr(t0, rt);
6e473128 3395 break;
6af0bf9c 3396 case OPC_LD:
dd4096cd 3397 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ |
be3a8c53 3398 ctx->default_tcg_memop_mask);
78723684 3399 gen_store_gpr(t0, rt);
6af0bf9c 3400 break;
7a387fff 3401 case OPC_LLD:
bf7910c6 3402 case R6_OPC_LLD:
dd4096cd 3403 op_ld_lld(t0, t0, mem_idx, ctx);
78723684 3404 gen_store_gpr(t0, rt);
7a387fff 3405 break;
6af0bf9c 3406 case OPC_LDL:
3cee3050 3407 t1 = tcg_temp_new();
908680c6
AJ
3408 /* Do a byte access to possibly trigger a page
3409 fault with the unaligned address. */
dd4096cd 3410 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
fc40787a
AJ
3411 tcg_gen_andi_tl(t1, t0, 7);
3412#ifndef TARGET_WORDS_BIGENDIAN
3413 tcg_gen_xori_tl(t1, t1, 7);
3414#endif
3415 tcg_gen_shli_tl(t1, t1, 3);
3416 tcg_gen_andi_tl(t0, t0, ~7);
dd4096cd 3417 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
fc40787a 3418 tcg_gen_shl_tl(t0, t0, t1);
eb02cc3f
AJ
3419 t2 = tcg_const_tl(-1);
3420 tcg_gen_shl_tl(t2, t2, t1);
78723684 3421 gen_load_gpr(t1, rt);
eb02cc3f 3422 tcg_gen_andc_tl(t1, t1, t2);
fc40787a
AJ
3423 tcg_temp_free(t2);
3424 tcg_gen_or_tl(t0, t0, t1);
3cee3050 3425 tcg_temp_free(t1);
fc40787a 3426 gen_store_gpr(t0, rt);
6af0bf9c 3427 break;
6af0bf9c 3428 case OPC_LDR:
3cee3050 3429 t1 = tcg_temp_new();
908680c6
AJ
3430 /* Do a byte access to possibly trigger a page
3431 fault with the unaligned address. */
dd4096cd 3432 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
fc40787a
AJ
3433 tcg_gen_andi_tl(t1, t0, 7);
3434#ifdef TARGET_WORDS_BIGENDIAN
3435 tcg_gen_xori_tl(t1, t1, 7);
3436#endif
3437 tcg_gen_shli_tl(t1, t1, 3);
3438 tcg_gen_andi_tl(t0, t0, ~7);
dd4096cd 3439 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
fc40787a
AJ
3440 tcg_gen_shr_tl(t0, t0, t1);
3441 tcg_gen_xori_tl(t1, t1, 63);
3442 t2 = tcg_const_tl(0xfffffffffffffffeull);
3443 tcg_gen_shl_tl(t2, t2, t1);
78723684 3444 gen_load_gpr(t1, rt);
fc40787a
AJ
3445 tcg_gen_and_tl(t1, t1, t2);
3446 tcg_temp_free(t2);
3447 tcg_gen_or_tl(t0, t0, t1);
3cee3050 3448 tcg_temp_free(t1);
fc40787a 3449 gen_store_gpr(t0, rt);
6af0bf9c 3450 break;
364d4831 3451 case OPC_LDPC:
3cee3050 3452 t1 = tcg_const_tl(pc_relative_pc(ctx));
364d4831 3453 gen_op_addr_add(ctx, t0, t0, t1);
3cee3050 3454 tcg_temp_free(t1);
dd4096cd 3455 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
364d4831
NF
3456 gen_store_gpr(t0, rt);
3457 break;
6af0bf9c 3458#endif
364d4831 3459 case OPC_LWPC:
3cee3050 3460 t1 = tcg_const_tl(pc_relative_pc(ctx));
364d4831 3461 gen_op_addr_add(ctx, t0, t0, t1);
3cee3050 3462 tcg_temp_free(t1);
dd4096cd 3463 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESL);
364d4831
NF
3464 gen_store_gpr(t0, rt);
3465 break;
76964147
JH
3466 case OPC_LWE:
3467 mem_idx = MIPS_HFLAG_UM;
3468 /* fall through */
6af0bf9c 3469 case OPC_LW:
dd4096cd 3470 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESL |
be3a8c53 3471 ctx->default_tcg_memop_mask);
78723684 3472 gen_store_gpr(t0, rt);
6af0bf9c 3473 break;
76964147
JH
3474 case OPC_LHE:
3475 mem_idx = MIPS_HFLAG_UM;
3476 /* fall through */
6af0bf9c 3477 case OPC_LH:
dd4096cd 3478 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESW |
be3a8c53 3479 ctx->default_tcg_memop_mask);
78723684 3480 gen_store_gpr(t0, rt);
6af0bf9c 3481 break;
76964147
JH
3482 case OPC_LHUE:
3483 mem_idx = MIPS_HFLAG_UM;
3484 /* fall through */
6af0bf9c 3485 case OPC_LHU:
dd4096cd 3486 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUW |
be3a8c53 3487 ctx->default_tcg_memop_mask);
78723684 3488 gen_store_gpr(t0, rt);
6af0bf9c 3489 break;
76964147
JH
3490 case OPC_LBE:
3491 mem_idx = MIPS_HFLAG_UM;
3492 /* fall through */
6af0bf9c 3493 case OPC_LB:
dd4096cd 3494 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_SB);
78723684 3495 gen_store_gpr(t0, rt);
6af0bf9c 3496 break;
76964147
JH
3497 case OPC_LBUE:
3498 mem_idx = MIPS_HFLAG_UM;
3499 /* fall through */
6af0bf9c 3500 case OPC_LBU:
dd4096cd 3501 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_UB);
78723684 3502 gen_store_gpr(t0, rt);
6af0bf9c 3503 break;
76964147
JH
3504 case OPC_LWLE:
3505 mem_idx = MIPS_HFLAG_UM;
3506 /* fall through */
6af0bf9c 3507 case OPC_LWL:
3cee3050 3508 t1 = tcg_temp_new();
908680c6
AJ
3509 /* Do a byte access to possibly trigger a page
3510 fault with the unaligned address. */
dd4096cd 3511 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
fc40787a
AJ
3512 tcg_gen_andi_tl(t1, t0, 3);
3513#ifndef TARGET_WORDS_BIGENDIAN
3514 tcg_gen_xori_tl(t1, t1, 3);
3515#endif
3516 tcg_gen_shli_tl(t1, t1, 3);
3517 tcg_gen_andi_tl(t0, t0, ~3);
dd4096cd 3518 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL);
fc40787a 3519 tcg_gen_shl_tl(t0, t0, t1);
eb02cc3f
AJ
3520 t2 = tcg_const_tl(-1);
3521 tcg_gen_shl_tl(t2, t2, t1);
6958549d 3522 gen_load_gpr(t1, rt);
eb02cc3f 3523 tcg_gen_andc_tl(t1, t1, t2);
fc40787a
AJ
3524 tcg_temp_free(t2);
3525 tcg_gen_or_tl(t0, t0, t1);
3cee3050 3526 tcg_temp_free(t1);
fc40787a
AJ
3527 tcg_gen_ext32s_tl(t0, t0);
3528 gen_store_gpr(t0, rt);
6af0bf9c 3529 break;
76964147
JH
3530 case OPC_LWRE:
3531 mem_idx = MIPS_HFLAG_UM;
3532 /* fall through */
6af0bf9c 3533 case OPC_LWR:
3cee3050 3534 t1 = tcg_temp_new();
908680c6
AJ
3535 /* Do a byte access to possibly trigger a page
3536 fault with the unaligned address. */
dd4096cd 3537 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
fc40787a
AJ
3538 tcg_gen_andi_tl(t1, t0, 3);
3539#ifdef TARGET_WORDS_BIGENDIAN
3540 tcg_gen_xori_tl(t1, t1, 3);
3541#endif
3542 tcg_gen_shli_tl(t1, t1, 3);
3543 tcg_gen_andi_tl(t0, t0, ~3);
dd4096cd 3544 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL);
fc40787a
AJ
3545 tcg_gen_shr_tl(t0, t0, t1);
3546 tcg_gen_xori_tl(t1, t1, 31);
3547 t2 = tcg_const_tl(0xfffffffeull);
3548 tcg_gen_shl_tl(t2, t2, t1);
6958549d 3549 gen_load_gpr(t1, rt);
fc40787a
AJ
3550 tcg_gen_and_tl(t1, t1, t2);
3551 tcg_temp_free(t2);
3552 tcg_gen_or_tl(t0, t0, t1);
3cee3050 3553 tcg_temp_free(t1);
c728154b 3554 tcg_gen_ext32s_tl(t0, t0);
fc40787a 3555 gen_store_gpr(t0, rt);
6af0bf9c 3556 break;
76964147
JH
3557 case OPC_LLE:
3558 mem_idx = MIPS_HFLAG_UM;
3559 /* fall through */
6af0bf9c 3560 case OPC_LL:
4368b29a 3561 case R6_OPC_LL:
dd4096cd 3562 op_ld_ll(t0, t0, mem_idx, ctx);
78723684 3563 gen_store_gpr(t0, rt);
6af0bf9c 3564 break;
d66c7132 3565 }
d66c7132 3566 tcg_temp_free(t0);
d66c7132
AJ
3567}
3568
0b16dcd1
AR
3569static void gen_llwp(DisasContext *ctx, uint32_t base, int16_t offset,
3570 uint32_t reg1, uint32_t reg2)
3571{
3572 TCGv taddr = tcg_temp_new();
3573 TCGv_i64 tval = tcg_temp_new_i64();
3574 TCGv tmp1 = tcg_temp_new();
3575 TCGv tmp2 = tcg_temp_new();
3576
3577 gen_base_offset_addr(ctx, taddr, base, offset);
3578 tcg_gen_qemu_ld64(tval, taddr, ctx->mem_idx);
3579#ifdef TARGET_WORDS_BIGENDIAN
3580 tcg_gen_extr_i64_tl(tmp2, tmp1, tval);
3581#else
3582 tcg_gen_extr_i64_tl(tmp1, tmp2, tval);
3583#endif
3584 gen_store_gpr(tmp1, reg1);
3585 tcg_temp_free(tmp1);
3586 gen_store_gpr(tmp2, reg2);
3587 tcg_temp_free(tmp2);
3588 tcg_gen_st_i64(tval, cpu_env, offsetof(CPUMIPSState, llval_wp));
3589 tcg_temp_free_i64(tval);
3590 tcg_gen_st_tl(taddr, cpu_env, offsetof(CPUMIPSState, lladdr));
3591 tcg_temp_free(taddr);
3592}
3593
5c13fdfd
AJ
3594/* Store */
3595static void gen_st (DisasContext *ctx, uint32_t opc, int rt,
72e1f16f 3596 int base, int offset)
5c13fdfd 3597{
5c13fdfd
AJ
3598 TCGv t0 = tcg_temp_new();
3599 TCGv t1 = tcg_temp_new();
dd4096cd 3600 int mem_idx = ctx->mem_idx;
5c13fdfd
AJ
3601
3602 gen_base_offset_addr(ctx, t0, base, offset);
3603 gen_load_gpr(t1, rt);
3604 switch (opc) {
3605#if defined(TARGET_MIPS64)
3606 case OPC_SD:
dd4096cd 3607 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEQ |
be3a8c53 3608 ctx->default_tcg_memop_mask);
5c13fdfd
AJ
3609 break;
3610 case OPC_SDL:
dd4096cd 3611 gen_helper_0e2i(sdl, t1, t0, mem_idx);
5c13fdfd
AJ
3612 break;
3613 case OPC_SDR:
dd4096cd 3614 gen_helper_0e2i(sdr, t1, t0, mem_idx);
5c13fdfd
AJ
3615 break;
3616#endif
76964147
JH
3617 case OPC_SWE:
3618 mem_idx = MIPS_HFLAG_UM;
3619 /* fall through */
5c13fdfd 3620 case OPC_SW:
dd4096cd 3621 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUL |
be3a8c53 3622 ctx->default_tcg_memop_mask);
5c13fdfd 3623 break;
76964147
JH
3624 case OPC_SHE:
3625 mem_idx = MIPS_HFLAG_UM;
3626 /* fall through */
5c13fdfd 3627 case OPC_SH:
dd4096cd 3628 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUW |
be3a8c53 3629 ctx->default_tcg_memop_mask);
5c13fdfd 3630 break;
76964147
JH
3631 case OPC_SBE:
3632 mem_idx = MIPS_HFLAG_UM;
3633 /* fall through */
5c13fdfd 3634 case OPC_SB:
dd4096cd 3635 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_8);
5c13fdfd 3636 break;
76964147
JH
3637 case OPC_SWLE:
3638 mem_idx = MIPS_HFLAG_UM;
3639 /* fall through */
5c13fdfd 3640 case OPC_SWL:
dd4096cd 3641 gen_helper_0e2i(swl, t1, t0, mem_idx);
5c13fdfd 3642 break;
76964147
JH
3643 case OPC_SWRE:
3644 mem_idx = MIPS_HFLAG_UM;
3645 /* fall through */
5c13fdfd 3646 case OPC_SWR:
dd4096cd 3647 gen_helper_0e2i(swr, t1, t0, mem_idx);
5c13fdfd
AJ
3648 break;
3649 }
5c13fdfd
AJ
3650 tcg_temp_free(t0);
3651 tcg_temp_free(t1);
3652}
3653
3654
d66c7132
AJ
3655/* Store conditional */
3656static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt,
3657 int base, int16_t offset)
3658{
d66c7132 3659 TCGv t0, t1;
dd4096cd 3660 int mem_idx = ctx->mem_idx;
d66c7132 3661
2d2826b9 3662#ifdef CONFIG_USER_ONLY
d66c7132 3663 t0 = tcg_temp_local_new();
d66c7132 3664 t1 = tcg_temp_local_new();
2d2826b9
AJ
3665#else
3666 t0 = tcg_temp_new();
3667 t1 = tcg_temp_new();
3668#endif
3669 gen_base_offset_addr(ctx, t0, base, offset);
d66c7132
AJ
3670 gen_load_gpr(t1, rt);
3671 switch (opc) {
3672#if defined(TARGET_MIPS64)
3673 case OPC_SCD:
bf7910c6 3674 case R6_OPC_SCD:
dd4096cd 3675 op_st_scd(t1, t0, rt, mem_idx, ctx);
d66c7132
AJ
3676 break;
3677#endif
76964147
JH
3678 case OPC_SCE:
3679 mem_idx = MIPS_HFLAG_UM;
3680 /* fall through */
6af0bf9c 3681 case OPC_SC:
4368b29a 3682 case R6_OPC_SC:
dd4096cd 3683 op_st_sc(t1, t0, rt, mem_idx, ctx);
6af0bf9c 3684 break;
6af0bf9c 3685 }
78723684 3686 tcg_temp_free(t1);
d66c7132 3687 tcg_temp_free(t0);
6af0bf9c
FB
3688}
3689
0b16dcd1
AR
3690static void gen_scwp(DisasContext *ctx, uint32_t base, int16_t offset,
3691 uint32_t reg1, uint32_t reg2)
3692{
3693 TCGv taddr = tcg_temp_local_new();
3694 TCGv lladdr = tcg_temp_local_new();
3695 TCGv_i64 tval = tcg_temp_new_i64();
3696 TCGv_i64 llval = tcg_temp_new_i64();
3697 TCGv_i64 val = tcg_temp_new_i64();
3698 TCGv tmp1 = tcg_temp_new();
3699 TCGv tmp2 = tcg_temp_new();
3700 TCGLabel *lab_fail = gen_new_label();
3701 TCGLabel *lab_done = gen_new_label();
3702
3703 gen_base_offset_addr(ctx, taddr, base, offset);
3704
3705 tcg_gen_ld_tl(lladdr, cpu_env, offsetof(CPUMIPSState, lladdr));
3706 tcg_gen_brcond_tl(TCG_COND_NE, taddr, lladdr, lab_fail);
3707
3708 gen_load_gpr(tmp1, reg1);
3709 gen_load_gpr(tmp2, reg2);
3710
3711#ifdef TARGET_WORDS_BIGENDIAN
3712 tcg_gen_concat_tl_i64(tval, tmp2, tmp1);
3713#else
3714 tcg_gen_concat_tl_i64(tval, tmp1, tmp2);
3715#endif
3716
3717 tcg_gen_ld_i64(llval, cpu_env, offsetof(CPUMIPSState, llval_wp));
3718 tcg_gen_atomic_cmpxchg_i64(val, taddr, llval, tval,
3719 ctx->mem_idx, MO_64);
3720 if (reg1 != 0) {
3721 tcg_gen_movi_tl(cpu_gpr[reg1], 1);
3722 }
3723 tcg_gen_brcond_i64(TCG_COND_EQ, val, llval, lab_done);
3724
3725 gen_set_label(lab_fail);
3726
3727 if (reg1 != 0) {
3728 tcg_gen_movi_tl(cpu_gpr[reg1], 0);
3729 }
3730 gen_set_label(lab_done);
3731 tcg_gen_movi_tl(lladdr, -1);
3732 tcg_gen_st_tl(lladdr, cpu_env, offsetof(CPUMIPSState, lladdr));
3733}
3734
6ea83fed 3735/* Load and store */
7a387fff 3736static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
b52d3bfa 3737 TCGv t0)
6ea83fed 3738{
6ea83fed 3739 /* Don't do NOP if destination is zero: we must perform the actual
ead9360e 3740 memory access. */
6ea83fed
FB
3741 switch (opc) {
3742 case OPC_LWC1:
b6d96bed 3743 {
a7812ae4 3744 TCGv_i32 fp0 = tcg_temp_new_i32();
be3a8c53
YK
3745 tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, MO_TESL |
3746 ctx->default_tcg_memop_mask);
7c979afd 3747 gen_store_fpr32(ctx, fp0, ft);
a7812ae4 3748 tcg_temp_free_i32(fp0);
b6d96bed 3749 }
6ea83fed
FB
3750 break;
3751 case OPC_SWC1:
b6d96bed 3752 {
a7812ae4 3753 TCGv_i32 fp0 = tcg_temp_new_i32();
7c979afd 3754 gen_load_fpr32(ctx, fp0, ft);
be3a8c53
YK
3755 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL |
3756 ctx->default_tcg_memop_mask);
a7812ae4 3757 tcg_temp_free_i32(fp0);
b6d96bed 3758 }
6ea83fed
FB
3759 break;
3760 case OPC_LDC1:
b6d96bed 3761 {
a7812ae4 3762 TCGv_i64 fp0 = tcg_temp_new_i64();
be3a8c53
YK
3763 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ |
3764 ctx->default_tcg_memop_mask);
b6d96bed 3765 gen_store_fpr64(ctx, fp0, ft);
a7812ae4 3766 tcg_temp_free_i64(fp0);
b6d96bed 3767 }
6ea83fed
FB
3768 break;
3769 case OPC_SDC1:
b6d96bed 3770 {
a7812ae4 3771 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 3772 gen_load_fpr64(ctx, fp0, ft);
be3a8c53
YK
3773 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ |
3774 ctx->default_tcg_memop_mask);
a7812ae4 3775 tcg_temp_free_i64(fp0);
b6d96bed 3776 }
6ea83fed
FB
3777 break;
3778 default:
9d68ac14 3779 MIPS_INVAL("flt_ldst");
9c708c7f 3780 generate_exception_end(ctx, EXCP_RI);
b52d3bfa 3781 break;
6ea83fed 3782 }
6ea83fed 3783}
6ea83fed 3784
5ab5c041
AJ
3785static void gen_cop1_ldst(DisasContext *ctx, uint32_t op, int rt,
3786 int rs, int16_t imm)
26ebe468 3787{
b52d3bfa
YK
3788 TCGv t0 = tcg_temp_new();
3789
5ab5c041 3790 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
26ebe468 3791 check_cp1_enabled(ctx);
d9224450
MR
3792 switch (op) {
3793 case OPC_LDC1:
3794 case OPC_SDC1:
3795 check_insn(ctx, ISA_MIPS2);
3796 /* Fallthrough */
3797 default:
b52d3bfa
YK
3798 gen_base_offset_addr(ctx, t0, rs, imm);
3799 gen_flt_ldst(ctx, op, rt, t0);
d9224450 3800 }
26ebe468
NF
3801 } else {
3802 generate_exception_err(ctx, EXCP_CpU, 1);
3803 }
b52d3bfa 3804 tcg_temp_free(t0);
26ebe468
NF
3805}
3806
6af0bf9c 3807/* Arithmetic with immediate operand */
d75c135e 3808static void gen_arith_imm(DisasContext *ctx, uint32_t opc,
72e1f16f 3809 int rt, int rs, int imm)
6af0bf9c 3810{
324d9e32 3811 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
6af0bf9c 3812
7a387fff 3813 if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
ead9360e
TS
3814 /* If no destination, treat it as a NOP.
3815 For addi, we must generate the overflow exception when needed. */
324d9e32 3816 return;
6af0bf9c
FB
3817 }
3818 switch (opc) {
3819 case OPC_ADDI:
48d38ca5 3820 {
324d9e32
AJ
3821 TCGv t0 = tcg_temp_local_new();
3822 TCGv t1 = tcg_temp_new();
3823 TCGv t2 = tcg_temp_new();
42a268c2 3824 TCGLabel *l1 = gen_new_label();
48d38ca5 3825
324d9e32
AJ
3826 gen_load_gpr(t1, rs);
3827 tcg_gen_addi_tl(t0, t1, uimm);
3828 tcg_gen_ext32s_tl(t0, t0);
48d38ca5 3829
324d9e32
AJ
3830 tcg_gen_xori_tl(t1, t1, ~uimm);
3831 tcg_gen_xori_tl(t2, t0, uimm);
3832 tcg_gen_and_tl(t1, t1, t2);
3833 tcg_temp_free(t2);
3834 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
3835 tcg_temp_free(t1);
48d38ca5
TS
3836 /* operands of same sign, result different sign */
3837 generate_exception(ctx, EXCP_OVERFLOW);
3838 gen_set_label(l1);
78723684 3839 tcg_gen_ext32s_tl(t0, t0);
324d9e32
AJ
3840 gen_store_gpr(t0, rt);
3841 tcg_temp_free(t0);
48d38ca5 3842 }
6af0bf9c
FB
3843 break;
3844 case OPC_ADDIU:
324d9e32
AJ
3845 if (rs != 0) {
3846 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3847 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
3848 } else {
3849 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
3850 }
6af0bf9c 3851 break;
d26bc211 3852#if defined(TARGET_MIPS64)
7a387fff 3853 case OPC_DADDI:
48d38ca5 3854 {
324d9e32
AJ
3855 TCGv t0 = tcg_temp_local_new();
3856 TCGv t1 = tcg_temp_new();
3857 TCGv t2 = tcg_temp_new();
42a268c2 3858 TCGLabel *l1 = gen_new_label();
48d38ca5 3859
324d9e32
AJ
3860 gen_load_gpr(t1, rs);
3861 tcg_gen_addi_tl(t0, t1, uimm);
48d38ca5 3862
324d9e32
AJ
3863 tcg_gen_xori_tl(t1, t1, ~uimm);
3864 tcg_gen_xori_tl(t2, t0, uimm);
3865 tcg_gen_and_tl(t1, t1, t2);
3866 tcg_temp_free(t2);
3867 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
3868 tcg_temp_free(t1);
48d38ca5
TS
3869 /* operands of same sign, result different sign */
3870 generate_exception(ctx, EXCP_OVERFLOW);
3871 gen_set_label(l1);
324d9e32
AJ
3872 gen_store_gpr(t0, rt);
3873 tcg_temp_free(t0);
48d38ca5 3874 }
7a387fff
TS
3875 break;
3876 case OPC_DADDIU:
324d9e32
AJ
3877 if (rs != 0) {
3878 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3879 } else {
3880 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
3881 }
7a387fff
TS
3882 break;
3883#endif
324d9e32 3884 }
324d9e32
AJ
3885}
3886
3887/* Logic with immediate operand */
d75c135e 3888static void gen_logic_imm(DisasContext *ctx, uint32_t opc,
9fa77488 3889 int rt, int rs, int16_t imm)
324d9e32
AJ
3890{
3891 target_ulong uimm;
324d9e32
AJ
3892
3893 if (rt == 0) {
3894 /* If no destination, treat it as a NOP. */
324d9e32
AJ
3895 return;
3896 }
3897 uimm = (uint16_t)imm;
3898 switch (opc) {
6af0bf9c 3899 case OPC_ANDI:
324d9e32
AJ
3900 if (likely(rs != 0))
3901 tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3902 else
3903 tcg_gen_movi_tl(cpu_gpr[rt], 0);
6af0bf9c
FB
3904 break;
3905 case OPC_ORI:
324d9e32
AJ
3906 if (rs != 0)
3907 tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3908 else
3909 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
6af0bf9c
FB
3910 break;
3911 case OPC_XORI:
324d9e32
AJ
3912 if (likely(rs != 0))
3913 tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3914 else
3915 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
6af0bf9c
FB
3916 break;
3917 case OPC_LUI:
d4ea6acd
LA
3918 if (rs != 0 && (ctx->insn_flags & ISA_MIPS32R6)) {
3919 /* OPC_AUI */
3920 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm << 16);
3921 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
d4ea6acd
LA
3922 } else {
3923 tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
d4ea6acd 3924 }
7c2c3ea3
EJ
3925 break;
3926
3927 default:
6af0bf9c 3928 break;
324d9e32 3929 }
324d9e32
AJ
3930}
3931
3932/* Set on less than with immediate operand */
d75c135e 3933static void gen_slt_imm(DisasContext *ctx, uint32_t opc,
9fa77488 3934 int rt, int rs, int16_t imm)
324d9e32
AJ
3935{
3936 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
324d9e32
AJ
3937 TCGv t0;
3938
3939 if (rt == 0) {
3940 /* If no destination, treat it as a NOP. */
324d9e32
AJ
3941 return;
3942 }
3943 t0 = tcg_temp_new();
3944 gen_load_gpr(t0, rs);
3945 switch (opc) {
3946 case OPC_SLTI:
e68dd28f 3947 tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
324d9e32
AJ
3948 break;
3949 case OPC_SLTIU:
e68dd28f 3950 tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
324d9e32
AJ
3951 break;
3952 }
324d9e32
AJ
3953 tcg_temp_free(t0);
3954}
3955
3956/* Shifts with immediate operand */
d75c135e 3957static void gen_shift_imm(DisasContext *ctx, uint32_t opc,
324d9e32
AJ
3958 int rt, int rs, int16_t imm)
3959{
3960 target_ulong uimm = ((uint16_t)imm) & 0x1f;
324d9e32
AJ
3961 TCGv t0;
3962
3963 if (rt == 0) {
3964 /* If no destination, treat it as a NOP. */
324d9e32
AJ
3965 return;
3966 }
3967
3968 t0 = tcg_temp_new();
3969 gen_load_gpr(t0, rs);
3970 switch (opc) {
6af0bf9c 3971 case OPC_SLL:
78723684 3972 tcg_gen_shli_tl(t0, t0, uimm);
324d9e32 3973 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
6af0bf9c
FB
3974 break;
3975 case OPC_SRA:
324d9e32 3976 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
6af0bf9c
FB
3977 break;
3978 case OPC_SRL:
ea63e2c3
NF
3979 if (uimm != 0) {
3980 tcg_gen_ext32u_tl(t0, t0);
3981 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
3982 } else {
3983 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
5a63bcb2 3984 }
ea63e2c3
NF
3985 break;
3986 case OPC_ROTR:
3987 if (uimm != 0) {
3988 TCGv_i32 t1 = tcg_temp_new_i32();
3989
3990 tcg_gen_trunc_tl_i32(t1, t0);
3991 tcg_gen_rotri_i32(t1, t1, uimm);
3992 tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
3993 tcg_temp_free_i32(t1);
3399e30f
NF
3994 } else {
3995 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
ea63e2c3 3996 }
7a387fff 3997 break;
d26bc211 3998#if defined(TARGET_MIPS64)
7a387fff 3999 case OPC_DSLL:
324d9e32 4000 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
7a387fff
TS
4001 break;
4002 case OPC_DSRA:
324d9e32 4003 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
7a387fff
TS
4004 break;
4005 case OPC_DSRL:
ea63e2c3 4006 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
ea63e2c3
NF
4007 break;
4008 case OPC_DROTR:
4009 if (uimm != 0) {
4010 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
3399e30f
NF
4011 } else {
4012 tcg_gen_mov_tl(cpu_gpr[rt], t0);
5a63bcb2 4013 }
7a387fff
TS
4014 break;
4015 case OPC_DSLL32:
324d9e32 4016 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
7a387fff
TS
4017 break;
4018 case OPC_DSRA32:
324d9e32 4019 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
7a387fff
TS
4020 break;
4021 case OPC_DSRL32:
ea63e2c3 4022 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
ea63e2c3
NF
4023 break;
4024 case OPC_DROTR32:
4025 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
6af0bf9c 4026 break;
7a387fff 4027#endif
6af0bf9c 4028 }
78723684 4029 tcg_temp_free(t0);
6af0bf9c
FB
4030}
4031
4032/* Arithmetic */
d75c135e
AJ
4033static void gen_arith(DisasContext *ctx, uint32_t opc,
4034 int rd, int rs, int rt)
6af0bf9c 4035{
7a387fff
TS
4036 if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
4037 && opc != OPC_DADD && opc != OPC_DSUB) {
ead9360e
TS
4038 /* If no destination, treat it as a NOP.
4039 For add & sub, we must generate the overflow exception when needed. */
460f00c4 4040 return;
185f0762 4041 }
460f00c4 4042
6af0bf9c
FB
4043 switch (opc) {
4044 case OPC_ADD:
48d38ca5 4045 {
460f00c4
AJ
4046 TCGv t0 = tcg_temp_local_new();
4047 TCGv t1 = tcg_temp_new();
4048 TCGv t2 = tcg_temp_new();
42a268c2 4049 TCGLabel *l1 = gen_new_label();
48d38ca5 4050
460f00c4
AJ
4051 gen_load_gpr(t1, rs);
4052 gen_load_gpr(t2, rt);
4053 tcg_gen_add_tl(t0, t1, t2);
4054 tcg_gen_ext32s_tl(t0, t0);
4055 tcg_gen_xor_tl(t1, t1, t2);
460f00c4 4056 tcg_gen_xor_tl(t2, t0, t2);
deb4203d 4057 tcg_gen_andc_tl(t1, t2, t1);
460f00c4
AJ
4058 tcg_temp_free(t2);
4059 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
4060 tcg_temp_free(t1);
48d38ca5
TS
4061 /* operands of same sign, result different sign */
4062 generate_exception(ctx, EXCP_OVERFLOW);
4063 gen_set_label(l1);
460f00c4
AJ
4064 gen_store_gpr(t0, rd);
4065 tcg_temp_free(t0);
48d38ca5 4066 }
6af0bf9c
FB
4067 break;
4068 case OPC_ADDU:
460f00c4
AJ
4069 if (rs != 0 && rt != 0) {
4070 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4071 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4072 } else if (rs == 0 && rt != 0) {
4073 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
4074 } else if (rs != 0 && rt == 0) {
4075 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
4076 } else {
4077 tcg_gen_movi_tl(cpu_gpr[rd], 0);
4078 }
6af0bf9c
FB
4079 break;
4080 case OPC_SUB:
48d38ca5 4081 {
460f00c4
AJ
4082 TCGv t0 = tcg_temp_local_new();
4083 TCGv t1 = tcg_temp_new();
4084 TCGv t2 = tcg_temp_new();
42a268c2 4085 TCGLabel *l1 = gen_new_label();
48d38ca5 4086
460f00c4
AJ
4087 gen_load_gpr(t1, rs);
4088 gen_load_gpr(t2, rt);
4089 tcg_gen_sub_tl(t0, t1, t2);
4090 tcg_gen_ext32s_tl(t0, t0);
4091 tcg_gen_xor_tl(t2, t1, t2);
4092 tcg_gen_xor_tl(t1, t0, t1);
4093 tcg_gen_and_tl(t1, t1, t2);
4094 tcg_temp_free(t2);
4095 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
4096 tcg_temp_free(t1);
31e3104f 4097 /* operands of different sign, first operand and result different sign */
48d38ca5
TS
4098 generate_exception(ctx, EXCP_OVERFLOW);
4099 gen_set_label(l1);
460f00c4
AJ
4100 gen_store_gpr(t0, rd);
4101 tcg_temp_free(t0);
48d38ca5 4102 }
6af0bf9c
FB
4103 break;
4104 case OPC_SUBU:
460f00c4
AJ
4105 if (rs != 0 && rt != 0) {
4106 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4107 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4108 } else if (rs == 0 && rt != 0) {
4109 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
6bb72b18 4110 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
460f00c4
AJ
4111 } else if (rs != 0 && rt == 0) {
4112 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
4113 } else {
4114 tcg_gen_movi_tl(cpu_gpr[rd], 0);
4115 }
6af0bf9c 4116 break;
d26bc211 4117#if defined(TARGET_MIPS64)
7a387fff 4118 case OPC_DADD:
48d38ca5 4119 {
460f00c4
AJ
4120 TCGv t0 = tcg_temp_local_new();
4121 TCGv t1 = tcg_temp_new();
4122 TCGv t2 = tcg_temp_new();
42a268c2 4123 TCGLabel *l1 = gen_new_label();
48d38ca5 4124
460f00c4
AJ
4125 gen_load_gpr(t1, rs);
4126 gen_load_gpr(t2, rt);
4127 tcg_gen_add_tl(t0, t1, t2);
4128 tcg_gen_xor_tl(t1, t1, t2);
460f00c4 4129 tcg_gen_xor_tl(t2, t0, t2);
deb4203d 4130 tcg_gen_andc_tl(t1, t2, t1);
460f00c4
AJ
4131 tcg_temp_free(t2);
4132 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
4133 tcg_temp_free(t1);
48d38ca5
TS
4134 /* operands of same sign, result different sign */
4135 generate_exception(ctx, EXCP_OVERFLOW);
4136 gen_set_label(l1);
460f00c4
AJ
4137 gen_store_gpr(t0, rd);
4138 tcg_temp_free(t0);
48d38ca5 4139 }
7a387fff
TS
4140 break;
4141 case OPC_DADDU:
460f00c4
AJ
4142 if (rs != 0 && rt != 0) {
4143 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4144 } else if (rs == 0 && rt != 0) {
4145 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
4146 } else if (rs != 0 && rt == 0) {
4147 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
4148 } else {
4149 tcg_gen_movi_tl(cpu_gpr[rd], 0);
4150 }
7a387fff
TS
4151 break;
4152 case OPC_DSUB:
48d38ca5 4153 {
460f00c4
AJ
4154 TCGv t0 = tcg_temp_local_new();
4155 TCGv t1 = tcg_temp_new();
4156 TCGv t2 = tcg_temp_new();
42a268c2 4157 TCGLabel *l1 = gen_new_label();
48d38ca5 4158
460f00c4
AJ
4159 gen_load_gpr(t1, rs);
4160 gen_load_gpr(t2, rt);
4161 tcg_gen_sub_tl(t0, t1, t2);
4162 tcg_gen_xor_tl(t2, t1, t2);
4163 tcg_gen_xor_tl(t1, t0, t1);
4164 tcg_gen_and_tl(t1, t1, t2);
4165 tcg_temp_free(t2);
4166 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
4167 tcg_temp_free(t1);
31e3104f 4168 /* operands of different sign, first operand and result different sign */
48d38ca5
TS
4169 generate_exception(ctx, EXCP_OVERFLOW);
4170 gen_set_label(l1);
460f00c4
AJ
4171 gen_store_gpr(t0, rd);
4172 tcg_temp_free(t0);
48d38ca5 4173 }
7a387fff
TS
4174 break;
4175 case OPC_DSUBU:
460f00c4
AJ
4176 if (rs != 0 && rt != 0) {
4177 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4178 } else if (rs == 0 && rt != 0) {
4179 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
4180 } else if (rs != 0 && rt == 0) {
4181 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
4182 } else {
4183 tcg_gen_movi_tl(cpu_gpr[rd], 0);
4184 }
7a387fff
TS
4185 break;
4186#endif
460f00c4
AJ
4187 case OPC_MUL:
4188 if (likely(rs != 0 && rt != 0)) {
4189 tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4190 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4191 } else {
4192 tcg_gen_movi_tl(cpu_gpr[rd], 0);
4193 }
6af0bf9c 4194 break;
460f00c4 4195 }
460f00c4
AJ
4196}
4197
4198/* Conditional move */
d75c135e 4199static void gen_cond_move(DisasContext *ctx, uint32_t opc,
9fa77488 4200 int rd, int rs, int rt)
460f00c4 4201{
acf12465 4202 TCGv t0, t1, t2;
460f00c4
AJ
4203
4204 if (rd == 0) {
acf12465 4205 /* If no destination, treat it as a NOP. */
460f00c4
AJ
4206 return;
4207 }
4208
acf12465
AJ
4209 t0 = tcg_temp_new();
4210 gen_load_gpr(t0, rt);
4211 t1 = tcg_const_tl(0);
4212 t2 = tcg_temp_new();
4213 gen_load_gpr(t2, rs);
460f00c4
AJ
4214 switch (opc) {
4215 case OPC_MOVN:
acf12465 4216 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
6af0bf9c 4217 break;
460f00c4 4218 case OPC_MOVZ:
acf12465 4219 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
460f00c4 4220 break;
b691d9d2
LA
4221 case OPC_SELNEZ:
4222 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, t1);
b691d9d2
LA
4223 break;
4224 case OPC_SELEQZ:
4225 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, t1);
b691d9d2 4226 break;
460f00c4 4227 }
acf12465
AJ
4228 tcg_temp_free(t2);
4229 tcg_temp_free(t1);
4230 tcg_temp_free(t0);
460f00c4
AJ
4231}
4232
4233/* Logic */
d75c135e 4234static void gen_logic(DisasContext *ctx, uint32_t opc,
9fa77488 4235 int rd, int rs, int rt)
460f00c4 4236{
460f00c4
AJ
4237 if (rd == 0) {
4238 /* If no destination, treat it as a NOP. */
460f00c4
AJ
4239 return;
4240 }
4241
4242 switch (opc) {
6af0bf9c 4243 case OPC_AND:
460f00c4
AJ
4244 if (likely(rs != 0 && rt != 0)) {
4245 tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4246 } else {
4247 tcg_gen_movi_tl(cpu_gpr[rd], 0);
4248 }
6af0bf9c
FB
4249 break;
4250 case OPC_NOR:
460f00c4
AJ
4251 if (rs != 0 && rt != 0) {
4252 tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4253 } else if (rs == 0 && rt != 0) {
4254 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
4255 } else if (rs != 0 && rt == 0) {
4256 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
4257 } else {
4258 tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
4259 }
6af0bf9c
FB
4260 break;
4261 case OPC_OR:
460f00c4
AJ
4262 if (likely(rs != 0 && rt != 0)) {
4263 tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4264 } else if (rs == 0 && rt != 0) {
4265 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
4266 } else if (rs != 0 && rt == 0) {
4267 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
4268 } else {
4269 tcg_gen_movi_tl(cpu_gpr[rd], 0);
4270 }
6af0bf9c
FB
4271 break;
4272 case OPC_XOR:
460f00c4
AJ
4273 if (likely(rs != 0 && rt != 0)) {
4274 tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4275 } else if (rs == 0 && rt != 0) {
4276 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
4277 } else if (rs != 0 && rt == 0) {
4278 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
4279 } else {
4280 tcg_gen_movi_tl(cpu_gpr[rd], 0);
4281 }
6af0bf9c 4282 break;
460f00c4 4283 }
460f00c4
AJ
4284}
4285
4286/* Set on lower than */
d75c135e 4287static void gen_slt(DisasContext *ctx, uint32_t opc,
9fa77488 4288 int rd, int rs, int rt)
460f00c4 4289{
460f00c4
AJ
4290 TCGv t0, t1;
4291
4292 if (rd == 0) {
4293 /* If no destination, treat it as a NOP. */
460f00c4
AJ
4294 return;
4295 }
4296
4297 t0 = tcg_temp_new();
4298 t1 = tcg_temp_new();
4299 gen_load_gpr(t0, rs);
4300 gen_load_gpr(t1, rt);
4301 switch (opc) {
4302 case OPC_SLT:
e68dd28f 4303 tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
6af0bf9c 4304 break;
460f00c4 4305 case OPC_SLTU:
e68dd28f 4306 tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
460f00c4
AJ
4307 break;
4308 }
460f00c4
AJ
4309 tcg_temp_free(t0);
4310 tcg_temp_free(t1);
4311}
20c4c97c 4312
460f00c4 4313/* Shifts */
d75c135e
AJ
4314static void gen_shift(DisasContext *ctx, uint32_t opc,
4315 int rd, int rs, int rt)
460f00c4 4316{
460f00c4 4317 TCGv t0, t1;
20c4c97c 4318
460f00c4
AJ
4319 if (rd == 0) {
4320 /* If no destination, treat it as a NOP.
4321 For add & sub, we must generate the overflow exception when needed. */
460f00c4
AJ
4322 return;
4323 }
4324
4325 t0 = tcg_temp_new();
4326 t1 = tcg_temp_new();
4327 gen_load_gpr(t0, rs);
4328 gen_load_gpr(t1, rt);
4329 switch (opc) {
6af0bf9c 4330 case OPC_SLLV:
78723684
TS
4331 tcg_gen_andi_tl(t0, t0, 0x1f);
4332 tcg_gen_shl_tl(t0, t1, t0);
460f00c4 4333 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
6af0bf9c
FB
4334 break;
4335 case OPC_SRAV:
78723684 4336 tcg_gen_andi_tl(t0, t0, 0x1f);
460f00c4 4337 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
6af0bf9c
FB
4338 break;
4339 case OPC_SRLV:
ea63e2c3
NF
4340 tcg_gen_ext32u_tl(t1, t1);
4341 tcg_gen_andi_tl(t0, t0, 0x1f);
4342 tcg_gen_shr_tl(t0, t1, t0);
4343 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
ea63e2c3
NF
4344 break;
4345 case OPC_ROTRV:
4346 {
4347 TCGv_i32 t2 = tcg_temp_new_i32();
4348 TCGv_i32 t3 = tcg_temp_new_i32();
4349
4350 tcg_gen_trunc_tl_i32(t2, t0);
4351 tcg_gen_trunc_tl_i32(t3, t1);
4352 tcg_gen_andi_i32(t2, t2, 0x1f);
4353 tcg_gen_rotr_i32(t2, t3, t2);
4354 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
4355 tcg_temp_free_i32(t2);
4356 tcg_temp_free_i32(t3);
5a63bcb2 4357 }
7a387fff 4358 break;
d26bc211 4359#if defined(TARGET_MIPS64)
7a387fff 4360 case OPC_DSLLV:
78723684 4361 tcg_gen_andi_tl(t0, t0, 0x3f);
460f00c4 4362 tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
7a387fff
TS
4363 break;
4364 case OPC_DSRAV:
78723684 4365 tcg_gen_andi_tl(t0, t0, 0x3f);
460f00c4 4366 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
7a387fff
TS
4367 break;
4368 case OPC_DSRLV:
ea63e2c3
NF
4369 tcg_gen_andi_tl(t0, t0, 0x3f);
4370 tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
ea63e2c3
NF
4371 break;
4372 case OPC_DROTRV:
4373 tcg_gen_andi_tl(t0, t0, 0x3f);
4374 tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
6af0bf9c 4375 break;
7a387fff 4376#endif
6af0bf9c 4377 }
78723684
TS
4378 tcg_temp_free(t0);
4379 tcg_temp_free(t1);
6af0bf9c
FB
4380}
4381
86efbfb6
FN
4382/* Copy GPR to and from TX79 HI1/LO1 register. */
4383static void gen_HILO1_tx79(DisasContext *ctx, uint32_t opc, int reg)
4384{
baa609db 4385 if (reg == 0 && (opc == MMI_OPC_MFHI1 || opc == MMI_OPC_MFLO1)) {
86efbfb6
FN
4386 /* Treat as NOP. */
4387 return;
4388 }
4389
4390 switch (opc) {
baa609db 4391 case MMI_OPC_MFHI1:
86efbfb6
FN
4392 tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[1]);
4393 break;
baa609db 4394 case MMI_OPC_MFLO1:
86efbfb6
FN
4395 tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[1]);
4396 break;
baa609db 4397 case MMI_OPC_MTHI1:
86efbfb6
FN
4398 if (reg != 0) {
4399 tcg_gen_mov_tl(cpu_HI[1], cpu_gpr[reg]);
4400 } else {
4401 tcg_gen_movi_tl(cpu_HI[1], 0);
4402 }
4403 break;
baa609db 4404 case MMI_OPC_MTLO1:
86efbfb6
FN
4405 if (reg != 0) {
4406 tcg_gen_mov_tl(cpu_LO[1], cpu_gpr[reg]);
4407 } else {
4408 tcg_gen_movi_tl(cpu_LO[1], 0);
4409 }
4410 break;
4411 default:
4412 MIPS_INVAL("mfthilo1 TX79");
4413 generate_exception_end(ctx, EXCP_RI);
4414 break;
4415 }
4416}
4417
6af0bf9c 4418/* Arithmetic on HI/LO registers */
26135ead 4419static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg)
6af0bf9c 4420{
86efbfb6 4421 if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
ead9360e 4422 /* Treat as NOP. */
a1f6684d 4423 return;
6af0bf9c 4424 }
4133498f 4425
4133498f 4426 if (acc != 0) {
86efbfb6 4427 check_dsp(ctx);
4133498f
JL
4428 }
4429
6af0bf9c
FB
4430 switch (opc) {
4431 case OPC_MFHI:
4133498f
JL
4432#if defined(TARGET_MIPS64)
4433 if (acc != 0) {
4434 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]);
4435 } else
4436#endif
4437 {
4438 tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]);
4439 }
6af0bf9c
FB
4440 break;
4441 case OPC_MFLO:
4133498f
JL
4442#if defined(TARGET_MIPS64)
4443 if (acc != 0) {
4444 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]);
4445 } else
4446#endif
4447 {
4448 tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]);
4449 }
6af0bf9c
FB
4450 break;
4451 case OPC_MTHI:
4133498f
JL
4452 if (reg != 0) {
4453#if defined(TARGET_MIPS64)
4454 if (acc != 0) {
4455 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_gpr[reg]);
4456 } else
4457#endif
4458 {
4459 tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]);
4460 }
4461 } else {
4462 tcg_gen_movi_tl(cpu_HI[acc], 0);
4463 }
6af0bf9c
FB
4464 break;
4465 case OPC_MTLO:
4133498f
JL
4466 if (reg != 0) {
4467#if defined(TARGET_MIPS64)
4468 if (acc != 0) {
4469 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_gpr[reg]);
4470 } else
4471#endif
4472 {
4473 tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]);
4474 }
4475 } else {
4476 tcg_gen_movi_tl(cpu_LO[acc], 0);
4477 }
6af0bf9c 4478 break;
6af0bf9c 4479 }
6af0bf9c
FB
4480}
4481
d4ea6acd
LA
4482static inline void gen_r6_ld(target_long addr, int reg, int memidx,
4483 TCGMemOp memop)
4484{
4485 TCGv t0 = tcg_const_tl(addr);
4486 tcg_gen_qemu_ld_tl(t0, t0, memidx, memop);
4487 gen_store_gpr(t0, reg);
4488 tcg_temp_free(t0);
4489}
4490
ab39ee45
YK
4491static inline void gen_pcrel(DisasContext *ctx, int opc, target_ulong pc,
4492 int rs)
d4ea6acd
LA
4493{
4494 target_long offset;
4495 target_long addr;
4496
ab39ee45 4497 switch (MASK_OPC_PCREL_TOP2BITS(opc)) {
d4ea6acd
LA
4498 case OPC_ADDIUPC:
4499 if (rs != 0) {
4500 offset = sextract32(ctx->opcode << 2, 0, 21);
ab39ee45 4501 addr = addr_add(ctx, pc, offset);
d4ea6acd
LA
4502 tcg_gen_movi_tl(cpu_gpr[rs], addr);
4503 }
4504 break;
4505 case R6_OPC_LWPC:
4506 offset = sextract32(ctx->opcode << 2, 0, 21);
ab39ee45 4507 addr = addr_add(ctx, pc, offset);
d4ea6acd
LA
4508 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TESL);
4509 break;
4510#if defined(TARGET_MIPS64)
4511 case OPC_LWUPC:
4512 check_mips_64(ctx);
4513 offset = sextract32(ctx->opcode << 2, 0, 21);
ab39ee45 4514 addr = addr_add(ctx, pc, offset);
d4ea6acd
LA
4515 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEUL);
4516 break;
4517#endif
4518 default:
ab39ee45 4519 switch (MASK_OPC_PCREL_TOP5BITS(opc)) {
d4ea6acd
LA
4520 case OPC_AUIPC:
4521 if (rs != 0) {
ab39ee45
YK
4522 offset = sextract32(ctx->opcode, 0, 16) << 16;
4523 addr = addr_add(ctx, pc, offset);
d4ea6acd
LA
4524 tcg_gen_movi_tl(cpu_gpr[rs], addr);
4525 }
4526 break;
4527 case OPC_ALUIPC:
4528 if (rs != 0) {
ab39ee45
YK
4529 offset = sextract32(ctx->opcode, 0, 16) << 16;
4530 addr = ~0xFFFF & addr_add(ctx, pc, offset);
d4ea6acd
LA
4531 tcg_gen_movi_tl(cpu_gpr[rs], addr);
4532 }
4533 break;
4534#if defined(TARGET_MIPS64)
4535 case R6_OPC_LDPC: /* bits 16 and 17 are part of immediate */
4536 case R6_OPC_LDPC + (1 << 16):
4537 case R6_OPC_LDPC + (2 << 16):
4538 case R6_OPC_LDPC + (3 << 16):
4539 check_mips_64(ctx);
4540 offset = sextract32(ctx->opcode << 3, 0, 21);
ab39ee45 4541 addr = addr_add(ctx, (pc & ~0x7), offset);
d4ea6acd
LA
4542 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEQ);
4543 break;
4544#endif
4545 default:
4546 MIPS_INVAL("OPC_PCREL");
9c708c7f 4547 generate_exception_end(ctx, EXCP_RI);
d4ea6acd
LA
4548 break;
4549 }
4550 break;
4551 }
4552}
4553
b42ee5e1
LA
4554static void gen_r6_muldiv(DisasContext *ctx, int opc, int rd, int rs, int rt)
4555{
b42ee5e1
LA
4556 TCGv t0, t1;
4557
4558 if (rd == 0) {
4559 /* Treat as NOP. */
b42ee5e1
LA
4560 return;
4561 }
4562
4563 t0 = tcg_temp_new();
4564 t1 = tcg_temp_new();
4565
4566 gen_load_gpr(t0, rs);
4567 gen_load_gpr(t1, rt);
4568
4569 switch (opc) {
4570 case R6_OPC_DIV:
4571 {
4572 TCGv t2 = tcg_temp_new();
4573 TCGv t3 = tcg_temp_new();
4574 tcg_gen_ext32s_tl(t0, t0);
4575 tcg_gen_ext32s_tl(t1, t1);
4576 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
4577 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
4578 tcg_gen_and_tl(t2, t2, t3);
4579 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4580 tcg_gen_or_tl(t2, t2, t3);
4581 tcg_gen_movi_tl(t3, 0);
4582 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4583 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
4584 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4585 tcg_temp_free(t3);
4586 tcg_temp_free(t2);
4587 }
b42ee5e1
LA
4588 break;
4589 case R6_OPC_MOD:
4590 {
4591 TCGv t2 = tcg_temp_new();
4592 TCGv t3 = tcg_temp_new();
4593 tcg_gen_ext32s_tl(t0, t0);
4594 tcg_gen_ext32s_tl(t1, t1);
4595 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
4596 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
4597 tcg_gen_and_tl(t2, t2, t3);
4598 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4599 tcg_gen_or_tl(t2, t2, t3);
4600 tcg_gen_movi_tl(t3, 0);
4601 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4602 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
4603 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4604 tcg_temp_free(t3);
4605 tcg_temp_free(t2);
4606 }
b42ee5e1
LA
4607 break;
4608 case R6_OPC_DIVU:
4609 {
4610 TCGv t2 = tcg_const_tl(0);
4611 TCGv t3 = tcg_const_tl(1);
4612 tcg_gen_ext32u_tl(t0, t0);
4613 tcg_gen_ext32u_tl(t1, t1);
4614 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4615 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
4616 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4617 tcg_temp_free(t3);
4618 tcg_temp_free(t2);
4619 }
b42ee5e1
LA
4620 break;
4621 case R6_OPC_MODU:
4622 {
4623 TCGv t2 = tcg_const_tl(0);
4624 TCGv t3 = tcg_const_tl(1);
4625 tcg_gen_ext32u_tl(t0, t0);
4626 tcg_gen_ext32u_tl(t1, t1);
4627 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4628 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
4629 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4630 tcg_temp_free(t3);
4631 tcg_temp_free(t2);
4632 }
b42ee5e1
LA
4633 break;
4634 case R6_OPC_MUL:
4635 {
4636 TCGv_i32 t2 = tcg_temp_new_i32();
4637 TCGv_i32 t3 = tcg_temp_new_i32();
4638 tcg_gen_trunc_tl_i32(t2, t0);
4639 tcg_gen_trunc_tl_i32(t3, t1);
4640 tcg_gen_mul_i32(t2, t2, t3);
4641 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
4642 tcg_temp_free_i32(t2);
4643 tcg_temp_free_i32(t3);
4644 }
b42ee5e1
LA
4645 break;
4646 case R6_OPC_MUH:
4647 {
4648 TCGv_i32 t2 = tcg_temp_new_i32();
4649 TCGv_i32 t3 = tcg_temp_new_i32();
4650 tcg_gen_trunc_tl_i32(t2, t0);
4651 tcg_gen_trunc_tl_i32(t3, t1);
4652 tcg_gen_muls2_i32(t2, t3, t2, t3);
4653 tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
4654 tcg_temp_free_i32(t2);
4655 tcg_temp_free_i32(t3);
4656 }
b42ee5e1
LA
4657 break;
4658 case R6_OPC_MULU:
4659 {
4660 TCGv_i32 t2 = tcg_temp_new_i32();
4661 TCGv_i32 t3 = tcg_temp_new_i32();
4662 tcg_gen_trunc_tl_i32(t2, t0);
4663 tcg_gen_trunc_tl_i32(t3, t1);
4664 tcg_gen_mul_i32(t2, t2, t3);
4665 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
4666 tcg_temp_free_i32(t2);
4667 tcg_temp_free_i32(t3);
4668 }
b42ee5e1
LA
4669 break;
4670 case R6_OPC_MUHU:
4671 {
4672 TCGv_i32 t2 = tcg_temp_new_i32();
4673 TCGv_i32 t3 = tcg_temp_new_i32();
4674 tcg_gen_trunc_tl_i32(t2, t0);
4675 tcg_gen_trunc_tl_i32(t3, t1);
4676 tcg_gen_mulu2_i32(t2, t3, t2, t3);
4677 tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
4678 tcg_temp_free_i32(t2);
4679 tcg_temp_free_i32(t3);
4680 }
b42ee5e1
LA
4681 break;
4682#if defined(TARGET_MIPS64)
4683 case R6_OPC_DDIV:
4684 {
4685 TCGv t2 = tcg_temp_new();
4686 TCGv t3 = tcg_temp_new();
4687 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
4688 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
4689 tcg_gen_and_tl(t2, t2, t3);
4690 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4691 tcg_gen_or_tl(t2, t2, t3);
4692 tcg_gen_movi_tl(t3, 0);
4693 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4694 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
4695 tcg_temp_free(t3);
4696 tcg_temp_free(t2);
4697 }
b42ee5e1
LA
4698 break;
4699 case R6_OPC_DMOD:
4700 {
4701 TCGv t2 = tcg_temp_new();
4702 TCGv t3 = tcg_temp_new();
4703 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
4704 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
4705 tcg_gen_and_tl(t2, t2, t3);
4706 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4707 tcg_gen_or_tl(t2, t2, t3);
4708 tcg_gen_movi_tl(t3, 0);
4709 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4710 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
4711 tcg_temp_free(t3);
4712 tcg_temp_free(t2);
4713 }
b42ee5e1
LA
4714 break;
4715 case R6_OPC_DDIVU:
4716 {
4717 TCGv t2 = tcg_const_tl(0);
4718 TCGv t3 = tcg_const_tl(1);
4719 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4720 tcg_gen_divu_i64(cpu_gpr[rd], t0, t1);
4721 tcg_temp_free(t3);
4722 tcg_temp_free(t2);
4723 }
b42ee5e1
LA
4724 break;
4725 case R6_OPC_DMODU:
4726 {
4727 TCGv t2 = tcg_const_tl(0);
4728 TCGv t3 = tcg_const_tl(1);
4729 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4730 tcg_gen_remu_i64(cpu_gpr[rd], t0, t1);
4731 tcg_temp_free(t3);
4732 tcg_temp_free(t2);
4733 }
b42ee5e1
LA
4734 break;
4735 case R6_OPC_DMUL:
4736 tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
b42ee5e1
LA
4737 break;
4738 case R6_OPC_DMUH:
4739 {
4740 TCGv t2 = tcg_temp_new();
4741 tcg_gen_muls2_i64(t2, cpu_gpr[rd], t0, t1);
4742 tcg_temp_free(t2);
4743 }
b42ee5e1
LA
4744 break;
4745 case R6_OPC_DMULU:
4746 tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
b42ee5e1
LA
4747 break;
4748 case R6_OPC_DMUHU:
4749 {
4750 TCGv t2 = tcg_temp_new();
4751 tcg_gen_mulu2_i64(t2, cpu_gpr[rd], t0, t1);
4752 tcg_temp_free(t2);
4753 }
b42ee5e1
LA
4754 break;
4755#endif
4756 default:
9d68ac14 4757 MIPS_INVAL("r6 mul/div");
9c708c7f 4758 generate_exception_end(ctx, EXCP_RI);
b42ee5e1
LA
4759 goto out;
4760 }
b42ee5e1
LA
4761 out:
4762 tcg_temp_free(t0);
4763 tcg_temp_free(t1);
4764}
4765
c42171c3
FN
4766static void gen_div1_tx79(DisasContext *ctx, uint32_t opc, int rs, int rt)
4767{
4768 TCGv t0, t1;
4769
4770 t0 = tcg_temp_new();
4771 t1 = tcg_temp_new();
4772
4773 gen_load_gpr(t0, rs);
4774 gen_load_gpr(t1, rt);
4775
4776 switch (opc) {
baa609db 4777 case MMI_OPC_DIV1:
c42171c3
FN
4778 {
4779 TCGv t2 = tcg_temp_new();
4780 TCGv t3 = tcg_temp_new();
4781 tcg_gen_ext32s_tl(t0, t0);
4782 tcg_gen_ext32s_tl(t1, t1);
4783 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
4784 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
4785 tcg_gen_and_tl(t2, t2, t3);
4786 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4787 tcg_gen_or_tl(t2, t2, t3);
4788 tcg_gen_movi_tl(t3, 0);
4789 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4790 tcg_gen_div_tl(cpu_LO[1], t0, t1);
4791 tcg_gen_rem_tl(cpu_HI[1], t0, t1);
4792 tcg_gen_ext32s_tl(cpu_LO[1], cpu_LO[1]);
4793 tcg_gen_ext32s_tl(cpu_HI[1], cpu_HI[1]);
4794 tcg_temp_free(t3);
4795 tcg_temp_free(t2);
4796 }
4797 break;
baa609db 4798 case MMI_OPC_DIVU1:
c42171c3
FN
4799 {
4800 TCGv t2 = tcg_const_tl(0);
4801 TCGv t3 = tcg_const_tl(1);
4802 tcg_gen_ext32u_tl(t0, t0);
4803 tcg_gen_ext32u_tl(t1, t1);
4804 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4805 tcg_gen_divu_tl(cpu_LO[1], t0, t1);
4806 tcg_gen_remu_tl(cpu_HI[1], t0, t1);
4807 tcg_gen_ext32s_tl(cpu_LO[1], cpu_LO[1]);
4808 tcg_gen_ext32s_tl(cpu_HI[1], cpu_HI[1]);
4809 tcg_temp_free(t3);
4810 tcg_temp_free(t2);
4811 }
4812 break;
4813 default:
4814 MIPS_INVAL("div1 TX79");
4815 generate_exception_end(ctx, EXCP_RI);
4816 goto out;
4817 }
4818 out:
4819 tcg_temp_free(t0);
4820 tcg_temp_free(t1);
4821}
4822
26135ead
RS
4823static void gen_muldiv(DisasContext *ctx, uint32_t opc,
4824 int acc, int rs, int rt)
6af0bf9c 4825{
d45f89f4
AJ
4826 TCGv t0, t1;
4827
51127181
AJ
4828 t0 = tcg_temp_new();
4829 t1 = tcg_temp_new();
6af0bf9c 4830
78723684
TS
4831 gen_load_gpr(t0, rs);
4832 gen_load_gpr(t1, rt);
51127181 4833
26135ead 4834 if (acc != 0) {
c42171c3 4835 check_dsp(ctx);
26135ead
RS
4836 }
4837
6af0bf9c
FB
4838 switch (opc) {
4839 case OPC_DIV:
48d38ca5 4840 {
51127181
AJ
4841 TCGv t2 = tcg_temp_new();
4842 TCGv t3 = tcg_temp_new();
d45f89f4
AJ
4843 tcg_gen_ext32s_tl(t0, t0);
4844 tcg_gen_ext32s_tl(t1, t1);
51127181
AJ
4845 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
4846 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
4847 tcg_gen_and_tl(t2, t2, t3);
4848 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4849 tcg_gen_or_tl(t2, t2, t3);
4850 tcg_gen_movi_tl(t3, 0);
4851 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
26135ead
RS
4852 tcg_gen_div_tl(cpu_LO[acc], t0, t1);
4853 tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
4854 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
4855 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
51127181
AJ
4856 tcg_temp_free(t3);
4857 tcg_temp_free(t2);
48d38ca5 4858 }
6af0bf9c
FB
4859 break;
4860 case OPC_DIVU:
48d38ca5 4861 {
51127181
AJ
4862 TCGv t2 = tcg_const_tl(0);
4863 TCGv t3 = tcg_const_tl(1);
0c0ed03b
AJ
4864 tcg_gen_ext32u_tl(t0, t0);
4865 tcg_gen_ext32u_tl(t1, t1);
51127181 4866 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
26135ead
RS
4867 tcg_gen_divu_tl(cpu_LO[acc], t0, t1);
4868 tcg_gen_remu_tl(cpu_HI[acc], t0, t1);
4869 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
4870 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
51127181
AJ
4871 tcg_temp_free(t3);
4872 tcg_temp_free(t2);
48d38ca5 4873 }
6af0bf9c
FB
4874 break;
4875 case OPC_MULT:
214c465f 4876 {
ce1dd5d1
RH
4877 TCGv_i32 t2 = tcg_temp_new_i32();
4878 TCGv_i32 t3 = tcg_temp_new_i32();
ce1dd5d1
RH
4879 tcg_gen_trunc_tl_i32(t2, t0);
4880 tcg_gen_trunc_tl_i32(t3, t1);
4881 tcg_gen_muls2_i32(t2, t3, t2, t3);
4882 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
4883 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
4884 tcg_temp_free_i32(t2);
4885 tcg_temp_free_i32(t3);
214c465f 4886 }
6af0bf9c
FB
4887 break;
4888 case OPC_MULTU:
214c465f 4889 {
ce1dd5d1
RH
4890 TCGv_i32 t2 = tcg_temp_new_i32();
4891 TCGv_i32 t3 = tcg_temp_new_i32();
ce1dd5d1
RH
4892 tcg_gen_trunc_tl_i32(t2, t0);
4893 tcg_gen_trunc_tl_i32(t3, t1);
4894 tcg_gen_mulu2_i32(t2, t3, t2, t3);
4895 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
4896 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
4897 tcg_temp_free_i32(t2);
4898 tcg_temp_free_i32(t3);
214c465f 4899 }
6af0bf9c 4900 break;
d26bc211 4901#if defined(TARGET_MIPS64)
7a387fff 4902 case OPC_DDIV:
48d38ca5 4903 {
51127181
AJ
4904 TCGv t2 = tcg_temp_new();
4905 TCGv t3 = tcg_temp_new();
4906 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
4907 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
4908 tcg_gen_and_tl(t2, t2, t3);
4909 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4910 tcg_gen_or_tl(t2, t2, t3);
4911 tcg_gen_movi_tl(t3, 0);
4912 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
26135ead
RS
4913 tcg_gen_div_tl(cpu_LO[acc], t0, t1);
4914 tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
51127181
AJ
4915 tcg_temp_free(t3);
4916 tcg_temp_free(t2);
48d38ca5 4917 }
7a387fff
TS
4918 break;
4919 case OPC_DDIVU:
48d38ca5 4920 {
51127181
AJ
4921 TCGv t2 = tcg_const_tl(0);
4922 TCGv t3 = tcg_const_tl(1);
4923 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
26135ead
RS
4924 tcg_gen_divu_i64(cpu_LO[acc], t0, t1);
4925 tcg_gen_remu_i64(cpu_HI[acc], t0, t1);
51127181
AJ
4926 tcg_temp_free(t3);
4927 tcg_temp_free(t2);
48d38ca5 4928 }
7a387fff
TS
4929 break;
4930 case OPC_DMULT:
26135ead 4931 tcg_gen_muls2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
7a387fff
TS
4932 break;
4933 case OPC_DMULTU:
26135ead 4934 tcg_gen_mulu2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
7a387fff
TS
4935 break;
4936#endif
6af0bf9c 4937 case OPC_MADD:
214c465f 4938 {
d45f89f4
AJ
4939 TCGv_i64 t2 = tcg_temp_new_i64();
4940 TCGv_i64 t3 = tcg_temp_new_i64();
4941
4942 tcg_gen_ext_tl_i64(t2, t0);
4943 tcg_gen_ext_tl_i64(t3, t1);
4944 tcg_gen_mul_i64(t2, t2, t3);
4133498f 4945 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
d45f89f4
AJ
4946 tcg_gen_add_i64(t2, t2, t3);
4947 tcg_temp_free_i64(t3);
71f303cd
RH
4948 gen_move_low32(cpu_LO[acc], t2);
4949 gen_move_high32(cpu_HI[acc], t2);
d45f89f4 4950 tcg_temp_free_i64(t2);
214c465f 4951 }
6af0bf9c
FB
4952 break;
4953 case OPC_MADDU:
4133498f 4954 {
d45f89f4
AJ
4955 TCGv_i64 t2 = tcg_temp_new_i64();
4956 TCGv_i64 t3 = tcg_temp_new_i64();
214c465f 4957
78723684
TS
4958 tcg_gen_ext32u_tl(t0, t0);
4959 tcg_gen_ext32u_tl(t1, t1);
d45f89f4
AJ
4960 tcg_gen_extu_tl_i64(t2, t0);
4961 tcg_gen_extu_tl_i64(t3, t1);
4962 tcg_gen_mul_i64(t2, t2, t3);
4133498f 4963 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
d45f89f4
AJ
4964 tcg_gen_add_i64(t2, t2, t3);
4965 tcg_temp_free_i64(t3);
71f303cd
RH
4966 gen_move_low32(cpu_LO[acc], t2);
4967 gen_move_high32(cpu_HI[acc], t2);
d45f89f4 4968 tcg_temp_free_i64(t2);
214c465f 4969 }
6af0bf9c
FB
4970 break;
4971 case OPC_MSUB:
214c465f 4972 {
d45f89f4
AJ
4973 TCGv_i64 t2 = tcg_temp_new_i64();
4974 TCGv_i64 t3 = tcg_temp_new_i64();
4975
4976 tcg_gen_ext_tl_i64(t2, t0);
4977 tcg_gen_ext_tl_i64(t3, t1);
4978 tcg_gen_mul_i64(t2, t2, t3);
4133498f 4979 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
98070ce0 4980 tcg_gen_sub_i64(t2, t3, t2);
d45f89f4 4981 tcg_temp_free_i64(t3);
71f303cd
RH
4982 gen_move_low32(cpu_LO[acc], t2);
4983 gen_move_high32(cpu_HI[acc], t2);
d45f89f4 4984 tcg_temp_free_i64(t2);
214c465f 4985 }
6af0bf9c
FB
4986 break;
4987 case OPC_MSUBU:
214c465f 4988 {
d45f89f4
AJ
4989 TCGv_i64 t2 = tcg_temp_new_i64();
4990 TCGv_i64 t3 = tcg_temp_new_i64();
214c465f 4991
78723684
TS
4992 tcg_gen_ext32u_tl(t0, t0);
4993 tcg_gen_ext32u_tl(t1, t1);
d45f89f4
AJ
4994 tcg_gen_extu_tl_i64(t2, t0);
4995 tcg_gen_extu_tl_i64(t3, t1);
4996 tcg_gen_mul_i64(t2, t2, t3);
4133498f 4997 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
98070ce0 4998 tcg_gen_sub_i64(t2, t3, t2);
d45f89f4 4999 tcg_temp_free_i64(t3);
71f303cd
RH
5000 gen_move_low32(cpu_LO[acc], t2);
5001 gen_move_high32(cpu_HI[acc], t2);
d45f89f4 5002 tcg_temp_free_i64(t2);
214c465f 5003 }
6af0bf9c
FB
5004 break;
5005 default:
9d68ac14 5006 MIPS_INVAL("mul/div");
9c708c7f 5007 generate_exception_end(ctx, EXCP_RI);
78723684 5008 goto out;
6af0bf9c 5009 }
78723684
TS
5010 out:
5011 tcg_temp_free(t0);
5012 tcg_temp_free(t1);
6af0bf9c
FB
5013}
5014
21e8e8b2
FN
5015/*
5016 * These MULT and MULTU instructions implemented in for example the
5017 * Toshiba/Sony R5900 and the Toshiba TX19, TX39 and TX79 core
5018 * architectures are special three-operand variants with the syntax
5019 *
06de726b 5020 * MULT[U][1] rd, rs, rt
21e8e8b2
FN
5021 *
5022 * such that
5023 *
5024 * (rd, LO, HI) <- rs * rt
5025 *
5026 * where the low-order 32-bits of the result is placed into both the
5027 * GPR rd and the special register LO. The high-order 32-bits of the
5028 * result is placed into the special register HI.
5029 *
5030 * If the GPR rd is omitted in assembly language, it is taken to be 0,
5031 * which is the zero register that always reads as 0.
5032 */
5033static void gen_mul_txx9(DisasContext *ctx, uint32_t opc,
5034 int rd, int rs, int rt)
5035{
5036 TCGv t0 = tcg_temp_new();
5037 TCGv t1 = tcg_temp_new();
5038 int acc = 0;
5039
5040 gen_load_gpr(t0, rs);
5041 gen_load_gpr(t1, rt);
5042
5043 switch (opc) {
baa609db 5044 case MMI_OPC_MULT1:
06de726b
FN
5045 acc = 1;
5046 /* Fall through */
21e8e8b2
FN
5047 case OPC_MULT:
5048 {
5049 TCGv_i32 t2 = tcg_temp_new_i32();
5050 TCGv_i32 t3 = tcg_temp_new_i32();
5051 tcg_gen_trunc_tl_i32(t2, t0);
5052 tcg_gen_trunc_tl_i32(t3, t1);
5053 tcg_gen_muls2_i32(t2, t3, t2, t3);
5054 if (rd) {
5055 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
5056 }
5057 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
5058 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
5059 tcg_temp_free_i32(t2);
5060 tcg_temp_free_i32(t3);
5061 }
5062 break;
baa609db 5063 case MMI_OPC_MULTU1:
06de726b
FN
5064 acc = 1;
5065 /* Fall through */
21e8e8b2
FN
5066 case OPC_MULTU:
5067 {
5068 TCGv_i32 t2 = tcg_temp_new_i32();
5069 TCGv_i32 t3 = tcg_temp_new_i32();
5070 tcg_gen_trunc_tl_i32(t2, t0);
5071 tcg_gen_trunc_tl_i32(t3, t1);
5072 tcg_gen_mulu2_i32(t2, t3, t2, t3);
5073 if (rd) {
5074 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
5075 }
5076 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
5077 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
5078 tcg_temp_free_i32(t2);
5079 tcg_temp_free_i32(t3);
5080 }
5081 break;
5082 default:
5083 MIPS_INVAL("mul TXx9");
5084 generate_exception_end(ctx, EXCP_RI);
5085 goto out;
5086 }
5087
5088 out:
5089 tcg_temp_free(t0);
5090 tcg_temp_free(t1);
5091}
5092
e9c71dd1
TS
5093static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
5094 int rd, int rs, int rt)
5095{
f157bfe1
AJ
5096 TCGv t0 = tcg_temp_new();
5097 TCGv t1 = tcg_temp_new();
e9c71dd1 5098
6c5c1e20
TS
5099 gen_load_gpr(t0, rs);
5100 gen_load_gpr(t1, rt);
e9c71dd1
TS
5101
5102 switch (opc) {
5103 case OPC_VR54XX_MULS:
895c2d04 5104 gen_helper_muls(t0, cpu_env, t0, t1);
6958549d 5105 break;
e9c71dd1 5106 case OPC_VR54XX_MULSU:
895c2d04 5107 gen_helper_mulsu(t0, cpu_env, t0, t1);
6958549d 5108 break;
e9c71dd1 5109 case OPC_VR54XX_MACC:
895c2d04 5110 gen_helper_macc(t0, cpu_env, t0, t1);
6958549d 5111 break;
e9c71dd1 5112 case OPC_VR54XX_MACCU:
895c2d04 5113 gen_helper_maccu(t0, cpu_env, t0, t1);
6958549d 5114 break;
e9c71dd1 5115 case OPC_VR54XX_MSAC:
895c2d04 5116 gen_helper_msac(t0, cpu_env, t0, t1);
6958549d 5117 break;
e9c71dd1 5118 case OPC_VR54XX_MSACU:
895c2d04 5119 gen_helper_msacu(t0, cpu_env, t0, t1);
6958549d 5120 break;
e9c71dd1 5121 case OPC_VR54XX_MULHI:
895c2d04 5122 gen_helper_mulhi(t0, cpu_env, t0, t1);
6958549d 5123 break;
e9c71dd1 5124 case OPC_VR54XX_MULHIU:
895c2d04 5125 gen_helper_mulhiu(t0, cpu_env, t0, t1);
6958549d 5126 break;
e9c71dd1 5127 case OPC_VR54XX_MULSHI:
895c2d04 5128 gen_helper_mulshi(t0, cpu_env, t0, t1);
6958549d 5129 break;
e9c71dd1 5130 case OPC_VR54XX_MULSHIU:
895c2d04 5131 gen_helper_mulshiu(t0, cpu_env, t0, t1);
6958549d 5132 break;
e9c71dd1 5133 case OPC_VR54XX_MACCHI:
895c2d04 5134 gen_helper_macchi(t0, cpu_env, t0, t1);
6958549d 5135 break;
e9c71dd1 5136 case OPC_VR54XX_MACCHIU:
895c2d04 5137 gen_helper_macchiu(t0, cpu_env, t0, t1);
6958549d 5138 break;
e9c71dd1 5139 case OPC_VR54XX_MSACHI:
895c2d04 5140 gen_helper_msachi(t0, cpu_env, t0, t1);
6958549d 5141 break;
e9c71dd1 5142 case OPC_VR54XX_MSACHIU:
895c2d04 5143 gen_helper_msachiu(t0, cpu_env, t0, t1);
6958549d 5144 break;
e9c71dd1
TS
5145 default:
5146 MIPS_INVAL("mul vr54xx");
9c708c7f 5147 generate_exception_end(ctx, EXCP_RI);
6c5c1e20 5148 goto out;
e9c71dd1 5149 }
6c5c1e20 5150 gen_store_gpr(t0, rd);
6c5c1e20
TS
5151
5152 out:
5153 tcg_temp_free(t0);
5154 tcg_temp_free(t1);
e9c71dd1
TS
5155}
5156
7a387fff 5157static void gen_cl (DisasContext *ctx, uint32_t opc,
6af0bf9c
FB
5158 int rd, int rs)
5159{
20e1fb52 5160 TCGv t0;
6c5c1e20 5161
6af0bf9c 5162 if (rd == 0) {
ead9360e 5163 /* Treat as NOP. */
20e1fb52 5164 return;
6af0bf9c 5165 }
1a0196c5 5166 t0 = cpu_gpr[rd];
6c5c1e20 5167 gen_load_gpr(t0, rs);
1a0196c5 5168
6af0bf9c
FB
5169 switch (opc) {
5170 case OPC_CLO:
4267d3e6 5171 case R6_OPC_CLO:
1a0196c5
RH
5172#if defined(TARGET_MIPS64)
5173 case OPC_DCLO:
5174 case R6_OPC_DCLO:
5175#endif
5176 tcg_gen_not_tl(t0, t0);
6af0bf9c 5177 break;
1a0196c5
RH
5178 }
5179
5180 switch (opc) {
5181 case OPC_CLO:
5182 case R6_OPC_CLO:
6af0bf9c 5183 case OPC_CLZ:
4267d3e6 5184 case R6_OPC_CLZ:
1a0196c5
RH
5185 tcg_gen_ext32u_tl(t0, t0);
5186 tcg_gen_clzi_tl(t0, t0, TARGET_LONG_BITS);
5187 tcg_gen_subi_tl(t0, t0, TARGET_LONG_BITS - 32);
6af0bf9c 5188 break;
d26bc211 5189#if defined(TARGET_MIPS64)
7a387fff 5190 case OPC_DCLO:
4267d3e6 5191 case R6_OPC_DCLO:
7a387fff 5192 case OPC_DCLZ:
4267d3e6 5193 case R6_OPC_DCLZ:
1a0196c5 5194 tcg_gen_clzi_i64(t0, t0, 64);
7a387fff
TS
5195 break;
5196#endif
6af0bf9c 5197 }
6af0bf9c
FB
5198}
5199
161f85e6 5200/* Godson integer instructions */
bd277fa1
RH
5201static void gen_loongson_integer(DisasContext *ctx, uint32_t opc,
5202 int rd, int rs, int rt)
161f85e6 5203{
161f85e6
AJ
5204 TCGv t0, t1;
5205
5206 if (rd == 0) {
5207 /* Treat as NOP. */
161f85e6
AJ
5208 return;
5209 }
5210
5211 switch (opc) {
5212 case OPC_MULT_G_2E:
5213 case OPC_MULT_G_2F:
5214 case OPC_MULTU_G_2E:
5215 case OPC_MULTU_G_2F:
5216#if defined(TARGET_MIPS64)
5217 case OPC_DMULT_G_2E:
5218 case OPC_DMULT_G_2F:
5219 case OPC_DMULTU_G_2E:
5220 case OPC_DMULTU_G_2F:
5221#endif
5222 t0 = tcg_temp_new();
5223 t1 = tcg_temp_new();
5224 break;
5225 default:
5226 t0 = tcg_temp_local_new();
5227 t1 = tcg_temp_local_new();
5228 break;
5229 }
5230
5231 gen_load_gpr(t0, rs);
5232 gen_load_gpr(t1, rt);
5233
5234 switch (opc) {
5235 case OPC_MULT_G_2E:
5236 case OPC_MULT_G_2F:
5237 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
5238 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
161f85e6
AJ
5239 break;
5240 case OPC_MULTU_G_2E:
5241 case OPC_MULTU_G_2F:
5242 tcg_gen_ext32u_tl(t0, t0);
5243 tcg_gen_ext32u_tl(t1, t1);
5244 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
5245 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
161f85e6
AJ
5246 break;
5247 case OPC_DIV_G_2E:
5248 case OPC_DIV_G_2F:
5249 {
42a268c2
RH
5250 TCGLabel *l1 = gen_new_label();
5251 TCGLabel *l2 = gen_new_label();
5252 TCGLabel *l3 = gen_new_label();
161f85e6
AJ
5253 tcg_gen_ext32s_tl(t0, t0);
5254 tcg_gen_ext32s_tl(t1, t1);
5255 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5256 tcg_gen_movi_tl(cpu_gpr[rd], 0);
5257 tcg_gen_br(l3);
5258 gen_set_label(l1);
5259 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
5260 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
5261 tcg_gen_mov_tl(cpu_gpr[rd], t0);
5262 tcg_gen_br(l3);
5263 gen_set_label(l2);
5264 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
5265 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5266 gen_set_label(l3);
5267 }
161f85e6
AJ
5268 break;
5269 case OPC_DIVU_G_2E:
5270 case OPC_DIVU_G_2F:
5271 {
42a268c2
RH
5272 TCGLabel *l1 = gen_new_label();
5273 TCGLabel *l2 = gen_new_label();
161f85e6
AJ
5274 tcg_gen_ext32u_tl(t0, t0);
5275 tcg_gen_ext32u_tl(t1, t1);
5276 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5277 tcg_gen_movi_tl(cpu_gpr[rd], 0);
5278 tcg_gen_br(l2);
5279 gen_set_label(l1);
5280 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
5281 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5282 gen_set_label(l2);
5283 }
161f85e6
AJ
5284 break;
5285 case OPC_MOD_G_2E:
5286 case OPC_MOD_G_2F:
5287 {
42a268c2
RH
5288 TCGLabel *l1 = gen_new_label();
5289 TCGLabel *l2 = gen_new_label();
5290 TCGLabel *l3 = gen_new_label();
161f85e6
AJ
5291 tcg_gen_ext32u_tl(t0, t0);
5292 tcg_gen_ext32u_tl(t1, t1);
5293 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
5294 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
5295 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
5296 gen_set_label(l1);
5297 tcg_gen_movi_tl(cpu_gpr[rd], 0);
5298 tcg_gen_br(l3);
5299 gen_set_label(l2);
5300 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
5301 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5302 gen_set_label(l3);
5303 }
161f85e6
AJ
5304 break;
5305 case OPC_MODU_G_2E:
5306 case OPC_MODU_G_2F:
5307 {
42a268c2
RH
5308 TCGLabel *l1 = gen_new_label();
5309 TCGLabel *l2 = gen_new_label();
161f85e6
AJ
5310 tcg_gen_ext32u_tl(t0, t0);
5311 tcg_gen_ext32u_tl(t1, t1);
5312 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5313 tcg_gen_movi_tl(cpu_gpr[rd], 0);
5314 tcg_gen_br(l2);
5315 gen_set_label(l1);
5316 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
5317 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5318 gen_set_label(l2);
5319 }
161f85e6
AJ
5320 break;
5321#if defined(TARGET_MIPS64)
5322 case OPC_DMULT_G_2E:
5323 case OPC_DMULT_G_2F:
5324 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
161f85e6
AJ
5325 break;
5326 case OPC_DMULTU_G_2E:
5327 case OPC_DMULTU_G_2F:
5328 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
161f85e6
AJ
5329 break;
5330 case OPC_DDIV_G_2E:
5331 case OPC_DDIV_G_2F:
5332 {
42a268c2
RH
5333 TCGLabel *l1 = gen_new_label();
5334 TCGLabel *l2 = gen_new_label();
5335 TCGLabel *l3 = gen_new_label();
161f85e6
AJ
5336 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5337 tcg_gen_movi_tl(cpu_gpr[rd], 0);
5338 tcg_gen_br(l3);
5339 gen_set_label(l1);
5340 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
5341 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
5342 tcg_gen_mov_tl(cpu_gpr[rd], t0);
5343 tcg_gen_br(l3);
5344 gen_set_label(l2);
5345 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
5346 gen_set_label(l3);
5347 }
161f85e6
AJ
5348 break;
5349 case OPC_DDIVU_G_2E:
5350 case OPC_DDIVU_G_2F:
5351 {
42a268c2
RH
5352 TCGLabel *l1 = gen_new_label();
5353 TCGLabel *l2 = gen_new_label();
161f85e6
AJ
5354 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5355 tcg_gen_movi_tl(cpu_gpr[rd], 0);
5356 tcg_gen_br(l2);
5357 gen_set_label(l1);
5358 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
5359 gen_set_label(l2);
5360 }
161f85e6
AJ
5361 break;
5362 case OPC_DMOD_G_2E:
5363 case OPC_DMOD_G_2F:
5364 {
42a268c2
RH
5365 TCGLabel *l1 = gen_new_label();
5366 TCGLabel *l2 = gen_new_label();
5367 TCGLabel *l3 = gen_new_label();
161f85e6
AJ
5368 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
5369 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
5370 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
5371 gen_set_label(l1);
5372 tcg_gen_movi_tl(cpu_gpr[rd], 0);
5373 tcg_gen_br(l3);
5374 gen_set_label(l2);
5375 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
5376 gen_set_label(l3);
5377 }
161f85e6
AJ
5378 break;
5379 case OPC_DMODU_G_2E:
5380 case OPC_DMODU_G_2F:
5381 {
42a268c2
RH
5382 TCGLabel *l1 = gen_new_label();
5383 TCGLabel *l2 = gen_new_label();
161f85e6
AJ
5384 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5385 tcg_gen_movi_tl(cpu_gpr[rd], 0);
5386 tcg_gen_br(l2);
5387 gen_set_label(l1);
5388 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
5389 gen_set_label(l2);
5390 }
161f85e6
AJ
5391 break;
5392#endif
5393 }
5394
161f85e6
AJ
5395 tcg_temp_free(t0);
5396 tcg_temp_free(t1);
5397}
5398
bd277fa1
RH
5399/* Loongson multimedia instructions */
5400static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt)
5401{
bd277fa1
RH
5402 uint32_t opc, shift_max;
5403 TCGv_i64 t0, t1;
5404
5405 opc = MASK_LMI(ctx->opcode);
5406 switch (opc) {
5407 case OPC_ADD_CP2:
5408 case OPC_SUB_CP2:
5409 case OPC_DADD_CP2:
5410 case OPC_DSUB_CP2:
5411 t0 = tcg_temp_local_new_i64();
5412 t1 = tcg_temp_local_new_i64();
5413 break;
5414 default:
5415 t0 = tcg_temp_new_i64();
5416 t1 = tcg_temp_new_i64();
5417 break;
5418 }
5419
b5a587b6 5420 check_cp1_enabled(ctx);
bd277fa1
RH
5421 gen_load_fpr64(ctx, t0, rs);
5422 gen_load_fpr64(ctx, t1, rt);
5423
5424#define LMI_HELPER(UP, LO) \
9d68ac14 5425 case OPC_##UP: gen_helper_##LO(t0, t0, t1); break
bd277fa1 5426#define LMI_HELPER_1(UP, LO) \
9d68ac14 5427 case OPC_##UP: gen_helper_##LO(t0, t0); break
bd277fa1 5428#define LMI_DIRECT(UP, LO, OP) \
9d68ac14 5429 case OPC_##UP: tcg_gen_##OP##_i64(t0, t0, t1); break
bd277fa1
RH
5430
5431 switch (opc) {
5432 LMI_HELPER(PADDSH, paddsh);
5433 LMI_HELPER(PADDUSH, paddush);
5434 LMI_HELPER(PADDH, paddh);
5435 LMI_HELPER(PADDW, paddw);
5436 LMI_HELPER(PADDSB, paddsb);
5437 LMI_HELPER(PADDUSB, paddusb);
5438 LMI_HELPER(PADDB, paddb);
5439
5440 LMI_HELPER(PSUBSH, psubsh);
5441 LMI_HELPER(PSUBUSH, psubush);
5442 LMI_HELPER(PSUBH, psubh);
5443 LMI_HELPER(PSUBW, psubw);
5444 LMI_HELPER(PSUBSB, psubsb);
5445 LMI_HELPER(PSUBUSB, psubusb);
5446 LMI_HELPER(PSUBB, psubb);
5447
5448 LMI_HELPER(PSHUFH, pshufh);
5449 LMI_HELPER(PACKSSWH, packsswh);
5450 LMI_HELPER(PACKSSHB, packsshb);
5451 LMI_HELPER(PACKUSHB, packushb);
5452
5453 LMI_HELPER(PUNPCKLHW, punpcklhw);
5454 LMI_HELPER(PUNPCKHHW, punpckhhw);
5455 LMI_HELPER(PUNPCKLBH, punpcklbh);
5456 LMI_HELPER(PUNPCKHBH, punpckhbh);
5457 LMI_HELPER(PUNPCKLWD, punpcklwd);
5458 LMI_HELPER(PUNPCKHWD, punpckhwd);
5459
5460 LMI_HELPER(PAVGH, pavgh);
5461 LMI_HELPER(PAVGB, pavgb);
5462 LMI_HELPER(PMAXSH, pmaxsh);
5463 LMI_HELPER(PMINSH, pminsh);
5464 LMI_HELPER(PMAXUB, pmaxub);
5465 LMI_HELPER(PMINUB, pminub);
5466
5467 LMI_HELPER(PCMPEQW, pcmpeqw);
5468 LMI_HELPER(PCMPGTW, pcmpgtw);
5469 LMI_HELPER(PCMPEQH, pcmpeqh);
5470 LMI_HELPER(PCMPGTH, pcmpgth);
5471 LMI_HELPER(PCMPEQB, pcmpeqb);
5472 LMI_HELPER(PCMPGTB, pcmpgtb);
5473
5474 LMI_HELPER(PSLLW, psllw);
5475 LMI_HELPER(PSLLH, psllh);
5476 LMI_HELPER(PSRLW, psrlw);
5477 LMI_HELPER(PSRLH, psrlh);
5478 LMI_HELPER(PSRAW, psraw);
5479 LMI_HELPER(PSRAH, psrah);
5480
5481 LMI_HELPER(PMULLH, pmullh);
5482 LMI_HELPER(PMULHH, pmulhh);
5483 LMI_HELPER(PMULHUH, pmulhuh);
5484 LMI_HELPER(PMADDHW, pmaddhw);
5485
5486 LMI_HELPER(PASUBUB, pasubub);
5487 LMI_HELPER_1(BIADD, biadd);
5488 LMI_HELPER_1(PMOVMSKB, pmovmskb);
5489
5490 LMI_DIRECT(PADDD, paddd, add);
5491 LMI_DIRECT(PSUBD, psubd, sub);
5492 LMI_DIRECT(XOR_CP2, xor, xor);
5493 LMI_DIRECT(NOR_CP2, nor, nor);
5494 LMI_DIRECT(AND_CP2, and, and);
bb7cab5f 5495 LMI_DIRECT(OR_CP2, or, or);
bd277fa1 5496
9099a36b
H
5497 case OPC_PANDN:
5498 tcg_gen_andc_i64(t0, t1, t0);
5499 break;
5500
bd277fa1
RH
5501 case OPC_PINSRH_0:
5502 tcg_gen_deposit_i64(t0, t0, t1, 0, 16);
bd277fa1
RH
5503 break;
5504 case OPC_PINSRH_1:
5505 tcg_gen_deposit_i64(t0, t0, t1, 16, 16);
bd277fa1
RH
5506 break;
5507 case OPC_PINSRH_2:
5508 tcg_gen_deposit_i64(t0, t0, t1, 32, 16);
bd277fa1
RH
5509 break;
5510 case OPC_PINSRH_3:
5511 tcg_gen_deposit_i64(t0, t0, t1, 48, 16);
bd277fa1
RH
5512 break;
5513
5514 case OPC_PEXTRH:
5515 tcg_gen_andi_i64(t1, t1, 3);
5516 tcg_gen_shli_i64(t1, t1, 4);
5517 tcg_gen_shr_i64(t0, t0, t1);
5518 tcg_gen_ext16u_i64(t0, t0);
bd277fa1
RH
5519 break;
5520
5521 case OPC_ADDU_CP2:
5522 tcg_gen_add_i64(t0, t0, t1);
5523 tcg_gen_ext32s_i64(t0, t0);
bd277fa1
RH
5524 break;
5525 case OPC_SUBU_CP2:
5526 tcg_gen_sub_i64(t0, t0, t1);
5527 tcg_gen_ext32s_i64(t0, t0);
bd277fa1
RH
5528 break;
5529
5530 case OPC_SLL_CP2:
bd277fa1
RH
5531 shift_max = 32;
5532 goto do_shift;
5533 case OPC_SRL_CP2:
bd277fa1
RH
5534 shift_max = 32;
5535 goto do_shift;
5536 case OPC_SRA_CP2:
bd277fa1
RH
5537 shift_max = 32;
5538 goto do_shift;
5539 case OPC_DSLL_CP2:
bd277fa1
RH
5540 shift_max = 64;
5541 goto do_shift;
5542 case OPC_DSRL_CP2:
bd277fa1
RH
5543 shift_max = 64;
5544 goto do_shift;
5545 case OPC_DSRA_CP2:
bd277fa1
RH
5546 shift_max = 64;
5547 goto do_shift;
5548 do_shift:
5549 /* Make sure shift count isn't TCG undefined behaviour. */
5550 tcg_gen_andi_i64(t1, t1, shift_max - 1);
5551
5552 switch (opc) {
5553 case OPC_SLL_CP2:
5554 case OPC_DSLL_CP2:
5555 tcg_gen_shl_i64(t0, t0, t1);
5556 break;
5557 case OPC_SRA_CP2:
5558 case OPC_DSRA_CP2:
5559 /* Since SRA is UndefinedResult without sign-extended inputs,
5560 we can treat SRA and DSRA the same. */
5561 tcg_gen_sar_i64(t0, t0, t1);
5562 break;
5563 case OPC_SRL_CP2:
5564 /* We want to shift in zeros for SRL; zero-extend first. */
5565 tcg_gen_ext32u_i64(t0, t0);
5566 /* FALLTHRU */
5567 case OPC_DSRL_CP2:
5568 tcg_gen_shr_i64(t0, t0, t1);
5569 break;
5570 }
5571
5572 if (shift_max == 32) {
5573 tcg_gen_ext32s_i64(t0, t0);
5574 }
5575
5576 /* Shifts larger than MAX produce zero. */
5577 tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max);
5578 tcg_gen_neg_i64(t1, t1);
5579 tcg_gen_and_i64(t0, t0, t1);
5580 break;
5581
5582 case OPC_ADD_CP2:
5583 case OPC_DADD_CP2:
5584 {
5585 TCGv_i64 t2 = tcg_temp_new_i64();
42a268c2 5586 TCGLabel *lab = gen_new_label();
bd277fa1
RH
5587
5588 tcg_gen_mov_i64(t2, t0);
5589 tcg_gen_add_i64(t0, t1, t2);
5590 if (opc == OPC_ADD_CP2) {
5591 tcg_gen_ext32s_i64(t0, t0);
5592 }
5593 tcg_gen_xor_i64(t1, t1, t2);
5594 tcg_gen_xor_i64(t2, t2, t0);
5595 tcg_gen_andc_i64(t1, t2, t1);
5596 tcg_temp_free_i64(t2);
5597 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
5598 generate_exception(ctx, EXCP_OVERFLOW);
5599 gen_set_label(lab);
bd277fa1
RH
5600 break;
5601 }
5602
5603 case OPC_SUB_CP2:
5604 case OPC_DSUB_CP2:
5605 {
5606 TCGv_i64 t2 = tcg_temp_new_i64();
42a268c2 5607 TCGLabel *lab = gen_new_label();
bd277fa1
RH
5608
5609 tcg_gen_mov_i64(t2, t0);
5610 tcg_gen_sub_i64(t0, t1, t2);
5611 if (opc == OPC_SUB_CP2) {
5612 tcg_gen_ext32s_i64(t0, t0);
5613 }
5614 tcg_gen_xor_i64(t1, t1, t2);
5615 tcg_gen_xor_i64(t2, t2, t0);
5616 tcg_gen_and_i64(t1, t1, t2);
5617 tcg_temp_free_i64(t2);
5618 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
5619 generate_exception(ctx, EXCP_OVERFLOW);
5620 gen_set_label(lab);
bd277fa1
RH
5621 break;
5622 }
5623
5624 case OPC_PMULUW:
5625 tcg_gen_ext32u_i64(t0, t0);
5626 tcg_gen_ext32u_i64(t1, t1);
5627 tcg_gen_mul_i64(t0, t0, t1);
bd277fa1
RH
5628 break;
5629
5630 case OPC_SEQU_CP2:
5631 case OPC_SEQ_CP2:
5632 case OPC_SLTU_CP2:
5633 case OPC_SLT_CP2:
5634 case OPC_SLEU_CP2:
5635 case OPC_SLE_CP2:
5636 /* ??? Document is unclear: Set FCC[CC]. Does that mean the
5637 FD field is the CC field? */
5638 default:
9d68ac14 5639 MIPS_INVAL("loongson_cp2");
9c708c7f 5640 generate_exception_end(ctx, EXCP_RI);
bd277fa1
RH
5641 return;
5642 }
5643
5644#undef LMI_HELPER
5645#undef LMI_DIRECT
5646
5647 gen_store_fpr64(ctx, t0, rd);
5648
bd277fa1
RH
5649 tcg_temp_free_i64(t0);
5650 tcg_temp_free_i64(t1);
5651}
5652
6af0bf9c 5653/* Traps */
7a387fff 5654static void gen_trap (DisasContext *ctx, uint32_t opc,
6af0bf9c
FB
5655 int rs, int rt, int16_t imm)
5656{
5657 int cond;
cdc0faa6 5658 TCGv t0 = tcg_temp_new();
1ba74fb8 5659 TCGv t1 = tcg_temp_new();
6af0bf9c
FB
5660
5661 cond = 0;
5662 /* Load needed operands */
5663 switch (opc) {
5664 case OPC_TEQ:
5665 case OPC_TGE:
5666 case OPC_TGEU:
5667 case OPC_TLT:
5668 case OPC_TLTU:
5669 case OPC_TNE:
5670 /* Compare two registers */
5671 if (rs != rt) {
be24bb4f
TS
5672 gen_load_gpr(t0, rs);
5673 gen_load_gpr(t1, rt);
6af0bf9c
FB
5674 cond = 1;
5675 }
179e32bb 5676 break;
6af0bf9c
FB
5677 case OPC_TEQI:
5678 case OPC_TGEI:
5679 case OPC_TGEIU:
5680 case OPC_TLTI:
5681 case OPC_TLTIU:
5682 case OPC_TNEI:
5683 /* Compare register to immediate */
5684 if (rs != 0 || imm != 0) {
be24bb4f
TS
5685 gen_load_gpr(t0, rs);
5686 tcg_gen_movi_tl(t1, (int32_t)imm);
6af0bf9c
FB
5687 cond = 1;
5688 }
5689 break;
5690 }
5691 if (cond == 0) {
5692 switch (opc) {
5693 case OPC_TEQ: /* rs == rs */
5694 case OPC_TEQI: /* r0 == 0 */
5695 case OPC_TGE: /* rs >= rs */
5696 case OPC_TGEI: /* r0 >= 0 */
5697 case OPC_TGEU: /* rs >= rs unsigned */
5698 case OPC_TGEIU: /* r0 >= 0 unsigned */
5699 /* Always trap */
9c708c7f 5700 generate_exception_end(ctx, EXCP_TRAP);
6af0bf9c
FB
5701 break;
5702 case OPC_TLT: /* rs < rs */
5703 case OPC_TLTI: /* r0 < 0 */
5704 case OPC_TLTU: /* rs < rs unsigned */
5705 case OPC_TLTIU: /* r0 < 0 unsigned */
5706 case OPC_TNE: /* rs != rs */
5707 case OPC_TNEI: /* r0 != 0 */
ead9360e 5708 /* Never trap: treat as NOP. */
cdc0faa6 5709 break;
6af0bf9c
FB
5710 }
5711 } else {
42a268c2 5712 TCGLabel *l1 = gen_new_label();
cdc0faa6 5713
6af0bf9c
FB
5714 switch (opc) {
5715 case OPC_TEQ:
5716 case OPC_TEQI:
cdc0faa6 5717 tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
6af0bf9c
FB
5718 break;
5719 case OPC_TGE:
5720 case OPC_TGEI:
cdc0faa6 5721 tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
6af0bf9c
FB
5722 break;
5723 case OPC_TGEU:
5724 case OPC_TGEIU:
cdc0faa6 5725 tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
6af0bf9c
FB
5726 break;
5727 case OPC_TLT:
5728 case OPC_TLTI:
cdc0faa6 5729 tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
6af0bf9c
FB
5730 break;
5731 case OPC_TLTU:
5732 case OPC_TLTIU:
cdc0faa6 5733 tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
6af0bf9c
FB
5734 break;
5735 case OPC_TNE:
5736 case OPC_TNEI:
cdc0faa6 5737 tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
6af0bf9c 5738 break;
6af0bf9c 5739 }
cdc0faa6 5740 generate_exception(ctx, EXCP_TRAP);
08ba7963
TS
5741 gen_set_label(l1);
5742 }
be24bb4f
TS
5743 tcg_temp_free(t0);
5744 tcg_temp_free(t1);
6af0bf9c
FB
5745}
5746
90aa39a1
SF
5747static inline bool use_goto_tb(DisasContext *ctx, target_ulong dest)
5748{
eeb3bba8 5749 if (unlikely(ctx->base.singlestep_enabled)) {
90aa39a1
SF
5750 return false;
5751 }
5752
5753#ifndef CONFIG_USER_ONLY
eeb3bba8 5754 return (ctx->base.tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
90aa39a1
SF
5755#else
5756 return true;
5757#endif
5758}
5759
356265ae 5760static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
c53be334 5761{
90aa39a1 5762 if (use_goto_tb(ctx, dest)) {
57fec1fe 5763 tcg_gen_goto_tb(n);
9b9e4393 5764 gen_save_pc(dest);
07ea28b4 5765 tcg_gen_exit_tb(ctx->base.tb, n);
6e256c93 5766 } else {
9b9e4393 5767 gen_save_pc(dest);
eeb3bba8 5768 if (ctx->base.singlestep_enabled) {
7b270ef2 5769 save_cpu_state(ctx, 0);
9c708c7f 5770 gen_helper_raise_exception_debug(cpu_env);
7b270ef2 5771 }
7f11636d 5772 tcg_gen_lookup_and_goto_ptr();
6e256c93 5773 }
c53be334
FB
5774}
5775
6af0bf9c 5776/* Branches (before delay slot) */
7a387fff 5777static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
7dca4ad0 5778 int insn_bytes,
b231c103
YK
5779 int rs, int rt, int32_t offset,
5780 int delayslot_size)
6af0bf9c 5781{
d077b6f7 5782 target_ulong btgt = -1;
3ad4bb2d 5783 int blink = 0;
2fdbad25 5784 int bcond_compute = 0;
1ba74fb8
AJ
5785 TCGv t0 = tcg_temp_new();
5786 TCGv t1 = tcg_temp_new();
3ad4bb2d
TS
5787
5788 if (ctx->hflags & MIPS_HFLAG_BMASK) {
923617a3 5789#ifdef MIPS_DEBUG_DISAS
339cd2a8 5790 LOG_DISAS("Branch in delay / forbidden slot at PC 0x"
eeb3bba8 5791 TARGET_FMT_lx "\n", ctx->base.pc_next);
923617a3 5792#endif
9c708c7f 5793 generate_exception_end(ctx, EXCP_RI);
6c5c1e20 5794 goto out;
3ad4bb2d 5795 }
6af0bf9c 5796
6af0bf9c
FB
5797 /* Load needed operands */
5798 switch (opc) {
5799 case OPC_BEQ:
5800 case OPC_BEQL:
5801 case OPC_BNE:
5802 case OPC_BNEL:
5803 /* Compare two registers */
5804 if (rs != rt) {
6c5c1e20
TS
5805 gen_load_gpr(t0, rs);
5806 gen_load_gpr(t1, rt);
2fdbad25 5807 bcond_compute = 1;
6af0bf9c 5808 }
eeb3bba8 5809 btgt = ctx->base.pc_next + insn_bytes + offset;
6af0bf9c
FB
5810 break;
5811 case OPC_BGEZ:
5812 case OPC_BGEZAL:
5813 case OPC_BGEZALL:
5814 case OPC_BGEZL:
5815 case OPC_BGTZ:
5816 case OPC_BGTZL:
5817 case OPC_BLEZ:
5818 case OPC_BLEZL:
5819 case OPC_BLTZ:
5820 case OPC_BLTZAL:
5821 case OPC_BLTZALL:
5822 case OPC_BLTZL:
5823 /* Compare to zero */
5824 if (rs != 0) {
6c5c1e20 5825 gen_load_gpr(t0, rs);
2fdbad25 5826 bcond_compute = 1;
6af0bf9c 5827 }
eeb3bba8 5828 btgt = ctx->base.pc_next + insn_bytes + offset;
6af0bf9c 5829 break;
e45a93e2
JL
5830 case OPC_BPOSGE32:
5831#if defined(TARGET_MIPS64)
5832 case OPC_BPOSGE64:
5833 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x7F);
5834#else
5835 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
5836#endif
5837 bcond_compute = 1;
eeb3bba8 5838 btgt = ctx->base.pc_next + insn_bytes + offset;
e45a93e2 5839 break;
6af0bf9c
FB
5840 case OPC_J:
5841 case OPC_JAL:
364d4831 5842 case OPC_JALX:
6af0bf9c 5843 /* Jump to immediate */
eeb3bba8
EC
5844 btgt = ((ctx->base.pc_next + insn_bytes) & (int32_t)0xF0000000) |
5845 (uint32_t)offset;
6af0bf9c
FB
5846 break;
5847 case OPC_JR:
5848 case OPC_JALR:
5849 /* Jump to register */
7a387fff
TS
5850 if (offset != 0 && offset != 16) {
5851 /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
cbeb0857 5852 others are reserved. */
923617a3 5853 MIPS_INVAL("jump hint");
9c708c7f 5854 generate_exception_end(ctx, EXCP_RI);
6c5c1e20 5855 goto out;
6af0bf9c 5856 }
d077b6f7 5857 gen_load_gpr(btarget, rs);
6af0bf9c
FB
5858 break;
5859 default:
5860 MIPS_INVAL("branch/jump");
9c708c7f 5861 generate_exception_end(ctx, EXCP_RI);
6c5c1e20 5862 goto out;
6af0bf9c 5863 }
2fdbad25 5864 if (bcond_compute == 0) {
6af0bf9c
FB
5865 /* No condition to be computed */
5866 switch (opc) {
5867 case OPC_BEQ: /* rx == rx */
5868 case OPC_BEQL: /* rx == rx likely */
5869 case OPC_BGEZ: /* 0 >= 0 */
5870 case OPC_BGEZL: /* 0 >= 0 likely */
5871 case OPC_BLEZ: /* 0 <= 0 */
5872 case OPC_BLEZL: /* 0 <= 0 likely */
5873 /* Always take */
4ad40f36 5874 ctx->hflags |= MIPS_HFLAG_B;
6af0bf9c
FB
5875 break;
5876 case OPC_BGEZAL: /* 0 >= 0 */
5877 case OPC_BGEZALL: /* 0 >= 0 likely */
5878 /* Always take and link */
5879 blink = 31;
4ad40f36 5880 ctx->hflags |= MIPS_HFLAG_B;
6af0bf9c
FB
5881 break;
5882 case OPC_BNE: /* rx != rx */
5883 case OPC_BGTZ: /* 0 > 0 */
5884 case OPC_BLTZ: /* 0 < 0 */
ead9360e 5885 /* Treat as NOP. */
6c5c1e20 5886 goto out;
eeef26cd 5887 case OPC_BLTZAL: /* 0 < 0 */
3c824109
NF
5888 /* Handle as an unconditional branch to get correct delay
5889 slot checking. */
5890 blink = 31;
eeb3bba8 5891 btgt = ctx->base.pc_next + insn_bytes + delayslot_size;
3c824109 5892 ctx->hflags |= MIPS_HFLAG_B;
3c824109 5893 break;
eeef26cd 5894 case OPC_BLTZALL: /* 0 < 0 likely */
eeb3bba8 5895 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 8);
9898128f 5896 /* Skip the instruction in the delay slot */
eeb3bba8 5897 ctx->base.pc_next += 4;
6c5c1e20 5898 goto out;
6af0bf9c
FB
5899 case OPC_BNEL: /* rx != rx likely */
5900 case OPC_BGTZL: /* 0 > 0 likely */
6af0bf9c
FB
5901 case OPC_BLTZL: /* 0 < 0 likely */
5902 /* Skip the instruction in the delay slot */
eeb3bba8 5903 ctx->base.pc_next += 4;
6c5c1e20 5904 goto out;
6af0bf9c 5905 case OPC_J:
4ad40f36 5906 ctx->hflags |= MIPS_HFLAG_B;
6af0bf9c 5907 break;
364d4831
NF
5908 case OPC_JALX:
5909 ctx->hflags |= MIPS_HFLAG_BX;
5910 /* Fallthrough */
6af0bf9c
FB
5911 case OPC_JAL:
5912 blink = 31;
4ad40f36 5913 ctx->hflags |= MIPS_HFLAG_B;
6af0bf9c
FB
5914 break;
5915 case OPC_JR:
4ad40f36 5916 ctx->hflags |= MIPS_HFLAG_BR;
6af0bf9c
FB
5917 break;
5918 case OPC_JALR:
5919 blink = rt;
4ad40f36 5920 ctx->hflags |= MIPS_HFLAG_BR;
6af0bf9c
FB
5921 break;
5922 default:
5923 MIPS_INVAL("branch/jump");
9c708c7f 5924 generate_exception_end(ctx, EXCP_RI);
6c5c1e20 5925 goto out;
6af0bf9c
FB
5926 }
5927 } else {
5928 switch (opc) {
5929 case OPC_BEQ:
e68dd28f 5930 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
6af0bf9c
FB
5931 goto not_likely;
5932 case OPC_BEQL:
e68dd28f 5933 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
6af0bf9c
FB
5934 goto likely;
5935 case OPC_BNE:
e68dd28f 5936 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
6af0bf9c
FB
5937 goto not_likely;
5938 case OPC_BNEL:
e68dd28f 5939 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
6af0bf9c
FB
5940 goto likely;
5941 case OPC_BGEZ:
e68dd28f 5942 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6af0bf9c
FB
5943 goto not_likely;
5944 case OPC_BGEZL:
e68dd28f 5945 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6af0bf9c
FB
5946 goto likely;
5947 case OPC_BGEZAL:
e68dd28f 5948 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6af0bf9c
FB
5949 blink = 31;
5950 goto not_likely;
5951 case OPC_BGEZALL:
e68dd28f 5952 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6af0bf9c 5953 blink = 31;
6af0bf9c
FB
5954 goto likely;
5955 case OPC_BGTZ:
e68dd28f 5956 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
6af0bf9c
FB
5957 goto not_likely;
5958 case OPC_BGTZL:
e68dd28f 5959 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
6af0bf9c
FB
5960 goto likely;
5961 case OPC_BLEZ:
e68dd28f 5962 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
6af0bf9c
FB
5963 goto not_likely;
5964 case OPC_BLEZL:
e68dd28f 5965 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
6af0bf9c
FB
5966 goto likely;
5967 case OPC_BLTZ:
e68dd28f 5968 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6af0bf9c
FB
5969 goto not_likely;
5970 case OPC_BLTZL:
e68dd28f 5971 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6af0bf9c 5972 goto likely;
e45a93e2
JL
5973 case OPC_BPOSGE32:
5974 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
e45a93e2
JL
5975 goto not_likely;
5976#if defined(TARGET_MIPS64)
5977 case OPC_BPOSGE64:
5978 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 64);
e45a93e2
JL
5979 goto not_likely;
5980#endif
6af0bf9c 5981 case OPC_BLTZAL:
e68dd28f 5982 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6af0bf9c 5983 blink = 31;
6af0bf9c 5984 not_likely:
4ad40f36 5985 ctx->hflags |= MIPS_HFLAG_BC;
6af0bf9c
FB
5986 break;
5987 case OPC_BLTZALL:
e68dd28f 5988 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6af0bf9c 5989 blink = 31;
6af0bf9c 5990 likely:
4ad40f36 5991 ctx->hflags |= MIPS_HFLAG_BL;
6af0bf9c 5992 break;
c53f4a62
TS
5993 default:
5994 MIPS_INVAL("conditional branch/jump");
9c708c7f 5995 generate_exception_end(ctx, EXCP_RI);
6c5c1e20 5996 goto out;
6af0bf9c 5997 }
6af0bf9c 5998 }
9b9e4393 5999
d077b6f7 6000 ctx->btarget = btgt;
b231c103
YK
6001
6002 switch (delayslot_size) {
6003 case 2:
6004 ctx->hflags |= MIPS_HFLAG_BDS16;
6005 break;
6006 case 4:
6007 ctx->hflags |= MIPS_HFLAG_BDS32;
6008 break;
6009 }
6010
6af0bf9c 6011 if (blink > 0) {
b231c103 6012 int post_delay = insn_bytes + delayslot_size;
364d4831
NF
6013 int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
6014
eeb3bba8
EC
6015 tcg_gen_movi_tl(cpu_gpr[blink],
6016 ctx->base.pc_next + post_delay + lowbit);
6af0bf9c 6017 }
6c5c1e20
TS
6018
6019 out:
364d4831
NF
6020 if (insn_bytes == 2)
6021 ctx->hflags |= MIPS_HFLAG_B16;
6c5c1e20
TS
6022 tcg_temp_free(t0);
6023 tcg_temp_free(t1);
6af0bf9c
FB
6024}
6025
764371d2
SM
6026
6027/* nanoMIPS Branches */
6028static void gen_compute_branch_nm(DisasContext *ctx, uint32_t opc,
6029 int insn_bytes,
6030 int rs, int rt, int32_t offset)
6031{
6032 target_ulong btgt = -1;
6033 int bcond_compute = 0;
6034 TCGv t0 = tcg_temp_new();
6035 TCGv t1 = tcg_temp_new();
6036
6037 /* Load needed operands */
6038 switch (opc) {
6039 case OPC_BEQ:
6040 case OPC_BNE:
6041 /* Compare two registers */
6042 if (rs != rt) {
6043 gen_load_gpr(t0, rs);
6044 gen_load_gpr(t1, rt);
6045 bcond_compute = 1;
6046 }
6047 btgt = ctx->base.pc_next + insn_bytes + offset;
6048 break;
6049 case OPC_BGEZAL:
6050 /* Compare to zero */
6051 if (rs != 0) {
6052 gen_load_gpr(t0, rs);
6053 bcond_compute = 1;
6054 }
6055 btgt = ctx->base.pc_next + insn_bytes + offset;
6056 break;
6057 case OPC_BPOSGE32:
6058 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
6059 bcond_compute = 1;
6060 btgt = ctx->base.pc_next + insn_bytes + offset;
6061 break;
6062 case OPC_JR:
6063 case OPC_JALR:
6064 /* Jump to register */
6065 if (offset != 0 && offset != 16) {
6066 /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
6067 others are reserved. */
6068 MIPS_INVAL("jump hint");
6069 generate_exception_end(ctx, EXCP_RI);
6070 goto out;
6071 }
6072 gen_load_gpr(btarget, rs);
6073 break;
6074 default:
6075 MIPS_INVAL("branch/jump");
6076 generate_exception_end(ctx, EXCP_RI);
6077 goto out;
6078 }
6079 if (bcond_compute == 0) {
6080 /* No condition to be computed */
6081 switch (opc) {
6082 case OPC_BEQ: /* rx == rx */
6083 /* Always take */
6084 ctx->hflags |= MIPS_HFLAG_B;
6085 break;
6086 case OPC_BGEZAL: /* 0 >= 0 */
6087 /* Always take and link */
6088 tcg_gen_movi_tl(cpu_gpr[31],
6089 ctx->base.pc_next + insn_bytes);
6090 ctx->hflags |= MIPS_HFLAG_B;
6091 break;
6092 case OPC_BNE: /* rx != rx */
6093 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 8);
6094 /* Skip the instruction in the delay slot */
6095 ctx->base.pc_next += 4;
6096 goto out;
6097 case OPC_JR:
6098 ctx->hflags |= MIPS_HFLAG_BR;
6099 break;
6100 case OPC_JALR:
6101 if (rt > 0) {
6102 tcg_gen_movi_tl(cpu_gpr[rt],
6103 ctx->base.pc_next + insn_bytes);
6104 }
6105 ctx->hflags |= MIPS_HFLAG_BR;
6106 break;
6107 default:
6108 MIPS_INVAL("branch/jump");
6109 generate_exception_end(ctx, EXCP_RI);
6110 goto out;
6111 }
6112 } else {
6113 switch (opc) {
6114 case OPC_BEQ:
6115 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
6116 goto not_likely;
6117 case OPC_BNE:
6118 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
6119 goto not_likely;
6120 case OPC_BGEZAL:
6121 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6122 tcg_gen_movi_tl(cpu_gpr[31],
6123 ctx->base.pc_next + insn_bytes);
6124 goto not_likely;
6125 case OPC_BPOSGE32:
6126 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
6127 not_likely:
6128 ctx->hflags |= MIPS_HFLAG_BC;
6129 break;
6130 default:
6131 MIPS_INVAL("conditional branch/jump");
6132 generate_exception_end(ctx, EXCP_RI);
6133 goto out;
6134 }
6135 }
6136
6137 ctx->btarget = btgt;
6138
6139 out:
6140 if (insn_bytes == 2) {
6141 ctx->hflags |= MIPS_HFLAG_B16;
6142 }
6143 tcg_temp_free(t0);
6144 tcg_temp_free(t1);
6145}
6146
6147
7a387fff
TS
6148/* special3 bitfield operations */
6149static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
356265ae 6150 int rs, int lsb, int msb)
7a387fff 6151{
a7812ae4
PB
6152 TCGv t0 = tcg_temp_new();
6153 TCGv t1 = tcg_temp_new();
6c5c1e20
TS
6154
6155 gen_load_gpr(t1, rs);
7a387fff
TS
6156 switch (opc) {
6157 case OPC_EXT:
b7f26e52 6158 if (lsb + msb > 31) {
7a387fff 6159 goto fail;
b7f26e52 6160 }
505ad7c2 6161 if (msb != 31) {
6eebb7a4 6162 tcg_gen_extract_tl(t0, t1, lsb, msb + 1);
505ad7c2 6163 } else {
6eebb7a4
RH
6164 /* The two checks together imply that lsb == 0,
6165 so this is a simple sign-extension. */
6166 tcg_gen_ext32s_tl(t0, t1);
505ad7c2 6167 }
7a387fff 6168 break;
c6d6dd7c 6169#if defined(TARGET_MIPS64)
7a387fff 6170 case OPC_DEXTU:
b7f26e52
RH
6171 lsb += 32;
6172 goto do_dext;
6173 case OPC_DEXTM:
6174 msb += 32;
6175 goto do_dext;
7a387fff 6176 case OPC_DEXT:
b7f26e52
RH
6177 do_dext:
6178 if (lsb + msb > 63) {
6179 goto fail;
6180 }
6eebb7a4 6181 tcg_gen_extract_tl(t0, t1, lsb, msb + 1);
7a387fff 6182 break;
c6d6dd7c 6183#endif
7a387fff 6184 case OPC_INS:
b7f26e52 6185 if (lsb > msb) {
7a387fff 6186 goto fail;
b7f26e52 6187 }
6c5c1e20 6188 gen_load_gpr(t0, rt);
e0d002f1 6189 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
505ad7c2 6190 tcg_gen_ext32s_tl(t0, t0);
7a387fff 6191 break;
c6d6dd7c 6192#if defined(TARGET_MIPS64)
7a387fff 6193 case OPC_DINSU:
b7f26e52
RH
6194 lsb += 32;
6195 /* FALLTHRU */
6196 case OPC_DINSM:
6197 msb += 32;
6198 /* FALLTHRU */
7a387fff 6199 case OPC_DINS:
b7f26e52
RH
6200 if (lsb > msb) {
6201 goto fail;
6202 }
6c5c1e20 6203 gen_load_gpr(t0, rt);
e0d002f1 6204 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
7a387fff 6205 break;
c6d6dd7c 6206#endif
7a387fff
TS
6207 default:
6208fail:
6209 MIPS_INVAL("bitops");
9c708c7f 6210 generate_exception_end(ctx, EXCP_RI);
6c5c1e20
TS
6211 tcg_temp_free(t0);
6212 tcg_temp_free(t1);
7a387fff
TS
6213 return;
6214 }
6c5c1e20
TS
6215 gen_store_gpr(t0, rt);
6216 tcg_temp_free(t0);
6217 tcg_temp_free(t1);
7a387fff
TS
6218}
6219
49bcf33c
AJ
6220static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
6221{
3a55fa47 6222 TCGv t0;
49bcf33c 6223
3a55fa47
AJ
6224 if (rd == 0) {
6225 /* If no destination, treat it as a NOP. */
3a55fa47
AJ
6226 return;
6227 }
6228
6229 t0 = tcg_temp_new();
6230 gen_load_gpr(t0, rt);
49bcf33c
AJ
6231 switch (op2) {
6232 case OPC_WSBH:
3a55fa47
AJ
6233 {
6234 TCGv t1 = tcg_temp_new();
06a57e5c 6235 TCGv t2 = tcg_const_tl(0x00FF00FF);
3a55fa47
AJ
6236
6237 tcg_gen_shri_tl(t1, t0, 8);
06a57e5c
AJ
6238 tcg_gen_and_tl(t1, t1, t2);
6239 tcg_gen_and_tl(t0, t0, t2);
3a55fa47 6240 tcg_gen_shli_tl(t0, t0, 8);
3a55fa47 6241 tcg_gen_or_tl(t0, t0, t1);
06a57e5c 6242 tcg_temp_free(t2);
3a55fa47
AJ
6243 tcg_temp_free(t1);
6244 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
6245 }
49bcf33c
AJ
6246 break;
6247 case OPC_SEB:
3a55fa47 6248 tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
49bcf33c
AJ
6249 break;
6250 case OPC_SEH:
3a55fa47 6251 tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
49bcf33c
AJ
6252 break;
6253#if defined(TARGET_MIPS64)
6254 case OPC_DSBH:
3a55fa47
AJ
6255 {
6256 TCGv t1 = tcg_temp_new();
06a57e5c 6257 TCGv t2 = tcg_const_tl(0x00FF00FF00FF00FFULL);
3a55fa47
AJ
6258
6259 tcg_gen_shri_tl(t1, t0, 8);
06a57e5c
AJ
6260 tcg_gen_and_tl(t1, t1, t2);
6261 tcg_gen_and_tl(t0, t0, t2);
3a55fa47 6262 tcg_gen_shli_tl(t0, t0, 8);
3a55fa47 6263 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
06a57e5c 6264 tcg_temp_free(t2);
3a55fa47
AJ
6265 tcg_temp_free(t1);
6266 }
49bcf33c
AJ
6267 break;
6268 case OPC_DSHD:
3a55fa47
AJ
6269 {
6270 TCGv t1 = tcg_temp_new();
06a57e5c 6271 TCGv t2 = tcg_const_tl(0x0000FFFF0000FFFFULL);
3a55fa47
AJ
6272
6273 tcg_gen_shri_tl(t1, t0, 16);
06a57e5c
AJ
6274 tcg_gen_and_tl(t1, t1, t2);
6275 tcg_gen_and_tl(t0, t0, t2);
3a55fa47 6276 tcg_gen_shli_tl(t0, t0, 16);
3a55fa47
AJ
6277 tcg_gen_or_tl(t0, t0, t1);
6278 tcg_gen_shri_tl(t1, t0, 32);
6279 tcg_gen_shli_tl(t0, t0, 32);
6280 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
06a57e5c 6281 tcg_temp_free(t2);
3a55fa47
AJ
6282 tcg_temp_free(t1);
6283 }
49bcf33c
AJ
6284 break;
6285#endif
6286 default:
6287 MIPS_INVAL("bsfhl");
9c708c7f 6288 generate_exception_end(ctx, EXCP_RI);
49bcf33c 6289 tcg_temp_free(t0);
49bcf33c
AJ
6290 return;
6291 }
49bcf33c 6292 tcg_temp_free(t0);
49bcf33c
AJ
6293}
6294
1f1b4c00
YK
6295static void gen_lsa(DisasContext *ctx, int opc, int rd, int rs, int rt,
6296 int imm2)
6297{
6298 TCGv t0;
6299 TCGv t1;
6300 if (rd == 0) {
6301 /* Treat as NOP. */
6302 return;
6303 }
6304 t0 = tcg_temp_new();
6305 t1 = tcg_temp_new();
6306 gen_load_gpr(t0, rs);
6307 gen_load_gpr(t1, rt);
6308 tcg_gen_shli_tl(t0, t0, imm2 + 1);
6309 tcg_gen_add_tl(cpu_gpr[rd], t0, t1);
6310 if (opc == OPC_LSA) {
6311 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
6312 }
6313
6314 tcg_temp_free(t1);
6315 tcg_temp_free(t0);
6316
6317 return;
6318}
6319
821f2008
JH
6320static void gen_align_bits(DisasContext *ctx, int wordsz, int rd, int rs,
6321 int rt, int bits)
284b731a 6322{
1f1b4c00
YK
6323 TCGv t0;
6324 if (rd == 0) {
6325 /* Treat as NOP. */
6326 return;
6327 }
6328 t0 = tcg_temp_new();
821f2008
JH
6329 if (bits == 0 || bits == wordsz) {
6330 if (bits == 0) {
6331 gen_load_gpr(t0, rt);
6332 } else {
6333 gen_load_gpr(t0, rs);
6334 }
6335 switch (wordsz) {
6336 case 32:
51243852
MD
6337 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
6338 break;
6339#if defined(TARGET_MIPS64)
821f2008 6340 case 64:
51243852
MD
6341 tcg_gen_mov_tl(cpu_gpr[rd], t0);
6342 break;
6343#endif
6344 }
1f1b4c00
YK
6345 } else {
6346 TCGv t1 = tcg_temp_new();
821f2008 6347 gen_load_gpr(t0, rt);
1f1b4c00 6348 gen_load_gpr(t1, rs);
821f2008
JH
6349 switch (wordsz) {
6350 case 32:
1f1b4c00
YK
6351 {
6352 TCGv_i64 t2 = tcg_temp_new_i64();
6353 tcg_gen_concat_tl_i64(t2, t1, t0);
821f2008 6354 tcg_gen_shri_i64(t2, t2, 32 - bits);
1f1b4c00
YK
6355 gen_move_low32(cpu_gpr[rd], t2);
6356 tcg_temp_free_i64(t2);
6357 }
6358 break;
284b731a 6359#if defined(TARGET_MIPS64)
821f2008
JH
6360 case 64:
6361 tcg_gen_shli_tl(t0, t0, bits);
6362 tcg_gen_shri_tl(t1, t1, 64 - bits);
1f1b4c00
YK
6363 tcg_gen_or_tl(cpu_gpr[rd], t1, t0);
6364 break;
284b731a 6365#endif
1f1b4c00
YK
6366 }
6367 tcg_temp_free(t1);
6368 }
6369
6370 tcg_temp_free(t0);
6371}
6372
821f2008
JH
6373static void gen_align(DisasContext *ctx, int wordsz, int rd, int rs, int rt,
6374 int bp)
6375{
6376 gen_align_bits(ctx, wordsz, rd, rs, rt, bp * 8);
6377}
6378
6379static void gen_ext(DisasContext *ctx, int wordsz, int rd, int rs, int rt,
6380 int shift)
6381{
6382 gen_align_bits(ctx, wordsz, rd, rs, rt, wordsz - shift);
6383}
6384
1f1b4c00
YK
6385static void gen_bitswap(DisasContext *ctx, int opc, int rd, int rt)
6386{
6387 TCGv t0;
6388 if (rd == 0) {
6389 /* Treat as NOP. */
6390 return;
6391 }
6392 t0 = tcg_temp_new();
6393 gen_load_gpr(t0, rt);
6394 switch (opc) {
6395 case OPC_BITSWAP:
6396 gen_helper_bitswap(cpu_gpr[rd], t0);
6397 break;
6398#if defined(TARGET_MIPS64)
6399 case OPC_DBITSWAP:
6400 gen_helper_dbitswap(cpu_gpr[rd], t0);
6401 break;
6402#endif
6403 }
6404 tcg_temp_free(t0);
284b731a
LA
6405}
6406
1f1b4c00
YK
6407#ifndef CONFIG_USER_ONLY
6408/* CP0 (MMU and control) */
5204ea79
LA
6409static inline void gen_mthc0_entrylo(TCGv arg, target_ulong off)
6410{
6411 TCGv_i64 t0 = tcg_temp_new_i64();
6412 TCGv_i64 t1 = tcg_temp_new_i64();
6413
6414 tcg_gen_ext_tl_i64(t0, arg);
6415 tcg_gen_ld_i64(t1, cpu_env, off);
6416#if defined(TARGET_MIPS64)
6417 tcg_gen_deposit_i64(t1, t1, t0, 30, 32);
6418#else
6419 tcg_gen_concat32_i64(t1, t1, t0);
6420#endif
6421 tcg_gen_st_i64(t1, cpu_env, off);
6422 tcg_temp_free_i64(t1);
6423 tcg_temp_free_i64(t0);
6424}
6425
6426static inline void gen_mthc0_store64(TCGv arg, target_ulong off)
6427{
6428 TCGv_i64 t0 = tcg_temp_new_i64();
6429 TCGv_i64 t1 = tcg_temp_new_i64();
6430
6431 tcg_gen_ext_tl_i64(t0, arg);
6432 tcg_gen_ld_i64(t1, cpu_env, off);
6433 tcg_gen_concat32_i64(t1, t1, t0);
6434 tcg_gen_st_i64(t1, cpu_env, off);
6435 tcg_temp_free_i64(t1);
6436 tcg_temp_free_i64(t0);
6437}
6438
6439static inline void gen_mfhc0_entrylo(TCGv arg, target_ulong off)
6440{
6441 TCGv_i64 t0 = tcg_temp_new_i64();
6442
6443 tcg_gen_ld_i64(t0, cpu_env, off);
6444#if defined(TARGET_MIPS64)
6445 tcg_gen_shri_i64(t0, t0, 30);
6446#else
6447 tcg_gen_shri_i64(t0, t0, 32);
6448#endif
6449 gen_move_low32(arg, t0);
6450 tcg_temp_free_i64(t0);
6451}
6452
6453static inline void gen_mfhc0_load64(TCGv arg, target_ulong off, int shift)
6454{
6455 TCGv_i64 t0 = tcg_temp_new_i64();
6456
6457 tcg_gen_ld_i64(t0, cpu_env, off);
6458 tcg_gen_shri_i64(t0, t0, 32 + shift);
6459 gen_move_low32(arg, t0);
6460 tcg_temp_free_i64(t0);
6461}
6462
d9bea114 6463static inline void gen_mfc0_load32 (TCGv arg, target_ulong off)
4f57689a 6464{
d9bea114 6465 TCGv_i32 t0 = tcg_temp_new_i32();
4f57689a 6466
d9bea114
AJ
6467 tcg_gen_ld_i32(t0, cpu_env, off);
6468 tcg_gen_ext_i32_tl(arg, t0);
6469 tcg_temp_free_i32(t0);
4f57689a
TS
6470}
6471
d9bea114 6472static inline void gen_mfc0_load64 (TCGv arg, target_ulong off)
4f57689a 6473{
d9bea114
AJ
6474 tcg_gen_ld_tl(arg, cpu_env, off);
6475 tcg_gen_ext32s_tl(arg, arg);
4f57689a
TS
6476}
6477
d9bea114 6478static inline void gen_mtc0_store32 (TCGv arg, target_ulong off)
f1aa6320 6479{
d9bea114 6480 TCGv_i32 t0 = tcg_temp_new_i32();
f1aa6320 6481
d9bea114
AJ
6482 tcg_gen_trunc_tl_i32(t0, arg);
6483 tcg_gen_st_i32(t0, cpu_env, off);
6484 tcg_temp_free_i32(t0);
f1aa6320
TS
6485}
6486
c98d3d79
YK
6487#define CP0_CHECK(c) \
6488 do { \
6489 if (!(c)) { \
6490 goto cp0_unimplemented; \
6491 } \
6492 } while (0)
6493
5204ea79
LA
6494static void gen_mfhc0(DisasContext *ctx, TCGv arg, int reg, int sel)
6495{
6496 const char *rn = "invalid";
6497
5204ea79
LA
6498 switch (reg) {
6499 case 2:
6500 switch (sel) {
6501 case 0:
59488dda 6502 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
5204ea79
LA
6503 gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
6504 rn = "EntryLo0";
6505 break;
6506 default:
c98d3d79 6507 goto cp0_unimplemented;
5204ea79
LA
6508 }
6509 break;
6510 case 3:
6511 switch (sel) {
6512 case 0:
59488dda 6513 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
5204ea79
LA
6514 gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
6515 rn = "EntryLo1";
6516 break;
6517 default:
c98d3d79 6518 goto cp0_unimplemented;
5204ea79
LA
6519 }
6520 break;
6521 case 17:
6522 switch (sel) {
6523 case 0:
6524 gen_mfhc0_load64(arg, offsetof(CPUMIPSState, lladdr),
6525 ctx->CP0_LLAddr_shift);
6526 rn = "LLAddr";
6527 break;
f6d4dd81
YK
6528 case 1:
6529 CP0_CHECK(ctx->mrp);
6530 gen_helper_mfhc0_maar(arg, cpu_env);
6531 rn = "MAAR";
6532 break;
5204ea79 6533 default:
c98d3d79 6534 goto cp0_unimplemented;
5204ea79
LA
6535 }
6536 break;
6537 case 28:
6538 switch (sel) {
6539 case 0:
6540 case 2:
6541 case 4:
6542 case 6:
6543 gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_TagLo), 0);
6544 rn = "TagLo";
6545 break;
6546 default:
c98d3d79 6547 goto cp0_unimplemented;
5204ea79
LA
6548 }
6549 break;
6550 default:
c98d3d79 6551 goto cp0_unimplemented;
5204ea79 6552 }
b44a7fb1 6553 trace_mips_translate_c0("mfhc0", rn, reg, sel);
5204ea79
LA
6554 return;
6555
c98d3d79 6556cp0_unimplemented:
965447ee 6557 qemu_log_mask(LOG_UNIMP, "mfhc0 %s (reg %d sel %d)\n", rn, reg, sel);
5204ea79
LA
6558 tcg_gen_movi_tl(arg, 0);
6559}
6560
6561static void gen_mthc0(DisasContext *ctx, TCGv arg, int reg, int sel)
6562{
6563 const char *rn = "invalid";
6564 uint64_t mask = ctx->PAMask >> 36;
6565
5204ea79
LA
6566 switch (reg) {
6567 case 2:
6568 switch (sel) {
6569 case 0:
59488dda 6570 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
5204ea79
LA
6571 tcg_gen_andi_tl(arg, arg, mask);
6572 gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
6573 rn = "EntryLo0";
6574 break;
6575 default:
c98d3d79 6576 goto cp0_unimplemented;
5204ea79
LA
6577 }
6578 break;
6579 case 3:
6580 switch (sel) {
6581 case 0:
59488dda 6582 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
5204ea79
LA
6583 tcg_gen_andi_tl(arg, arg, mask);
6584 gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
6585 rn = "EntryLo1";
6586 break;
6587 default:
c98d3d79 6588 goto cp0_unimplemented;
5204ea79
LA
6589 }
6590 break;
6591 case 17:
6592 switch (sel) {
6593 case 0:
6594 /* LLAddr is read-only (the only exception is bit 0 if LLB is
6595 supported); the CP0_LLAddr_rw_bitmask does not seem to be
6596 relevant for modern MIPS cores supporting MTHC0, therefore
6597 treating MTHC0 to LLAddr as NOP. */
6598 rn = "LLAddr";
6599 break;
f6d4dd81
YK
6600 case 1:
6601 CP0_CHECK(ctx->mrp);
6602 gen_helper_mthc0_maar(cpu_env, arg);
6603 rn = "MAAR";
6604 break;
5204ea79 6605 default:
c98d3d79 6606 goto cp0_unimplemented;
5204ea79
LA
6607 }
6608 break;
6609 case 28:
6610 switch (sel) {
6611 case 0:
6612 case 2:
6613 case 4:
6614 case 6:
6615 tcg_gen_andi_tl(arg, arg, mask);
6616 gen_mthc0_store64(arg, offsetof(CPUMIPSState, CP0_TagLo));
6617 rn = "TagLo";
6618 break;
6619 default:
c98d3d79 6620 goto cp0_unimplemented;
5204ea79
LA
6621 }
6622 break;
6623 default:
c98d3d79 6624 goto cp0_unimplemented;
5204ea79 6625 }
b44a7fb1 6626 trace_mips_translate_c0("mthc0", rn, reg, sel);
5204ea79 6627
c98d3d79 6628cp0_unimplemented:
965447ee 6629 qemu_log_mask(LOG_UNIMP, "mthc0 %s (reg %d sel %d)\n", rn, reg, sel);
5204ea79
LA
6630}
6631
e98c0d17
LA
6632static inline void gen_mfc0_unimplemented(DisasContext *ctx, TCGv arg)
6633{
6634 if (ctx->insn_flags & ISA_MIPS32R6) {
6635 tcg_gen_movi_tl(arg, 0);
6636 } else {
6637 tcg_gen_movi_tl(arg, ~0);
6638 }
6639}
6640
d75c135e 6641static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
873eb012 6642{
7a387fff 6643 const char *rn = "invalid";
873eb012 6644
e189e748 6645 if (sel != 0)
d75c135e 6646 check_insn(ctx, ISA_MIPS32);
e189e748 6647
873eb012
TS
6648 switch (reg) {
6649 case 0:
7a387fff
TS
6650 switch (sel) {
6651 case 0:
7db13fae 6652 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
7a387fff
TS
6653 rn = "Index";
6654 break;
6655 case 1:
f31b035a 6656 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6657 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
7a387fff 6658 rn = "MVPControl";
ead9360e 6659 break;
7a387fff 6660 case 2:
f31b035a 6661 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6662 gen_helper_mfc0_mvpconf0(arg, cpu_env);
7a387fff 6663 rn = "MVPConf0";
ead9360e 6664 break;
7a387fff 6665 case 3:
f31b035a 6666 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6667 gen_helper_mfc0_mvpconf1(arg, cpu_env);
7a387fff 6668 rn = "MVPConf1";
ead9360e 6669 break;
01bc435b
YK
6670 case 4:
6671 CP0_CHECK(ctx->vp);
6672 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl));
6673 rn = "VPControl";
6674 break;
7a387fff 6675 default:
f31b035a 6676 goto cp0_unimplemented;
7a387fff 6677 }
873eb012
TS
6678 break;
6679 case 1:
7a387fff
TS
6680 switch (sel) {
6681 case 0:
f31b035a 6682 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
895c2d04 6683 gen_helper_mfc0_random(arg, cpu_env);
7a387fff 6684 rn = "Random";
2423f660 6685 break;
7a387fff 6686 case 1:
f31b035a 6687 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6688 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
7a387fff 6689 rn = "VPEControl";
ead9360e 6690 break;
7a387fff 6691 case 2:
f31b035a 6692 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6693 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
7a387fff 6694 rn = "VPEConf0";
ead9360e 6695 break;
7a387fff 6696 case 3:
f31b035a 6697 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6698 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
7a387fff 6699 rn = "VPEConf1";
ead9360e 6700 break;
7a387fff 6701 case 4:
f31b035a 6702 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6703 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask));
7a387fff 6704 rn = "YQMask";
ead9360e 6705 break;
7a387fff 6706 case 5:
f31b035a 6707 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6708 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
7a387fff 6709 rn = "VPESchedule";
ead9360e 6710 break;
7a387fff 6711 case 6:
f31b035a 6712 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6713 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
7a387fff 6714 rn = "VPEScheFBack";
ead9360e 6715 break;
7a387fff 6716 case 7:
f31b035a 6717 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6718 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
7a387fff 6719 rn = "VPEOpt";
ead9360e 6720 break;
7a387fff 6721 default:
f31b035a 6722 goto cp0_unimplemented;
7a387fff 6723 }
873eb012
TS
6724 break;
6725 case 2:
7a387fff
TS
6726 switch (sel) {
6727 case 0:
284b731a
LA
6728 {
6729 TCGv_i64 tmp = tcg_temp_new_i64();
6730 tcg_gen_ld_i64(tmp, cpu_env,
6731 offsetof(CPUMIPSState, CP0_EntryLo0));
7207c7f9 6732#if defined(TARGET_MIPS64)
284b731a
LA
6733 if (ctx->rxi) {
6734 /* Move RI/XI fields to bits 31:30 */
6735 tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
6736 tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
6737 }
7207c7f9 6738#endif
284b731a
LA
6739 gen_move_low32(arg, tmp);
6740 tcg_temp_free_i64(tmp);
6741 }
2423f660
TS
6742 rn = "EntryLo0";
6743 break;
7a387fff 6744 case 1:
f31b035a 6745 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6746 gen_helper_mfc0_tcstatus(arg, cpu_env);
2423f660 6747 rn = "TCStatus";
ead9360e 6748 break;
7a387fff 6749 case 2:
f31b035a 6750 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6751 gen_helper_mfc0_tcbind(arg, cpu_env);
2423f660 6752 rn = "TCBind";
ead9360e 6753 break;
7a387fff 6754 case 3:
f31b035a 6755 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6756 gen_helper_mfc0_tcrestart(arg, cpu_env);
2423f660 6757 rn = "TCRestart";
ead9360e 6758 break;
7a387fff 6759 case 4:
f31b035a 6760 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6761 gen_helper_mfc0_tchalt(arg, cpu_env);
2423f660 6762 rn = "TCHalt";
ead9360e 6763 break;
7a387fff 6764 case 5:
f31b035a 6765 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6766 gen_helper_mfc0_tccontext(arg, cpu_env);
2423f660 6767 rn = "TCContext";
ead9360e 6768 break;
7a387fff 6769 case 6:
f31b035a 6770 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6771 gen_helper_mfc0_tcschedule(arg, cpu_env);
2423f660 6772 rn = "TCSchedule";
ead9360e 6773 break;
7a387fff 6774 case 7:
f31b035a 6775 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6776 gen_helper_mfc0_tcschefback(arg, cpu_env);
2423f660 6777 rn = "TCScheFBack";
ead9360e 6778 break;
7a387fff 6779 default:
f31b035a 6780 goto cp0_unimplemented;
7a387fff 6781 }
873eb012
TS
6782 break;
6783 case 3:
7a387fff
TS
6784 switch (sel) {
6785 case 0:
284b731a
LA
6786 {
6787 TCGv_i64 tmp = tcg_temp_new_i64();
6788 tcg_gen_ld_i64(tmp, cpu_env,
6789 offsetof(CPUMIPSState, CP0_EntryLo1));
7207c7f9 6790#if defined(TARGET_MIPS64)
284b731a
LA
6791 if (ctx->rxi) {
6792 /* Move RI/XI fields to bits 31:30 */
6793 tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
6794 tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
6795 }
7207c7f9 6796#endif
284b731a
LA
6797 gen_move_low32(arg, tmp);
6798 tcg_temp_free_i64(tmp);
6799 }
2423f660
TS
6800 rn = "EntryLo1";
6801 break;
01bc435b
YK
6802 case 1:
6803 CP0_CHECK(ctx->vp);
6804 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber));
6805 rn = "GlobalNumber";
6806 break;
7a387fff 6807 default:
f31b035a 6808 goto cp0_unimplemented;
1579a72e 6809 }
873eb012
TS
6810 break;
6811 case 4:
7a387fff
TS
6812 switch (sel) {
6813 case 0:
7db13fae 6814 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
d9bea114 6815 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
6816 rn = "Context";
6817 break;
7a387fff 6818 case 1:
d9bea114 6819// gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
2423f660 6820 rn = "ContextConfig";
f31b035a 6821 goto cp0_unimplemented;
d279279e 6822 case 2:
f31b035a 6823 CP0_CHECK(ctx->ulri);
e40df9a8
JH
6824 tcg_gen_ld_tl(arg, cpu_env,
6825 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
6826 tcg_gen_ext32s_tl(arg, arg);
f31b035a 6827 rn = "UserLocal";
d279279e 6828 break;
7a387fff 6829 default:
f31b035a 6830 goto cp0_unimplemented;
1579a72e 6831 }
873eb012
TS
6832 break;
6833 case 5:
7a387fff
TS
6834 switch (sel) {
6835 case 0:
7db13fae 6836 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
2423f660
TS
6837 rn = "PageMask";
6838 break;
7a387fff 6839 case 1:
d75c135e 6840 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6841 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
2423f660
TS
6842 rn = "PageGrain";
6843 break;
cec56a73
JH
6844 case 2:
6845 CP0_CHECK(ctx->sc);
6846 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl0));
6847 tcg_gen_ext32s_tl(arg, arg);
6848 rn = "SegCtl0";
6849 break;
6850 case 3:
6851 CP0_CHECK(ctx->sc);
6852 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl1));
6853 tcg_gen_ext32s_tl(arg, arg);
6854 rn = "SegCtl1";
6855 break;
6856 case 4:
6857 CP0_CHECK(ctx->sc);
6858 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl2));
6859 tcg_gen_ext32s_tl(arg, arg);
6860 rn = "SegCtl2";
6861 break;
5e31fdd5
YK
6862 case 5:
6863 check_pw(ctx);
6864 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWBase));
6865 rn = "PWBase";
6866 break;
fa75ad14
YK
6867 case 6:
6868 check_pw(ctx);
6869 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWField));
6870 rn = "PWField";
6871 break;
20b28ebc
YK
6872 case 7:
6873 check_pw(ctx);
6874 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWSize));
6875 rn = "PWSize";
6876 break;
7a387fff 6877 default:
f31b035a 6878 goto cp0_unimplemented;
1579a72e 6879 }
873eb012
TS
6880 break;
6881 case 6:
7a387fff
TS
6882 switch (sel) {
6883 case 0:
7db13fae 6884 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
2423f660
TS
6885 rn = "Wired";
6886 break;
7a387fff 6887 case 1:
d75c135e 6888 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6889 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
2423f660 6890 rn = "SRSConf0";
ead9360e 6891 break;
7a387fff 6892 case 2:
d75c135e 6893 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6894 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
2423f660 6895 rn = "SRSConf1";
ead9360e 6896 break;
7a387fff 6897 case 3:
d75c135e 6898 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6899 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
2423f660 6900 rn = "SRSConf2";
ead9360e 6901 break;
7a387fff 6902 case 4:
d75c135e 6903 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6904 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
2423f660 6905 rn = "SRSConf3";
ead9360e 6906 break;
7a387fff 6907 case 5:
d75c135e 6908 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6909 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
2423f660 6910 rn = "SRSConf4";
ead9360e 6911 break;
103be64c
YK
6912 case 6:
6913 check_pw(ctx);
6914 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWCtl));
6915 rn = "PWCtl";
6916 break;
7a387fff 6917 default:
f31b035a 6918 goto cp0_unimplemented;
1579a72e 6919 }
873eb012 6920 break;
8c0fdd85 6921 case 7:
7a387fff
TS
6922 switch (sel) {
6923 case 0:
d75c135e 6924 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6925 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
2423f660
TS
6926 rn = "HWREna";
6927 break;
7a387fff 6928 default:
f31b035a 6929 goto cp0_unimplemented;
1579a72e 6930 }
8c0fdd85 6931 break;
873eb012 6932 case 8:
7a387fff
TS
6933 switch (sel) {
6934 case 0:
7db13fae 6935 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
d9bea114 6936 tcg_gen_ext32s_tl(arg, arg);
f0b3f3ae 6937 rn = "BadVAddr";
2423f660 6938 break;
aea14095 6939 case 1:
f31b035a
LA
6940 CP0_CHECK(ctx->bi);
6941 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
6942 rn = "BadInstr";
aea14095
LA
6943 break;
6944 case 2:
f31b035a
LA
6945 CP0_CHECK(ctx->bp);
6946 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
6947 rn = "BadInstrP";
aea14095 6948 break;
25beba9b
SM
6949 case 3:
6950 CP0_CHECK(ctx->bi);
6951 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrX));
6952 tcg_gen_andi_tl(arg, arg, ~0xffff);
6953 rn = "BadInstrX";
6954 break;
6955 default:
f31b035a 6956 goto cp0_unimplemented;
aea14095 6957 }
873eb012
TS
6958 break;
6959 case 9:
7a387fff
TS
6960 switch (sel) {
6961 case 0:
2e70f6ef 6962 /* Mark as an IO operation because we read the time. */
eeb3bba8 6963 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
2e70f6ef 6964 gen_io_start();
bd79255d 6965 }
895c2d04 6966 gen_helper_mfc0_count(arg, cpu_env);
eeb3bba8 6967 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
2e70f6ef 6968 gen_io_end();
2e70f6ef 6969 }
55807224 6970 /* Break the TB to be able to take timer interrupts immediately
b28425ba
EC
6971 after reading count. DISAS_STOP isn't sufficient, we need to
6972 ensure we break completely out of translated code. */
eeb3bba8
EC
6973 gen_save_pc(ctx->base.pc_next + 4);
6974 ctx->base.is_jmp = DISAS_EXIT;
2423f660
TS
6975 rn = "Count";
6976 break;
6977 /* 6,7 are implementation dependent */
7a387fff 6978 default:
f31b035a 6979 goto cp0_unimplemented;
2423f660 6980 }
873eb012
TS
6981 break;
6982 case 10:
7a387fff
TS
6983 switch (sel) {
6984 case 0:
7db13fae 6985 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
d9bea114 6986 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
6987 rn = "EntryHi";
6988 break;
7a387fff 6989 default:
f31b035a 6990 goto cp0_unimplemented;
1579a72e 6991 }
873eb012
TS
6992 break;
6993 case 11:
7a387fff
TS
6994 switch (sel) {
6995 case 0:
7db13fae 6996 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
2423f660
TS
6997 rn = "Compare";
6998 break;
6999 /* 6,7 are implementation dependent */
7a387fff 7000 default:
f31b035a 7001 goto cp0_unimplemented;
2423f660 7002 }
873eb012
TS
7003 break;
7004 case 12:
7a387fff
TS
7005 switch (sel) {
7006 case 0:
7db13fae 7007 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
2423f660
TS
7008 rn = "Status";
7009 break;
7a387fff 7010 case 1:
d75c135e 7011 check_insn(ctx, ISA_MIPS32R2);
7db13fae 7012 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
2423f660
TS
7013 rn = "IntCtl";
7014 break;
7a387fff 7015 case 2:
d75c135e 7016 check_insn(ctx, ISA_MIPS32R2);
7db13fae 7017 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
2423f660
TS
7018 rn = "SRSCtl";
7019 break;
7a387fff 7020 case 3:
d75c135e 7021 check_insn(ctx, ISA_MIPS32R2);
7db13fae 7022 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
2423f660 7023 rn = "SRSMap";
fd88b6ab 7024 break;
7a387fff 7025 default:
f31b035a 7026 goto cp0_unimplemented;
7a387fff 7027 }
873eb012
TS
7028 break;
7029 case 13:
7a387fff
TS
7030 switch (sel) {
7031 case 0:
7db13fae 7032 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
2423f660
TS
7033 rn = "Cause";
7034 break;
7a387fff 7035 default:
f31b035a 7036 goto cp0_unimplemented;
7a387fff 7037 }
873eb012
TS
7038 break;
7039 case 14:
7a387fff
TS
7040 switch (sel) {
7041 case 0:
7db13fae 7042 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
d9bea114 7043 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
7044 rn = "EPC";
7045 break;
7a387fff 7046 default:
f31b035a 7047 goto cp0_unimplemented;
1579a72e 7048 }
873eb012
TS
7049 break;
7050 case 15:
7a387fff
TS
7051 switch (sel) {
7052 case 0:
7db13fae 7053 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
2423f660
TS
7054 rn = "PRid";
7055 break;
7a387fff 7056 case 1:
d75c135e 7057 check_insn(ctx, ISA_MIPS32R2);
74dbf824
JH
7058 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EBase));
7059 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
7060 rn = "EBase";
7061 break;
c870e3f5
YK
7062 case 3:
7063 check_insn(ctx, ISA_MIPS32R2);
7064 CP0_CHECK(ctx->cmgcr);
7065 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase));
7066 tcg_gen_ext32s_tl(arg, arg);
7067 rn = "CMGCRBase";
7068 break;
7a387fff 7069 default:
f31b035a 7070 goto cp0_unimplemented;
7a387fff 7071 }
873eb012
TS
7072 break;
7073 case 16:
7074 switch (sel) {
7075 case 0:
7db13fae 7076 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
873eb012
TS
7077 rn = "Config";
7078 break;
7079 case 1:
7db13fae 7080 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
873eb012
TS
7081 rn = "Config1";
7082 break;
7a387fff 7083 case 2:
7db13fae 7084 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
7a387fff
TS
7085 rn = "Config2";
7086 break;
7087 case 3:
7db13fae 7088 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
7a387fff
TS
7089 rn = "Config3";
7090 break;
b4160af1
PJ
7091 case 4:
7092 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
7093 rn = "Config4";
7094 break;
b4dd99a3
PJ
7095 case 5:
7096 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
7097 rn = "Config5";
7098 break;
e397ee33
TS
7099 /* 6,7 are implementation dependent */
7100 case 6:
7db13fae 7101 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
e397ee33
TS
7102 rn = "Config6";
7103 break;
7104 case 7:
7db13fae 7105 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
e397ee33
TS
7106 rn = "Config7";
7107 break;
873eb012 7108 default:
f31b035a 7109 goto cp0_unimplemented;
873eb012
TS
7110 }
7111 break;
7112 case 17:
7a387fff
TS
7113 switch (sel) {
7114 case 0:
895c2d04 7115 gen_helper_mfc0_lladdr(arg, cpu_env);
2423f660
TS
7116 rn = "LLAddr";
7117 break;
f6d4dd81
YK
7118 case 1:
7119 CP0_CHECK(ctx->mrp);
7120 gen_helper_mfc0_maar(arg, cpu_env);
7121 rn = "MAAR";
7122 break;
7123 case 2:
7124 CP0_CHECK(ctx->mrp);
7125 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI));
7126 rn = "MAARI";
7127 break;
7a387fff 7128 default:
f31b035a 7129 goto cp0_unimplemented;
7a387fff 7130 }
873eb012
TS
7131 break;
7132 case 18:
7a387fff 7133 switch (sel) {
c2e19f3c
AM
7134 case 0:
7135 case 1:
7136 case 2:
7137 case 3:
7138 case 4:
7139 case 5:
7140 case 6:
7141 case 7:
fa192d49 7142 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
895c2d04 7143 gen_helper_1e0i(mfc0_watchlo, arg, sel);
2423f660
TS
7144 rn = "WatchLo";
7145 break;
7a387fff 7146 default:
f31b035a 7147 goto cp0_unimplemented;
7a387fff 7148 }
873eb012
TS
7149 break;
7150 case 19:
7a387fff 7151 switch (sel) {
c2e19f3c
AM
7152 case 0:
7153 case 1:
7154 case 2:
7155 case 3:
7156 case 4:
7157 case 5:
7158 case 6:
7159 case 7:
fa192d49 7160 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
895c2d04 7161 gen_helper_1e0i(mfc0_watchhi, arg, sel);
2423f660
TS
7162 rn = "WatchHi";
7163 break;
7a387fff 7164 default:
f31b035a 7165 goto cp0_unimplemented;
7a387fff 7166 }
873eb012 7167 break;
8c0fdd85 7168 case 20:
7a387fff
TS
7169 switch (sel) {
7170 case 0:
d26bc211 7171#if defined(TARGET_MIPS64)
d75c135e 7172 check_insn(ctx, ISA_MIPS3);
7db13fae 7173 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
d9bea114 7174 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
7175 rn = "XContext";
7176 break;
703eaf37 7177#endif
7a387fff 7178 default:
f31b035a 7179 goto cp0_unimplemented;
7a387fff 7180 }
8c0fdd85
TS
7181 break;
7182 case 21:
7a387fff 7183 /* Officially reserved, but sel 0 is used for R1x000 framemask */
f31b035a 7184 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
7a387fff
TS
7185 switch (sel) {
7186 case 0:
7db13fae 7187 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
2423f660
TS
7188 rn = "Framemask";
7189 break;
7a387fff 7190 default:
f31b035a 7191 goto cp0_unimplemented;
7a387fff 7192 }
8c0fdd85
TS
7193 break;
7194 case 22:
d9bea114 7195 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
7196 rn = "'Diagnostic"; /* implementation dependent */
7197 break;
873eb012 7198 case 23:
7a387fff
TS
7199 switch (sel) {
7200 case 0:
895c2d04 7201 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
2423f660
TS
7202 rn = "Debug";
7203 break;
7a387fff 7204 case 1:
d9bea114 7205// gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
2423f660 7206 rn = "TraceControl";
3570d7f6 7207 goto cp0_unimplemented;
7a387fff 7208 case 2:
d9bea114 7209// gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
2423f660 7210 rn = "TraceControl2";
3570d7f6 7211 goto cp0_unimplemented;
7a387fff 7212 case 3:
d9bea114 7213// gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
2423f660 7214 rn = "UserTraceData";
3570d7f6 7215 goto cp0_unimplemented;
7a387fff 7216 case 4:
d9bea114 7217// gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
2423f660 7218 rn = "TraceBPC";
3570d7f6 7219 goto cp0_unimplemented;
7a387fff 7220 default:
f31b035a 7221 goto cp0_unimplemented;
7a387fff 7222 }
873eb012
TS
7223 break;
7224 case 24:
7a387fff
TS
7225 switch (sel) {
7226 case 0:
f0b3f3ae 7227 /* EJTAG support */
7db13fae 7228 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
d9bea114 7229 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
7230 rn = "DEPC";
7231 break;
7a387fff 7232 default:
f31b035a 7233 goto cp0_unimplemented;
7a387fff 7234 }
873eb012 7235 break;
8c0fdd85 7236 case 25:
7a387fff
TS
7237 switch (sel) {
7238 case 0:
7db13fae 7239 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
2423f660 7240 rn = "Performance0";
7a387fff
TS
7241 break;
7242 case 1:
d9bea114 7243// gen_helper_mfc0_performance1(arg);
2423f660 7244 rn = "Performance1";
3570d7f6 7245 goto cp0_unimplemented;
7a387fff 7246 case 2:
d9bea114 7247// gen_helper_mfc0_performance2(arg);
2423f660 7248 rn = "Performance2";
3570d7f6 7249 goto cp0_unimplemented;
7a387fff 7250 case 3:
d9bea114 7251// gen_helper_mfc0_performance3(arg);
2423f660 7252 rn = "Performance3";
3570d7f6 7253 goto cp0_unimplemented;
7a387fff 7254 case 4:
d9bea114 7255// gen_helper_mfc0_performance4(arg);
2423f660 7256 rn = "Performance4";
3570d7f6 7257 goto cp0_unimplemented;
7a387fff 7258 case 5:
d9bea114 7259// gen_helper_mfc0_performance5(arg);
2423f660 7260 rn = "Performance5";
3570d7f6 7261 goto cp0_unimplemented;
7a387fff 7262 case 6:
d9bea114 7263// gen_helper_mfc0_performance6(arg);
2423f660 7264 rn = "Performance6";
3570d7f6 7265 goto cp0_unimplemented;
7a387fff 7266 case 7:
d9bea114 7267// gen_helper_mfc0_performance7(arg);
2423f660 7268 rn = "Performance7";
3570d7f6 7269 goto cp0_unimplemented;
7a387fff 7270 default:
f31b035a 7271 goto cp0_unimplemented;
7a387fff 7272 }
8c0fdd85
TS
7273 break;
7274 case 26:
0d74a222
LA
7275 switch (sel) {
7276 case 0:
7277 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl));
7278 rn = "ErrCtl";
7279 break;
7280 default:
7281 goto cp0_unimplemented;
7282 }
da80682b 7283 break;
8c0fdd85 7284 case 27:
7a387fff 7285 switch (sel) {
c2e19f3c
AM
7286 case 0:
7287 case 1:
7288 case 2:
7289 case 3:
d9bea114 7290 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
7291 rn = "CacheErr";
7292 break;
7a387fff 7293 default:
f31b035a 7294 goto cp0_unimplemented;
7a387fff 7295 }
8c0fdd85 7296 break;
873eb012
TS
7297 case 28:
7298 switch (sel) {
7299 case 0:
7a387fff
TS
7300 case 2:
7301 case 4:
7302 case 6:
284b731a
LA
7303 {
7304 TCGv_i64 tmp = tcg_temp_new_i64();
7305 tcg_gen_ld_i64(tmp, cpu_env, offsetof(CPUMIPSState, CP0_TagLo));
7306 gen_move_low32(arg, tmp);
7307 tcg_temp_free_i64(tmp);
7308 }
873eb012
TS
7309 rn = "TagLo";
7310 break;
7311 case 1:
7a387fff
TS
7312 case 3:
7313 case 5:
7314 case 7:
7db13fae 7315 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
873eb012
TS
7316 rn = "DataLo";
7317 break;
7318 default:
f31b035a 7319 goto cp0_unimplemented;
873eb012
TS
7320 }
7321 break;
8c0fdd85 7322 case 29:
7a387fff
TS
7323 switch (sel) {
7324 case 0:
7325 case 2:
7326 case 4:
7327 case 6:
7db13fae 7328 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
7a387fff
TS
7329 rn = "TagHi";
7330 break;
7331 case 1:
7332 case 3:
7333 case 5:
7334 case 7:
7db13fae 7335 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
7a387fff
TS
7336 rn = "DataHi";
7337 break;
7338 default:
f31b035a 7339 goto cp0_unimplemented;
7a387fff 7340 }
8c0fdd85 7341 break;
873eb012 7342 case 30:
7a387fff
TS
7343 switch (sel) {
7344 case 0:
7db13fae 7345 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
d9bea114 7346 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
7347 rn = "ErrorEPC";
7348 break;
7a387fff 7349 default:
f31b035a 7350 goto cp0_unimplemented;
7a387fff 7351 }
873eb012
TS
7352 break;
7353 case 31:
7a387fff
TS
7354 switch (sel) {
7355 case 0:
f0b3f3ae 7356 /* EJTAG support */
7db13fae 7357 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
7358 rn = "DESAVE";
7359 break;
c2e19f3c
AM
7360 case 2:
7361 case 3:
7362 case 4:
7363 case 5:
7364 case 6:
7365 case 7:
f31b035a
LA
7366 CP0_CHECK(ctx->kscrexist & (1 << sel));
7367 tcg_gen_ld_tl(arg, cpu_env,
7368 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
7369 tcg_gen_ext32s_tl(arg, arg);
7370 rn = "KScratch";
e98c0d17 7371 break;
7a387fff 7372 default:
f31b035a 7373 goto cp0_unimplemented;
7a387fff 7374 }
873eb012
TS
7375 break;
7376 default:
f31b035a 7377 goto cp0_unimplemented;
873eb012 7378 }
b44a7fb1 7379 trace_mips_translate_c0("mfc0", rn, reg, sel);
873eb012
TS
7380 return;
7381
f31b035a 7382cp0_unimplemented:
965447ee 7383 qemu_log_mask(LOG_UNIMP, "mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
f31b035a 7384 gen_mfc0_unimplemented(ctx, arg);
873eb012
TS
7385}
7386
d75c135e 7387static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
8c0fdd85 7388{
7a387fff
TS
7389 const char *rn = "invalid";
7390
e189e748 7391 if (sel != 0)
d75c135e 7392 check_insn(ctx, ISA_MIPS32);
e189e748 7393
eeb3bba8 7394 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
2e70f6ef 7395 gen_io_start();
bd79255d 7396 }
2e70f6ef 7397
8c0fdd85
TS
7398 switch (reg) {
7399 case 0:
7a387fff
TS
7400 switch (sel) {
7401 case 0:
895c2d04 7402 gen_helper_mtc0_index(cpu_env, arg);
7a387fff
TS
7403 rn = "Index";
7404 break;
7405 case 1:
f31b035a 7406 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7407 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
7a387fff 7408 rn = "MVPControl";
ead9360e 7409 break;
7a387fff 7410 case 2:
f31b035a 7411 CP0_CHECK(ctx->insn_flags & ASE_MT);
ead9360e 7412 /* ignored */
7a387fff 7413 rn = "MVPConf0";
ead9360e 7414 break;
7a387fff 7415 case 3:
f31b035a 7416 CP0_CHECK(ctx->insn_flags & ASE_MT);
ead9360e 7417 /* ignored */
7a387fff 7418 rn = "MVPConf1";
ead9360e 7419 break;
01bc435b
YK
7420 case 4:
7421 CP0_CHECK(ctx->vp);
7422 /* ignored */
7423 rn = "VPControl";
7424 break;
7a387fff 7425 default:
f31b035a 7426 goto cp0_unimplemented;
7a387fff 7427 }
8c0fdd85
TS
7428 break;
7429 case 1:
7a387fff
TS
7430 switch (sel) {
7431 case 0:
2423f660 7432 /* ignored */
7a387fff 7433 rn = "Random";
2423f660 7434 break;
7a387fff 7435 case 1:
f31b035a 7436 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7437 gen_helper_mtc0_vpecontrol(cpu_env, arg);
7a387fff 7438 rn = "VPEControl";
ead9360e 7439 break;
7a387fff 7440 case 2:
f31b035a 7441 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7442 gen_helper_mtc0_vpeconf0(cpu_env, arg);
7a387fff 7443 rn = "VPEConf0";
ead9360e 7444 break;
7a387fff 7445 case 3:
f31b035a 7446 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7447 gen_helper_mtc0_vpeconf1(cpu_env, arg);
7a387fff 7448 rn = "VPEConf1";
ead9360e 7449 break;
7a387fff 7450 case 4:
f31b035a 7451 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7452 gen_helper_mtc0_yqmask(cpu_env, arg);
7a387fff 7453 rn = "YQMask";
ead9360e 7454 break;
7a387fff 7455 case 5:
f31b035a 7456 CP0_CHECK(ctx->insn_flags & ASE_MT);
d54a299b
LA
7457 tcg_gen_st_tl(arg, cpu_env,
7458 offsetof(CPUMIPSState, CP0_VPESchedule));
7a387fff 7459 rn = "VPESchedule";
ead9360e 7460 break;
7a387fff 7461 case 6:
f31b035a 7462 CP0_CHECK(ctx->insn_flags & ASE_MT);
d54a299b
LA
7463 tcg_gen_st_tl(arg, cpu_env,
7464 offsetof(CPUMIPSState, CP0_VPEScheFBack));
7a387fff 7465 rn = "VPEScheFBack";
ead9360e 7466 break;
7a387fff 7467 case 7:
f31b035a 7468 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7469 gen_helper_mtc0_vpeopt(cpu_env, arg);
7a387fff 7470 rn = "VPEOpt";
ead9360e 7471 break;
7a387fff 7472 default:
f31b035a 7473 goto cp0_unimplemented;
7a387fff 7474 }
8c0fdd85
TS
7475 break;
7476 case 2:
7a387fff
TS
7477 switch (sel) {
7478 case 0:
895c2d04 7479 gen_helper_mtc0_entrylo0(cpu_env, arg);
2423f660
TS
7480 rn = "EntryLo0";
7481 break;
7a387fff 7482 case 1:
f31b035a 7483 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7484 gen_helper_mtc0_tcstatus(cpu_env, arg);
2423f660 7485 rn = "TCStatus";
ead9360e 7486 break;
7a387fff 7487 case 2:
f31b035a 7488 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7489 gen_helper_mtc0_tcbind(cpu_env, arg);
2423f660 7490 rn = "TCBind";
ead9360e 7491 break;
7a387fff 7492 case 3:
f31b035a 7493 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7494 gen_helper_mtc0_tcrestart(cpu_env, arg);
2423f660 7495 rn = "TCRestart";
ead9360e 7496 break;
7a387fff 7497 case 4:
f31b035a 7498 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7499 gen_helper_mtc0_tchalt(cpu_env, arg);
2423f660 7500 rn = "TCHalt";
ead9360e 7501 break;
7a387fff 7502 case 5:
f31b035a 7503 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7504 gen_helper_mtc0_tccontext(cpu_env, arg);
2423f660 7505 rn = "TCContext";
ead9360e 7506 break;
7a387fff 7507 case 6:
f31b035a 7508 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7509 gen_helper_mtc0_tcschedule(cpu_env, arg);
2423f660 7510 rn = "TCSchedule";
ead9360e 7511 break;
7a387fff 7512 case 7:
f31b035a 7513 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7514 gen_helper_mtc0_tcschefback(cpu_env, arg);
2423f660 7515 rn = "TCScheFBack";
ead9360e 7516 break;
7a387fff 7517 default:
f31b035a 7518 goto cp0_unimplemented;
7a387fff 7519 }
8c0fdd85
TS
7520 break;
7521 case 3:
7a387fff
TS
7522 switch (sel) {
7523 case 0:
895c2d04 7524 gen_helper_mtc0_entrylo1(cpu_env, arg);
2423f660
TS
7525 rn = "EntryLo1";
7526 break;
01bc435b
YK
7527 case 1:
7528 CP0_CHECK(ctx->vp);
7529 /* ignored */
7530 rn = "GlobalNumber";
7531 break;
7a387fff 7532 default:
f31b035a 7533 goto cp0_unimplemented;
876d4b07 7534 }
8c0fdd85
TS
7535 break;
7536 case 4:
7a387fff
TS
7537 switch (sel) {
7538 case 0:
895c2d04 7539 gen_helper_mtc0_context(cpu_env, arg);
2423f660
TS
7540 rn = "Context";
7541 break;
7a387fff 7542 case 1:
895c2d04 7543// gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
2423f660 7544 rn = "ContextConfig";
f31b035a 7545 goto cp0_unimplemented;
d279279e 7546 case 2:
f31b035a
LA
7547 CP0_CHECK(ctx->ulri);
7548 tcg_gen_st_tl(arg, cpu_env,
7549 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
7550 rn = "UserLocal";
d279279e 7551 break;
7a387fff 7552 default:
f31b035a 7553 goto cp0_unimplemented;
876d4b07 7554 }
8c0fdd85
TS
7555 break;
7556 case 5:
7a387fff
TS
7557 switch (sel) {
7558 case 0:
895c2d04 7559 gen_helper_mtc0_pagemask(cpu_env, arg);
2423f660
TS
7560 rn = "PageMask";
7561 break;
7a387fff 7562 case 1:
d75c135e 7563 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7564 gen_helper_mtc0_pagegrain(cpu_env, arg);
2423f660 7565 rn = "PageGrain";
eeb3bba8 7566 ctx->base.is_jmp = DISAS_STOP;
2423f660 7567 break;
cec56a73
JH
7568 case 2:
7569 CP0_CHECK(ctx->sc);
7570 gen_helper_mtc0_segctl0(cpu_env, arg);
7571 rn = "SegCtl0";
7572 break;
7573 case 3:
7574 CP0_CHECK(ctx->sc);
7575 gen_helper_mtc0_segctl1(cpu_env, arg);
7576 rn = "SegCtl1";
7577 break;
7578 case 4:
7579 CP0_CHECK(ctx->sc);
7580 gen_helper_mtc0_segctl2(cpu_env, arg);
7581 rn = "SegCtl2";
7582 break;
5e31fdd5
YK
7583 case 5:
7584 check_pw(ctx);
7585 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_PWBase));
7586 rn = "PWBase";
7587 break;
fa75ad14
YK
7588 case 6:
7589 check_pw(ctx);
7590 gen_helper_mtc0_pwfield(cpu_env, arg);
7591 rn = "PWField";
7592 break;
20b28ebc
YK
7593 case 7:
7594 check_pw(ctx);
7595 gen_helper_mtc0_pwsize(cpu_env, arg);
7596 rn = "PWSize";
7597 break;
7a387fff 7598 default:
f31b035a 7599 goto cp0_unimplemented;
876d4b07 7600 }
8c0fdd85
TS
7601 break;
7602 case 6:
7a387fff
TS
7603 switch (sel) {
7604 case 0:
895c2d04 7605 gen_helper_mtc0_wired(cpu_env, arg);
2423f660
TS
7606 rn = "Wired";
7607 break;
7a387fff 7608 case 1:
d75c135e 7609 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7610 gen_helper_mtc0_srsconf0(cpu_env, arg);
2423f660 7611 rn = "SRSConf0";
ead9360e 7612 break;
7a387fff 7613 case 2:
d75c135e 7614 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7615 gen_helper_mtc0_srsconf1(cpu_env, arg);
2423f660 7616 rn = "SRSConf1";
ead9360e 7617 break;
7a387fff 7618 case 3:
d75c135e 7619 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7620 gen_helper_mtc0_srsconf2(cpu_env, arg);
2423f660 7621 rn = "SRSConf2";
ead9360e 7622 break;
7a387fff 7623 case 4:
d75c135e 7624 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7625 gen_helper_mtc0_srsconf3(cpu_env, arg);
2423f660 7626 rn = "SRSConf3";
ead9360e 7627 break;
7a387fff 7628 case 5:
d75c135e 7629 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7630 gen_helper_mtc0_srsconf4(cpu_env, arg);
2423f660 7631 rn = "SRSConf4";
ead9360e 7632 break;
103be64c
YK
7633 case 6:
7634 check_pw(ctx);
7635 gen_helper_mtc0_pwctl(cpu_env, arg);
7636 rn = "PWCtl";
7637 break;
7a387fff 7638 default:
f31b035a 7639 goto cp0_unimplemented;
876d4b07 7640 }
8c0fdd85
TS
7641 break;
7642 case 7:
7a387fff
TS
7643 switch (sel) {
7644 case 0:
d75c135e 7645 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7646 gen_helper_mtc0_hwrena(cpu_env, arg);
eeb3bba8 7647 ctx->base.is_jmp = DISAS_STOP;
2423f660
TS
7648 rn = "HWREna";
7649 break;
7a387fff 7650 default:
f31b035a 7651 goto cp0_unimplemented;
876d4b07 7652 }
8c0fdd85
TS
7653 break;
7654 case 8:
aea14095
LA
7655 switch (sel) {
7656 case 0:
7657 /* ignored */
7658 rn = "BadVAddr";
7659 break;
7660 case 1:
7661 /* ignored */
7662 rn = "BadInstr";
7663 break;
7664 case 2:
7665 /* ignored */
7666 rn = "BadInstrP";
7667 break;
25beba9b
SM
7668 case 3:
7669 /* ignored */
7670 rn = "BadInstrX";
7671 break;
aea14095 7672 default:
f31b035a 7673 goto cp0_unimplemented;
aea14095 7674 }
8c0fdd85
TS
7675 break;
7676 case 9:
7a387fff
TS
7677 switch (sel) {
7678 case 0:
895c2d04 7679 gen_helper_mtc0_count(cpu_env, arg);
2423f660
TS
7680 rn = "Count";
7681 break;
876d4b07 7682 /* 6,7 are implementation dependent */
7a387fff 7683 default:
f31b035a 7684 goto cp0_unimplemented;
876d4b07 7685 }
8c0fdd85
TS
7686 break;
7687 case 10:
7a387fff
TS
7688 switch (sel) {
7689 case 0:
895c2d04 7690 gen_helper_mtc0_entryhi(cpu_env, arg);
2423f660
TS
7691 rn = "EntryHi";
7692 break;
7a387fff 7693 default:
f31b035a 7694 goto cp0_unimplemented;
876d4b07 7695 }
8c0fdd85
TS
7696 break;
7697 case 11:
7a387fff
TS
7698 switch (sel) {
7699 case 0:
895c2d04 7700 gen_helper_mtc0_compare(cpu_env, arg);
2423f660
TS
7701 rn = "Compare";
7702 break;
7703 /* 6,7 are implementation dependent */
7a387fff 7704 default:
f31b035a 7705 goto cp0_unimplemented;
876d4b07 7706 }
8c0fdd85
TS
7707 break;
7708 case 12:
7a387fff
TS
7709 switch (sel) {
7710 case 0:
867abc7e 7711 save_cpu_state(ctx, 1);
895c2d04 7712 gen_helper_mtc0_status(cpu_env, arg);
b28425ba 7713 /* DISAS_STOP isn't good enough here, hflags may have changed. */
eeb3bba8
EC
7714 gen_save_pc(ctx->base.pc_next + 4);
7715 ctx->base.is_jmp = DISAS_EXIT;
2423f660
TS
7716 rn = "Status";
7717 break;
7a387fff 7718 case 1:
d75c135e 7719 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7720 gen_helper_mtc0_intctl(cpu_env, arg);
8487327a 7721 /* Stop translation as we may have switched the execution mode */
eeb3bba8 7722 ctx->base.is_jmp = DISAS_STOP;
2423f660
TS
7723 rn = "IntCtl";
7724 break;
7a387fff 7725 case 2:
d75c135e 7726 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7727 gen_helper_mtc0_srsctl(cpu_env, arg);
8487327a 7728 /* Stop translation as we may have switched the execution mode */
eeb3bba8 7729 ctx->base.is_jmp = DISAS_STOP;
2423f660
TS
7730 rn = "SRSCtl";
7731 break;
7a387fff 7732 case 3:
d75c135e 7733 check_insn(ctx, ISA_MIPS32R2);
7db13fae 7734 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
8487327a 7735 /* Stop translation as we may have switched the execution mode */
eeb3bba8 7736 ctx->base.is_jmp = DISAS_STOP;
2423f660 7737 rn = "SRSMap";
fd88b6ab 7738 break;
7a387fff 7739 default:
f31b035a 7740 goto cp0_unimplemented;
876d4b07 7741 }
8c0fdd85
TS
7742 break;
7743 case 13:
7a387fff
TS
7744 switch (sel) {
7745 case 0:
867abc7e 7746 save_cpu_state(ctx, 1);
895c2d04 7747 gen_helper_mtc0_cause(cpu_env, arg);
b28425ba
EC
7748 /* Stop translation as we may have triggered an interrupt.
7749 * DISAS_STOP isn't sufficient, we need to ensure we break out of
7750 * translated code to check for pending interrupts. */
eeb3bba8
EC
7751 gen_save_pc(ctx->base.pc_next + 4);
7752 ctx->base.is_jmp = DISAS_EXIT;
2423f660
TS
7753 rn = "Cause";
7754 break;
7a387fff 7755 default:
f31b035a 7756 goto cp0_unimplemented;
876d4b07 7757 }
8c0fdd85
TS
7758 break;
7759 case 14:
7a387fff
TS
7760 switch (sel) {
7761 case 0:
d54a299b 7762 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
2423f660
TS
7763 rn = "EPC";
7764 break;
7a387fff 7765 default:
f31b035a 7766 goto cp0_unimplemented;
876d4b07 7767 }
8c0fdd85
TS
7768 break;
7769 case 15:
7a387fff
TS
7770 switch (sel) {
7771 case 0:
2423f660
TS
7772 /* ignored */
7773 rn = "PRid";
7774 break;
7a387fff 7775 case 1:
d75c135e 7776 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7777 gen_helper_mtc0_ebase(cpu_env, arg);
2423f660
TS
7778 rn = "EBase";
7779 break;
7a387fff 7780 default:
f31b035a 7781 goto cp0_unimplemented;
1579a72e 7782 }
8c0fdd85
TS
7783 break;
7784 case 16:
7785 switch (sel) {
7786 case 0:
895c2d04 7787 gen_helper_mtc0_config0(cpu_env, arg);
7a387fff 7788 rn = "Config";
2423f660 7789 /* Stop translation as we may have switched the execution mode */
eeb3bba8 7790 ctx->base.is_jmp = DISAS_STOP;
7a387fff
TS
7791 break;
7792 case 1:
e397ee33 7793 /* ignored, read only */
7a387fff
TS
7794 rn = "Config1";
7795 break;
7796 case 2:
895c2d04 7797 gen_helper_mtc0_config2(cpu_env, arg);
7a387fff 7798 rn = "Config2";
2423f660 7799 /* Stop translation as we may have switched the execution mode */
eeb3bba8 7800 ctx->base.is_jmp = DISAS_STOP;
8c0fdd85 7801 break;
7a387fff 7802 case 3:
90f12d73 7803 gen_helper_mtc0_config3(cpu_env, arg);
7a387fff 7804 rn = "Config3";
90f12d73 7805 /* Stop translation as we may have switched the execution mode */
eeb3bba8 7806 ctx->base.is_jmp = DISAS_STOP;
7a387fff 7807 break;
b4160af1
PJ
7808 case 4:
7809 gen_helper_mtc0_config4(cpu_env, arg);
7810 rn = "Config4";
eeb3bba8 7811 ctx->base.is_jmp = DISAS_STOP;
b4160af1 7812 break;
b4dd99a3
PJ
7813 case 5:
7814 gen_helper_mtc0_config5(cpu_env, arg);
7815 rn = "Config5";
7816 /* Stop translation as we may have switched the execution mode */
eeb3bba8 7817 ctx->base.is_jmp = DISAS_STOP;
b4dd99a3 7818 break;
e397ee33
TS
7819 /* 6,7 are implementation dependent */
7820 case 6:
7821 /* ignored */
7822 rn = "Config6";
7823 break;
7824 case 7:
7825 /* ignored */
7826 rn = "Config7";
7827 break;
8c0fdd85
TS
7828 default:
7829 rn = "Invalid config selector";
f31b035a 7830 goto cp0_unimplemented;
8c0fdd85
TS
7831 }
7832 break;
7833 case 17:
7a387fff
TS
7834 switch (sel) {
7835 case 0:
895c2d04 7836 gen_helper_mtc0_lladdr(cpu_env, arg);
2423f660
TS
7837 rn = "LLAddr";
7838 break;
f6d4dd81
YK
7839 case 1:
7840 CP0_CHECK(ctx->mrp);
7841 gen_helper_mtc0_maar(cpu_env, arg);
7842 rn = "MAAR";
7843 break;
7844 case 2:
7845 CP0_CHECK(ctx->mrp);
7846 gen_helper_mtc0_maari(cpu_env, arg);
7847 rn = "MAARI";
7848 break;
7a387fff 7849 default:
f31b035a 7850 goto cp0_unimplemented;
7a387fff 7851 }
8c0fdd85
TS
7852 break;
7853 case 18:
7a387fff 7854 switch (sel) {
c2e19f3c
AM
7855 case 0:
7856 case 1:
7857 case 2:
7858 case 3:
7859 case 4:
7860 case 5:
7861 case 6:
7862 case 7:
fa192d49 7863 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
895c2d04 7864 gen_helper_0e1i(mtc0_watchlo, arg, sel);
2423f660
TS
7865 rn = "WatchLo";
7866 break;
7a387fff 7867 default:
f31b035a 7868 goto cp0_unimplemented;
7a387fff 7869 }
8c0fdd85
TS
7870 break;
7871 case 19:
7a387fff 7872 switch (sel) {
c2e19f3c
AM
7873 case 0:
7874 case 1:
7875 case 2:
7876 case 3:
7877 case 4:
7878 case 5:
7879 case 6:
7880 case 7:
fa192d49 7881 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
895c2d04 7882 gen_helper_0e1i(mtc0_watchhi, arg, sel);
2423f660
TS
7883 rn = "WatchHi";
7884 break;
7a387fff 7885 default:
f31b035a 7886 goto cp0_unimplemented;
7a387fff 7887 }
8c0fdd85
TS
7888 break;
7889 case 20:
7a387fff
TS
7890 switch (sel) {
7891 case 0:
d26bc211 7892#if defined(TARGET_MIPS64)
d75c135e 7893 check_insn(ctx, ISA_MIPS3);
895c2d04 7894 gen_helper_mtc0_xcontext(cpu_env, arg);
2423f660
TS
7895 rn = "XContext";
7896 break;
703eaf37 7897#endif
7a387fff 7898 default:
f31b035a 7899 goto cp0_unimplemented;
7a387fff 7900 }
8c0fdd85
TS
7901 break;
7902 case 21:
7a387fff 7903 /* Officially reserved, but sel 0 is used for R1x000 framemask */
f31b035a 7904 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
7a387fff
TS
7905 switch (sel) {
7906 case 0:
895c2d04 7907 gen_helper_mtc0_framemask(cpu_env, arg);
2423f660
TS
7908 rn = "Framemask";
7909 break;
7a387fff 7910 default:
f31b035a 7911 goto cp0_unimplemented;
7a387fff
TS
7912 }
7913 break;
8c0fdd85 7914 case 22:
7a387fff
TS
7915 /* ignored */
7916 rn = "Diagnostic"; /* implementation dependent */
2423f660 7917 break;
8c0fdd85 7918 case 23:
7a387fff
TS
7919 switch (sel) {
7920 case 0:
895c2d04 7921 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
b28425ba 7922 /* DISAS_STOP isn't good enough here, hflags may have changed. */
eeb3bba8
EC
7923 gen_save_pc(ctx->base.pc_next + 4);
7924 ctx->base.is_jmp = DISAS_EXIT;
2423f660
TS
7925 rn = "Debug";
7926 break;
7a387fff 7927 case 1:
895c2d04 7928// gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
2423f660 7929 rn = "TraceControl";
8487327a 7930 /* Stop translation as we may have switched the execution mode */
eeb3bba8 7931 ctx->base.is_jmp = DISAS_STOP;
3570d7f6 7932 goto cp0_unimplemented;
7a387fff 7933 case 2:
895c2d04 7934// gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
2423f660 7935 rn = "TraceControl2";
8487327a 7936 /* Stop translation as we may have switched the execution mode */
eeb3bba8 7937 ctx->base.is_jmp = DISAS_STOP;
3570d7f6 7938 goto cp0_unimplemented;
7a387fff 7939 case 3:
8487327a 7940 /* Stop translation as we may have switched the execution mode */
eeb3bba8 7941 ctx->base.is_jmp = DISAS_STOP;
895c2d04 7942// gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
2423f660 7943 rn = "UserTraceData";
8487327a 7944 /* Stop translation as we may have switched the execution mode */
eeb3bba8 7945 ctx->base.is_jmp = DISAS_STOP;
3570d7f6 7946 goto cp0_unimplemented;
7a387fff 7947 case 4:
895c2d04 7948// gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
8487327a 7949 /* Stop translation as we may have switched the execution mode */
eeb3bba8 7950 ctx->base.is_jmp = DISAS_STOP;
2423f660 7951 rn = "TraceBPC";
3570d7f6 7952 goto cp0_unimplemented;
7a387fff 7953 default:
f31b035a 7954 goto cp0_unimplemented;
7a387fff 7955 }
8c0fdd85
TS
7956 break;
7957 case 24:
7a387fff
TS
7958 switch (sel) {
7959 case 0:
f1aa6320 7960 /* EJTAG support */
d54a299b 7961 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
2423f660
TS
7962 rn = "DEPC";
7963 break;
7a387fff 7964 default:
f31b035a 7965 goto cp0_unimplemented;
7a387fff 7966 }
8c0fdd85
TS
7967 break;
7968 case 25:
7a387fff
TS
7969 switch (sel) {
7970 case 0:
895c2d04 7971 gen_helper_mtc0_performance0(cpu_env, arg);
2423f660
TS
7972 rn = "Performance0";
7973 break;
7a387fff 7974 case 1:
d9bea114 7975// gen_helper_mtc0_performance1(arg);
2423f660 7976 rn = "Performance1";
3570d7f6 7977 goto cp0_unimplemented;
7a387fff 7978 case 2:
d9bea114 7979// gen_helper_mtc0_performance2(arg);
2423f660 7980 rn = "Performance2";
3570d7f6 7981 goto cp0_unimplemented;
7a387fff 7982 case 3:
d9bea114 7983// gen_helper_mtc0_performance3(arg);
2423f660 7984 rn = "Performance3";
3570d7f6 7985 goto cp0_unimplemented;
7a387fff 7986 case 4:
d9bea114 7987// gen_helper_mtc0_performance4(arg);
2423f660 7988 rn = "Performance4";
3570d7f6 7989 goto cp0_unimplemented;
7a387fff 7990 case 5:
d9bea114 7991// gen_helper_mtc0_performance5(arg);
2423f660 7992 rn = "Performance5";
3570d7f6 7993 goto cp0_unimplemented;
7a387fff 7994 case 6:
d9bea114 7995// gen_helper_mtc0_performance6(arg);
2423f660 7996 rn = "Performance6";
3570d7f6 7997 goto cp0_unimplemented;
7a387fff 7998 case 7:
d9bea114 7999// gen_helper_mtc0_performance7(arg);
2423f660 8000 rn = "Performance7";
3570d7f6 8001 goto cp0_unimplemented;
7a387fff 8002 default:
f31b035a 8003 goto cp0_unimplemented;
7a387fff 8004 }
8c0fdd85
TS
8005 break;
8006 case 26:
0d74a222
LA
8007 switch (sel) {
8008 case 0:
8009 gen_helper_mtc0_errctl(cpu_env, arg);
eeb3bba8 8010 ctx->base.is_jmp = DISAS_STOP;
0d74a222
LA
8011 rn = "ErrCtl";
8012 break;
8013 default:
8014 goto cp0_unimplemented;
8015 }
2423f660 8016 break;
8c0fdd85 8017 case 27:
7a387fff 8018 switch (sel) {
c2e19f3c
AM
8019 case 0:
8020 case 1:
8021 case 2:
8022 case 3:
2423f660
TS
8023 /* ignored */
8024 rn = "CacheErr";
8025 break;
7a387fff 8026 default:
f31b035a 8027 goto cp0_unimplemented;
7a387fff 8028 }
8c0fdd85
TS
8029 break;
8030 case 28:
8031 switch (sel) {
8032 case 0:
7a387fff
TS
8033 case 2:
8034 case 4:
8035 case 6:
895c2d04 8036 gen_helper_mtc0_taglo(cpu_env, arg);
8c0fdd85
TS
8037 rn = "TagLo";
8038 break;
7a387fff
TS
8039 case 1:
8040 case 3:
8041 case 5:
8042 case 7:
895c2d04 8043 gen_helper_mtc0_datalo(cpu_env, arg);
7a387fff
TS
8044 rn = "DataLo";
8045 break;
8c0fdd85 8046 default:
f31b035a 8047 goto cp0_unimplemented;
8c0fdd85
TS
8048 }
8049 break;
8050 case 29:
7a387fff
TS
8051 switch (sel) {
8052 case 0:
8053 case 2:
8054 case 4:
8055 case 6:
895c2d04 8056 gen_helper_mtc0_taghi(cpu_env, arg);
7a387fff
TS
8057 rn = "TagHi";
8058 break;
8059 case 1:
8060 case 3:
8061 case 5:
8062 case 7:
895c2d04 8063 gen_helper_mtc0_datahi(cpu_env, arg);
7a387fff
TS
8064 rn = "DataHi";
8065 break;
8066 default:
8067 rn = "invalid sel";
f31b035a 8068 goto cp0_unimplemented;
7a387fff 8069 }
8c0fdd85
TS
8070 break;
8071 case 30:
7a387fff
TS
8072 switch (sel) {
8073 case 0:
d54a299b 8074 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
2423f660
TS
8075 rn = "ErrorEPC";
8076 break;
7a387fff 8077 default:
f31b035a 8078 goto cp0_unimplemented;
7a387fff 8079 }
8c0fdd85
TS
8080 break;
8081 case 31:
7a387fff
TS
8082 switch (sel) {
8083 case 0:
f1aa6320 8084 /* EJTAG support */
7db13fae 8085 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
8086 rn = "DESAVE";
8087 break;
c2e19f3c
AM
8088 case 2:
8089 case 3:
8090 case 4:
8091 case 5:
8092 case 6:
8093 case 7:
f31b035a
LA
8094 CP0_CHECK(ctx->kscrexist & (1 << sel));
8095 tcg_gen_st_tl(arg, cpu_env,
8096 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
8097 rn = "KScratch";
e98c0d17 8098 break;
7a387fff 8099 default:
f31b035a 8100 goto cp0_unimplemented;
7a387fff 8101 }
8c0fdd85
TS
8102 break;
8103 default:
f31b035a 8104 goto cp0_unimplemented;
8c0fdd85 8105 }
b44a7fb1
PMD
8106 trace_mips_translate_c0("mtc0", rn, reg, sel);
8107
bf20dc07 8108 /* For simplicity assume that all writes can cause interrupts. */
eeb3bba8 8109 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
2e70f6ef 8110 gen_io_end();
b28425ba 8111 /* DISAS_STOP isn't sufficient, we need to ensure we break out of
b74cddcb 8112 * translated code to check for pending interrupts. */
eeb3bba8
EC
8113 gen_save_pc(ctx->base.pc_next + 4);
8114 ctx->base.is_jmp = DISAS_EXIT;
2e70f6ef 8115 }
8c0fdd85
TS
8116 return;
8117
f31b035a 8118cp0_unimplemented:
965447ee 8119 qemu_log_mask(LOG_UNIMP, "mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
8c0fdd85
TS
8120}
8121
d26bc211 8122#if defined(TARGET_MIPS64)
d75c135e 8123static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
9c2149c8
TS
8124{
8125 const char *rn = "invalid";
8126
e189e748 8127 if (sel != 0)
d75c135e 8128 check_insn(ctx, ISA_MIPS64);
e189e748 8129
9c2149c8
TS
8130 switch (reg) {
8131 case 0:
8132 switch (sel) {
8133 case 0:
7db13fae 8134 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
9c2149c8
TS
8135 rn = "Index";
8136 break;
8137 case 1:
f31b035a 8138 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 8139 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
9c2149c8 8140 rn = "MVPControl";
ead9360e 8141 break;
9c2149c8 8142 case 2:
f31b035a 8143 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 8144 gen_helper_mfc0_mvpconf0(arg, cpu_env);
9c2149c8 8145 rn = "MVPConf0";
ead9360e 8146 break;
9c2149c8 8147 case 3:
f31b035a 8148 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 8149 gen_helper_mfc0_mvpconf1(arg, cpu_env);
9c2149c8 8150 rn = "MVPConf1";
ead9360e 8151 break;
01bc435b
YK
8152 case 4:
8153 CP0_CHECK(ctx->vp);
8154 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl));
8155 rn = "VPControl";
8156 break;
9c2149c8 8157 default:
f31b035a 8158 goto cp0_unimplemented;
9c2149c8
TS
8159 }
8160 break;
8161 case 1:
8162 switch (sel) {
8163 case 0:
f31b035a 8164 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
895c2d04 8165 gen_helper_mfc0_random(arg, cpu_env);
9c2149c8 8166 rn = "Random";
2423f660 8167 break;
9c2149c8 8168 case 1:
f31b035a 8169 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 8170 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
9c2149c8 8171 rn = "VPEControl";
ead9360e 8172 break;
9c2149c8 8173 case 2:
f31b035a 8174 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 8175 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
9c2149c8 8176 rn = "VPEConf0";
ead9360e 8177 break;
9c2149c8 8178 case 3:
f31b035a 8179 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 8180 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
9c2149c8 8181 rn = "VPEConf1";
ead9360e 8182 break;
9c2149c8 8183 case 4:
f31b035a 8184 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 8185 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_YQMask));
9c2149c8 8186 rn = "YQMask";
ead9360e 8187 break;
9c2149c8 8188 case 5:
f31b035a 8189 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 8190 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
9c2149c8 8191 rn = "VPESchedule";
ead9360e 8192 break;
9c2149c8 8193 case 6:
f31b035a 8194 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 8195 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
9c2149c8 8196 rn = "VPEScheFBack";
ead9360e 8197 break;
9c2149c8 8198 case 7:
f31b035a 8199 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 8200 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
9c2149c8 8201 rn = "VPEOpt";
ead9360e 8202 break;
9c2149c8 8203 default:
f31b035a 8204 goto cp0_unimplemented;
9c2149c8
TS
8205 }
8206 break;
8207 case 2:
8208 switch (sel) {
8209 case 0:
7db13fae 8210 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
2423f660
TS
8211 rn = "EntryLo0";
8212 break;
9c2149c8 8213 case 1:
f31b035a 8214 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 8215 gen_helper_mfc0_tcstatus(arg, cpu_env);
2423f660 8216 rn = "TCStatus";
ead9360e 8217 break;
9c2149c8 8218 case 2:
f31b035a 8219 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 8220 gen_helper_mfc0_tcbind(arg, cpu_env);
2423f660 8221 rn = "TCBind";
ead9360e 8222 break;
9c2149c8 8223 case 3:
f31b035a 8224 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 8225 gen_helper_dmfc0_tcrestart(arg, cpu_env);
2423f660 8226 rn = "TCRestart";
ead9360e 8227 break;
9c2149c8 8228 case 4:
f31b035a 8229 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 8230 gen_helper_dmfc0_tchalt(arg, cpu_env);
2423f660 8231 rn = "TCHalt";
ead9360e 8232 break;
9c2149c8 8233 case 5:
f31b035a 8234 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 8235 gen_helper_dmfc0_tccontext(arg, cpu_env);
2423f660 8236 rn = "TCContext";
ead9360e 8237 break;
9c2149c8 8238 case 6:
f31b035a 8239 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 8240 gen_helper_dmfc0_tcschedule(arg, cpu_env);
2423f660 8241 rn = "TCSchedule";
ead9360e 8242 break;
9c2149c8 8243 case 7:
f31b035a 8244 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 8245 gen_helper_dmfc0_tcschefback(arg, cpu_env);
2423f660 8246 rn = "TCScheFBack";
ead9360e 8247 break;
9c2149c8 8248 default:
f31b035a 8249 goto cp0_unimplemented;
9c2149c8
TS
8250 }
8251 break;
8252 case 3:
8253 switch (sel) {
8254 case 0:
7db13fae 8255 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
2423f660
TS
8256 rn = "EntryLo1";
8257 break;
01bc435b
YK
8258 case 1:
8259 CP0_CHECK(ctx->vp);
8260 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber));
8261 rn = "GlobalNumber";
8262 break;
9c2149c8 8263 default:
f31b035a 8264 goto cp0_unimplemented;
1579a72e 8265 }
9c2149c8
TS
8266 break;
8267 case 4:
8268 switch (sel) {
8269 case 0:
7db13fae 8270 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
2423f660
TS
8271 rn = "Context";
8272 break;
9c2149c8 8273 case 1:
d9bea114 8274// gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
2423f660 8275 rn = "ContextConfig";
f31b035a 8276 goto cp0_unimplemented;
d279279e 8277 case 2:
f31b035a
LA
8278 CP0_CHECK(ctx->ulri);
8279 tcg_gen_ld_tl(arg, cpu_env,
8280 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
8281 rn = "UserLocal";
d279279e 8282 break;
9c2149c8 8283 default:
f31b035a 8284 goto cp0_unimplemented;
876d4b07 8285 }
9c2149c8
TS
8286 break;
8287 case 5:
8288 switch (sel) {
8289 case 0:
7db13fae 8290 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
2423f660
TS
8291 rn = "PageMask";
8292 break;
9c2149c8 8293 case 1:
d75c135e 8294 check_insn(ctx, ISA_MIPS32R2);
7db13fae 8295 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
2423f660
TS
8296 rn = "PageGrain";
8297 break;
cec56a73
JH
8298 case 2:
8299 CP0_CHECK(ctx->sc);
8300 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl0));
8301 rn = "SegCtl0";
8302 break;
8303 case 3:
8304 CP0_CHECK(ctx->sc);
8305 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl1));
8306 rn = "SegCtl1";
8307 break;
8308 case 4:
8309 CP0_CHECK(ctx->sc);
8310 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl2));
8311 rn = "SegCtl2";
8312 break;
5e31fdd5
YK
8313 case 5:
8314 check_pw(ctx);
8315 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWBase));
8316 rn = "PWBase";
8317 break;
fa75ad14
YK
8318 case 6:
8319 check_pw(ctx);
8320 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWField));
8321 rn = "PWField";
8322 break;
20b28ebc
YK
8323 case 7:
8324 check_pw(ctx);
8325 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWSize));
8326 rn = "PWSize";
8327 break;
9c2149c8 8328 default:
f31b035a 8329 goto cp0_unimplemented;
876d4b07 8330 }
9c2149c8
TS
8331 break;
8332 case 6:
8333 switch (sel) {
8334 case 0:
7db13fae 8335 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
2423f660
TS
8336 rn = "Wired";
8337 break;
9c2149c8 8338 case 1:
d75c135e 8339 check_insn(ctx, ISA_MIPS32R2);
7db13fae 8340 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
2423f660 8341 rn = "SRSConf0";
ead9360e 8342 break;
9c2149c8 8343 case 2:
d75c135e 8344 check_insn(ctx, ISA_MIPS32R2);
7db13fae 8345 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
2423f660 8346 rn = "SRSConf1";
ead9360e 8347 break;
9c2149c8 8348 case 3:
d75c135e 8349 check_insn(ctx, ISA_MIPS32R2);
7db13fae 8350 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
2423f660 8351 rn = "SRSConf2";
ead9360e 8352 break;
9c2149c8 8353 case 4:
d75c135e 8354 check_insn(ctx, ISA_MIPS32R2);
7db13fae 8355 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
2423f660 8356 rn = "SRSConf3";
ead9360e 8357 break;
9c2149c8 8358 case 5:
d75c135e 8359 check_insn(ctx, ISA_MIPS32R2);
7db13fae 8360 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
2423f660 8361 rn = "SRSConf4";
ead9360e 8362 break;
103be64c
YK
8363 case 6:
8364 check_pw(ctx);
8365 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWCtl));
8366 rn = "PWCtl";
8367 break;
9c2149c8 8368 default:
f31b035a 8369 goto cp0_unimplemented;
876d4b07 8370 }
9c2149c8
TS
8371 break;
8372 case 7:
8373 switch (sel) {
8374 case 0:
d75c135e 8375 check_insn(ctx, ISA_MIPS32R2);
7db13fae 8376 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
2423f660
TS
8377 rn = "HWREna";
8378 break;
9c2149c8 8379 default:
f31b035a 8380 goto cp0_unimplemented;
876d4b07 8381 }
9c2149c8
TS
8382 break;
8383 case 8:
8384 switch (sel) {
8385 case 0:
7db13fae 8386 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
f0b3f3ae 8387 rn = "BadVAddr";
2423f660 8388 break;
aea14095 8389 case 1:
f31b035a
LA
8390 CP0_CHECK(ctx->bi);
8391 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
8392 rn = "BadInstr";
aea14095
LA
8393 break;
8394 case 2:
f31b035a
LA
8395 CP0_CHECK(ctx->bp);
8396 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
8397 rn = "BadInstrP";
aea14095 8398 break;
25beba9b
SM
8399 case 3:
8400 CP0_CHECK(ctx->bi);
8401 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrX));
8402 tcg_gen_andi_tl(arg, arg, ~0xffff);
8403 rn = "BadInstrX";
8404 break;
9c2149c8 8405 default:
f31b035a 8406 goto cp0_unimplemented;
876d4b07 8407 }
9c2149c8
TS
8408 break;
8409 case 9:
8410 switch (sel) {
8411 case 0:
2e70f6ef 8412 /* Mark as an IO operation because we read the time. */
eeb3bba8 8413 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
2e70f6ef 8414 gen_io_start();
bd79255d 8415 }
895c2d04 8416 gen_helper_mfc0_count(arg, cpu_env);
eeb3bba8 8417 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
2e70f6ef 8418 gen_io_end();
2e70f6ef 8419 }
55807224 8420 /* Break the TB to be able to take timer interrupts immediately
b28425ba
EC
8421 after reading count. DISAS_STOP isn't sufficient, we need to
8422 ensure we break completely out of translated code. */
eeb3bba8
EC
8423 gen_save_pc(ctx->base.pc_next + 4);
8424 ctx->base.is_jmp = DISAS_EXIT;
2423f660
TS
8425 rn = "Count";
8426 break;
8427 /* 6,7 are implementation dependent */
9c2149c8 8428 default:
f31b035a 8429 goto cp0_unimplemented;
876d4b07 8430 }
9c2149c8
TS
8431 break;
8432 case 10:
8433 switch (sel) {
8434 case 0:
7db13fae 8435 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
2423f660
TS
8436 rn = "EntryHi";
8437 break;
9c2149c8 8438 default:
f31b035a 8439 goto cp0_unimplemented;
876d4b07 8440 }
9c2149c8
TS
8441 break;
8442 case 11:
8443 switch (sel) {
8444 case 0:
7db13fae 8445 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
2423f660
TS
8446 rn = "Compare";
8447 break;
876d4b07 8448 /* 6,7 are implementation dependent */
9c2149c8 8449 default:
f31b035a 8450 goto cp0_unimplemented;
876d4b07 8451 }
9c2149c8
TS
8452 break;
8453 case 12:
8454 switch (sel) {
8455 case 0:
7db13fae 8456 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
2423f660
TS
8457 rn = "Status";
8458 break;
9c2149c8 8459 case 1:
d75c135e 8460 check_insn(ctx, ISA_MIPS32R2);
7db13fae 8461 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
2423f660
TS
8462 rn = "IntCtl";
8463 break;
9c2149c8 8464 case 2:
d75c135e 8465 check_insn(ctx, ISA_MIPS32R2);
7db13fae 8466 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
2423f660
TS
8467 rn = "SRSCtl";
8468 break;
9c2149c8 8469 case 3:
d75c135e 8470 check_insn(ctx, ISA_MIPS32R2);
7db13fae 8471 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
2423f660
TS
8472 rn = "SRSMap";
8473 break;
9c2149c8 8474 default:
f31b035a 8475 goto cp0_unimplemented;
876d4b07 8476 }
9c2149c8
TS
8477 break;
8478 case 13:
8479 switch (sel) {
8480 case 0:
7db13fae 8481 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
2423f660
TS
8482 rn = "Cause";
8483 break;
9c2149c8 8484 default:
f31b035a 8485 goto cp0_unimplemented;
876d4b07 8486 }
9c2149c8
TS
8487 break;
8488 case 14:
8489 switch (sel) {
8490 case 0:
7db13fae 8491 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
2423f660
TS
8492 rn = "EPC";
8493 break;
9c2149c8 8494 default:
f31b035a 8495 goto cp0_unimplemented;
876d4b07 8496 }
9c2149c8
TS
8497 break;
8498 case 15:
8499 switch (sel) {
8500 case 0:
7db13fae 8501 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
2423f660
TS
8502 rn = "PRid";
8503 break;
9c2149c8 8504 case 1:
d75c135e 8505 check_insn(ctx, ISA_MIPS32R2);
74dbf824 8506 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EBase));
2423f660
TS
8507 rn = "EBase";
8508 break;
c870e3f5
YK
8509 case 3:
8510 check_insn(ctx, ISA_MIPS32R2);
8511 CP0_CHECK(ctx->cmgcr);
8512 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase));
8513 rn = "CMGCRBase";
8514 break;
9c2149c8 8515 default:
f31b035a 8516 goto cp0_unimplemented;
876d4b07 8517 }
9c2149c8
TS
8518 break;
8519 case 16:
8520 switch (sel) {
8521 case 0:
7db13fae 8522 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
9c2149c8
TS
8523 rn = "Config";
8524 break;
8525 case 1:
7db13fae 8526 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
9c2149c8
TS
8527 rn = "Config1";
8528 break;
8529 case 2:
7db13fae 8530 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
9c2149c8
TS
8531 rn = "Config2";
8532 break;
8533 case 3:
7db13fae 8534 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
9c2149c8
TS
8535 rn = "Config3";
8536 break;
faf1f68b
LA
8537 case 4:
8538 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
8539 rn = "Config4";
8540 break;
8541 case 5:
8542 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
8543 rn = "Config5";
8544 break;
9c2149c8 8545 /* 6,7 are implementation dependent */
f0b3f3ae 8546 case 6:
7db13fae 8547 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
f0b3f3ae
TS
8548 rn = "Config6";
8549 break;
8550 case 7:
7db13fae 8551 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
f0b3f3ae
TS
8552 rn = "Config7";
8553 break;
9c2149c8 8554 default:
f31b035a 8555 goto cp0_unimplemented;
9c2149c8
TS
8556 }
8557 break;
8558 case 17:
8559 switch (sel) {
8560 case 0:
895c2d04 8561 gen_helper_dmfc0_lladdr(arg, cpu_env);
2423f660
TS
8562 rn = "LLAddr";
8563 break;
f6d4dd81
YK
8564 case 1:
8565 CP0_CHECK(ctx->mrp);
8566 gen_helper_dmfc0_maar(arg, cpu_env);
8567 rn = "MAAR";
8568 break;
8569 case 2:
8570 CP0_CHECK(ctx->mrp);
8571 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI));
8572 rn = "MAARI";
8573 break;
9c2149c8 8574 default:
f31b035a 8575 goto cp0_unimplemented;
9c2149c8
TS
8576 }
8577 break;
8578 case 18:
8579 switch (sel) {
c2e19f3c
AM
8580 case 0:
8581 case 1:
8582 case 2:
8583 case 3:
8584 case 4:
8585 case 5:
8586 case 6:
8587 case 7:
fa192d49 8588 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
895c2d04 8589 gen_helper_1e0i(dmfc0_watchlo, arg, sel);
2423f660
TS
8590 rn = "WatchLo";
8591 break;
9c2149c8 8592 default:
f31b035a 8593 goto cp0_unimplemented;
9c2149c8
TS
8594 }
8595 break;
8596 case 19:
8597 switch (sel) {
c2e19f3c
AM
8598 case 0:
8599 case 1:
8600 case 2:
8601 case 3:
8602 case 4:
8603 case 5:
8604 case 6:
8605 case 7:
fa192d49 8606 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
895c2d04 8607 gen_helper_1e0i(mfc0_watchhi, arg, sel);
2423f660
TS
8608 rn = "WatchHi";
8609 break;
9c2149c8 8610 default:
f31b035a 8611 goto cp0_unimplemented;
9c2149c8
TS
8612 }
8613 break;
8614 case 20:
8615 switch (sel) {
8616 case 0:
d75c135e 8617 check_insn(ctx, ISA_MIPS3);
7db13fae 8618 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
2423f660
TS
8619 rn = "XContext";
8620 break;
9c2149c8 8621 default:
f31b035a 8622 goto cp0_unimplemented;
9c2149c8
TS
8623 }
8624 break;
8625 case 21:
8626 /* Officially reserved, but sel 0 is used for R1x000 framemask */
f31b035a 8627 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
9c2149c8
TS
8628 switch (sel) {
8629 case 0:
7db13fae 8630 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
2423f660
TS
8631 rn = "Framemask";
8632 break;
9c2149c8 8633 default:
f31b035a 8634 goto cp0_unimplemented;
9c2149c8
TS
8635 }
8636 break;
8637 case 22:
d9bea114 8638 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
8639 rn = "'Diagnostic"; /* implementation dependent */
8640 break;
9c2149c8
TS
8641 case 23:
8642 switch (sel) {
8643 case 0:
895c2d04 8644 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
2423f660
TS
8645 rn = "Debug";
8646 break;
9c2149c8 8647 case 1:
895c2d04 8648// gen_helper_dmfc0_tracecontrol(arg, cpu_env); /* PDtrace support */
2423f660 8649 rn = "TraceControl";
3570d7f6 8650 goto cp0_unimplemented;
9c2149c8 8651 case 2:
895c2d04 8652// gen_helper_dmfc0_tracecontrol2(arg, cpu_env); /* PDtrace support */
2423f660 8653 rn = "TraceControl2";
3570d7f6 8654 goto cp0_unimplemented;
9c2149c8 8655 case 3:
895c2d04 8656// gen_helper_dmfc0_usertracedata(arg, cpu_env); /* PDtrace support */
2423f660 8657 rn = "UserTraceData";
3570d7f6 8658 goto cp0_unimplemented;
9c2149c8 8659 case 4:
895c2d04 8660// gen_helper_dmfc0_tracebpc(arg, cpu_env); /* PDtrace support */
2423f660 8661 rn = "TraceBPC";
3570d7f6 8662 goto cp0_unimplemented;
9c2149c8 8663 default:
f31b035a 8664 goto cp0_unimplemented;
9c2149c8
TS
8665 }
8666 break;
8667 case 24:
8668 switch (sel) {
8669 case 0:
f0b3f3ae 8670 /* EJTAG support */
7db13fae 8671 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
2423f660
TS
8672 rn = "DEPC";
8673 break;
9c2149c8 8674 default:
f31b035a 8675 goto cp0_unimplemented;
9c2149c8
TS
8676 }
8677 break;
8678 case 25:
8679 switch (sel) {
8680 case 0:
7db13fae 8681 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
2423f660 8682 rn = "Performance0";
9c2149c8
TS
8683 break;
8684 case 1:
d9bea114 8685// gen_helper_dmfc0_performance1(arg);
2423f660 8686 rn = "Performance1";
3570d7f6 8687 goto cp0_unimplemented;
9c2149c8 8688 case 2:
d9bea114 8689// gen_helper_dmfc0_performance2(arg);
2423f660 8690 rn = "Performance2";
3570d7f6 8691 goto cp0_unimplemented;
9c2149c8 8692 case 3:
d9bea114 8693// gen_helper_dmfc0_performance3(arg);
2423f660 8694 rn = "Performance3";
3570d7f6 8695 goto cp0_unimplemented;
9c2149c8 8696 case 4:
d9bea114 8697// gen_helper_dmfc0_performance4(arg);
2423f660 8698 rn = "Performance4";
3570d7f6 8699 goto cp0_unimplemented;
9c2149c8 8700 case 5:
d9bea114 8701// gen_helper_dmfc0_performance5(arg);
2423f660 8702 rn = "Performance5";
3570d7f6 8703 goto cp0_unimplemented;
9c2149c8 8704 case 6:
d9bea114 8705// gen_helper_dmfc0_performance6(arg);
2423f660 8706 rn = "Performance6";
3570d7f6 8707 goto cp0_unimplemented;
9c2149c8 8708 case 7:
d9bea114 8709// gen_helper_dmfc0_performance7(arg);
2423f660 8710 rn = "Performance7";
3570d7f6 8711 goto cp0_unimplemented;
9c2149c8 8712 default:
f31b035a 8713 goto cp0_unimplemented;
9c2149c8
TS
8714 }
8715 break;
8716 case 26:
0d74a222
LA
8717 switch (sel) {
8718 case 0:
8719 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl));
8720 rn = "ErrCtl";
8721 break;
8722 default:
8723 goto cp0_unimplemented;
8724 }
da80682b 8725 break;
9c2149c8
TS
8726 case 27:
8727 switch (sel) {
8728 /* ignored */
c2e19f3c
AM
8729 case 0:
8730 case 1:
8731 case 2:
8732 case 3:
d9bea114 8733 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
8734 rn = "CacheErr";
8735 break;
9c2149c8 8736 default:
f31b035a 8737 goto cp0_unimplemented;
9c2149c8
TS
8738 }
8739 break;
8740 case 28:
8741 switch (sel) {
8742 case 0:
8743 case 2:
8744 case 4:
8745 case 6:
7db13fae 8746 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
9c2149c8
TS
8747 rn = "TagLo";
8748 break;
8749 case 1:
8750 case 3:
8751 case 5:
8752 case 7:
7db13fae 8753 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
9c2149c8
TS
8754 rn = "DataLo";
8755 break;
8756 default:
f31b035a 8757 goto cp0_unimplemented;
9c2149c8
TS
8758 }
8759 break;
8760 case 29:
8761 switch (sel) {
8762 case 0:
8763 case 2:
8764 case 4:
8765 case 6:
7db13fae 8766 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
9c2149c8
TS
8767 rn = "TagHi";
8768 break;
8769 case 1:
8770 case 3:
8771 case 5:
8772 case 7:
7db13fae 8773 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
9c2149c8
TS
8774 rn = "DataHi";
8775 break;
8776 default:
f31b035a 8777 goto cp0_unimplemented;
9c2149c8
TS
8778 }
8779 break;
8780 case 30:
8781 switch (sel) {
8782 case 0:
7db13fae 8783 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
2423f660
TS
8784 rn = "ErrorEPC";
8785 break;
9c2149c8 8786 default:
f31b035a 8787 goto cp0_unimplemented;
9c2149c8
TS
8788 }
8789 break;
8790 case 31:
8791 switch (sel) {
8792 case 0:
f0b3f3ae 8793 /* EJTAG support */
7db13fae 8794 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
8795 rn = "DESAVE";
8796 break;
c2e19f3c
AM
8797 case 2:
8798 case 3:
8799 case 4:
8800 case 5:
8801 case 6:
8802 case 7:
f31b035a
LA
8803 CP0_CHECK(ctx->kscrexist & (1 << sel));
8804 tcg_gen_ld_tl(arg, cpu_env,
8805 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
8806 rn = "KScratch";
e98c0d17 8807 break;
9c2149c8 8808 default:
f31b035a 8809 goto cp0_unimplemented;
9c2149c8
TS
8810 }
8811 break;
8812 default:
f31b035a 8813 goto cp0_unimplemented;
9c2149c8 8814 }
b44a7fb1 8815 trace_mips_translate_c0("dmfc0", rn, reg, sel);
9c2149c8
TS
8816 return;
8817
f31b035a 8818cp0_unimplemented:
965447ee 8819 qemu_log_mask(LOG_UNIMP, "dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
f31b035a 8820 gen_mfc0_unimplemented(ctx, arg);
9c2149c8
TS
8821}
8822
d75c135e 8823static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
9c2149c8
TS
8824{
8825 const char *rn = "invalid";
8826
e189e748 8827 if (sel != 0)
d75c135e 8828 check_insn(ctx, ISA_MIPS64);
e189e748 8829
eeb3bba8 8830 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
2e70f6ef 8831 gen_io_start();
bd79255d 8832 }
2e70f6ef 8833
9c2149c8
TS
8834 switch (reg) {
8835 case 0:
8836 switch (sel) {
8837 case 0:
895c2d04 8838 gen_helper_mtc0_index(cpu_env, arg);
9c2149c8
TS
8839 rn = "Index";
8840 break;
8841 case 1:
f31b035a 8842 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 8843 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
9c2149c8 8844 rn = "MVPControl";
ead9360e 8845 break;
9c2149c8 8846 case 2:
f31b035a 8847 CP0_CHECK(ctx->insn_flags & ASE_MT);
ead9360e 8848 /* ignored */
9c2149c8 8849 rn = "MVPConf0";
ead9360e 8850 break;
9c2149c8 8851 case 3:
f31b035a 8852 CP0_CHECK(ctx->insn_flags & ASE_MT);
ead9360e 8853 /* ignored */
9c2149c8 8854 rn = "MVPConf1";
ead9360e 8855 break;
01bc435b
YK
8856 case 4:
8857 CP0_CHECK(ctx->vp);
8858 /* ignored */
8859 rn = "VPControl";
8860 break;
9c2149c8 8861 default:
f31b035a 8862 goto cp0_unimplemented;
9c2149c8
TS
8863 }
8864 break;
8865 case 1:
8866 switch (sel) {
8867 case 0:
2423f660 8868 /* ignored */
9c2149c8 8869 rn = "Random";
2423f660 8870 break;
9c2149c8 8871 case 1:
f31b035a 8872 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 8873 gen_helper_mtc0_vpecontrol(cpu_env, arg);
9c2149c8 8874 rn = "VPEControl";
ead9360e 8875 break;
9c2149c8 8876 case 2:
f31b035a 8877 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 8878 gen_helper_mtc0_vpeconf0(cpu_env, arg);
9c2149c8 8879 rn = "VPEConf0";
ead9360e 8880 break;
9c2149c8 8881 case 3:
f31b035a 8882 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 8883 gen_helper_mtc0_vpeconf1(cpu_env, arg);
9c2149c8 8884 rn = "VPEConf1";
ead9360e 8885 break;
9c2149c8 8886 case 4:
f31b035a 8887 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 8888 gen_helper_mtc0_yqmask(cpu_env, arg);
9c2149c8 8889 rn = "YQMask";
ead9360e 8890 break;
9c2149c8 8891 case 5:
f31b035a 8892 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 8893 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
9c2149c8 8894 rn = "VPESchedule";
ead9360e 8895 break;
9c2149c8 8896 case 6:
f31b035a 8897 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 8898 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
9c2149c8 8899 rn = "VPEScheFBack";
ead9360e 8900 break;
9c2149c8 8901 case 7:
f31b035a 8902 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 8903 gen_helper_mtc0_vpeopt(cpu_env, arg);
9c2149c8 8904 rn = "VPEOpt";
ead9360e 8905 break;
9c2149c8 8906 default:
f31b035a 8907 goto cp0_unimplemented;
9c2149c8
TS
8908 }
8909 break;
8910 case 2:
8911 switch (sel) {
8912 case 0:
7207c7f9 8913 gen_helper_dmtc0_entrylo0(cpu_env, arg);
2423f660
TS
8914 rn = "EntryLo0";
8915 break;
9c2149c8 8916 case 1:
f31b035a 8917 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 8918 gen_helper_mtc0_tcstatus(cpu_env, arg);
2423f660 8919 rn = "TCStatus";
ead9360e 8920 break;
9c2149c8 8921 case 2:
f31b035a 8922 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 8923 gen_helper_mtc0_tcbind(cpu_env, arg);
2423f660 8924 rn = "TCBind";
ead9360e 8925 break;
9c2149c8 8926 case 3:
f31b035a 8927 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 8928 gen_helper_mtc0_tcrestart(cpu_env, arg);
2423f660 8929 rn = "TCRestart";
ead9360e 8930 break;
9c2149c8 8931 case 4:
f31b035a 8932 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 8933 gen_helper_mtc0_tchalt(cpu_env, arg);
2423f660 8934 rn = "TCHalt";
ead9360e 8935 break;
9c2149c8 8936 case 5:
f31b035a 8937 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 8938 gen_helper_mtc0_tccontext(cpu_env, arg);
2423f660 8939 rn = "TCContext";
ead9360e 8940 break;
9c2149c8 8941 case 6:
f31b035a 8942 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 8943 gen_helper_mtc0_tcschedule(cpu_env, arg);
2423f660 8944 rn = "TCSchedule";
ead9360e 8945 break;
9c2149c8 8946 case 7:
f31b035a 8947 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 8948 gen_helper_mtc0_tcschefback(cpu_env, arg);
2423f660 8949 rn = "TCScheFBack";
ead9360e 8950 break;
9c2149c8 8951 default:
f31b035a 8952 goto cp0_unimplemented;
9c2149c8
TS
8953 }
8954 break;
8955 case 3:
8956 switch (sel) {
8957 case 0:
7207c7f9 8958 gen_helper_dmtc0_entrylo1(cpu_env, arg);
2423f660
TS
8959 rn = "EntryLo1";
8960 break;
01bc435b
YK
8961 case 1:
8962 CP0_CHECK(ctx->vp);
8963 /* ignored */
8964 rn = "GlobalNumber";
8965 break;
9c2149c8 8966 default:
f31b035a 8967 goto cp0_unimplemented;
876d4b07 8968 }
9c2149c8
TS
8969 break;
8970 case 4:
8971 switch (sel) {
8972 case 0:
895c2d04 8973 gen_helper_mtc0_context(cpu_env, arg);
2423f660
TS
8974 rn = "Context";
8975 break;
9c2149c8 8976 case 1:
895c2d04 8977// gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
2423f660 8978 rn = "ContextConfig";
f31b035a 8979 goto cp0_unimplemented;
d279279e 8980 case 2:
f31b035a
LA
8981 CP0_CHECK(ctx->ulri);
8982 tcg_gen_st_tl(arg, cpu_env,
8983 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
8984 rn = "UserLocal";
d279279e 8985 break;
9c2149c8 8986 default:
f31b035a 8987 goto cp0_unimplemented;
876d4b07 8988 }
9c2149c8
TS
8989 break;
8990 case 5:
8991 switch (sel) {
8992 case 0:
895c2d04 8993 gen_helper_mtc0_pagemask(cpu_env, arg);
2423f660
TS
8994 rn = "PageMask";
8995 break;
9c2149c8 8996 case 1:
d75c135e 8997 check_insn(ctx, ISA_MIPS32R2);
895c2d04 8998 gen_helper_mtc0_pagegrain(cpu_env, arg);
2423f660
TS
8999 rn = "PageGrain";
9000 break;
cec56a73
JH
9001 case 2:
9002 CP0_CHECK(ctx->sc);
9003 gen_helper_mtc0_segctl0(cpu_env, arg);
9004 rn = "SegCtl0";
9005 break;
9006 case 3:
9007 CP0_CHECK(ctx->sc);
9008 gen_helper_mtc0_segctl1(cpu_env, arg);
9009 rn = "SegCtl1";
9010 break;
9011 case 4:
9012 CP0_CHECK(ctx->sc);
9013 gen_helper_mtc0_segctl2(cpu_env, arg);
9014 rn = "SegCtl2";
9015 break;
5e31fdd5
YK
9016 case 5:
9017 check_pw(ctx);
9018 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWBase));
9019 rn = "PWBase";
9020 break;
fa75ad14
YK
9021 case 6:
9022 check_pw(ctx);
9023 gen_helper_mtc0_pwfield(cpu_env, arg);
9024 rn = "PWField";
9025 break;
20b28ebc
YK
9026 case 7:
9027 check_pw(ctx);
9028 gen_helper_mtc0_pwsize(cpu_env, arg);
9029 rn = "PWSize";
9030 break;
9c2149c8 9031 default:
f31b035a 9032 goto cp0_unimplemented;
876d4b07 9033 }
9c2149c8
TS
9034 break;
9035 case 6:
9036 switch (sel) {
9037 case 0:
895c2d04 9038 gen_helper_mtc0_wired(cpu_env, arg);
2423f660
TS
9039 rn = "Wired";
9040 break;
9c2149c8 9041 case 1:
d75c135e 9042 check_insn(ctx, ISA_MIPS32R2);
895c2d04 9043 gen_helper_mtc0_srsconf0(cpu_env, arg);
2423f660 9044 rn = "SRSConf0";
ead9360e 9045 break;
9c2149c8 9046 case 2:
d75c135e 9047 check_insn(ctx, ISA_MIPS32R2);
895c2d04 9048 gen_helper_mtc0_srsconf1(cpu_env, arg);
2423f660 9049 rn = "SRSConf1";
ead9360e 9050 break;
9c2149c8 9051 case 3:
d75c135e 9052 check_insn(ctx, ISA_MIPS32R2);
895c2d04 9053 gen_helper_mtc0_srsconf2(cpu_env, arg);
2423f660 9054 rn = "SRSConf2";
ead9360e 9055 break;
9c2149c8 9056 case 4:
d75c135e 9057 check_insn(ctx, ISA_MIPS32R2);
895c2d04 9058 gen_helper_mtc0_srsconf3(cpu_env, arg);
2423f660 9059 rn = "SRSConf3";
ead9360e 9060 break;
9c2149c8 9061 case 5:
d75c135e 9062 check_insn(ctx, ISA_MIPS32R2);
895c2d04 9063 gen_helper_mtc0_srsconf4(cpu_env, arg);
2423f660 9064 rn = "SRSConf4";
ead9360e 9065 break;
103be64c
YK
9066 case 6:
9067 check_pw(ctx);
9068 gen_helper_mtc0_pwctl(cpu_env, arg);
9069 rn = "PWCtl";
9070 break;
9c2149c8 9071 default:
f31b035a 9072 goto cp0_unimplemented;
876d4b07 9073 }
9c2149c8
TS
9074 break;
9075 case 7:
9076 switch (sel) {
9077 case 0:
d75c135e 9078 check_insn(ctx, ISA_MIPS32R2);
895c2d04 9079 gen_helper_mtc0_hwrena(cpu_env, arg);
eeb3bba8 9080 ctx->base.is_jmp = DISAS_STOP;
2423f660
TS
9081 rn = "HWREna";
9082 break;
9c2149c8 9083 default:
f31b035a 9084 goto cp0_unimplemented;
876d4b07 9085 }
9c2149c8
TS
9086 break;
9087 case 8:
aea14095
LA
9088 switch (sel) {
9089 case 0:
9090 /* ignored */
9091 rn = "BadVAddr";
9092 break;
9093 case 1:
9094 /* ignored */
9095 rn = "BadInstr";
9096 break;
9097 case 2:
9098 /* ignored */
9099 rn = "BadInstrP";
9100 break;
25beba9b
SM
9101 case 3:
9102 /* ignored */
9103 rn = "BadInstrX";
9104 break;
aea14095 9105 default:
f31b035a 9106 goto cp0_unimplemented;
aea14095 9107 }
9c2149c8
TS
9108 break;
9109 case 9:
9110 switch (sel) {
9111 case 0:
895c2d04 9112 gen_helper_mtc0_count(cpu_env, arg);
2423f660
TS
9113 rn = "Count";
9114 break;
876d4b07 9115 /* 6,7 are implementation dependent */
9c2149c8 9116 default:
f31b035a 9117 goto cp0_unimplemented;
876d4b07
TS
9118 }
9119 /* Stop translation as we may have switched the execution mode */
eeb3bba8 9120 ctx->base.is_jmp = DISAS_STOP;
9c2149c8
TS
9121 break;
9122 case 10:
9123 switch (sel) {
9124 case 0:
895c2d04 9125 gen_helper_mtc0_entryhi(cpu_env, arg);
2423f660
TS
9126 rn = "EntryHi";
9127 break;
9c2149c8 9128 default:
f31b035a 9129 goto cp0_unimplemented;
876d4b07 9130 }
9c2149c8
TS
9131 break;
9132 case 11:
9133 switch (sel) {
9134 case 0:
895c2d04 9135 gen_helper_mtc0_compare(cpu_env, arg);
2423f660
TS
9136 rn = "Compare";
9137 break;
876d4b07 9138 /* 6,7 are implementation dependent */
9c2149c8 9139 default:
f31b035a 9140 goto cp0_unimplemented;
876d4b07 9141 }
de9a95f0 9142 /* Stop translation as we may have switched the execution mode */
eeb3bba8 9143 ctx->base.is_jmp = DISAS_STOP;
9c2149c8
TS
9144 break;
9145 case 12:
9146 switch (sel) {
9147 case 0:
867abc7e 9148 save_cpu_state(ctx, 1);
895c2d04 9149 gen_helper_mtc0_status(cpu_env, arg);
b28425ba 9150 /* DISAS_STOP isn't good enough here, hflags may have changed. */
eeb3bba8
EC
9151 gen_save_pc(ctx->base.pc_next + 4);
9152 ctx->base.is_jmp = DISAS_EXIT;
2423f660
TS
9153 rn = "Status";
9154 break;
9c2149c8 9155 case 1:
d75c135e 9156 check_insn(ctx, ISA_MIPS32R2);
895c2d04 9157 gen_helper_mtc0_intctl(cpu_env, arg);
8487327a 9158 /* Stop translation as we may have switched the execution mode */
eeb3bba8 9159 ctx->base.is_jmp = DISAS_STOP;
2423f660
TS
9160 rn = "IntCtl";
9161 break;
9c2149c8 9162 case 2:
d75c135e 9163 check_insn(ctx, ISA_MIPS32R2);
895c2d04 9164 gen_helper_mtc0_srsctl(cpu_env, arg);
8487327a 9165 /* Stop translation as we may have switched the execution mode */
eeb3bba8 9166 ctx->base.is_jmp = DISAS_STOP;
2423f660
TS
9167 rn = "SRSCtl";
9168 break;
9c2149c8 9169 case 3:
d75c135e 9170 check_insn(ctx, ISA_MIPS32R2);
7db13fae 9171 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
8487327a 9172 /* Stop translation as we may have switched the execution mode */
eeb3bba8 9173 ctx->base.is_jmp = DISAS_STOP;
2423f660
TS
9174 rn = "SRSMap";
9175 break;
9176 default:
f31b035a 9177 goto cp0_unimplemented;
876d4b07 9178 }
9c2149c8
TS
9179 break;
9180 case 13:
9181 switch (sel) {
9182 case 0:
867abc7e 9183 save_cpu_state(ctx, 1);
895c2d04 9184 gen_helper_mtc0_cause(cpu_env, arg);
b28425ba
EC
9185 /* Stop translation as we may have triggered an interrupt.
9186 * DISAS_STOP isn't sufficient, we need to ensure we break out of
9187 * translated code to check for pending interrupts. */
eeb3bba8
EC
9188 gen_save_pc(ctx->base.pc_next + 4);
9189 ctx->base.is_jmp = DISAS_EXIT;
2423f660
TS
9190 rn = "Cause";
9191 break;
9c2149c8 9192 default:
f31b035a 9193 goto cp0_unimplemented;
876d4b07 9194 }
9c2149c8
TS
9195 break;
9196 case 14:
9197 switch (sel) {
9198 case 0:
7db13fae 9199 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
2423f660
TS
9200 rn = "EPC";
9201 break;
9c2149c8 9202 default:
f31b035a 9203 goto cp0_unimplemented;
876d4b07 9204 }
9c2149c8
TS
9205 break;
9206 case 15:
9207 switch (sel) {
9208 case 0:
2423f660
TS
9209 /* ignored */
9210 rn = "PRid";
9211 break;
9c2149c8 9212 case 1:
d75c135e 9213 check_insn(ctx, ISA_MIPS32R2);
895c2d04 9214 gen_helper_mtc0_ebase(cpu_env, arg);
2423f660
TS
9215 rn = "EBase";
9216 break;
9c2149c8 9217 default:
f31b035a 9218 goto cp0_unimplemented;
876d4b07 9219 }
9c2149c8
TS
9220 break;
9221 case 16:
9222 switch (sel) {
9223 case 0:
895c2d04 9224 gen_helper_mtc0_config0(cpu_env, arg);
9c2149c8 9225 rn = "Config";
2423f660 9226 /* Stop translation as we may have switched the execution mode */
eeb3bba8 9227 ctx->base.is_jmp = DISAS_STOP;
9c2149c8
TS
9228 break;
9229 case 1:
1fc7bf6e 9230 /* ignored, read only */
9c2149c8
TS
9231 rn = "Config1";
9232 break;
9233 case 2:
895c2d04 9234 gen_helper_mtc0_config2(cpu_env, arg);
9c2149c8 9235 rn = "Config2";
2423f660 9236 /* Stop translation as we may have switched the execution mode */
eeb3bba8 9237 ctx->base.is_jmp = DISAS_STOP;
9c2149c8
TS
9238 break;
9239 case 3:
90f12d73 9240 gen_helper_mtc0_config3(cpu_env, arg);
9c2149c8 9241 rn = "Config3";
90f12d73 9242 /* Stop translation as we may have switched the execution mode */
eeb3bba8 9243 ctx->base.is_jmp = DISAS_STOP;
9c2149c8 9244 break;
faf1f68b
LA
9245 case 4:
9246 /* currently ignored */
9247 rn = "Config4";
9248 break;
9249 case 5:
9250 gen_helper_mtc0_config5(cpu_env, arg);
9251 rn = "Config5";
9252 /* Stop translation as we may have switched the execution mode */
eeb3bba8 9253 ctx->base.is_jmp = DISAS_STOP;
faf1f68b 9254 break;
9c2149c8
TS
9255 /* 6,7 are implementation dependent */
9256 default:
9257 rn = "Invalid config selector";
f31b035a 9258 goto cp0_unimplemented;
9c2149c8 9259 }
9c2149c8
TS
9260 break;
9261 case 17:
9262 switch (sel) {
9263 case 0:
895c2d04 9264 gen_helper_mtc0_lladdr(cpu_env, arg);
2423f660
TS
9265 rn = "LLAddr";
9266 break;
f6d4dd81
YK
9267 case 1:
9268 CP0_CHECK(ctx->mrp);
9269 gen_helper_mtc0_maar(cpu_env, arg);
9270 rn = "MAAR";
9271 break;
9272 case 2:
9273 CP0_CHECK(ctx->mrp);
9274 gen_helper_mtc0_maari(cpu_env, arg);
9275 rn = "MAARI";
9276 break;
9c2149c8 9277 default:
f31b035a 9278 goto cp0_unimplemented;
9c2149c8
TS
9279 }
9280 break;
9281 case 18:
9282 switch (sel) {
c2e19f3c
AM
9283 case 0:
9284 case 1:
9285 case 2:
9286 case 3:
9287 case 4:
9288 case 5:
9289 case 6:
9290 case 7:
fa192d49 9291 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
895c2d04 9292 gen_helper_0e1i(mtc0_watchlo, arg, sel);
2423f660
TS
9293 rn = "WatchLo";
9294 break;
9c2149c8 9295 default:
f31b035a 9296 goto cp0_unimplemented;
9c2149c8
TS
9297 }
9298 break;
9299 case 19:
9300 switch (sel) {
c2e19f3c
AM
9301 case 0:
9302 case 1:
9303 case 2:
9304 case 3:
9305 case 4:
9306 case 5:
9307 case 6:
9308 case 7:
fa192d49 9309 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
895c2d04 9310 gen_helper_0e1i(mtc0_watchhi, arg, sel);
2423f660
TS
9311 rn = "WatchHi";
9312 break;
9c2149c8 9313 default:
f31b035a 9314 goto cp0_unimplemented;
9c2149c8
TS
9315 }
9316 break;
9317 case 20:
9318 switch (sel) {
9319 case 0:
d75c135e 9320 check_insn(ctx, ISA_MIPS3);
895c2d04 9321 gen_helper_mtc0_xcontext(cpu_env, arg);
2423f660
TS
9322 rn = "XContext";
9323 break;
9c2149c8 9324 default:
f31b035a 9325 goto cp0_unimplemented;
9c2149c8
TS
9326 }
9327 break;
9328 case 21:
9329 /* Officially reserved, but sel 0 is used for R1x000 framemask */
f31b035a 9330 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
9c2149c8
TS
9331 switch (sel) {
9332 case 0:
895c2d04 9333 gen_helper_mtc0_framemask(cpu_env, arg);
2423f660
TS
9334 rn = "Framemask";
9335 break;
9c2149c8 9336 default:
f31b035a 9337 goto cp0_unimplemented;
9c2149c8
TS
9338 }
9339 break;
9340 case 22:
9341 /* ignored */
9342 rn = "Diagnostic"; /* implementation dependent */
876d4b07 9343 break;
9c2149c8
TS
9344 case 23:
9345 switch (sel) {
9346 case 0:
895c2d04 9347 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
b28425ba 9348 /* DISAS_STOP isn't good enough here, hflags may have changed. */
eeb3bba8
EC
9349 gen_save_pc(ctx->base.pc_next + 4);
9350 ctx->base.is_jmp = DISAS_EXIT;
2423f660
TS
9351 rn = "Debug";
9352 break;
9c2149c8 9353 case 1:
895c2d04 9354// gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
8487327a 9355 /* Stop translation as we may have switched the execution mode */
eeb3bba8 9356 ctx->base.is_jmp = DISAS_STOP;
2423f660 9357 rn = "TraceControl";
3570d7f6 9358 goto cp0_unimplemented;
9c2149c8 9359 case 2:
895c2d04 9360// gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
8487327a 9361 /* Stop translation as we may have switched the execution mode */
eeb3bba8 9362 ctx->base.is_jmp = DISAS_STOP;
2423f660 9363 rn = "TraceControl2";
3570d7f6 9364 goto cp0_unimplemented;
9c2149c8 9365 case 3:
895c2d04 9366// gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
8487327a 9367 /* Stop translation as we may have switched the execution mode */
eeb3bba8 9368 ctx->base.is_jmp = DISAS_STOP;
2423f660 9369 rn = "UserTraceData";
3570d7f6 9370 goto cp0_unimplemented;
9c2149c8 9371 case 4:
895c2d04 9372// gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
8487327a 9373 /* Stop translation as we may have switched the execution mode */
eeb3bba8 9374 ctx->base.is_jmp = DISAS_STOP;
2423f660 9375 rn = "TraceBPC";
3570d7f6 9376 goto cp0_unimplemented;
9c2149c8 9377 default:
f31b035a 9378 goto cp0_unimplemented;
9c2149c8 9379 }
9c2149c8
TS
9380 break;
9381 case 24:
9382 switch (sel) {
9383 case 0:
f1aa6320 9384 /* EJTAG support */
7db13fae 9385 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
2423f660
TS
9386 rn = "DEPC";
9387 break;
9c2149c8 9388 default:
f31b035a 9389 goto cp0_unimplemented;
9c2149c8
TS
9390 }
9391 break;
9392 case 25:
9393 switch (sel) {
9394 case 0:
895c2d04 9395 gen_helper_mtc0_performance0(cpu_env, arg);
2423f660
TS
9396 rn = "Performance0";
9397 break;
9c2149c8 9398 case 1:
895c2d04 9399// gen_helper_mtc0_performance1(cpu_env, arg);
2423f660 9400 rn = "Performance1";
3570d7f6 9401 goto cp0_unimplemented;
9c2149c8 9402 case 2:
895c2d04 9403// gen_helper_mtc0_performance2(cpu_env, arg);
2423f660 9404 rn = "Performance2";
3570d7f6 9405 goto cp0_unimplemented;
9c2149c8 9406 case 3:
895c2d04 9407// gen_helper_mtc0_performance3(cpu_env, arg);
2423f660 9408 rn = "Performance3";
3570d7f6 9409 goto cp0_unimplemented;
9c2149c8 9410 case 4:
895c2d04 9411// gen_helper_mtc0_performance4(cpu_env, arg);
2423f660 9412 rn = "Performance4";
3570d7f6 9413 goto cp0_unimplemented;
9c2149c8 9414 case 5:
895c2d04 9415// gen_helper_mtc0_performance5(cpu_env, arg);
2423f660 9416 rn = "Performance5";
3570d7f6 9417 goto cp0_unimplemented;
9c2149c8 9418 case 6:
895c2d04 9419// gen_helper_mtc0_performance6(cpu_env, arg);
2423f660 9420 rn = "Performance6";
3570d7f6 9421 goto cp0_unimplemented;
9c2149c8 9422 case 7:
895c2d04 9423// gen_helper_mtc0_performance7(cpu_env, arg);
2423f660 9424 rn = "Performance7";
3570d7f6 9425 goto cp0_unimplemented;
9c2149c8 9426 default:
f31b035a 9427 goto cp0_unimplemented;
9c2149c8 9428 }
876d4b07 9429 break;
9c2149c8 9430 case 26:
0d74a222
LA
9431 switch (sel) {
9432 case 0:
9433 gen_helper_mtc0_errctl(cpu_env, arg);
eeb3bba8 9434 ctx->base.is_jmp = DISAS_STOP;
0d74a222
LA
9435 rn = "ErrCtl";
9436 break;
9437 default:
9438 goto cp0_unimplemented;
9439 }
876d4b07 9440 break;
9c2149c8
TS
9441 case 27:
9442 switch (sel) {
c2e19f3c
AM
9443 case 0:
9444 case 1:
9445 case 2:
9446 case 3:
2423f660
TS
9447 /* ignored */
9448 rn = "CacheErr";
9449 break;
9c2149c8 9450 default:
f31b035a 9451 goto cp0_unimplemented;
9c2149c8 9452 }
876d4b07 9453 break;
9c2149c8
TS
9454 case 28:
9455 switch (sel) {
9456 case 0:
9457 case 2:
9458 case 4:
9459 case 6:
895c2d04 9460 gen_helper_mtc0_taglo(cpu_env, arg);
9c2149c8
TS
9461 rn = "TagLo";
9462 break;
9463 case 1:
9464 case 3:
9465 case 5:
9466 case 7:
895c2d04 9467 gen_helper_mtc0_datalo(cpu_env, arg);
9c2149c8
TS
9468 rn = "DataLo";
9469 break;
9470 default:
f31b035a 9471 goto cp0_unimplemented;
9c2149c8
TS
9472 }
9473 break;
9474 case 29:
9475 switch (sel) {
9476 case 0:
9477 case 2:
9478 case 4:
9479 case 6:
895c2d04 9480 gen_helper_mtc0_taghi(cpu_env, arg);
9c2149c8
TS
9481 rn = "TagHi";
9482 break;
9483 case 1:
9484 case 3:
9485 case 5:
9486 case 7:
895c2d04 9487 gen_helper_mtc0_datahi(cpu_env, arg);
9c2149c8
TS
9488 rn = "DataHi";
9489 break;
9490 default:
9491 rn = "invalid sel";
f31b035a 9492 goto cp0_unimplemented;
9c2149c8 9493 }
876d4b07 9494 break;
9c2149c8
TS
9495 case 30:
9496 switch (sel) {
9497 case 0:
7db13fae 9498 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
2423f660
TS
9499 rn = "ErrorEPC";
9500 break;
9c2149c8 9501 default:
f31b035a 9502 goto cp0_unimplemented;
9c2149c8
TS
9503 }
9504 break;
9505 case 31:
9506 switch (sel) {
9507 case 0:
f1aa6320 9508 /* EJTAG support */
7db13fae 9509 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
9510 rn = "DESAVE";
9511 break;
c2e19f3c
AM
9512 case 2:
9513 case 3:
9514 case 4:
9515 case 5:
9516 case 6:
9517 case 7:
f31b035a
LA
9518 CP0_CHECK(ctx->kscrexist & (1 << sel));
9519 tcg_gen_st_tl(arg, cpu_env,
9520 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
9521 rn = "KScratch";
e98c0d17 9522 break;
9c2149c8 9523 default:
f31b035a 9524 goto cp0_unimplemented;
9c2149c8 9525 }
9c2149c8
TS
9526 break;
9527 default:
f31b035a 9528 goto cp0_unimplemented;
9c2149c8 9529 }
b44a7fb1
PMD
9530 trace_mips_translate_c0("dmtc0", rn, reg, sel);
9531
bf20dc07 9532 /* For simplicity assume that all writes can cause interrupts. */
eeb3bba8 9533 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
2e70f6ef 9534 gen_io_end();
b28425ba 9535 /* DISAS_STOP isn't sufficient, we need to ensure we break out of
b74cddcb 9536 * translated code to check for pending interrupts. */
eeb3bba8
EC
9537 gen_save_pc(ctx->base.pc_next + 4);
9538 ctx->base.is_jmp = DISAS_EXIT;
2e70f6ef 9539 }
9c2149c8
TS
9540 return;
9541
f31b035a 9542cp0_unimplemented:
965447ee 9543 qemu_log_mask(LOG_UNIMP, "dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
9c2149c8 9544}
d26bc211 9545#endif /* TARGET_MIPS64 */
9c2149c8 9546
7db13fae 9547static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
ead9360e
TS
9548 int u, int sel, int h)
9549{
9550 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
a7812ae4 9551 TCGv t0 = tcg_temp_local_new();
ead9360e
TS
9552
9553 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
b5dc7732
TS
9554 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
9555 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
1a3fd9c3 9556 tcg_gen_movi_tl(t0, -1);
ead9360e
TS
9557 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
9558 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
1a3fd9c3 9559 tcg_gen_movi_tl(t0, -1);
ead9360e
TS
9560 else if (u == 0) {
9561 switch (rt) {
5a25ce94
EI
9562 case 1:
9563 switch (sel) {
9564 case 1:
895c2d04 9565 gen_helper_mftc0_vpecontrol(t0, cpu_env);
5a25ce94
EI
9566 break;
9567 case 2:
895c2d04 9568 gen_helper_mftc0_vpeconf0(t0, cpu_env);
5a25ce94
EI
9569 break;
9570 default:
9571 goto die;
9572 break;
9573 }
9574 break;
ead9360e
TS
9575 case 2:
9576 switch (sel) {
9577 case 1:
895c2d04 9578 gen_helper_mftc0_tcstatus(t0, cpu_env);
ead9360e
TS
9579 break;
9580 case 2:
895c2d04 9581 gen_helper_mftc0_tcbind(t0, cpu_env);
ead9360e
TS
9582 break;
9583 case 3:
895c2d04 9584 gen_helper_mftc0_tcrestart(t0, cpu_env);
ead9360e
TS
9585 break;
9586 case 4:
895c2d04 9587 gen_helper_mftc0_tchalt(t0, cpu_env);
ead9360e
TS
9588 break;
9589 case 5:
895c2d04 9590 gen_helper_mftc0_tccontext(t0, cpu_env);
ead9360e
TS
9591 break;
9592 case 6:
895c2d04 9593 gen_helper_mftc0_tcschedule(t0, cpu_env);
ead9360e
TS
9594 break;
9595 case 7:
895c2d04 9596 gen_helper_mftc0_tcschefback(t0, cpu_env);
ead9360e
TS
9597 break;
9598 default:
d75c135e 9599 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
9600 break;
9601 }
9602 break;
9603 case 10:
9604 switch (sel) {
9605 case 0:
895c2d04 9606 gen_helper_mftc0_entryhi(t0, cpu_env);
ead9360e
TS
9607 break;
9608 default:
d75c135e 9609 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
9610 break;
9611 }
9612 case 12:
9613 switch (sel) {
9614 case 0:
895c2d04 9615 gen_helper_mftc0_status(t0, cpu_env);
ead9360e
TS
9616 break;
9617 default:
d75c135e 9618 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
9619 break;
9620 }
5a25ce94
EI
9621 case 13:
9622 switch (sel) {
9623 case 0:
895c2d04 9624 gen_helper_mftc0_cause(t0, cpu_env);
5a25ce94
EI
9625 break;
9626 default:
9627 goto die;
9628 break;
9629 }
9630 break;
9631 case 14:
9632 switch (sel) {
9633 case 0:
895c2d04 9634 gen_helper_mftc0_epc(t0, cpu_env);
5a25ce94
EI
9635 break;
9636 default:
9637 goto die;
9638 break;
9639 }
9640 break;
9641 case 15:
9642 switch (sel) {
9643 case 1:
895c2d04 9644 gen_helper_mftc0_ebase(t0, cpu_env);
5a25ce94
EI
9645 break;
9646 default:
9647 goto die;
9648 break;
9649 }
9650 break;
9651 case 16:
9652 switch (sel) {
c2e19f3c
AM
9653 case 0:
9654 case 1:
9655 case 2:
9656 case 3:
9657 case 4:
9658 case 5:
9659 case 6:
9660 case 7:
895c2d04 9661 gen_helper_mftc0_configx(t0, cpu_env, tcg_const_tl(sel));
5a25ce94
EI
9662 break;
9663 default:
9664 goto die;
9665 break;
9666 }
9667 break;
ead9360e
TS
9668 case 23:
9669 switch (sel) {
9670 case 0:
895c2d04 9671 gen_helper_mftc0_debug(t0, cpu_env);
ead9360e
TS
9672 break;
9673 default:
d75c135e 9674 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
9675 break;
9676 }
9677 break;
9678 default:
d75c135e 9679 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
9680 }
9681 } else switch (sel) {
9682 /* GPR registers. */
9683 case 0:
895c2d04 9684 gen_helper_1e0i(mftgpr, t0, rt);
ead9360e
TS
9685 break;
9686 /* Auxiliary CPU registers */
9687 case 1:
9688 switch (rt) {
9689 case 0:
895c2d04 9690 gen_helper_1e0i(mftlo, t0, 0);
ead9360e
TS
9691 break;
9692 case 1:
895c2d04 9693 gen_helper_1e0i(mfthi, t0, 0);
ead9360e
TS
9694 break;
9695 case 2:
895c2d04 9696 gen_helper_1e0i(mftacx, t0, 0);
ead9360e
TS
9697 break;
9698 case 4:
895c2d04 9699 gen_helper_1e0i(mftlo, t0, 1);
ead9360e
TS
9700 break;
9701 case 5:
895c2d04 9702 gen_helper_1e0i(mfthi, t0, 1);
ead9360e
TS
9703 break;
9704 case 6:
895c2d04 9705 gen_helper_1e0i(mftacx, t0, 1);
ead9360e
TS
9706 break;
9707 case 8:
895c2d04 9708 gen_helper_1e0i(mftlo, t0, 2);
ead9360e
TS
9709 break;
9710 case 9:
895c2d04 9711 gen_helper_1e0i(mfthi, t0, 2);
ead9360e
TS
9712 break;
9713 case 10:
895c2d04 9714 gen_helper_1e0i(mftacx, t0, 2);
ead9360e
TS
9715 break;
9716 case 12:
895c2d04 9717 gen_helper_1e0i(mftlo, t0, 3);
ead9360e
TS
9718 break;
9719 case 13:
895c2d04 9720 gen_helper_1e0i(mfthi, t0, 3);
ead9360e
TS
9721 break;
9722 case 14:
895c2d04 9723 gen_helper_1e0i(mftacx, t0, 3);
ead9360e
TS
9724 break;
9725 case 16:
895c2d04 9726 gen_helper_mftdsp(t0, cpu_env);
ead9360e
TS
9727 break;
9728 default:
9729 goto die;
9730 }
9731 break;
9732 /* Floating point (COP1). */
9733 case 2:
9734 /* XXX: For now we support only a single FPU context. */
9735 if (h == 0) {
a7812ae4 9736 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9737
7c979afd 9738 gen_load_fpr32(ctx, fp0, rt);
b6d96bed 9739 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 9740 tcg_temp_free_i32(fp0);
ead9360e 9741 } else {
a7812ae4 9742 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9743
7f6613ce 9744 gen_load_fpr32h(ctx, fp0, rt);
b6d96bed 9745 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 9746 tcg_temp_free_i32(fp0);
ead9360e
TS
9747 }
9748 break;
9749 case 3:
9750 /* XXX: For now we support only a single FPU context. */
895c2d04 9751 gen_helper_1e0i(cfc1, t0, rt);
ead9360e
TS
9752 break;
9753 /* COP2: Not implemented. */
9754 case 4:
9755 case 5:
9756 /* fall through */
9757 default:
9758 goto die;
9759 }
b44a7fb1 9760 trace_mips_translate_tr("mftr", rt, u, sel, h);
1a3fd9c3
TS
9761 gen_store_gpr(t0, rd);
9762 tcg_temp_free(t0);
ead9360e
TS
9763 return;
9764
9765die:
1a3fd9c3 9766 tcg_temp_free(t0);
d12d51d5 9767 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
9c708c7f 9768 generate_exception_end(ctx, EXCP_RI);
ead9360e
TS
9769}
9770
7db13fae 9771static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
ead9360e
TS
9772 int u, int sel, int h)
9773{
9774 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
a7812ae4 9775 TCGv t0 = tcg_temp_local_new();
ead9360e 9776
1a3fd9c3 9777 gen_load_gpr(t0, rt);
ead9360e 9778 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
b5dc7732
TS
9779 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
9780 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
ead9360e
TS
9781 /* NOP */ ;
9782 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
9783 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
9784 /* NOP */ ;
9785 else if (u == 0) {
9786 switch (rd) {
5a25ce94
EI
9787 case 1:
9788 switch (sel) {
9789 case 1:
895c2d04 9790 gen_helper_mttc0_vpecontrol(cpu_env, t0);
5a25ce94
EI
9791 break;
9792 case 2:
895c2d04 9793 gen_helper_mttc0_vpeconf0(cpu_env, t0);
5a25ce94
EI
9794 break;
9795 default:
9796 goto die;
9797 break;
9798 }
9799 break;
ead9360e
TS
9800 case 2:
9801 switch (sel) {
9802 case 1:
895c2d04 9803 gen_helper_mttc0_tcstatus(cpu_env, t0);
ead9360e
TS
9804 break;
9805 case 2:
895c2d04 9806 gen_helper_mttc0_tcbind(cpu_env, t0);
ead9360e
TS
9807 break;
9808 case 3:
895c2d04 9809 gen_helper_mttc0_tcrestart(cpu_env, t0);
ead9360e
TS
9810 break;
9811 case 4:
895c2d04 9812 gen_helper_mttc0_tchalt(cpu_env, t0);
ead9360e
TS
9813 break;
9814 case 5:
895c2d04 9815 gen_helper_mttc0_tccontext(cpu_env, t0);
ead9360e
TS
9816 break;
9817 case 6:
895c2d04 9818 gen_helper_mttc0_tcschedule(cpu_env, t0);
ead9360e
TS
9819 break;
9820 case 7:
895c2d04 9821 gen_helper_mttc0_tcschefback(cpu_env, t0);
ead9360e
TS
9822 break;
9823 default:
d75c135e 9824 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
9825 break;
9826 }
9827 break;
9828 case 10:
9829 switch (sel) {
9830 case 0:
895c2d04 9831 gen_helper_mttc0_entryhi(cpu_env, t0);
ead9360e
TS
9832 break;
9833 default:
d75c135e 9834 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
9835 break;
9836 }
9837 case 12:
9838 switch (sel) {
9839 case 0:
895c2d04 9840 gen_helper_mttc0_status(cpu_env, t0);
ead9360e
TS
9841 break;
9842 default:
d75c135e 9843 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
9844 break;
9845 }
5a25ce94
EI
9846 case 13:
9847 switch (sel) {
9848 case 0:
895c2d04 9849 gen_helper_mttc0_cause(cpu_env, t0);
5a25ce94
EI
9850 break;
9851 default:
9852 goto die;
9853 break;
9854 }
9855 break;
9856 case 15:
9857 switch (sel) {
9858 case 1:
895c2d04 9859 gen_helper_mttc0_ebase(cpu_env, t0);
5a25ce94
EI
9860 break;
9861 default:
9862 goto die;
9863 break;
9864 }
9865 break;
ead9360e
TS
9866 case 23:
9867 switch (sel) {
9868 case 0:
895c2d04 9869 gen_helper_mttc0_debug(cpu_env, t0);
ead9360e
TS
9870 break;
9871 default:
d75c135e 9872 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
9873 break;
9874 }
9875 break;
9876 default:
d75c135e 9877 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
9878 }
9879 } else switch (sel) {
9880 /* GPR registers. */
9881 case 0:
895c2d04 9882 gen_helper_0e1i(mttgpr, t0, rd);
ead9360e
TS
9883 break;
9884 /* Auxiliary CPU registers */
9885 case 1:
9886 switch (rd) {
9887 case 0:
895c2d04 9888 gen_helper_0e1i(mttlo, t0, 0);
ead9360e
TS
9889 break;
9890 case 1:
895c2d04 9891 gen_helper_0e1i(mtthi, t0, 0);
ead9360e
TS
9892 break;
9893 case 2:
895c2d04 9894 gen_helper_0e1i(mttacx, t0, 0);
ead9360e
TS
9895 break;
9896 case 4:
895c2d04 9897 gen_helper_0e1i(mttlo, t0, 1);
ead9360e
TS
9898 break;
9899 case 5:
895c2d04 9900 gen_helper_0e1i(mtthi, t0, 1);
ead9360e
TS
9901 break;
9902 case 6:
895c2d04 9903 gen_helper_0e1i(mttacx, t0, 1);
ead9360e
TS
9904 break;
9905 case 8:
895c2d04 9906 gen_helper_0e1i(mttlo, t0, 2);
ead9360e
TS
9907 break;
9908 case 9:
895c2d04 9909 gen_helper_0e1i(mtthi, t0, 2);
ead9360e
TS
9910 break;
9911 case 10:
895c2d04 9912 gen_helper_0e1i(mttacx, t0, 2);
ead9360e
TS
9913 break;
9914 case 12:
895c2d04 9915 gen_helper_0e1i(mttlo, t0, 3);
ead9360e
TS
9916 break;
9917 case 13:
895c2d04 9918 gen_helper_0e1i(mtthi, t0, 3);
ead9360e
TS
9919 break;
9920 case 14:
895c2d04 9921 gen_helper_0e1i(mttacx, t0, 3);
ead9360e
TS
9922 break;
9923 case 16:
895c2d04 9924 gen_helper_mttdsp(cpu_env, t0);
ead9360e
TS
9925 break;
9926 default:
9927 goto die;
9928 }
9929 break;
9930 /* Floating point (COP1). */
9931 case 2:
9932 /* XXX: For now we support only a single FPU context. */
9933 if (h == 0) {
a7812ae4 9934 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
9935
9936 tcg_gen_trunc_tl_i32(fp0, t0);
7c979afd 9937 gen_store_fpr32(ctx, fp0, rd);
a7812ae4 9938 tcg_temp_free_i32(fp0);
ead9360e 9939 } else {
a7812ae4 9940 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
9941
9942 tcg_gen_trunc_tl_i32(fp0, t0);
7f6613ce 9943 gen_store_fpr32h(ctx, fp0, rd);
a7812ae4 9944 tcg_temp_free_i32(fp0);
ead9360e
TS
9945 }
9946 break;
9947 case 3:
9948 /* XXX: For now we support only a single FPU context. */
736d120a
PJ
9949 {
9950 TCGv_i32 fs_tmp = tcg_const_i32(rd);
9951
9952 gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
9953 tcg_temp_free_i32(fs_tmp);
9954 }
4cf8a45f 9955 /* Stop translation as we may have changed hflags */
eeb3bba8 9956 ctx->base.is_jmp = DISAS_STOP;
ead9360e
TS
9957 break;
9958 /* COP2: Not implemented. */
9959 case 4:
9960 case 5:
9961 /* fall through */
9962 default:
9963 goto die;
9964 }
b44a7fb1 9965 trace_mips_translate_tr("mttr", rd, u, sel, h);
1a3fd9c3 9966 tcg_temp_free(t0);
ead9360e
TS
9967 return;
9968
9969die:
1a3fd9c3 9970 tcg_temp_free(t0);
d12d51d5 9971 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
9c708c7f 9972 generate_exception_end(ctx, EXCP_RI);
ead9360e
TS
9973}
9974
7db13fae 9975static void gen_cp0 (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
6af0bf9c 9976{
287c4b84 9977 const char *opn = "ldst";
6af0bf9c 9978
2e15497c 9979 check_cp0_enabled(ctx);
6af0bf9c
FB
9980 switch (opc) {
9981 case OPC_MFC0:
9982 if (rt == 0) {
ead9360e 9983 /* Treat as NOP. */
6af0bf9c
FB
9984 return;
9985 }
d75c135e 9986 gen_mfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
6af0bf9c
FB
9987 opn = "mfc0";
9988 break;
9989 case OPC_MTC0:
1a3fd9c3 9990 {
1fc7bf6e 9991 TCGv t0 = tcg_temp_new();
1a3fd9c3
TS
9992
9993 gen_load_gpr(t0, rt);
d75c135e 9994 gen_mtc0(ctx, t0, rd, ctx->opcode & 0x7);
1a3fd9c3
TS
9995 tcg_temp_free(t0);
9996 }
6af0bf9c
FB
9997 opn = "mtc0";
9998 break;
d26bc211 9999#if defined(TARGET_MIPS64)
9c2149c8 10000 case OPC_DMFC0:
d75c135e 10001 check_insn(ctx, ISA_MIPS3);
9c2149c8 10002 if (rt == 0) {
ead9360e 10003 /* Treat as NOP. */
9c2149c8
TS
10004 return;
10005 }
d75c135e 10006 gen_dmfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
9c2149c8
TS
10007 opn = "dmfc0";
10008 break;
10009 case OPC_DMTC0:
d75c135e 10010 check_insn(ctx, ISA_MIPS3);
1a3fd9c3 10011 {
1fc7bf6e 10012 TCGv t0 = tcg_temp_new();
1a3fd9c3
TS
10013
10014 gen_load_gpr(t0, rt);
d75c135e 10015 gen_dmtc0(ctx, t0, rd, ctx->opcode & 0x7);
1a3fd9c3
TS
10016 tcg_temp_free(t0);
10017 }
9c2149c8
TS
10018 opn = "dmtc0";
10019 break;
534ce69f 10020#endif
5204ea79
LA
10021 case OPC_MFHC0:
10022 check_mvh(ctx);
10023 if (rt == 0) {
10024 /* Treat as NOP. */
10025 return;
10026 }
10027 gen_mfhc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
10028 opn = "mfhc0";
10029 break;
10030 case OPC_MTHC0:
10031 check_mvh(ctx);
10032 {
10033 TCGv t0 = tcg_temp_new();
10034 gen_load_gpr(t0, rt);
10035 gen_mthc0(ctx, t0, rd, ctx->opcode & 0x7);
10036 tcg_temp_free(t0);
10037 }
10038 opn = "mthc0";
10039 break;
ead9360e 10040 case OPC_MFTR:
9affc1c5 10041 check_cp0_enabled(ctx);
ead9360e
TS
10042 if (rd == 0) {
10043 /* Treat as NOP. */
10044 return;
10045 }
6c5c1e20 10046 gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
ead9360e 10047 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
ead9360e
TS
10048 opn = "mftr";
10049 break;
10050 case OPC_MTTR:
9affc1c5 10051 check_cp0_enabled(ctx);
6c5c1e20 10052 gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
ead9360e
TS
10053 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
10054 opn = "mttr";
10055 break;
6af0bf9c 10056 case OPC_TLBWI:
6af0bf9c 10057 opn = "tlbwi";
c01fccd2 10058 if (!env->tlb->helper_tlbwi)
29929e34 10059 goto die;
895c2d04 10060 gen_helper_tlbwi(cpu_env);
6af0bf9c 10061 break;
9456c2fb
LA
10062 case OPC_TLBINV:
10063 opn = "tlbinv";
10064 if (ctx->ie >= 2) {
10065 if (!env->tlb->helper_tlbinv) {
10066 goto die;
10067 }
10068 gen_helper_tlbinv(cpu_env);
10069 } /* treat as nop if TLBINV not supported */
10070 break;
10071 case OPC_TLBINVF:
10072 opn = "tlbinvf";
10073 if (ctx->ie >= 2) {
10074 if (!env->tlb->helper_tlbinvf) {
10075 goto die;
10076 }
10077 gen_helper_tlbinvf(cpu_env);
10078 } /* treat as nop if TLBINV not supported */
10079 break;
6af0bf9c 10080 case OPC_TLBWR:
6af0bf9c 10081 opn = "tlbwr";
c01fccd2 10082 if (!env->tlb->helper_tlbwr)
29929e34 10083 goto die;
895c2d04 10084 gen_helper_tlbwr(cpu_env);
6af0bf9c
FB
10085 break;
10086 case OPC_TLBP:
6af0bf9c 10087 opn = "tlbp";
c01fccd2 10088 if (!env->tlb->helper_tlbp)
29929e34 10089 goto die;
895c2d04 10090 gen_helper_tlbp(cpu_env);
6af0bf9c
FB
10091 break;
10092 case OPC_TLBR:
6af0bf9c 10093 opn = "tlbr";
c01fccd2 10094 if (!env->tlb->helper_tlbr)
29929e34 10095 goto die;
895c2d04 10096 gen_helper_tlbr(cpu_env);
6af0bf9c 10097 break;
ce9782f4 10098 case OPC_ERET: /* OPC_ERETNC */
339cd2a8
LA
10099 if ((ctx->insn_flags & ISA_MIPS32R6) &&
10100 (ctx->hflags & MIPS_HFLAG_BMASK)) {
339cd2a8 10101 goto die;
ce9782f4
LA
10102 } else {
10103 int bit_shift = (ctx->hflags & MIPS_HFLAG_M16) ? 16 : 6;
10104 if (ctx->opcode & (1 << bit_shift)) {
10105 /* OPC_ERETNC */
10106 opn = "eretnc";
10107 check_insn(ctx, ISA_MIPS32R5);
10108 gen_helper_eretnc(cpu_env);
10109 } else {
10110 /* OPC_ERET */
10111 opn = "eret";
10112 check_insn(ctx, ISA_MIPS2);
10113 gen_helper_eret(cpu_env);
10114 }
eeb3bba8 10115 ctx->base.is_jmp = DISAS_EXIT;
339cd2a8 10116 }
6af0bf9c
FB
10117 break;
10118 case OPC_DERET:
10119 opn = "deret";
d75c135e 10120 check_insn(ctx, ISA_MIPS32);
339cd2a8
LA
10121 if ((ctx->insn_flags & ISA_MIPS32R6) &&
10122 (ctx->hflags & MIPS_HFLAG_BMASK)) {
339cd2a8
LA
10123 goto die;
10124 }
6af0bf9c 10125 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
923617a3 10126 MIPS_INVAL(opn);
9c708c7f 10127 generate_exception_end(ctx, EXCP_RI);
6af0bf9c 10128 } else {
895c2d04 10129 gen_helper_deret(cpu_env);
eeb3bba8 10130 ctx->base.is_jmp = DISAS_EXIT;
6af0bf9c
FB
10131 }
10132 break;
4ad40f36
FB
10133 case OPC_WAIT:
10134 opn = "wait";
d75c135e 10135 check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
339cd2a8
LA
10136 if ((ctx->insn_flags & ISA_MIPS32R6) &&
10137 (ctx->hflags & MIPS_HFLAG_BMASK)) {
339cd2a8
LA
10138 goto die;
10139 }
4ad40f36 10140 /* If we get an exception, we want to restart at next instruction */
eeb3bba8 10141 ctx->base.pc_next += 4;
4ad40f36 10142 save_cpu_state(ctx, 1);
eeb3bba8 10143 ctx->base.pc_next -= 4;
895c2d04 10144 gen_helper_wait(cpu_env);
eeb3bba8 10145 ctx->base.is_jmp = DISAS_NORETURN;
4ad40f36 10146 break;
6af0bf9c 10147 default:
29929e34 10148 die:
923617a3 10149 MIPS_INVAL(opn);
9c708c7f 10150 generate_exception_end(ctx, EXCP_RI);
6af0bf9c
FB
10151 return;
10152 }
2abf314d 10153 (void)opn; /* avoid a compiler warning */
6af0bf9c 10154}
f1aa6320 10155#endif /* !CONFIG_USER_ONLY */
6af0bf9c 10156
6ea83fed 10157/* CP1 Branches (before delay slot) */
d75c135e
AJ
10158static void gen_compute_branch1(DisasContext *ctx, uint32_t op,
10159 int32_t cc, int32_t offset)
6ea83fed
FB
10160{
10161 target_ulong btarget;
a7812ae4 10162 TCGv_i32 t0 = tcg_temp_new_i32();
6ea83fed 10163
339cd2a8 10164 if ((ctx->insn_flags & ISA_MIPS32R6) && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9c708c7f 10165 generate_exception_end(ctx, EXCP_RI);
339cd2a8
LA
10166 goto out;
10167 }
10168
e189e748 10169 if (cc != 0)
d75c135e 10170 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
e189e748 10171
eeb3bba8 10172 btarget = ctx->base.pc_next + 4 + offset;
6ea83fed 10173
7a387fff
TS
10174 switch (op) {
10175 case OPC_BC1F:
d94536f4
AJ
10176 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10177 tcg_gen_not_i32(t0, t0);
10178 tcg_gen_andi_i32(t0, t0, 1);
10179 tcg_gen_extu_i32_tl(bcond, t0);
6ea83fed 10180 goto not_likely;
7a387fff 10181 case OPC_BC1FL:
d94536f4
AJ
10182 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10183 tcg_gen_not_i32(t0, t0);
10184 tcg_gen_andi_i32(t0, t0, 1);
10185 tcg_gen_extu_i32_tl(bcond, t0);
6ea83fed 10186 goto likely;
7a387fff 10187 case OPC_BC1T:
d94536f4
AJ
10188 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10189 tcg_gen_andi_i32(t0, t0, 1);
10190 tcg_gen_extu_i32_tl(bcond, t0);
5a5012ec 10191 goto not_likely;
7a387fff 10192 case OPC_BC1TL:
d94536f4
AJ
10193 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10194 tcg_gen_andi_i32(t0, t0, 1);
10195 tcg_gen_extu_i32_tl(bcond, t0);
6ea83fed
FB
10196 likely:
10197 ctx->hflags |= MIPS_HFLAG_BL;
10198 break;
5a5012ec 10199 case OPC_BC1FANY2:
a16336e4 10200 {
d94536f4
AJ
10201 TCGv_i32 t1 = tcg_temp_new_i32();
10202 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10203 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
d7f66b52 10204 tcg_gen_nand_i32(t0, t0, t1);
d94536f4 10205 tcg_temp_free_i32(t1);
d94536f4
AJ
10206 tcg_gen_andi_i32(t0, t0, 1);
10207 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 10208 }
5a5012ec
TS
10209 goto not_likely;
10210 case OPC_BC1TANY2:
a16336e4 10211 {
d94536f4
AJ
10212 TCGv_i32 t1 = tcg_temp_new_i32();
10213 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10214 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
10215 tcg_gen_or_i32(t0, t0, t1);
10216 tcg_temp_free_i32(t1);
10217 tcg_gen_andi_i32(t0, t0, 1);
10218 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 10219 }
5a5012ec
TS
10220 goto not_likely;
10221 case OPC_BC1FANY4:
a16336e4 10222 {
d94536f4
AJ
10223 TCGv_i32 t1 = tcg_temp_new_i32();
10224 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10225 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
d7f66b52 10226 tcg_gen_and_i32(t0, t0, t1);
d94536f4 10227 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
d7f66b52 10228 tcg_gen_and_i32(t0, t0, t1);
d94536f4 10229 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
d7f66b52 10230 tcg_gen_nand_i32(t0, t0, t1);
d94536f4 10231 tcg_temp_free_i32(t1);
d94536f4
AJ
10232 tcg_gen_andi_i32(t0, t0, 1);
10233 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 10234 }
5a5012ec
TS
10235 goto not_likely;
10236 case OPC_BC1TANY4:
a16336e4 10237 {
d94536f4
AJ
10238 TCGv_i32 t1 = tcg_temp_new_i32();
10239 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10240 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
10241 tcg_gen_or_i32(t0, t0, t1);
10242 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
10243 tcg_gen_or_i32(t0, t0, t1);
10244 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
10245 tcg_gen_or_i32(t0, t0, t1);
10246 tcg_temp_free_i32(t1);
10247 tcg_gen_andi_i32(t0, t0, 1);
10248 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 10249 }
5a5012ec
TS
10250 not_likely:
10251 ctx->hflags |= MIPS_HFLAG_BC;
5a5012ec
TS
10252 break;
10253 default:
9d68ac14 10254 MIPS_INVAL("cp1 cond branch");
9c708c7f 10255 generate_exception_end(ctx, EXCP_RI);
6c5c1e20 10256 goto out;
6ea83fed 10257 }
6ea83fed 10258 ctx->btarget = btarget;
b231c103 10259 ctx->hflags |= MIPS_HFLAG_BDS32;
6c5c1e20 10260 out:
a7812ae4 10261 tcg_temp_free_i32(t0);
6ea83fed
FB
10262}
10263
31837be3
YK
10264/* R6 CP1 Branches */
10265static void gen_compute_branch1_r6(DisasContext *ctx, uint32_t op,
65935f07
YK
10266 int32_t ft, int32_t offset,
10267 int delayslot_size)
31837be3
YK
10268{
10269 target_ulong btarget;
31837be3
YK
10270 TCGv_i64 t0 = tcg_temp_new_i64();
10271
10272 if (ctx->hflags & MIPS_HFLAG_BMASK) {
10273#ifdef MIPS_DEBUG_DISAS
339cd2a8 10274 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
eeb3bba8 10275 "\n", ctx->base.pc_next);
31837be3 10276#endif
9c708c7f 10277 generate_exception_end(ctx, EXCP_RI);
31837be3
YK
10278 goto out;
10279 }
10280
10281 gen_load_fpr64(ctx, t0, ft);
10282 tcg_gen_andi_i64(t0, t0, 1);
10283
eeb3bba8 10284 btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
31837be3
YK
10285
10286 switch (op) {
10287 case OPC_BC1EQZ:
10288 tcg_gen_xori_i64(t0, t0, 1);
31837be3
YK
10289 ctx->hflags |= MIPS_HFLAG_BC;
10290 break;
10291 case OPC_BC1NEZ:
10292 /* t0 already set */
31837be3
YK
10293 ctx->hflags |= MIPS_HFLAG_BC;
10294 break;
10295 default:
9d68ac14 10296 MIPS_INVAL("cp1 cond branch");
9c708c7f 10297 generate_exception_end(ctx, EXCP_RI);
31837be3
YK
10298 goto out;
10299 }
10300
10301 tcg_gen_trunc_i64_tl(bcond, t0);
10302
31837be3 10303 ctx->btarget = btarget;
65935f07
YK
10304
10305 switch (delayslot_size) {
10306 case 2:
10307 ctx->hflags |= MIPS_HFLAG_BDS16;
10308 break;
10309 case 4:
10310 ctx->hflags |= MIPS_HFLAG_BDS32;
10311 break;
10312 }
31837be3
YK
10313
10314out:
10315 tcg_temp_free_i64(t0);
10316}
10317
6af0bf9c 10318/* Coprocessor 1 (FPU) */
5a5012ec 10319
5a5012ec
TS
10320#define FOP(func, fmt) (((fmt) << 21) | (func))
10321
bf4120ad
NF
10322enum fopcode {
10323 OPC_ADD_S = FOP(0, FMT_S),
10324 OPC_SUB_S = FOP(1, FMT_S),
10325 OPC_MUL_S = FOP(2, FMT_S),
10326 OPC_DIV_S = FOP(3, FMT_S),
10327 OPC_SQRT_S = FOP(4, FMT_S),
10328 OPC_ABS_S = FOP(5, FMT_S),
10329 OPC_MOV_S = FOP(6, FMT_S),
10330 OPC_NEG_S = FOP(7, FMT_S),
10331 OPC_ROUND_L_S = FOP(8, FMT_S),
10332 OPC_TRUNC_L_S = FOP(9, FMT_S),
10333 OPC_CEIL_L_S = FOP(10, FMT_S),
10334 OPC_FLOOR_L_S = FOP(11, FMT_S),
10335 OPC_ROUND_W_S = FOP(12, FMT_S),
10336 OPC_TRUNC_W_S = FOP(13, FMT_S),
10337 OPC_CEIL_W_S = FOP(14, FMT_S),
10338 OPC_FLOOR_W_S = FOP(15, FMT_S),
e7f16abb 10339 OPC_SEL_S = FOP(16, FMT_S),
bf4120ad
NF
10340 OPC_MOVCF_S = FOP(17, FMT_S),
10341 OPC_MOVZ_S = FOP(18, FMT_S),
10342 OPC_MOVN_S = FOP(19, FMT_S),
e7f16abb 10343 OPC_SELEQZ_S = FOP(20, FMT_S),
bf4120ad
NF
10344 OPC_RECIP_S = FOP(21, FMT_S),
10345 OPC_RSQRT_S = FOP(22, FMT_S),
e7f16abb
LA
10346 OPC_SELNEZ_S = FOP(23, FMT_S),
10347 OPC_MADDF_S = FOP(24, FMT_S),
10348 OPC_MSUBF_S = FOP(25, FMT_S),
10349 OPC_RINT_S = FOP(26, FMT_S),
10350 OPC_CLASS_S = FOP(27, FMT_S),
10351 OPC_MIN_S = FOP(28, FMT_S),
bf4120ad 10352 OPC_RECIP2_S = FOP(28, FMT_S),
e7f16abb 10353 OPC_MINA_S = FOP(29, FMT_S),
bf4120ad 10354 OPC_RECIP1_S = FOP(29, FMT_S),
e7f16abb 10355 OPC_MAX_S = FOP(30, FMT_S),
bf4120ad 10356 OPC_RSQRT1_S = FOP(30, FMT_S),
e7f16abb 10357 OPC_MAXA_S = FOP(31, FMT_S),
bf4120ad
NF
10358 OPC_RSQRT2_S = FOP(31, FMT_S),
10359 OPC_CVT_D_S = FOP(33, FMT_S),
10360 OPC_CVT_W_S = FOP(36, FMT_S),
10361 OPC_CVT_L_S = FOP(37, FMT_S),
10362 OPC_CVT_PS_S = FOP(38, FMT_S),
10363 OPC_CMP_F_S = FOP (48, FMT_S),
10364 OPC_CMP_UN_S = FOP (49, FMT_S),
10365 OPC_CMP_EQ_S = FOP (50, FMT_S),
10366 OPC_CMP_UEQ_S = FOP (51, FMT_S),
10367 OPC_CMP_OLT_S = FOP (52, FMT_S),
10368 OPC_CMP_ULT_S = FOP (53, FMT_S),
10369 OPC_CMP_OLE_S = FOP (54, FMT_S),
10370 OPC_CMP_ULE_S = FOP (55, FMT_S),
10371 OPC_CMP_SF_S = FOP (56, FMT_S),
10372 OPC_CMP_NGLE_S = FOP (57, FMT_S),
10373 OPC_CMP_SEQ_S = FOP (58, FMT_S),
10374 OPC_CMP_NGL_S = FOP (59, FMT_S),
10375 OPC_CMP_LT_S = FOP (60, FMT_S),
10376 OPC_CMP_NGE_S = FOP (61, FMT_S),
10377 OPC_CMP_LE_S = FOP (62, FMT_S),
10378 OPC_CMP_NGT_S = FOP (63, FMT_S),
10379
10380 OPC_ADD_D = FOP(0, FMT_D),
10381 OPC_SUB_D = FOP(1, FMT_D),
10382 OPC_MUL_D = FOP(2, FMT_D),
10383 OPC_DIV_D = FOP(3, FMT_D),
10384 OPC_SQRT_D = FOP(4, FMT_D),
10385 OPC_ABS_D = FOP(5, FMT_D),
10386 OPC_MOV_D = FOP(6, FMT_D),
10387 OPC_NEG_D = FOP(7, FMT_D),
10388 OPC_ROUND_L_D = FOP(8, FMT_D),
10389 OPC_TRUNC_L_D = FOP(9, FMT_D),
10390 OPC_CEIL_L_D = FOP(10, FMT_D),
10391 OPC_FLOOR_L_D = FOP(11, FMT_D),
10392 OPC_ROUND_W_D = FOP(12, FMT_D),
10393 OPC_TRUNC_W_D = FOP(13, FMT_D),
10394 OPC_CEIL_W_D = FOP(14, FMT_D),
10395 OPC_FLOOR_W_D = FOP(15, FMT_D),
e7f16abb 10396 OPC_SEL_D = FOP(16, FMT_D),
bf4120ad
NF
10397 OPC_MOVCF_D = FOP(17, FMT_D),
10398 OPC_MOVZ_D = FOP(18, FMT_D),
10399 OPC_MOVN_D = FOP(19, FMT_D),
e7f16abb 10400 OPC_SELEQZ_D = FOP(20, FMT_D),
bf4120ad
NF
10401 OPC_RECIP_D = FOP(21, FMT_D),
10402 OPC_RSQRT_D = FOP(22, FMT_D),
e7f16abb
LA
10403 OPC_SELNEZ_D = FOP(23, FMT_D),
10404 OPC_MADDF_D = FOP(24, FMT_D),
10405 OPC_MSUBF_D = FOP(25, FMT_D),
10406 OPC_RINT_D = FOP(26, FMT_D),
10407 OPC_CLASS_D = FOP(27, FMT_D),
10408 OPC_MIN_D = FOP(28, FMT_D),
bf4120ad 10409 OPC_RECIP2_D = FOP(28, FMT_D),
e7f16abb 10410 OPC_MINA_D = FOP(29, FMT_D),
bf4120ad 10411 OPC_RECIP1_D = FOP(29, FMT_D),
e7f16abb 10412 OPC_MAX_D = FOP(30, FMT_D),
bf4120ad 10413 OPC_RSQRT1_D = FOP(30, FMT_D),
e7f16abb 10414 OPC_MAXA_D = FOP(31, FMT_D),
bf4120ad
NF
10415 OPC_RSQRT2_D = FOP(31, FMT_D),
10416 OPC_CVT_S_D = FOP(32, FMT_D),
10417 OPC_CVT_W_D = FOP(36, FMT_D),
10418 OPC_CVT_L_D = FOP(37, FMT_D),
10419 OPC_CMP_F_D = FOP (48, FMT_D),
10420 OPC_CMP_UN_D = FOP (49, FMT_D),
10421 OPC_CMP_EQ_D = FOP (50, FMT_D),
10422 OPC_CMP_UEQ_D = FOP (51, FMT_D),
10423 OPC_CMP_OLT_D = FOP (52, FMT_D),
10424 OPC_CMP_ULT_D = FOP (53, FMT_D),
10425 OPC_CMP_OLE_D = FOP (54, FMT_D),
10426 OPC_CMP_ULE_D = FOP (55, FMT_D),
10427 OPC_CMP_SF_D = FOP (56, FMT_D),
10428 OPC_CMP_NGLE_D = FOP (57, FMT_D),
10429 OPC_CMP_SEQ_D = FOP (58, FMT_D),
10430 OPC_CMP_NGL_D = FOP (59, FMT_D),
10431 OPC_CMP_LT_D = FOP (60, FMT_D),
10432 OPC_CMP_NGE_D = FOP (61, FMT_D),
10433 OPC_CMP_LE_D = FOP (62, FMT_D),
10434 OPC_CMP_NGT_D = FOP (63, FMT_D),
10435
10436 OPC_CVT_S_W = FOP(32, FMT_W),
10437 OPC_CVT_D_W = FOP(33, FMT_W),
10438 OPC_CVT_S_L = FOP(32, FMT_L),
10439 OPC_CVT_D_L = FOP(33, FMT_L),
10440 OPC_CVT_PS_PW = FOP(38, FMT_W),
10441
10442 OPC_ADD_PS = FOP(0, FMT_PS),
10443 OPC_SUB_PS = FOP(1, FMT_PS),
10444 OPC_MUL_PS = FOP(2, FMT_PS),
10445 OPC_DIV_PS = FOP(3, FMT_PS),
10446 OPC_ABS_PS = FOP(5, FMT_PS),
10447 OPC_MOV_PS = FOP(6, FMT_PS),
10448 OPC_NEG_PS = FOP(7, FMT_PS),
10449 OPC_MOVCF_PS = FOP(17, FMT_PS),
10450 OPC_MOVZ_PS = FOP(18, FMT_PS),
10451 OPC_MOVN_PS = FOP(19, FMT_PS),
10452 OPC_ADDR_PS = FOP(24, FMT_PS),
10453 OPC_MULR_PS = FOP(26, FMT_PS),
10454 OPC_RECIP2_PS = FOP(28, FMT_PS),
10455 OPC_RECIP1_PS = FOP(29, FMT_PS),
10456 OPC_RSQRT1_PS = FOP(30, FMT_PS),
10457 OPC_RSQRT2_PS = FOP(31, FMT_PS),
10458
10459 OPC_CVT_S_PU = FOP(32, FMT_PS),
10460 OPC_CVT_PW_PS = FOP(36, FMT_PS),
10461 OPC_CVT_S_PL = FOP(40, FMT_PS),
10462 OPC_PLL_PS = FOP(44, FMT_PS),
10463 OPC_PLU_PS = FOP(45, FMT_PS),
10464 OPC_PUL_PS = FOP(46, FMT_PS),
10465 OPC_PUU_PS = FOP(47, FMT_PS),
10466 OPC_CMP_F_PS = FOP (48, FMT_PS),
10467 OPC_CMP_UN_PS = FOP (49, FMT_PS),
10468 OPC_CMP_EQ_PS = FOP (50, FMT_PS),
10469 OPC_CMP_UEQ_PS = FOP (51, FMT_PS),
10470 OPC_CMP_OLT_PS = FOP (52, FMT_PS),
10471 OPC_CMP_ULT_PS = FOP (53, FMT_PS),
10472 OPC_CMP_OLE_PS = FOP (54, FMT_PS),
10473 OPC_CMP_ULE_PS = FOP (55, FMT_PS),
10474 OPC_CMP_SF_PS = FOP (56, FMT_PS),
10475 OPC_CMP_NGLE_PS = FOP (57, FMT_PS),
10476 OPC_CMP_SEQ_PS = FOP (58, FMT_PS),
10477 OPC_CMP_NGL_PS = FOP (59, FMT_PS),
10478 OPC_CMP_LT_PS = FOP (60, FMT_PS),
10479 OPC_CMP_NGE_PS = FOP (61, FMT_PS),
10480 OPC_CMP_LE_PS = FOP (62, FMT_PS),
10481 OPC_CMP_NGT_PS = FOP (63, FMT_PS),
10482};
10483
3f493883
YK
10484enum r6_f_cmp_op {
10485 R6_OPC_CMP_AF_S = FOP(0, FMT_W),
10486 R6_OPC_CMP_UN_S = FOP(1, FMT_W),
10487 R6_OPC_CMP_EQ_S = FOP(2, FMT_W),
10488 R6_OPC_CMP_UEQ_S = FOP(3, FMT_W),
10489 R6_OPC_CMP_LT_S = FOP(4, FMT_W),
10490 R6_OPC_CMP_ULT_S = FOP(5, FMT_W),
10491 R6_OPC_CMP_LE_S = FOP(6, FMT_W),
10492 R6_OPC_CMP_ULE_S = FOP(7, FMT_W),
10493 R6_OPC_CMP_SAF_S = FOP(8, FMT_W),
10494 R6_OPC_CMP_SUN_S = FOP(9, FMT_W),
10495 R6_OPC_CMP_SEQ_S = FOP(10, FMT_W),
10496 R6_OPC_CMP_SEUQ_S = FOP(11, FMT_W),
10497 R6_OPC_CMP_SLT_S = FOP(12, FMT_W),
10498 R6_OPC_CMP_SULT_S = FOP(13, FMT_W),
10499 R6_OPC_CMP_SLE_S = FOP(14, FMT_W),
10500 R6_OPC_CMP_SULE_S = FOP(15, FMT_W),
10501 R6_OPC_CMP_OR_S = FOP(17, FMT_W),
10502 R6_OPC_CMP_UNE_S = FOP(18, FMT_W),
10503 R6_OPC_CMP_NE_S = FOP(19, FMT_W),
10504 R6_OPC_CMP_SOR_S = FOP(25, FMT_W),
10505 R6_OPC_CMP_SUNE_S = FOP(26, FMT_W),
10506 R6_OPC_CMP_SNE_S = FOP(27, FMT_W),
10507
10508 R6_OPC_CMP_AF_D = FOP(0, FMT_L),
10509 R6_OPC_CMP_UN_D = FOP(1, FMT_L),
10510 R6_OPC_CMP_EQ_D = FOP(2, FMT_L),
10511 R6_OPC_CMP_UEQ_D = FOP(3, FMT_L),
10512 R6_OPC_CMP_LT_D = FOP(4, FMT_L),
10513 R6_OPC_CMP_ULT_D = FOP(5, FMT_L),
10514 R6_OPC_CMP_LE_D = FOP(6, FMT_L),
10515 R6_OPC_CMP_ULE_D = FOP(7, FMT_L),
10516 R6_OPC_CMP_SAF_D = FOP(8, FMT_L),
10517 R6_OPC_CMP_SUN_D = FOP(9, FMT_L),
10518 R6_OPC_CMP_SEQ_D = FOP(10, FMT_L),
10519 R6_OPC_CMP_SEUQ_D = FOP(11, FMT_L),
10520 R6_OPC_CMP_SLT_D = FOP(12, FMT_L),
10521 R6_OPC_CMP_SULT_D = FOP(13, FMT_L),
10522 R6_OPC_CMP_SLE_D = FOP(14, FMT_L),
10523 R6_OPC_CMP_SULE_D = FOP(15, FMT_L),
10524 R6_OPC_CMP_OR_D = FOP(17, FMT_L),
10525 R6_OPC_CMP_UNE_D = FOP(18, FMT_L),
10526 R6_OPC_CMP_NE_D = FOP(19, FMT_L),
10527 R6_OPC_CMP_SOR_D = FOP(25, FMT_L),
10528 R6_OPC_CMP_SUNE_D = FOP(26, FMT_L),
10529 R6_OPC_CMP_SNE_D = FOP(27, FMT_L),
10530};
7a387fff 10531static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
6ea83fed 10532{
72c3a3ee 10533 TCGv t0 = tcg_temp_new();
6ea83fed
FB
10534
10535 switch (opc) {
10536 case OPC_MFC1:
b6d96bed 10537 {
a7812ae4 10538 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 10539
7c979afd 10540 gen_load_fpr32(ctx, fp0, fs);
b6d96bed 10541 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 10542 tcg_temp_free_i32(fp0);
6958549d 10543 }
6c5c1e20 10544 gen_store_gpr(t0, rt);
6ea83fed
FB
10545 break;
10546 case OPC_MTC1:
6c5c1e20 10547 gen_load_gpr(t0, rt);
b6d96bed 10548 {
a7812ae4 10549 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
10550
10551 tcg_gen_trunc_tl_i32(fp0, t0);
7c979afd 10552 gen_store_fpr32(ctx, fp0, fs);
a7812ae4 10553 tcg_temp_free_i32(fp0);
6958549d 10554 }
6ea83fed
FB
10555 break;
10556 case OPC_CFC1:
895c2d04 10557 gen_helper_1e0i(cfc1, t0, fs);
6c5c1e20 10558 gen_store_gpr(t0, rt);
6ea83fed
FB
10559 break;
10560 case OPC_CTC1:
6c5c1e20 10561 gen_load_gpr(t0, rt);
9c708c7f 10562 save_cpu_state(ctx, 0);
736d120a
PJ
10563 {
10564 TCGv_i32 fs_tmp = tcg_const_i32(fs);
10565
10566 gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
10567 tcg_temp_free_i32(fs_tmp);
10568 }
4cf8a45f 10569 /* Stop translation as we may have changed hflags */
eeb3bba8 10570 ctx->base.is_jmp = DISAS_STOP;
6ea83fed 10571 break;
72c3a3ee 10572#if defined(TARGET_MIPS64)
9c2149c8 10573 case OPC_DMFC1:
72c3a3ee 10574 gen_load_fpr64(ctx, t0, fs);
6c5c1e20 10575 gen_store_gpr(t0, rt);
5a5012ec 10576 break;
9c2149c8 10577 case OPC_DMTC1:
6c5c1e20 10578 gen_load_gpr(t0, rt);
72c3a3ee 10579 gen_store_fpr64(ctx, t0, fs);
5a5012ec 10580 break;
72c3a3ee 10581#endif
5a5012ec 10582 case OPC_MFHC1:
b6d96bed 10583 {
a7812ae4 10584 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 10585
7f6613ce 10586 gen_load_fpr32h(ctx, fp0, fs);
b6d96bed 10587 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 10588 tcg_temp_free_i32(fp0);
6958549d 10589 }
6c5c1e20 10590 gen_store_gpr(t0, rt);
5a5012ec
TS
10591 break;
10592 case OPC_MTHC1:
6c5c1e20 10593 gen_load_gpr(t0, rt);
b6d96bed 10594 {
a7812ae4 10595 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
10596
10597 tcg_gen_trunc_tl_i32(fp0, t0);
7f6613ce 10598 gen_store_fpr32h(ctx, fp0, fs);
a7812ae4 10599 tcg_temp_free_i32(fp0);
6958549d 10600 }
5a5012ec 10601 break;
6ea83fed 10602 default:
9d68ac14 10603 MIPS_INVAL("cp1 move");
9c708c7f 10604 generate_exception_end(ctx, EXCP_RI);
6c5c1e20 10605 goto out;
6ea83fed 10606 }
6c5c1e20
TS
10607
10608 out:
10609 tcg_temp_free(t0);
6ea83fed
FB
10610}
10611
5a5012ec
TS
10612static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
10613{
42a268c2 10614 TCGLabel *l1;
e214b9bb 10615 TCGCond cond;
af58f9ca
AJ
10616 TCGv_i32 t0;
10617
10618 if (rd == 0) {
10619 /* Treat as NOP. */
10620 return;
10621 }
6ea83fed 10622
e214b9bb 10623 if (tf)
e214b9bb 10624 cond = TCG_COND_EQ;
27848470
TS
10625 else
10626 cond = TCG_COND_NE;
10627
af58f9ca
AJ
10628 l1 = gen_new_label();
10629 t0 = tcg_temp_new_i32();
fa31af0e 10630 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
af58f9ca 10631 tcg_gen_brcondi_i32(cond, t0, 0, l1);
a4e8338d 10632 tcg_temp_free_i32(t0);
af58f9ca
AJ
10633 if (rs == 0) {
10634 tcg_gen_movi_tl(cpu_gpr[rd], 0);
10635 } else {
10636 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
10637 }
e214b9bb 10638 gen_set_label(l1);
5a5012ec
TS
10639}
10640
7c979afd
LA
10641static inline void gen_movcf_s(DisasContext *ctx, int fs, int fd, int cc,
10642 int tf)
a16336e4 10643{
a16336e4 10644 int cond;
cbc37b28 10645 TCGv_i32 t0 = tcg_temp_new_i32();
42a268c2 10646 TCGLabel *l1 = gen_new_label();
a16336e4 10647
a16336e4
TS
10648 if (tf)
10649 cond = TCG_COND_EQ;
10650 else
10651 cond = TCG_COND_NE;
10652
fa31af0e 10653 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
cbc37b28 10654 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7c979afd
LA
10655 gen_load_fpr32(ctx, t0, fs);
10656 gen_store_fpr32(ctx, t0, fd);
a16336e4 10657 gen_set_label(l1);
cbc37b28 10658 tcg_temp_free_i32(t0);
5a5012ec 10659}
a16336e4 10660
b6d96bed 10661static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
a16336e4 10662{
a16336e4 10663 int cond;
cbc37b28
AJ
10664 TCGv_i32 t0 = tcg_temp_new_i32();
10665 TCGv_i64 fp0;
42a268c2 10666 TCGLabel *l1 = gen_new_label();
a16336e4 10667
a16336e4
TS
10668 if (tf)
10669 cond = TCG_COND_EQ;
10670 else
10671 cond = TCG_COND_NE;
10672
fa31af0e 10673 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
cbc37b28 10674 tcg_gen_brcondi_i32(cond, t0, 0, l1);
a4e8338d 10675 tcg_temp_free_i32(t0);
11f94258 10676 fp0 = tcg_temp_new_i64();
9bf3eb2c 10677 gen_load_fpr64(ctx, fp0, fs);
9bf3eb2c 10678 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10679 tcg_temp_free_i64(fp0);
cbc37b28 10680 gen_set_label(l1);
a16336e4
TS
10681}
10682
7f6613ce
PJ
10683static inline void gen_movcf_ps(DisasContext *ctx, int fs, int fd,
10684 int cc, int tf)
a16336e4
TS
10685{
10686 int cond;
cbc37b28 10687 TCGv_i32 t0 = tcg_temp_new_i32();
42a268c2
RH
10688 TCGLabel *l1 = gen_new_label();
10689 TCGLabel *l2 = gen_new_label();
a16336e4
TS
10690
10691 if (tf)
10692 cond = TCG_COND_EQ;
10693 else
10694 cond = TCG_COND_NE;
10695
fa31af0e 10696 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
cbc37b28 10697 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7c979afd
LA
10698 gen_load_fpr32(ctx, t0, fs);
10699 gen_store_fpr32(ctx, t0, fd);
a16336e4 10700 gen_set_label(l1);
9bf3eb2c 10701
fa31af0e 10702 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc+1));
cbc37b28 10703 tcg_gen_brcondi_i32(cond, t0, 0, l2);
7f6613ce
PJ
10704 gen_load_fpr32h(ctx, t0, fs);
10705 gen_store_fpr32h(ctx, t0, fd);
52a0e9eb 10706 tcg_temp_free_i32(t0);
a16336e4 10707 gen_set_label(l2);
a16336e4
TS
10708}
10709
e7f16abb
LA
10710static void gen_sel_s(DisasContext *ctx, enum fopcode op1, int fd, int ft,
10711 int fs)
10712{
10713 TCGv_i32 t1 = tcg_const_i32(0);
10714 TCGv_i32 fp0 = tcg_temp_new_i32();
10715 TCGv_i32 fp1 = tcg_temp_new_i32();
10716 TCGv_i32 fp2 = tcg_temp_new_i32();
7c979afd
LA
10717 gen_load_fpr32(ctx, fp0, fd);
10718 gen_load_fpr32(ctx, fp1, ft);
10719 gen_load_fpr32(ctx, fp2, fs);
e7f16abb
LA
10720
10721 switch (op1) {
10722 case OPC_SEL_S:
10723 tcg_gen_andi_i32(fp0, fp0, 1);
10724 tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
10725 break;
10726 case OPC_SELEQZ_S:
10727 tcg_gen_andi_i32(fp1, fp1, 1);
10728 tcg_gen_movcond_i32(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
10729 break;
10730 case OPC_SELNEZ_S:
10731 tcg_gen_andi_i32(fp1, fp1, 1);
10732 tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
10733 break;
10734 default:
10735 MIPS_INVAL("gen_sel_s");
9c708c7f 10736 generate_exception_end(ctx, EXCP_RI);
e7f16abb
LA
10737 break;
10738 }
10739
7c979afd 10740 gen_store_fpr32(ctx, fp0, fd);
e7f16abb
LA
10741 tcg_temp_free_i32(fp2);
10742 tcg_temp_free_i32(fp1);
10743 tcg_temp_free_i32(fp0);
10744 tcg_temp_free_i32(t1);
10745}
10746
10747static void gen_sel_d(DisasContext *ctx, enum fopcode op1, int fd, int ft,
10748 int fs)
10749{
10750 TCGv_i64 t1 = tcg_const_i64(0);
10751 TCGv_i64 fp0 = tcg_temp_new_i64();
10752 TCGv_i64 fp1 = tcg_temp_new_i64();
10753 TCGv_i64 fp2 = tcg_temp_new_i64();
10754 gen_load_fpr64(ctx, fp0, fd);
10755 gen_load_fpr64(ctx, fp1, ft);
10756 gen_load_fpr64(ctx, fp2, fs);
10757
10758 switch (op1) {
10759 case OPC_SEL_D:
10760 tcg_gen_andi_i64(fp0, fp0, 1);
10761 tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
10762 break;
10763 case OPC_SELEQZ_D:
10764 tcg_gen_andi_i64(fp1, fp1, 1);
10765 tcg_gen_movcond_i64(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
10766 break;
10767 case OPC_SELNEZ_D:
10768 tcg_gen_andi_i64(fp1, fp1, 1);
10769 tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
10770 break;
10771 default:
10772 MIPS_INVAL("gen_sel_d");
9c708c7f 10773 generate_exception_end(ctx, EXCP_RI);
e7f16abb
LA
10774 break;
10775 }
10776
10777 gen_store_fpr64(ctx, fp0, fd);
10778 tcg_temp_free_i64(fp2);
10779 tcg_temp_free_i64(fp1);
10780 tcg_temp_free_i64(fp0);
10781 tcg_temp_free_i64(t1);
10782}
6ea83fed 10783
bf4120ad 10784static void gen_farith (DisasContext *ctx, enum fopcode op1,
5e755519 10785 int ft, int fs, int fd, int cc)
6ea83fed 10786{
7a387fff 10787 uint32_t func = ctx->opcode & 0x3f;
bf4120ad
NF
10788 switch (op1) {
10789 case OPC_ADD_S:
b6d96bed 10790 {
a7812ae4
PB
10791 TCGv_i32 fp0 = tcg_temp_new_i32();
10792 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 10793
7c979afd
LA
10794 gen_load_fpr32(ctx, fp0, fs);
10795 gen_load_fpr32(ctx, fp1, ft);
895c2d04 10796 gen_helper_float_add_s(fp0, cpu_env, fp0, fp1);
a7812ae4 10797 tcg_temp_free_i32(fp1);
7c979afd 10798 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 10799 tcg_temp_free_i32(fp0);
b6d96bed 10800 }
5a5012ec 10801 break;
bf4120ad 10802 case OPC_SUB_S:
b6d96bed 10803 {
a7812ae4
PB
10804 TCGv_i32 fp0 = tcg_temp_new_i32();
10805 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 10806
7c979afd
LA
10807 gen_load_fpr32(ctx, fp0, fs);
10808 gen_load_fpr32(ctx, fp1, ft);
895c2d04 10809 gen_helper_float_sub_s(fp0, cpu_env, fp0, fp1);
a7812ae4 10810 tcg_temp_free_i32(fp1);
7c979afd 10811 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 10812 tcg_temp_free_i32(fp0);
b6d96bed 10813 }
5a5012ec 10814 break;
bf4120ad 10815 case OPC_MUL_S:
b6d96bed 10816 {
a7812ae4
PB
10817 TCGv_i32 fp0 = tcg_temp_new_i32();
10818 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 10819
7c979afd
LA
10820 gen_load_fpr32(ctx, fp0, fs);
10821 gen_load_fpr32(ctx, fp1, ft);
895c2d04 10822 gen_helper_float_mul_s(fp0, cpu_env, fp0, fp1);
a7812ae4 10823 tcg_temp_free_i32(fp1);
7c979afd 10824 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 10825 tcg_temp_free_i32(fp0);
b6d96bed 10826 }
5a5012ec 10827 break;
bf4120ad 10828 case OPC_DIV_S:
b6d96bed 10829 {
a7812ae4
PB
10830 TCGv_i32 fp0 = tcg_temp_new_i32();
10831 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 10832
7c979afd
LA
10833 gen_load_fpr32(ctx, fp0, fs);
10834 gen_load_fpr32(ctx, fp1, ft);
895c2d04 10835 gen_helper_float_div_s(fp0, cpu_env, fp0, fp1);
a7812ae4 10836 tcg_temp_free_i32(fp1);
7c979afd 10837 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 10838 tcg_temp_free_i32(fp0);
b6d96bed 10839 }
5a5012ec 10840 break;
bf4120ad 10841 case OPC_SQRT_S:
b6d96bed 10842 {
a7812ae4 10843 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 10844
7c979afd 10845 gen_load_fpr32(ctx, fp0, fs);
895c2d04 10846 gen_helper_float_sqrt_s(fp0, cpu_env, fp0);
7c979afd 10847 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 10848 tcg_temp_free_i32(fp0);
b6d96bed 10849 }
5a5012ec 10850 break;
bf4120ad 10851 case OPC_ABS_S:
b6d96bed 10852 {
a7812ae4 10853 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 10854
7c979afd 10855 gen_load_fpr32(ctx, fp0, fs);
6be77480
AM
10856 if (ctx->abs2008) {
10857 tcg_gen_andi_i32(fp0, fp0, 0x7fffffffUL);
10858 } else {
10859 gen_helper_float_abs_s(fp0, fp0);
10860 }
7c979afd 10861 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 10862 tcg_temp_free_i32(fp0);
b6d96bed 10863 }
5a5012ec 10864 break;
bf4120ad 10865 case OPC_MOV_S:
b6d96bed 10866 {
a7812ae4 10867 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 10868
7c979afd
LA
10869 gen_load_fpr32(ctx, fp0, fs);
10870 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 10871 tcg_temp_free_i32(fp0);
b6d96bed 10872 }
5a5012ec 10873 break;
bf4120ad 10874 case OPC_NEG_S:
b6d96bed 10875 {
a7812ae4 10876 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 10877
7c979afd 10878 gen_load_fpr32(ctx, fp0, fs);
6be77480
AM
10879 if (ctx->abs2008) {
10880 tcg_gen_xori_i32(fp0, fp0, 1UL << 31);
10881 } else {
10882 gen_helper_float_chs_s(fp0, fp0);
10883 }
7c979afd 10884 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 10885 tcg_temp_free_i32(fp0);
b6d96bed 10886 }
5a5012ec 10887 break;
bf4120ad 10888 case OPC_ROUND_L_S:
5e755519 10889 check_cp1_64bitmode(ctx);
b6d96bed 10890 {
a7812ae4
PB
10891 TCGv_i32 fp32 = tcg_temp_new_i32();
10892 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 10893
7c979afd 10894 gen_load_fpr32(ctx, fp32, fs);
87552089
AM
10895 if (ctx->nan2008) {
10896 gen_helper_float_round_2008_l_s(fp64, cpu_env, fp32);
10897 } else {
10898 gen_helper_float_round_l_s(fp64, cpu_env, fp32);
10899 }
a7812ae4 10900 tcg_temp_free_i32(fp32);
b6d96bed 10901 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 10902 tcg_temp_free_i64(fp64);
b6d96bed 10903 }
5a5012ec 10904 break;
bf4120ad 10905 case OPC_TRUNC_L_S:
5e755519 10906 check_cp1_64bitmode(ctx);
b6d96bed 10907 {
a7812ae4
PB
10908 TCGv_i32 fp32 = tcg_temp_new_i32();
10909 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 10910
7c979afd 10911 gen_load_fpr32(ctx, fp32, fs);
87552089
AM
10912 if (ctx->nan2008) {
10913 gen_helper_float_trunc_2008_l_s(fp64, cpu_env, fp32);
10914 } else {
10915 gen_helper_float_trunc_l_s(fp64, cpu_env, fp32);
10916 }
a7812ae4 10917 tcg_temp_free_i32(fp32);
b6d96bed 10918 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 10919 tcg_temp_free_i64(fp64);
b6d96bed 10920 }
5a5012ec 10921 break;
bf4120ad 10922 case OPC_CEIL_L_S:
5e755519 10923 check_cp1_64bitmode(ctx);
b6d96bed 10924 {
a7812ae4
PB
10925 TCGv_i32 fp32 = tcg_temp_new_i32();
10926 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 10927
7c979afd 10928 gen_load_fpr32(ctx, fp32, fs);
87552089
AM
10929 if (ctx->nan2008) {
10930 gen_helper_float_ceil_2008_l_s(fp64, cpu_env, fp32);
10931 } else {
10932 gen_helper_float_ceil_l_s(fp64, cpu_env, fp32);
10933 }
a7812ae4 10934 tcg_temp_free_i32(fp32);
b6d96bed 10935 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 10936 tcg_temp_free_i64(fp64);
b6d96bed 10937 }
5a5012ec 10938 break;
bf4120ad 10939 case OPC_FLOOR_L_S:
5e755519 10940 check_cp1_64bitmode(ctx);
b6d96bed 10941 {
a7812ae4
PB
10942 TCGv_i32 fp32 = tcg_temp_new_i32();
10943 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 10944
7c979afd 10945 gen_load_fpr32(ctx, fp32, fs);
87552089
AM
10946 if (ctx->nan2008) {
10947 gen_helper_float_floor_2008_l_s(fp64, cpu_env, fp32);
10948 } else {
10949 gen_helper_float_floor_l_s(fp64, cpu_env, fp32);
10950 }
a7812ae4 10951 tcg_temp_free_i32(fp32);
b6d96bed 10952 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 10953 tcg_temp_free_i64(fp64);
b6d96bed 10954 }
5a5012ec 10955 break;
bf4120ad 10956 case OPC_ROUND_W_S:
b6d96bed 10957 {
a7812ae4 10958 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 10959
7c979afd 10960 gen_load_fpr32(ctx, fp0, fs);
87552089
AM
10961 if (ctx->nan2008) {
10962 gen_helper_float_round_2008_w_s(fp0, cpu_env, fp0);
10963 } else {
10964 gen_helper_float_round_w_s(fp0, cpu_env, fp0);
10965 }
7c979afd 10966 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 10967 tcg_temp_free_i32(fp0);
b6d96bed 10968 }
5a5012ec 10969 break;
bf4120ad 10970 case OPC_TRUNC_W_S:
b6d96bed 10971 {
a7812ae4 10972 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 10973
7c979afd 10974 gen_load_fpr32(ctx, fp0, fs);
87552089
AM
10975 if (ctx->nan2008) {
10976 gen_helper_float_trunc_2008_w_s(fp0, cpu_env, fp0);
10977 } else {
10978 gen_helper_float_trunc_w_s(fp0, cpu_env, fp0);
10979 }
7c979afd 10980 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 10981 tcg_temp_free_i32(fp0);
b6d96bed 10982 }
5a5012ec 10983 break;
bf4120ad 10984 case OPC_CEIL_W_S:
b6d96bed 10985 {
a7812ae4 10986 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 10987
7c979afd 10988 gen_load_fpr32(ctx, fp0, fs);
87552089
AM
10989 if (ctx->nan2008) {
10990 gen_helper_float_ceil_2008_w_s(fp0, cpu_env, fp0);
10991 } else {
10992 gen_helper_float_ceil_w_s(fp0, cpu_env, fp0);
10993 }
7c979afd 10994 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 10995 tcg_temp_free_i32(fp0);
b6d96bed 10996 }
5a5012ec 10997 break;
bf4120ad 10998 case OPC_FLOOR_W_S:
b6d96bed 10999 {
a7812ae4 11000 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 11001
7c979afd 11002 gen_load_fpr32(ctx, fp0, fs);
87552089
AM
11003 if (ctx->nan2008) {
11004 gen_helper_float_floor_2008_w_s(fp0, cpu_env, fp0);
11005 } else {
11006 gen_helper_float_floor_w_s(fp0, cpu_env, fp0);
11007 }
7c979afd 11008 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 11009 tcg_temp_free_i32(fp0);
b6d96bed 11010 }
5a5012ec 11011 break;
e7f16abb
LA
11012 case OPC_SEL_S:
11013 check_insn(ctx, ISA_MIPS32R6);
11014 gen_sel_s(ctx, op1, fd, ft, fs);
e7f16abb
LA
11015 break;
11016 case OPC_SELEQZ_S:
11017 check_insn(ctx, ISA_MIPS32R6);
11018 gen_sel_s(ctx, op1, fd, ft, fs);
e7f16abb
LA
11019 break;
11020 case OPC_SELNEZ_S:
11021 check_insn(ctx, ISA_MIPS32R6);
11022 gen_sel_s(ctx, op1, fd, ft, fs);
e7f16abb 11023 break;
bf4120ad 11024 case OPC_MOVCF_S:
fecd2646 11025 check_insn_opc_removed(ctx, ISA_MIPS32R6);
7c979afd 11026 gen_movcf_s(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
5a5012ec 11027 break;
bf4120ad 11028 case OPC_MOVZ_S:
fecd2646 11029 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a16336e4 11030 {
42a268c2 11031 TCGLabel *l1 = gen_new_label();
c9297f4d 11032 TCGv_i32 fp0;
a16336e4 11033
c9297f4d
AJ
11034 if (ft != 0) {
11035 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
11036 }
11037 fp0 = tcg_temp_new_i32();
7c979afd
LA
11038 gen_load_fpr32(ctx, fp0, fs);
11039 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 11040 tcg_temp_free_i32(fp0);
a16336e4
TS
11041 gen_set_label(l1);
11042 }
5a5012ec 11043 break;
bf4120ad 11044 case OPC_MOVN_S:
fecd2646 11045 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a16336e4 11046 {
42a268c2 11047 TCGLabel *l1 = gen_new_label();
c9297f4d
AJ
11048 TCGv_i32 fp0;
11049
11050 if (ft != 0) {
11051 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
11052 fp0 = tcg_temp_new_i32();
7c979afd
LA
11053 gen_load_fpr32(ctx, fp0, fs);
11054 gen_store_fpr32(ctx, fp0, fd);
c9297f4d
AJ
11055 tcg_temp_free_i32(fp0);
11056 gen_set_label(l1);
11057 }
a16336e4 11058 }
5a5012ec 11059 break;
bf4120ad 11060 case OPC_RECIP_S:
b6d96bed 11061 {
a7812ae4 11062 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 11063
7c979afd 11064 gen_load_fpr32(ctx, fp0, fs);
895c2d04 11065 gen_helper_float_recip_s(fp0, cpu_env, fp0);
7c979afd 11066 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 11067 tcg_temp_free_i32(fp0);
b6d96bed 11068 }
57fa1fb3 11069 break;
bf4120ad 11070 case OPC_RSQRT_S:
b6d96bed 11071 {
a7812ae4 11072 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 11073
7c979afd 11074 gen_load_fpr32(ctx, fp0, fs);
895c2d04 11075 gen_helper_float_rsqrt_s(fp0, cpu_env, fp0);
7c979afd 11076 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 11077 tcg_temp_free_i32(fp0);
b6d96bed 11078 }
57fa1fb3 11079 break;
e7f16abb
LA
11080 case OPC_MADDF_S:
11081 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 11082 {
a7812ae4
PB
11083 TCGv_i32 fp0 = tcg_temp_new_i32();
11084 TCGv_i32 fp1 = tcg_temp_new_i32();
e7f16abb 11085 TCGv_i32 fp2 = tcg_temp_new_i32();
7c979afd
LA
11086 gen_load_fpr32(ctx, fp0, fs);
11087 gen_load_fpr32(ctx, fp1, ft);
11088 gen_load_fpr32(ctx, fp2, fd);
e7f16abb 11089 gen_helper_float_maddf_s(fp2, cpu_env, fp0, fp1, fp2);
7c979afd 11090 gen_store_fpr32(ctx, fp2, fd);
e7f16abb 11091 tcg_temp_free_i32(fp2);
a7812ae4 11092 tcg_temp_free_i32(fp1);
a7812ae4 11093 tcg_temp_free_i32(fp0);
b6d96bed 11094 }
57fa1fb3 11095 break;
e7f16abb
LA
11096 case OPC_MSUBF_S:
11097 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 11098 {
a7812ae4 11099 TCGv_i32 fp0 = tcg_temp_new_i32();
e7f16abb
LA
11100 TCGv_i32 fp1 = tcg_temp_new_i32();
11101 TCGv_i32 fp2 = tcg_temp_new_i32();
7c979afd
LA
11102 gen_load_fpr32(ctx, fp0, fs);
11103 gen_load_fpr32(ctx, fp1, ft);
11104 gen_load_fpr32(ctx, fp2, fd);
e7f16abb 11105 gen_helper_float_msubf_s(fp2, cpu_env, fp0, fp1, fp2);
7c979afd 11106 gen_store_fpr32(ctx, fp2, fd);
e7f16abb
LA
11107 tcg_temp_free_i32(fp2);
11108 tcg_temp_free_i32(fp1);
a7812ae4 11109 tcg_temp_free_i32(fp0);
b6d96bed 11110 }
57fa1fb3 11111 break;
e7f16abb
LA
11112 case OPC_RINT_S:
11113 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 11114 {
a7812ae4 11115 TCGv_i32 fp0 = tcg_temp_new_i32();
7c979afd 11116 gen_load_fpr32(ctx, fp0, fs);
e7f16abb 11117 gen_helper_float_rint_s(fp0, cpu_env, fp0);
7c979afd 11118 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 11119 tcg_temp_free_i32(fp0);
b6d96bed 11120 }
57fa1fb3 11121 break;
e7f16abb
LA
11122 case OPC_CLASS_S:
11123 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 11124 {
e7f16abb 11125 TCGv_i32 fp0 = tcg_temp_new_i32();
7c979afd 11126 gen_load_fpr32(ctx, fp0, fs);
af39bc8c 11127 gen_helper_float_class_s(fp0, cpu_env, fp0);
7c979afd 11128 gen_store_fpr32(ctx, fp0, fd);
e7f16abb 11129 tcg_temp_free_i32(fp0);
e7f16abb
LA
11130 }
11131 break;
11132 case OPC_MIN_S: /* OPC_RECIP2_S */
11133 if (ctx->insn_flags & ISA_MIPS32R6) {
11134 /* OPC_MIN_S */
a7812ae4
PB
11135 TCGv_i32 fp0 = tcg_temp_new_i32();
11136 TCGv_i32 fp1 = tcg_temp_new_i32();
e7f16abb 11137 TCGv_i32 fp2 = tcg_temp_new_i32();
7c979afd
LA
11138 gen_load_fpr32(ctx, fp0, fs);
11139 gen_load_fpr32(ctx, fp1, ft);
e7f16abb 11140 gen_helper_float_min_s(fp2, cpu_env, fp0, fp1);
7c979afd 11141 gen_store_fpr32(ctx, fp2, fd);
e7f16abb
LA
11142 tcg_temp_free_i32(fp2);
11143 tcg_temp_free_i32(fp1);
11144 tcg_temp_free_i32(fp0);
e7f16abb
LA
11145 } else {
11146 /* OPC_RECIP2_S */
11147 check_cp1_64bitmode(ctx);
11148 {
11149 TCGv_i32 fp0 = tcg_temp_new_i32();
11150 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 11151
7c979afd
LA
11152 gen_load_fpr32(ctx, fp0, fs);
11153 gen_load_fpr32(ctx, fp1, ft);
e7f16abb
LA
11154 gen_helper_float_recip2_s(fp0, cpu_env, fp0, fp1);
11155 tcg_temp_free_i32(fp1);
7c979afd 11156 gen_store_fpr32(ctx, fp0, fd);
e7f16abb
LA
11157 tcg_temp_free_i32(fp0);
11158 }
e7f16abb
LA
11159 }
11160 break;
11161 case OPC_MINA_S: /* OPC_RECIP1_S */
11162 if (ctx->insn_flags & ISA_MIPS32R6) {
11163 /* OPC_MINA_S */
11164 TCGv_i32 fp0 = tcg_temp_new_i32();
11165 TCGv_i32 fp1 = tcg_temp_new_i32();
11166 TCGv_i32 fp2 = tcg_temp_new_i32();
7c979afd
LA
11167 gen_load_fpr32(ctx, fp0, fs);
11168 gen_load_fpr32(ctx, fp1, ft);
e7f16abb 11169 gen_helper_float_mina_s(fp2, cpu_env, fp0, fp1);
7c979afd 11170 gen_store_fpr32(ctx, fp2, fd);
e7f16abb
LA
11171 tcg_temp_free_i32(fp2);
11172 tcg_temp_free_i32(fp1);
11173 tcg_temp_free_i32(fp0);
e7f16abb
LA
11174 } else {
11175 /* OPC_RECIP1_S */
11176 check_cp1_64bitmode(ctx);
11177 {
11178 TCGv_i32 fp0 = tcg_temp_new_i32();
11179
7c979afd 11180 gen_load_fpr32(ctx, fp0, fs);
e7f16abb 11181 gen_helper_float_recip1_s(fp0, cpu_env, fp0);
7c979afd 11182 gen_store_fpr32(ctx, fp0, fd);
e7f16abb
LA
11183 tcg_temp_free_i32(fp0);
11184 }
e7f16abb
LA
11185 }
11186 break;
11187 case OPC_MAX_S: /* OPC_RSQRT1_S */
11188 if (ctx->insn_flags & ISA_MIPS32R6) {
11189 /* OPC_MAX_S */
11190 TCGv_i32 fp0 = tcg_temp_new_i32();
11191 TCGv_i32 fp1 = tcg_temp_new_i32();
7c979afd
LA
11192 gen_load_fpr32(ctx, fp0, fs);
11193 gen_load_fpr32(ctx, fp1, ft);
e7f16abb 11194 gen_helper_float_max_s(fp1, cpu_env, fp0, fp1);
7c979afd 11195 gen_store_fpr32(ctx, fp1, fd);
e7f16abb
LA
11196 tcg_temp_free_i32(fp1);
11197 tcg_temp_free_i32(fp0);
e7f16abb
LA
11198 } else {
11199 /* OPC_RSQRT1_S */
11200 check_cp1_64bitmode(ctx);
11201 {
11202 TCGv_i32 fp0 = tcg_temp_new_i32();
11203
7c979afd 11204 gen_load_fpr32(ctx, fp0, fs);
e7f16abb 11205 gen_helper_float_rsqrt1_s(fp0, cpu_env, fp0);
7c979afd 11206 gen_store_fpr32(ctx, fp0, fd);
e7f16abb
LA
11207 tcg_temp_free_i32(fp0);
11208 }
e7f16abb
LA
11209 }
11210 break;
11211 case OPC_MAXA_S: /* OPC_RSQRT2_S */
11212 if (ctx->insn_flags & ISA_MIPS32R6) {
11213 /* OPC_MAXA_S */
11214 TCGv_i32 fp0 = tcg_temp_new_i32();
11215 TCGv_i32 fp1 = tcg_temp_new_i32();
7c979afd
LA
11216 gen_load_fpr32(ctx, fp0, fs);
11217 gen_load_fpr32(ctx, fp1, ft);
e7f16abb 11218 gen_helper_float_maxa_s(fp1, cpu_env, fp0, fp1);
7c979afd 11219 gen_store_fpr32(ctx, fp1, fd);
a7812ae4 11220 tcg_temp_free_i32(fp1);
a7812ae4 11221 tcg_temp_free_i32(fp0);
e7f16abb
LA
11222 } else {
11223 /* OPC_RSQRT2_S */
11224 check_cp1_64bitmode(ctx);
11225 {
11226 TCGv_i32 fp0 = tcg_temp_new_i32();
11227 TCGv_i32 fp1 = tcg_temp_new_i32();
11228
7c979afd
LA
11229 gen_load_fpr32(ctx, fp0, fs);
11230 gen_load_fpr32(ctx, fp1, ft);
e7f16abb
LA
11231 gen_helper_float_rsqrt2_s(fp0, cpu_env, fp0, fp1);
11232 tcg_temp_free_i32(fp1);
7c979afd 11233 gen_store_fpr32(ctx, fp0, fd);
e7f16abb
LA
11234 tcg_temp_free_i32(fp0);
11235 }
b6d96bed 11236 }
57fa1fb3 11237 break;
bf4120ad 11238 case OPC_CVT_D_S:
5e755519 11239 check_cp1_registers(ctx, fd);
b6d96bed 11240 {
a7812ae4
PB
11241 TCGv_i32 fp32 = tcg_temp_new_i32();
11242 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 11243
7c979afd 11244 gen_load_fpr32(ctx, fp32, fs);
895c2d04 11245 gen_helper_float_cvtd_s(fp64, cpu_env, fp32);
a7812ae4 11246 tcg_temp_free_i32(fp32);
b6d96bed 11247 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 11248 tcg_temp_free_i64(fp64);
b6d96bed 11249 }
5a5012ec 11250 break;
bf4120ad 11251 case OPC_CVT_W_S:
b6d96bed 11252 {
a7812ae4 11253 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 11254
7c979afd 11255 gen_load_fpr32(ctx, fp0, fs);
87552089
AM
11256 if (ctx->nan2008) {
11257 gen_helper_float_cvt_2008_w_s(fp0, cpu_env, fp0);
11258 } else {
11259 gen_helper_float_cvt_w_s(fp0, cpu_env, fp0);
11260 }
7c979afd 11261 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 11262 tcg_temp_free_i32(fp0);
b6d96bed 11263 }
5a5012ec 11264 break;
bf4120ad 11265 case OPC_CVT_L_S:
5e755519 11266 check_cp1_64bitmode(ctx);
b6d96bed 11267 {
a7812ae4
PB
11268 TCGv_i32 fp32 = tcg_temp_new_i32();
11269 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 11270
7c979afd 11271 gen_load_fpr32(ctx, fp32, fs);
87552089
AM
11272 if (ctx->nan2008) {
11273 gen_helper_float_cvt_2008_l_s(fp64, cpu_env, fp32);
11274 } else {
11275 gen_helper_float_cvt_l_s(fp64, cpu_env, fp32);
11276 }
a7812ae4 11277 tcg_temp_free_i32(fp32);
b6d96bed 11278 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 11279 tcg_temp_free_i64(fp64);
b6d96bed 11280 }
5a5012ec 11281 break;
bf4120ad 11282 case OPC_CVT_PS_S:
e29c9628 11283 check_ps(ctx);
b6d96bed 11284 {
a7812ae4
PB
11285 TCGv_i64 fp64 = tcg_temp_new_i64();
11286 TCGv_i32 fp32_0 = tcg_temp_new_i32();
11287 TCGv_i32 fp32_1 = tcg_temp_new_i32();
b6d96bed 11288
7c979afd
LA
11289 gen_load_fpr32(ctx, fp32_0, fs);
11290 gen_load_fpr32(ctx, fp32_1, ft);
13d24f49 11291 tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0);
a7812ae4
PB
11292 tcg_temp_free_i32(fp32_1);
11293 tcg_temp_free_i32(fp32_0);
36aa55dc 11294 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 11295 tcg_temp_free_i64(fp64);
b6d96bed 11296 }
5a5012ec 11297 break;
bf4120ad
NF
11298 case OPC_CMP_F_S:
11299 case OPC_CMP_UN_S:
11300 case OPC_CMP_EQ_S:
11301 case OPC_CMP_UEQ_S:
11302 case OPC_CMP_OLT_S:
11303 case OPC_CMP_ULT_S:
11304 case OPC_CMP_OLE_S:
11305 case OPC_CMP_ULE_S:
11306 case OPC_CMP_SF_S:
11307 case OPC_CMP_NGLE_S:
11308 case OPC_CMP_SEQ_S:
11309 case OPC_CMP_NGL_S:
11310 case OPC_CMP_LT_S:
11311 case OPC_CMP_NGE_S:
11312 case OPC_CMP_LE_S:
11313 case OPC_CMP_NGT_S:
fecd2646 11314 check_insn_opc_removed(ctx, ISA_MIPS32R6);
8153667c
NF
11315 if (ctx->opcode & (1 << 6)) {
11316 gen_cmpabs_s(ctx, func-48, ft, fs, cc);
8153667c
NF
11317 } else {
11318 gen_cmp_s(ctx, func-48, ft, fs, cc);
5a1e8ffb 11319 }
5a5012ec 11320 break;
bf4120ad 11321 case OPC_ADD_D:
5e755519 11322 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 11323 {
a7812ae4
PB
11324 TCGv_i64 fp0 = tcg_temp_new_i64();
11325 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
11326
11327 gen_load_fpr64(ctx, fp0, fs);
11328 gen_load_fpr64(ctx, fp1, ft);
895c2d04 11329 gen_helper_float_add_d(fp0, cpu_env, fp0, fp1);
a7812ae4 11330 tcg_temp_free_i64(fp1);
b6d96bed 11331 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11332 tcg_temp_free_i64(fp0);
b6d96bed 11333 }
6ea83fed 11334 break;
bf4120ad 11335 case OPC_SUB_D:
5e755519 11336 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 11337 {
a7812ae4
PB
11338 TCGv_i64 fp0 = tcg_temp_new_i64();
11339 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
11340
11341 gen_load_fpr64(ctx, fp0, fs);
11342 gen_load_fpr64(ctx, fp1, ft);
895c2d04 11343 gen_helper_float_sub_d(fp0, cpu_env, fp0, fp1);
a7812ae4 11344 tcg_temp_free_i64(fp1);
b6d96bed 11345 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11346 tcg_temp_free_i64(fp0);
b6d96bed 11347 }
6ea83fed 11348 break;
bf4120ad 11349 case OPC_MUL_D:
5e755519 11350 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 11351 {
a7812ae4
PB
11352 TCGv_i64 fp0 = tcg_temp_new_i64();
11353 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
11354
11355 gen_load_fpr64(ctx, fp0, fs);
11356 gen_load_fpr64(ctx, fp1, ft);
895c2d04 11357 gen_helper_float_mul_d(fp0, cpu_env, fp0, fp1);
a7812ae4 11358 tcg_temp_free_i64(fp1);
b6d96bed 11359 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11360 tcg_temp_free_i64(fp0);
b6d96bed 11361 }
6ea83fed 11362 break;
bf4120ad 11363 case OPC_DIV_D:
5e755519 11364 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 11365 {
a7812ae4
PB
11366 TCGv_i64 fp0 = tcg_temp_new_i64();
11367 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
11368
11369 gen_load_fpr64(ctx, fp0, fs);
11370 gen_load_fpr64(ctx, fp1, ft);
895c2d04 11371 gen_helper_float_div_d(fp0, cpu_env, fp0, fp1);
a7812ae4 11372 tcg_temp_free_i64(fp1);
b6d96bed 11373 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11374 tcg_temp_free_i64(fp0);
b6d96bed 11375 }
6ea83fed 11376 break;
bf4120ad 11377 case OPC_SQRT_D:
5e755519 11378 check_cp1_registers(ctx, fs | fd);
b6d96bed 11379 {
a7812ae4 11380 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
11381
11382 gen_load_fpr64(ctx, fp0, fs);
895c2d04 11383 gen_helper_float_sqrt_d(fp0, cpu_env, fp0);
b6d96bed 11384 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11385 tcg_temp_free_i64(fp0);
b6d96bed 11386 }
6ea83fed 11387 break;
bf4120ad 11388 case OPC_ABS_D:
5e755519 11389 check_cp1_registers(ctx, fs | fd);
b6d96bed 11390 {
a7812ae4 11391 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
11392
11393 gen_load_fpr64(ctx, fp0, fs);
6be77480
AM
11394 if (ctx->abs2008) {
11395 tcg_gen_andi_i64(fp0, fp0, 0x7fffffffffffffffULL);
11396 } else {
11397 gen_helper_float_abs_d(fp0, fp0);
11398 }
b6d96bed 11399 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11400 tcg_temp_free_i64(fp0);
b6d96bed 11401 }
6ea83fed 11402 break;
bf4120ad 11403 case OPC_MOV_D:
5e755519 11404 check_cp1_registers(ctx, fs | fd);
b6d96bed 11405 {
a7812ae4 11406 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
11407
11408 gen_load_fpr64(ctx, fp0, fs);
11409 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11410 tcg_temp_free_i64(fp0);
b6d96bed 11411 }
6ea83fed 11412 break;
bf4120ad 11413 case OPC_NEG_D:
5e755519 11414 check_cp1_registers(ctx, fs | fd);
b6d96bed 11415 {
a7812ae4 11416 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
11417
11418 gen_load_fpr64(ctx, fp0, fs);
6be77480
AM
11419 if (ctx->abs2008) {
11420 tcg_gen_xori_i64(fp0, fp0, 1ULL << 63);
11421 } else {
11422 gen_helper_float_chs_d(fp0, fp0);
11423 }
b6d96bed 11424 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11425 tcg_temp_free_i64(fp0);
b6d96bed 11426 }
6ea83fed 11427 break;
bf4120ad 11428 case OPC_ROUND_L_D:
5e755519 11429 check_cp1_64bitmode(ctx);
b6d96bed 11430 {
a7812ae4 11431 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
11432
11433 gen_load_fpr64(ctx, fp0, fs);
87552089
AM
11434 if (ctx->nan2008) {
11435 gen_helper_float_round_2008_l_d(fp0, cpu_env, fp0);
11436 } else {
11437 gen_helper_float_round_l_d(fp0, cpu_env, fp0);
11438 }
b6d96bed 11439 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11440 tcg_temp_free_i64(fp0);
b6d96bed 11441 }
5a5012ec 11442 break;
bf4120ad 11443 case OPC_TRUNC_L_D:
5e755519 11444 check_cp1_64bitmode(ctx);
b6d96bed 11445 {
a7812ae4 11446 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
11447
11448 gen_load_fpr64(ctx, fp0, fs);
87552089
AM
11449 if (ctx->nan2008) {
11450 gen_helper_float_trunc_2008_l_d(fp0, cpu_env, fp0);
11451 } else {
11452 gen_helper_float_trunc_l_d(fp0, cpu_env, fp0);
11453 }
b6d96bed 11454 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11455 tcg_temp_free_i64(fp0);
b6d96bed 11456 }
5a5012ec 11457 break;
bf4120ad 11458 case OPC_CEIL_L_D:
5e755519 11459 check_cp1_64bitmode(ctx);
b6d96bed 11460 {
a7812ae4 11461 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
11462
11463 gen_load_fpr64(ctx, fp0, fs);
87552089
AM
11464 if (ctx->nan2008) {
11465 gen_helper_float_ceil_2008_l_d(fp0, cpu_env, fp0);
11466 } else {
11467 gen_helper_float_ceil_l_d(fp0, cpu_env, fp0);
11468 }
b6d96bed 11469 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11470 tcg_temp_free_i64(fp0);
b6d96bed 11471 }
5a5012ec 11472 break;
bf4120ad 11473 case OPC_FLOOR_L_D:
5e755519 11474 check_cp1_64bitmode(ctx);
b6d96bed 11475 {
a7812ae4 11476 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
11477
11478 gen_load_fpr64(ctx, fp0, fs);
87552089
AM
11479 if (ctx->nan2008) {
11480 gen_helper_float_floor_2008_l_d(fp0, cpu_env, fp0);
11481 } else {
11482 gen_helper_float_floor_l_d(fp0, cpu_env, fp0);
11483 }
b6d96bed 11484 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11485 tcg_temp_free_i64(fp0);
b6d96bed 11486 }
5a5012ec 11487 break;
bf4120ad 11488 case OPC_ROUND_W_D:
5e755519 11489 check_cp1_registers(ctx, fs);
b6d96bed 11490 {
a7812ae4
PB
11491 TCGv_i32 fp32 = tcg_temp_new_i32();
11492 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
11493
11494 gen_load_fpr64(ctx, fp64, fs);
87552089
AM
11495 if (ctx->nan2008) {
11496 gen_helper_float_round_2008_w_d(fp32, cpu_env, fp64);
11497 } else {
11498 gen_helper_float_round_w_d(fp32, cpu_env, fp64);
11499 }
a7812ae4 11500 tcg_temp_free_i64(fp64);
7c979afd 11501 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 11502 tcg_temp_free_i32(fp32);
b6d96bed 11503 }
6ea83fed 11504 break;
bf4120ad 11505 case OPC_TRUNC_W_D:
5e755519 11506 check_cp1_registers(ctx, fs);
b6d96bed 11507 {
a7812ae4
PB
11508 TCGv_i32 fp32 = tcg_temp_new_i32();
11509 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
11510
11511 gen_load_fpr64(ctx, fp64, fs);
87552089
AM
11512 if (ctx->nan2008) {
11513 gen_helper_float_trunc_2008_w_d(fp32, cpu_env, fp64);
11514 } else {
11515 gen_helper_float_trunc_w_d(fp32, cpu_env, fp64);
11516 }
a7812ae4 11517 tcg_temp_free_i64(fp64);
7c979afd 11518 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 11519 tcg_temp_free_i32(fp32);
b6d96bed 11520 }
6ea83fed 11521 break;
bf4120ad 11522 case OPC_CEIL_W_D:
5e755519 11523 check_cp1_registers(ctx, fs);
b6d96bed 11524 {
a7812ae4
PB
11525 TCGv_i32 fp32 = tcg_temp_new_i32();
11526 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
11527
11528 gen_load_fpr64(ctx, fp64, fs);
87552089
AM
11529 if (ctx->nan2008) {
11530 gen_helper_float_ceil_2008_w_d(fp32, cpu_env, fp64);
11531 } else {
11532 gen_helper_float_ceil_w_d(fp32, cpu_env, fp64);
11533 }
a7812ae4 11534 tcg_temp_free_i64(fp64);
7c979afd 11535 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 11536 tcg_temp_free_i32(fp32);
b6d96bed 11537 }
6ea83fed 11538 break;
bf4120ad 11539 case OPC_FLOOR_W_D:
5e755519 11540 check_cp1_registers(ctx, fs);
b6d96bed 11541 {
a7812ae4
PB
11542 TCGv_i32 fp32 = tcg_temp_new_i32();
11543 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
11544
11545 gen_load_fpr64(ctx, fp64, fs);
87552089
AM
11546 if (ctx->nan2008) {
11547 gen_helper_float_floor_2008_w_d(fp32, cpu_env, fp64);
11548 } else {
11549 gen_helper_float_floor_w_d(fp32, cpu_env, fp64);
11550 }
a7812ae4 11551 tcg_temp_free_i64(fp64);
7c979afd 11552 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 11553 tcg_temp_free_i32(fp32);
b6d96bed 11554 }
6ea83fed 11555 break;
e7f16abb
LA
11556 case OPC_SEL_D:
11557 check_insn(ctx, ISA_MIPS32R6);
11558 gen_sel_d(ctx, op1, fd, ft, fs);
e7f16abb
LA
11559 break;
11560 case OPC_SELEQZ_D:
11561 check_insn(ctx, ISA_MIPS32R6);
11562 gen_sel_d(ctx, op1, fd, ft, fs);
e7f16abb
LA
11563 break;
11564 case OPC_SELNEZ_D:
11565 check_insn(ctx, ISA_MIPS32R6);
11566 gen_sel_d(ctx, op1, fd, ft, fs);
e7f16abb 11567 break;
bf4120ad 11568 case OPC_MOVCF_D:
fecd2646 11569 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b6d96bed 11570 gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
dd016883 11571 break;
bf4120ad 11572 case OPC_MOVZ_D:
fecd2646 11573 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a16336e4 11574 {
42a268c2 11575 TCGLabel *l1 = gen_new_label();
c9297f4d 11576 TCGv_i64 fp0;
a16336e4 11577
c9297f4d
AJ
11578 if (ft != 0) {
11579 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
11580 }
11581 fp0 = tcg_temp_new_i64();
b6d96bed
TS
11582 gen_load_fpr64(ctx, fp0, fs);
11583 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11584 tcg_temp_free_i64(fp0);
a16336e4
TS
11585 gen_set_label(l1);
11586 }
5a5012ec 11587 break;
bf4120ad 11588 case OPC_MOVN_D:
fecd2646 11589 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a16336e4 11590 {
42a268c2 11591 TCGLabel *l1 = gen_new_label();
c9297f4d
AJ
11592 TCGv_i64 fp0;
11593
11594 if (ft != 0) {
11595 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
11596 fp0 = tcg_temp_new_i64();
11597 gen_load_fpr64(ctx, fp0, fs);
11598 gen_store_fpr64(ctx, fp0, fd);
11599 tcg_temp_free_i64(fp0);
11600 gen_set_label(l1);
11601 }
a16336e4 11602 }
6ea83fed 11603 break;
bf4120ad 11604 case OPC_RECIP_D:
ca6c7803 11605 check_cp1_registers(ctx, fs | fd);
b6d96bed 11606 {
a7812ae4 11607 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
11608
11609 gen_load_fpr64(ctx, fp0, fs);
895c2d04 11610 gen_helper_float_recip_d(fp0, cpu_env, fp0);
b6d96bed 11611 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11612 tcg_temp_free_i64(fp0);
b6d96bed 11613 }
57fa1fb3 11614 break;
bf4120ad 11615 case OPC_RSQRT_D:
ca6c7803 11616 check_cp1_registers(ctx, fs | fd);
b6d96bed 11617 {
a7812ae4 11618 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
11619
11620 gen_load_fpr64(ctx, fp0, fs);
895c2d04 11621 gen_helper_float_rsqrt_d(fp0, cpu_env, fp0);
b6d96bed 11622 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11623 tcg_temp_free_i64(fp0);
b6d96bed 11624 }
57fa1fb3 11625 break;
e7f16abb
LA
11626 case OPC_MADDF_D:
11627 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 11628 {
a7812ae4
PB
11629 TCGv_i64 fp0 = tcg_temp_new_i64();
11630 TCGv_i64 fp1 = tcg_temp_new_i64();
e7f16abb 11631 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
11632 gen_load_fpr64(ctx, fp0, fs);
11633 gen_load_fpr64(ctx, fp1, ft);
e7f16abb
LA
11634 gen_load_fpr64(ctx, fp2, fd);
11635 gen_helper_float_maddf_d(fp2, cpu_env, fp0, fp1, fp2);
11636 gen_store_fpr64(ctx, fp2, fd);
11637 tcg_temp_free_i64(fp2);
a7812ae4 11638 tcg_temp_free_i64(fp1);
a7812ae4 11639 tcg_temp_free_i64(fp0);
b6d96bed 11640 }
57fa1fb3 11641 break;
e7f16abb
LA
11642 case OPC_MSUBF_D:
11643 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 11644 {
a7812ae4 11645 TCGv_i64 fp0 = tcg_temp_new_i64();
e7f16abb
LA
11646 TCGv_i64 fp1 = tcg_temp_new_i64();
11647 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed 11648 gen_load_fpr64(ctx, fp0, fs);
e7f16abb
LA
11649 gen_load_fpr64(ctx, fp1, ft);
11650 gen_load_fpr64(ctx, fp2, fd);
11651 gen_helper_float_msubf_d(fp2, cpu_env, fp0, fp1, fp2);
11652 gen_store_fpr64(ctx, fp2, fd);
11653 tcg_temp_free_i64(fp2);
11654 tcg_temp_free_i64(fp1);
a7812ae4 11655 tcg_temp_free_i64(fp0);
b6d96bed 11656 }
57fa1fb3 11657 break;
e7f16abb
LA
11658 case OPC_RINT_D:
11659 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 11660 {
a7812ae4 11661 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 11662 gen_load_fpr64(ctx, fp0, fs);
e7f16abb 11663 gen_helper_float_rint_d(fp0, cpu_env, fp0);
b6d96bed 11664 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11665 tcg_temp_free_i64(fp0);
b6d96bed 11666 }
57fa1fb3 11667 break;
e7f16abb
LA
11668 case OPC_CLASS_D:
11669 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 11670 {
e7f16abb
LA
11671 TCGv_i64 fp0 = tcg_temp_new_i64();
11672 gen_load_fpr64(ctx, fp0, fs);
af39bc8c 11673 gen_helper_float_class_d(fp0, cpu_env, fp0);
e7f16abb
LA
11674 gen_store_fpr64(ctx, fp0, fd);
11675 tcg_temp_free_i64(fp0);
e7f16abb
LA
11676 }
11677 break;
11678 case OPC_MIN_D: /* OPC_RECIP2_D */
11679 if (ctx->insn_flags & ISA_MIPS32R6) {
11680 /* OPC_MIN_D */
a7812ae4
PB
11681 TCGv_i64 fp0 = tcg_temp_new_i64();
11682 TCGv_i64 fp1 = tcg_temp_new_i64();
e7f16abb
LA
11683 gen_load_fpr64(ctx, fp0, fs);
11684 gen_load_fpr64(ctx, fp1, ft);
11685 gen_helper_float_min_d(fp1, cpu_env, fp0, fp1);
11686 gen_store_fpr64(ctx, fp1, fd);
11687 tcg_temp_free_i64(fp1);
11688 tcg_temp_free_i64(fp0);
e7f16abb
LA
11689 } else {
11690 /* OPC_RECIP2_D */
11691 check_cp1_64bitmode(ctx);
11692 {
11693 TCGv_i64 fp0 = tcg_temp_new_i64();
11694 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed 11695
e7f16abb
LA
11696 gen_load_fpr64(ctx, fp0, fs);
11697 gen_load_fpr64(ctx, fp1, ft);
11698 gen_helper_float_recip2_d(fp0, cpu_env, fp0, fp1);
11699 tcg_temp_free_i64(fp1);
11700 gen_store_fpr64(ctx, fp0, fd);
11701 tcg_temp_free_i64(fp0);
11702 }
e7f16abb
LA
11703 }
11704 break;
11705 case OPC_MINA_D: /* OPC_RECIP1_D */
11706 if (ctx->insn_flags & ISA_MIPS32R6) {
11707 /* OPC_MINA_D */
11708 TCGv_i64 fp0 = tcg_temp_new_i64();
11709 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
11710 gen_load_fpr64(ctx, fp0, fs);
11711 gen_load_fpr64(ctx, fp1, ft);
e7f16abb
LA
11712 gen_helper_float_mina_d(fp1, cpu_env, fp0, fp1);
11713 gen_store_fpr64(ctx, fp1, fd);
11714 tcg_temp_free_i64(fp1);
11715 tcg_temp_free_i64(fp0);
e7f16abb
LA
11716 } else {
11717 /* OPC_RECIP1_D */
11718 check_cp1_64bitmode(ctx);
11719 {
11720 TCGv_i64 fp0 = tcg_temp_new_i64();
11721
11722 gen_load_fpr64(ctx, fp0, fs);
11723 gen_helper_float_recip1_d(fp0, cpu_env, fp0);
11724 gen_store_fpr64(ctx, fp0, fd);
11725 tcg_temp_free_i64(fp0);
11726 }
e7f16abb
LA
11727 }
11728 break;
11729 case OPC_MAX_D: /* OPC_RSQRT1_D */
11730 if (ctx->insn_flags & ISA_MIPS32R6) {
11731 /* OPC_MAX_D */
11732 TCGv_i64 fp0 = tcg_temp_new_i64();
11733 TCGv_i64 fp1 = tcg_temp_new_i64();
11734 gen_load_fpr64(ctx, fp0, fs);
11735 gen_load_fpr64(ctx, fp1, ft);
11736 gen_helper_float_max_d(fp1, cpu_env, fp0, fp1);
11737 gen_store_fpr64(ctx, fp1, fd);
a7812ae4 11738 tcg_temp_free_i64(fp1);
a7812ae4 11739 tcg_temp_free_i64(fp0);
e7f16abb
LA
11740 } else {
11741 /* OPC_RSQRT1_D */
11742 check_cp1_64bitmode(ctx);
11743 {
11744 TCGv_i64 fp0 = tcg_temp_new_i64();
11745
11746 gen_load_fpr64(ctx, fp0, fs);
11747 gen_helper_float_rsqrt1_d(fp0, cpu_env, fp0);
11748 gen_store_fpr64(ctx, fp0, fd);
11749 tcg_temp_free_i64(fp0);
11750 }
e7f16abb
LA
11751 }
11752 break;
11753 case OPC_MAXA_D: /* OPC_RSQRT2_D */
11754 if (ctx->insn_flags & ISA_MIPS32R6) {
11755 /* OPC_MAXA_D */
11756 TCGv_i64 fp0 = tcg_temp_new_i64();
11757 TCGv_i64 fp1 = tcg_temp_new_i64();
11758 gen_load_fpr64(ctx, fp0, fs);
11759 gen_load_fpr64(ctx, fp1, ft);
11760 gen_helper_float_maxa_d(fp1, cpu_env, fp0, fp1);
11761 gen_store_fpr64(ctx, fp1, fd);
11762 tcg_temp_free_i64(fp1);
11763 tcg_temp_free_i64(fp0);
e7f16abb
LA
11764 } else {
11765 /* OPC_RSQRT2_D */
11766 check_cp1_64bitmode(ctx);
11767 {
11768 TCGv_i64 fp0 = tcg_temp_new_i64();
11769 TCGv_i64 fp1 = tcg_temp_new_i64();
11770
11771 gen_load_fpr64(ctx, fp0, fs);
11772 gen_load_fpr64(ctx, fp1, ft);
11773 gen_helper_float_rsqrt2_d(fp0, cpu_env, fp0, fp1);
11774 tcg_temp_free_i64(fp1);
11775 gen_store_fpr64(ctx, fp0, fd);
11776 tcg_temp_free_i64(fp0);
11777 }
b6d96bed 11778 }
57fa1fb3 11779 break;
bf4120ad
NF
11780 case OPC_CMP_F_D:
11781 case OPC_CMP_UN_D:
11782 case OPC_CMP_EQ_D:
11783 case OPC_CMP_UEQ_D:
11784 case OPC_CMP_OLT_D:
11785 case OPC_CMP_ULT_D:
11786 case OPC_CMP_OLE_D:
11787 case OPC_CMP_ULE_D:
11788 case OPC_CMP_SF_D:
11789 case OPC_CMP_NGLE_D:
11790 case OPC_CMP_SEQ_D:
11791 case OPC_CMP_NGL_D:
11792 case OPC_CMP_LT_D:
11793 case OPC_CMP_NGE_D:
11794 case OPC_CMP_LE_D:
11795 case OPC_CMP_NGT_D:
fecd2646 11796 check_insn_opc_removed(ctx, ISA_MIPS32R6);
8153667c
NF
11797 if (ctx->opcode & (1 << 6)) {
11798 gen_cmpabs_d(ctx, func-48, ft, fs, cc);
8153667c
NF
11799 } else {
11800 gen_cmp_d(ctx, func-48, ft, fs, cc);
5a1e8ffb 11801 }
6ea83fed 11802 break;
bf4120ad 11803 case OPC_CVT_S_D:
5e755519 11804 check_cp1_registers(ctx, fs);
b6d96bed 11805 {
a7812ae4
PB
11806 TCGv_i32 fp32 = tcg_temp_new_i32();
11807 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
11808
11809 gen_load_fpr64(ctx, fp64, fs);
895c2d04 11810 gen_helper_float_cvts_d(fp32, cpu_env, fp64);
a7812ae4 11811 tcg_temp_free_i64(fp64);
7c979afd 11812 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 11813 tcg_temp_free_i32(fp32);
b6d96bed 11814 }
5a5012ec 11815 break;
bf4120ad 11816 case OPC_CVT_W_D:
5e755519 11817 check_cp1_registers(ctx, fs);
b6d96bed 11818 {
a7812ae4
PB
11819 TCGv_i32 fp32 = tcg_temp_new_i32();
11820 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
11821
11822 gen_load_fpr64(ctx, fp64, fs);
87552089
AM
11823 if (ctx->nan2008) {
11824 gen_helper_float_cvt_2008_w_d(fp32, cpu_env, fp64);
11825 } else {
11826 gen_helper_float_cvt_w_d(fp32, cpu_env, fp64);
11827 }
a7812ae4 11828 tcg_temp_free_i64(fp64);
7c979afd 11829 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 11830 tcg_temp_free_i32(fp32);
b6d96bed 11831 }
5a5012ec 11832 break;
bf4120ad 11833 case OPC_CVT_L_D:
5e755519 11834 check_cp1_64bitmode(ctx);
b6d96bed 11835 {
a7812ae4 11836 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
11837
11838 gen_load_fpr64(ctx, fp0, fs);
87552089
AM
11839 if (ctx->nan2008) {
11840 gen_helper_float_cvt_2008_l_d(fp0, cpu_env, fp0);
11841 } else {
11842 gen_helper_float_cvt_l_d(fp0, cpu_env, fp0);
11843 }
b6d96bed 11844 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11845 tcg_temp_free_i64(fp0);
b6d96bed 11846 }
5a5012ec 11847 break;
bf4120ad 11848 case OPC_CVT_S_W:
b6d96bed 11849 {
a7812ae4 11850 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 11851
7c979afd 11852 gen_load_fpr32(ctx, fp0, fs);
895c2d04 11853 gen_helper_float_cvts_w(fp0, cpu_env, fp0);
7c979afd 11854 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 11855 tcg_temp_free_i32(fp0);
b6d96bed 11856 }
6ea83fed 11857 break;
bf4120ad 11858 case OPC_CVT_D_W:
5e755519 11859 check_cp1_registers(ctx, fd);
b6d96bed 11860 {
a7812ae4
PB
11861 TCGv_i32 fp32 = tcg_temp_new_i32();
11862 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 11863
7c979afd 11864 gen_load_fpr32(ctx, fp32, fs);
895c2d04 11865 gen_helper_float_cvtd_w(fp64, cpu_env, fp32);
a7812ae4 11866 tcg_temp_free_i32(fp32);
b6d96bed 11867 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 11868 tcg_temp_free_i64(fp64);
b6d96bed 11869 }
5a5012ec 11870 break;
bf4120ad 11871 case OPC_CVT_S_L:
5e755519 11872 check_cp1_64bitmode(ctx);
b6d96bed 11873 {
a7812ae4
PB
11874 TCGv_i32 fp32 = tcg_temp_new_i32();
11875 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
11876
11877 gen_load_fpr64(ctx, fp64, fs);
895c2d04 11878 gen_helper_float_cvts_l(fp32, cpu_env, fp64);
a7812ae4 11879 tcg_temp_free_i64(fp64);
7c979afd 11880 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 11881 tcg_temp_free_i32(fp32);
b6d96bed 11882 }
5a5012ec 11883 break;
bf4120ad 11884 case OPC_CVT_D_L:
5e755519 11885 check_cp1_64bitmode(ctx);
b6d96bed 11886 {
a7812ae4 11887 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
11888
11889 gen_load_fpr64(ctx, fp0, fs);
895c2d04 11890 gen_helper_float_cvtd_l(fp0, cpu_env, fp0);
b6d96bed 11891 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11892 tcg_temp_free_i64(fp0);
b6d96bed 11893 }
5a5012ec 11894 break;
bf4120ad 11895 case OPC_CVT_PS_PW:
e29c9628 11896 check_ps(ctx);
b6d96bed 11897 {
a7812ae4 11898 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
11899
11900 gen_load_fpr64(ctx, fp0, fs);
895c2d04 11901 gen_helper_float_cvtps_pw(fp0, cpu_env, fp0);
b6d96bed 11902 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11903 tcg_temp_free_i64(fp0);
b6d96bed 11904 }
5a5012ec 11905 break;
bf4120ad 11906 case OPC_ADD_PS:
e29c9628 11907 check_ps(ctx);
b6d96bed 11908 {
a7812ae4
PB
11909 TCGv_i64 fp0 = tcg_temp_new_i64();
11910 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
11911
11912 gen_load_fpr64(ctx, fp0, fs);
11913 gen_load_fpr64(ctx, fp1, ft);
895c2d04 11914 gen_helper_float_add_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 11915 tcg_temp_free_i64(fp1);
b6d96bed 11916 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11917 tcg_temp_free_i64(fp0);
b6d96bed 11918 }
6ea83fed 11919 break;
bf4120ad 11920 case OPC_SUB_PS:
e29c9628 11921 check_ps(ctx);
b6d96bed 11922 {
a7812ae4
PB
11923 TCGv_i64 fp0 = tcg_temp_new_i64();
11924 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
11925
11926 gen_load_fpr64(ctx, fp0, fs);
11927 gen_load_fpr64(ctx, fp1, ft);
895c2d04 11928 gen_helper_float_sub_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 11929 tcg_temp_free_i64(fp1);
b6d96bed 11930 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11931 tcg_temp_free_i64(fp0);
b6d96bed 11932 }
6ea83fed 11933 break;
bf4120ad 11934 case OPC_MUL_PS:
e29c9628 11935 check_ps(ctx);
b6d96bed 11936 {
a7812ae4
PB
11937 TCGv_i64 fp0 = tcg_temp_new_i64();
11938 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
11939
11940 gen_load_fpr64(ctx, fp0, fs);
11941 gen_load_fpr64(ctx, fp1, ft);
895c2d04 11942 gen_helper_float_mul_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 11943 tcg_temp_free_i64(fp1);
b6d96bed 11944 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11945 tcg_temp_free_i64(fp0);
b6d96bed 11946 }
6ea83fed 11947 break;
bf4120ad 11948 case OPC_ABS_PS:
e29c9628 11949 check_ps(ctx);
b6d96bed 11950 {
a7812ae4 11951 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
11952
11953 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 11954 gen_helper_float_abs_ps(fp0, fp0);
b6d96bed 11955 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11956 tcg_temp_free_i64(fp0);
b6d96bed 11957 }
6ea83fed 11958 break;
bf4120ad 11959 case OPC_MOV_PS:
e29c9628 11960 check_ps(ctx);
b6d96bed 11961 {
a7812ae4 11962 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
11963
11964 gen_load_fpr64(ctx, fp0, fs);
11965 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11966 tcg_temp_free_i64(fp0);
b6d96bed 11967 }
6ea83fed 11968 break;
bf4120ad 11969 case OPC_NEG_PS:
e29c9628 11970 check_ps(ctx);
b6d96bed 11971 {
a7812ae4 11972 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
11973
11974 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 11975 gen_helper_float_chs_ps(fp0, fp0);
b6d96bed 11976 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11977 tcg_temp_free_i64(fp0);
b6d96bed 11978 }
6ea83fed 11979 break;
bf4120ad 11980 case OPC_MOVCF_PS:
e29c9628 11981 check_ps(ctx);
7f6613ce 11982 gen_movcf_ps(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
6ea83fed 11983 break;
bf4120ad 11984 case OPC_MOVZ_PS:
e29c9628 11985 check_ps(ctx);
a16336e4 11986 {
42a268c2 11987 TCGLabel *l1 = gen_new_label();
30a3848b 11988 TCGv_i64 fp0;
a16336e4 11989
c9297f4d
AJ
11990 if (ft != 0)
11991 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
11992 fp0 = tcg_temp_new_i64();
11993 gen_load_fpr64(ctx, fp0, fs);
11994 gen_store_fpr64(ctx, fp0, fd);
11995 tcg_temp_free_i64(fp0);
a16336e4
TS
11996 gen_set_label(l1);
11997 }
6ea83fed 11998 break;
bf4120ad 11999 case OPC_MOVN_PS:
e29c9628 12000 check_ps(ctx);
a16336e4 12001 {
42a268c2 12002 TCGLabel *l1 = gen_new_label();
30a3848b 12003 TCGv_i64 fp0;
c9297f4d
AJ
12004
12005 if (ft != 0) {
12006 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
12007 fp0 = tcg_temp_new_i64();
12008 gen_load_fpr64(ctx, fp0, fs);
12009 gen_store_fpr64(ctx, fp0, fd);
12010 tcg_temp_free_i64(fp0);
12011 gen_set_label(l1);
12012 }
a16336e4 12013 }
6ea83fed 12014 break;
bf4120ad 12015 case OPC_ADDR_PS:
e29c9628 12016 check_ps(ctx);
b6d96bed 12017 {
a7812ae4
PB
12018 TCGv_i64 fp0 = tcg_temp_new_i64();
12019 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
12020
12021 gen_load_fpr64(ctx, fp0, ft);
12022 gen_load_fpr64(ctx, fp1, fs);
895c2d04 12023 gen_helper_float_addr_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 12024 tcg_temp_free_i64(fp1);
b6d96bed 12025 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 12026 tcg_temp_free_i64(fp0);
b6d96bed 12027 }
fbcc6828 12028 break;
bf4120ad 12029 case OPC_MULR_PS:
e29c9628 12030 check_ps(ctx);
b6d96bed 12031 {
a7812ae4
PB
12032 TCGv_i64 fp0 = tcg_temp_new_i64();
12033 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
12034
12035 gen_load_fpr64(ctx, fp0, ft);
12036 gen_load_fpr64(ctx, fp1, fs);
895c2d04 12037 gen_helper_float_mulr_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 12038 tcg_temp_free_i64(fp1);
b6d96bed 12039 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 12040 tcg_temp_free_i64(fp0);
b6d96bed 12041 }
57fa1fb3 12042 break;
bf4120ad 12043 case OPC_RECIP2_PS:
e29c9628 12044 check_ps(ctx);
b6d96bed 12045 {
a7812ae4
PB
12046 TCGv_i64 fp0 = tcg_temp_new_i64();
12047 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
12048
12049 gen_load_fpr64(ctx, fp0, fs);
d22d7289 12050 gen_load_fpr64(ctx, fp1, ft);
895c2d04 12051 gen_helper_float_recip2_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 12052 tcg_temp_free_i64(fp1);
b6d96bed 12053 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 12054 tcg_temp_free_i64(fp0);
b6d96bed 12055 }
57fa1fb3 12056 break;
bf4120ad 12057 case OPC_RECIP1_PS:
e29c9628 12058 check_ps(ctx);
b6d96bed 12059 {
a7812ae4 12060 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
12061
12062 gen_load_fpr64(ctx, fp0, fs);
895c2d04 12063 gen_helper_float_recip1_ps(fp0, cpu_env, fp0);
b6d96bed 12064 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 12065 tcg_temp_free_i64(fp0);
b6d96bed 12066 }
57fa1fb3 12067 break;
bf4120ad 12068 case OPC_RSQRT1_PS:
e29c9628 12069 check_ps(ctx);
b6d96bed 12070 {
a7812ae4 12071 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
12072
12073 gen_load_fpr64(ctx, fp0, fs);
895c2d04 12074 gen_helper_float_rsqrt1_ps(fp0, cpu_env, fp0);
b6d96bed 12075 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 12076 tcg_temp_free_i64(fp0);
b6d96bed 12077 }
57fa1fb3 12078 break;
bf4120ad 12079 case OPC_RSQRT2_PS:
e29c9628 12080 check_ps(ctx);
b6d96bed 12081 {
a7812ae4
PB
12082 TCGv_i64 fp0 = tcg_temp_new_i64();
12083 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
12084
12085 gen_load_fpr64(ctx, fp0, fs);
12086 gen_load_fpr64(ctx, fp1, ft);
895c2d04 12087 gen_helper_float_rsqrt2_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 12088 tcg_temp_free_i64(fp1);
b6d96bed 12089 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 12090 tcg_temp_free_i64(fp0);
b6d96bed 12091 }
57fa1fb3 12092 break;
bf4120ad 12093 case OPC_CVT_S_PU:
5e755519 12094 check_cp1_64bitmode(ctx);
b6d96bed 12095 {
a7812ae4 12096 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 12097
7f6613ce 12098 gen_load_fpr32h(ctx, fp0, fs);
895c2d04 12099 gen_helper_float_cvts_pu(fp0, cpu_env, fp0);
7c979afd 12100 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 12101 tcg_temp_free_i32(fp0);
b6d96bed 12102 }
dd016883 12103 break;
bf4120ad 12104 case OPC_CVT_PW_PS:
e29c9628 12105 check_ps(ctx);
b6d96bed 12106 {
a7812ae4 12107 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
12108
12109 gen_load_fpr64(ctx, fp0, fs);
895c2d04 12110 gen_helper_float_cvtpw_ps(fp0, cpu_env, fp0);
b6d96bed 12111 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 12112 tcg_temp_free_i64(fp0);
b6d96bed 12113 }
6ea83fed 12114 break;
bf4120ad 12115 case OPC_CVT_S_PL:
5e755519 12116 check_cp1_64bitmode(ctx);
b6d96bed 12117 {
a7812ae4 12118 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 12119
7c979afd 12120 gen_load_fpr32(ctx, fp0, fs);
895c2d04 12121 gen_helper_float_cvts_pl(fp0, cpu_env, fp0);
7c979afd 12122 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 12123 tcg_temp_free_i32(fp0);
b6d96bed 12124 }
6ea83fed 12125 break;
bf4120ad 12126 case OPC_PLL_PS:
e29c9628 12127 check_ps(ctx);
b6d96bed 12128 {
a7812ae4
PB
12129 TCGv_i32 fp0 = tcg_temp_new_i32();
12130 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 12131
7c979afd
LA
12132 gen_load_fpr32(ctx, fp0, fs);
12133 gen_load_fpr32(ctx, fp1, ft);
7f6613ce 12134 gen_store_fpr32h(ctx, fp0, fd);
7c979afd 12135 gen_store_fpr32(ctx, fp1, fd);
a7812ae4
PB
12136 tcg_temp_free_i32(fp0);
12137 tcg_temp_free_i32(fp1);
b6d96bed 12138 }
6ea83fed 12139 break;
bf4120ad 12140 case OPC_PLU_PS:
e29c9628 12141 check_ps(ctx);
b6d96bed 12142 {
a7812ae4
PB
12143 TCGv_i32 fp0 = tcg_temp_new_i32();
12144 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 12145
7c979afd 12146 gen_load_fpr32(ctx, fp0, fs);
7f6613ce 12147 gen_load_fpr32h(ctx, fp1, ft);
7c979afd 12148 gen_store_fpr32(ctx, fp1, fd);
7f6613ce 12149 gen_store_fpr32h(ctx, fp0, fd);
a7812ae4
PB
12150 tcg_temp_free_i32(fp0);
12151 tcg_temp_free_i32(fp1);
b6d96bed 12152 }
5a5012ec 12153 break;
bf4120ad 12154 case OPC_PUL_PS:
e29c9628 12155 check_ps(ctx);
b6d96bed 12156 {
a7812ae4
PB
12157 TCGv_i32 fp0 = tcg_temp_new_i32();
12158 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 12159
7f6613ce 12160 gen_load_fpr32h(ctx, fp0, fs);
7c979afd
LA
12161 gen_load_fpr32(ctx, fp1, ft);
12162 gen_store_fpr32(ctx, fp1, fd);
7f6613ce 12163 gen_store_fpr32h(ctx, fp0, fd);
a7812ae4
PB
12164 tcg_temp_free_i32(fp0);
12165 tcg_temp_free_i32(fp1);
b6d96bed 12166 }
5a5012ec 12167 break;
bf4120ad 12168 case OPC_PUU_PS:
e29c9628 12169 check_ps(ctx);
b6d96bed 12170 {
a7812ae4
PB
12171 TCGv_i32 fp0 = tcg_temp_new_i32();
12172 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 12173
7f6613ce
PJ
12174 gen_load_fpr32h(ctx, fp0, fs);
12175 gen_load_fpr32h(ctx, fp1, ft);
7c979afd 12176 gen_store_fpr32(ctx, fp1, fd);
7f6613ce 12177 gen_store_fpr32h(ctx, fp0, fd);
a7812ae4
PB
12178 tcg_temp_free_i32(fp0);
12179 tcg_temp_free_i32(fp1);
b6d96bed 12180 }
5a5012ec 12181 break;
bf4120ad
NF
12182 case OPC_CMP_F_PS:
12183 case OPC_CMP_UN_PS:
12184 case OPC_CMP_EQ_PS:
12185 case OPC_CMP_UEQ_PS:
12186 case OPC_CMP_OLT_PS:
12187 case OPC_CMP_ULT_PS:
12188 case OPC_CMP_OLE_PS:
12189 case OPC_CMP_ULE_PS:
12190 case OPC_CMP_SF_PS:
12191 case OPC_CMP_NGLE_PS:
12192 case OPC_CMP_SEQ_PS:
12193 case OPC_CMP_NGL_PS:
12194 case OPC_CMP_LT_PS:
12195 case OPC_CMP_NGE_PS:
12196 case OPC_CMP_LE_PS:
12197 case OPC_CMP_NGT_PS:
8153667c
NF
12198 if (ctx->opcode & (1 << 6)) {
12199 gen_cmpabs_ps(ctx, func-48, ft, fs, cc);
8153667c
NF
12200 } else {
12201 gen_cmp_ps(ctx, func-48, ft, fs, cc);
5a1e8ffb 12202 }
6ea83fed 12203 break;
5a5012ec 12204 default:
9d68ac14 12205 MIPS_INVAL("farith");
9c708c7f 12206 generate_exception_end(ctx, EXCP_RI);
6ea83fed
FB
12207 return;
12208 }
6ea83fed 12209}
6af0bf9c 12210
5a5012ec 12211/* Coprocessor 3 (FPU) */
5e755519
TS
12212static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
12213 int fd, int fs, int base, int index)
7a387fff 12214{
4e2474d6 12215 TCGv t0 = tcg_temp_new();
7a387fff 12216
93b12ccc 12217 if (base == 0) {
6c5c1e20 12218 gen_load_gpr(t0, index);
93b12ccc 12219 } else if (index == 0) {
6c5c1e20 12220 gen_load_gpr(t0, base);
93b12ccc 12221 } else {
05168674 12222 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]);
93b12ccc 12223 }
5a5012ec 12224 /* Don't do NOP if destination is zero: we must perform the actual
ead9360e 12225 memory access. */
5a5012ec
TS
12226 switch (opc) {
12227 case OPC_LWXC1:
8c0ab41f 12228 check_cop1x(ctx);
b6d96bed 12229 {
a7812ae4 12230 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 12231
5f68f5ae 12232 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
585c88d5 12233 tcg_gen_trunc_tl_i32(fp0, t0);
7c979afd 12234 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 12235 tcg_temp_free_i32(fp0);
b6d96bed 12236 }
5a5012ec
TS
12237 break;
12238 case OPC_LDXC1:
8c0ab41f
AJ
12239 check_cop1x(ctx);
12240 check_cp1_registers(ctx, fd);
b6d96bed 12241 {
a7812ae4 12242 TCGv_i64 fp0 = tcg_temp_new_i64();
5f68f5ae 12243 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
b6d96bed 12244 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 12245 tcg_temp_free_i64(fp0);
b6d96bed 12246 }
5a5012ec
TS
12247 break;
12248 case OPC_LUXC1:
8c0ab41f 12249 check_cp1_64bitmode(ctx);
6c5c1e20 12250 tcg_gen_andi_tl(t0, t0, ~0x7);
b6d96bed 12251 {
a7812ae4 12252 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 12253
5f68f5ae 12254 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
b6d96bed 12255 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 12256 tcg_temp_free_i64(fp0);
b6d96bed 12257 }
5a5012ec
TS
12258 break;
12259 case OPC_SWXC1:
8c0ab41f 12260 check_cop1x(ctx);
b6d96bed 12261 {
a7812ae4 12262 TCGv_i32 fp0 = tcg_temp_new_i32();
7c979afd 12263 gen_load_fpr32(ctx, fp0, fs);
5f68f5ae 12264 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL);
a7812ae4 12265 tcg_temp_free_i32(fp0);
b6d96bed 12266 }
5a5012ec
TS
12267 break;
12268 case OPC_SDXC1:
8c0ab41f
AJ
12269 check_cop1x(ctx);
12270 check_cp1_registers(ctx, fs);
b6d96bed 12271 {
a7812ae4 12272 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 12273 gen_load_fpr64(ctx, fp0, fs);
5f68f5ae 12274 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
a7812ae4 12275 tcg_temp_free_i64(fp0);
b6d96bed 12276 }
5a5012ec
TS
12277 break;
12278 case OPC_SUXC1:
8c0ab41f 12279 check_cp1_64bitmode(ctx);
6c5c1e20 12280 tcg_gen_andi_tl(t0, t0, ~0x7);
b6d96bed 12281 {
a7812ae4 12282 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 12283 gen_load_fpr64(ctx, fp0, fs);
5f68f5ae 12284 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
a7812ae4 12285 tcg_temp_free_i64(fp0);
b6d96bed 12286 }
5a5012ec 12287 break;
5a5012ec 12288 }
6c5c1e20 12289 tcg_temp_free(t0);
5a5012ec
TS
12290}
12291
5e755519
TS
12292static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
12293 int fd, int fr, int fs, int ft)
5a5012ec 12294{
5a5012ec
TS
12295 switch (opc) {
12296 case OPC_ALNV_PS:
e29c9628 12297 check_ps(ctx);
a16336e4 12298 {
a7812ae4 12299 TCGv t0 = tcg_temp_local_new();
c905fdac
AJ
12300 TCGv_i32 fp = tcg_temp_new_i32();
12301 TCGv_i32 fph = tcg_temp_new_i32();
42a268c2
RH
12302 TCGLabel *l1 = gen_new_label();
12303 TCGLabel *l2 = gen_new_label();
a16336e4 12304
6c5c1e20
TS
12305 gen_load_gpr(t0, fr);
12306 tcg_gen_andi_tl(t0, t0, 0x7);
6c5c1e20
TS
12307
12308 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
7c979afd 12309 gen_load_fpr32(ctx, fp, fs);
7f6613ce 12310 gen_load_fpr32h(ctx, fph, fs);
7c979afd 12311 gen_store_fpr32(ctx, fp, fd);
7f6613ce 12312 gen_store_fpr32h(ctx, fph, fd);
a16336e4
TS
12313 tcg_gen_br(l2);
12314 gen_set_label(l1);
6c5c1e20
TS
12315 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
12316 tcg_temp_free(t0);
a16336e4 12317#ifdef TARGET_WORDS_BIGENDIAN
7c979afd 12318 gen_load_fpr32(ctx, fp, fs);
7f6613ce
PJ
12319 gen_load_fpr32h(ctx, fph, ft);
12320 gen_store_fpr32h(ctx, fp, fd);
7c979afd 12321 gen_store_fpr32(ctx, fph, fd);
a16336e4 12322#else
7f6613ce 12323 gen_load_fpr32h(ctx, fph, fs);
7c979afd
LA
12324 gen_load_fpr32(ctx, fp, ft);
12325 gen_store_fpr32(ctx, fph, fd);
7f6613ce 12326 gen_store_fpr32h(ctx, fp, fd);
a16336e4
TS
12327#endif
12328 gen_set_label(l2);
c905fdac
AJ
12329 tcg_temp_free_i32(fp);
12330 tcg_temp_free_i32(fph);
a16336e4 12331 }
5a5012ec
TS
12332 break;
12333 case OPC_MADD_S:
b8aa4598 12334 check_cop1x(ctx);
b6d96bed 12335 {
a7812ae4
PB
12336 TCGv_i32 fp0 = tcg_temp_new_i32();
12337 TCGv_i32 fp1 = tcg_temp_new_i32();
12338 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed 12339
7c979afd
LA
12340 gen_load_fpr32(ctx, fp0, fs);
12341 gen_load_fpr32(ctx, fp1, ft);
12342 gen_load_fpr32(ctx, fp2, fr);
b3d6cd44 12343 gen_helper_float_madd_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
12344 tcg_temp_free_i32(fp0);
12345 tcg_temp_free_i32(fp1);
7c979afd 12346 gen_store_fpr32(ctx, fp2, fd);
a7812ae4 12347 tcg_temp_free_i32(fp2);
b6d96bed 12348 }
5a5012ec
TS
12349 break;
12350 case OPC_MADD_D:
b8aa4598
TS
12351 check_cop1x(ctx);
12352 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 12353 {
a7812ae4
PB
12354 TCGv_i64 fp0 = tcg_temp_new_i64();
12355 TCGv_i64 fp1 = tcg_temp_new_i64();
12356 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
12357
12358 gen_load_fpr64(ctx, fp0, fs);
12359 gen_load_fpr64(ctx, fp1, ft);
12360 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 12361 gen_helper_float_madd_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
12362 tcg_temp_free_i64(fp0);
12363 tcg_temp_free_i64(fp1);
b6d96bed 12364 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 12365 tcg_temp_free_i64(fp2);
b6d96bed 12366 }
5a5012ec
TS
12367 break;
12368 case OPC_MADD_PS:
e29c9628 12369 check_ps(ctx);
b6d96bed 12370 {
a7812ae4
PB
12371 TCGv_i64 fp0 = tcg_temp_new_i64();
12372 TCGv_i64 fp1 = tcg_temp_new_i64();
12373 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
12374
12375 gen_load_fpr64(ctx, fp0, fs);
12376 gen_load_fpr64(ctx, fp1, ft);
12377 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 12378 gen_helper_float_madd_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
12379 tcg_temp_free_i64(fp0);
12380 tcg_temp_free_i64(fp1);
b6d96bed 12381 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 12382 tcg_temp_free_i64(fp2);
b6d96bed 12383 }
5a5012ec
TS
12384 break;
12385 case OPC_MSUB_S:
b8aa4598 12386 check_cop1x(ctx);
b6d96bed 12387 {
a7812ae4
PB
12388 TCGv_i32 fp0 = tcg_temp_new_i32();
12389 TCGv_i32 fp1 = tcg_temp_new_i32();
12390 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed 12391
7c979afd
LA
12392 gen_load_fpr32(ctx, fp0, fs);
12393 gen_load_fpr32(ctx, fp1, ft);
12394 gen_load_fpr32(ctx, fp2, fr);
b3d6cd44 12395 gen_helper_float_msub_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
12396 tcg_temp_free_i32(fp0);
12397 tcg_temp_free_i32(fp1);
7c979afd 12398 gen_store_fpr32(ctx, fp2, fd);
a7812ae4 12399 tcg_temp_free_i32(fp2);
b6d96bed 12400 }
5a5012ec
TS
12401 break;
12402 case OPC_MSUB_D:
b8aa4598
TS
12403 check_cop1x(ctx);
12404 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 12405 {
a7812ae4
PB
12406 TCGv_i64 fp0 = tcg_temp_new_i64();
12407 TCGv_i64 fp1 = tcg_temp_new_i64();
12408 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
12409
12410 gen_load_fpr64(ctx, fp0, fs);
12411 gen_load_fpr64(ctx, fp1, ft);
12412 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 12413 gen_helper_float_msub_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
12414 tcg_temp_free_i64(fp0);
12415 tcg_temp_free_i64(fp1);
b6d96bed 12416 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 12417 tcg_temp_free_i64(fp2);
b6d96bed 12418 }
5a5012ec
TS
12419 break;
12420 case OPC_MSUB_PS:
e29c9628 12421 check_ps(ctx);
b6d96bed 12422 {
a7812ae4
PB
12423 TCGv_i64 fp0 = tcg_temp_new_i64();
12424 TCGv_i64 fp1 = tcg_temp_new_i64();
12425 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
12426
12427 gen_load_fpr64(ctx, fp0, fs);
12428 gen_load_fpr64(ctx, fp1, ft);
12429 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 12430 gen_helper_float_msub_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
12431 tcg_temp_free_i64(fp0);
12432 tcg_temp_free_i64(fp1);
b6d96bed 12433 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 12434 tcg_temp_free_i64(fp2);
b6d96bed 12435 }
5a5012ec
TS
12436 break;
12437 case OPC_NMADD_S:
b8aa4598 12438 check_cop1x(ctx);
b6d96bed 12439 {
a7812ae4
PB
12440 TCGv_i32 fp0 = tcg_temp_new_i32();
12441 TCGv_i32 fp1 = tcg_temp_new_i32();
12442 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed 12443
7c979afd
LA
12444 gen_load_fpr32(ctx, fp0, fs);
12445 gen_load_fpr32(ctx, fp1, ft);
12446 gen_load_fpr32(ctx, fp2, fr);
b3d6cd44 12447 gen_helper_float_nmadd_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
12448 tcg_temp_free_i32(fp0);
12449 tcg_temp_free_i32(fp1);
7c979afd 12450 gen_store_fpr32(ctx, fp2, fd);
a7812ae4 12451 tcg_temp_free_i32(fp2);
b6d96bed 12452 }
5a5012ec
TS
12453 break;
12454 case OPC_NMADD_D:
b8aa4598
TS
12455 check_cop1x(ctx);
12456 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 12457 {
a7812ae4
PB
12458 TCGv_i64 fp0 = tcg_temp_new_i64();
12459 TCGv_i64 fp1 = tcg_temp_new_i64();
12460 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
12461
12462 gen_load_fpr64(ctx, fp0, fs);
12463 gen_load_fpr64(ctx, fp1, ft);
12464 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 12465 gen_helper_float_nmadd_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
12466 tcg_temp_free_i64(fp0);
12467 tcg_temp_free_i64(fp1);
b6d96bed 12468 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 12469 tcg_temp_free_i64(fp2);
b6d96bed 12470 }
5a5012ec
TS
12471 break;
12472 case OPC_NMADD_PS:
e29c9628 12473 check_ps(ctx);
b6d96bed 12474 {
a7812ae4
PB
12475 TCGv_i64 fp0 = tcg_temp_new_i64();
12476 TCGv_i64 fp1 = tcg_temp_new_i64();
12477 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
12478
12479 gen_load_fpr64(ctx, fp0, fs);
12480 gen_load_fpr64(ctx, fp1, ft);
12481 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 12482 gen_helper_float_nmadd_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
12483 tcg_temp_free_i64(fp0);
12484 tcg_temp_free_i64(fp1);
b6d96bed 12485 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 12486 tcg_temp_free_i64(fp2);
b6d96bed 12487 }
5a5012ec
TS
12488 break;
12489 case OPC_NMSUB_S:
b8aa4598 12490 check_cop1x(ctx);
b6d96bed 12491 {
a7812ae4
PB
12492 TCGv_i32 fp0 = tcg_temp_new_i32();
12493 TCGv_i32 fp1 = tcg_temp_new_i32();
12494 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed 12495
7c979afd
LA
12496 gen_load_fpr32(ctx, fp0, fs);
12497 gen_load_fpr32(ctx, fp1, ft);
12498 gen_load_fpr32(ctx, fp2, fr);
b3d6cd44 12499 gen_helper_float_nmsub_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
12500 tcg_temp_free_i32(fp0);
12501 tcg_temp_free_i32(fp1);
7c979afd 12502 gen_store_fpr32(ctx, fp2, fd);
a7812ae4 12503 tcg_temp_free_i32(fp2);
b6d96bed 12504 }
5a5012ec
TS
12505 break;
12506 case OPC_NMSUB_D:
b8aa4598
TS
12507 check_cop1x(ctx);
12508 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 12509 {
a7812ae4
PB
12510 TCGv_i64 fp0 = tcg_temp_new_i64();
12511 TCGv_i64 fp1 = tcg_temp_new_i64();
12512 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
12513
12514 gen_load_fpr64(ctx, fp0, fs);
12515 gen_load_fpr64(ctx, fp1, ft);
12516 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 12517 gen_helper_float_nmsub_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
12518 tcg_temp_free_i64(fp0);
12519 tcg_temp_free_i64(fp1);
b6d96bed 12520 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 12521 tcg_temp_free_i64(fp2);
b6d96bed 12522 }
5a5012ec
TS
12523 break;
12524 case OPC_NMSUB_PS:
e29c9628 12525 check_ps(ctx);
b6d96bed 12526 {
a7812ae4
PB
12527 TCGv_i64 fp0 = tcg_temp_new_i64();
12528 TCGv_i64 fp1 = tcg_temp_new_i64();
12529 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
12530
12531 gen_load_fpr64(ctx, fp0, fs);
12532 gen_load_fpr64(ctx, fp1, ft);
12533 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 12534 gen_helper_float_nmsub_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
12535 tcg_temp_free_i64(fp0);
12536 tcg_temp_free_i64(fp1);
b6d96bed 12537 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 12538 tcg_temp_free_i64(fp2);
b6d96bed 12539 }
5a5012ec 12540 break;
923617a3 12541 default:
9d68ac14 12542 MIPS_INVAL("flt3_arith");
9c708c7f 12543 generate_exception_end(ctx, EXCP_RI);
5a5012ec
TS
12544 return;
12545 }
7a387fff
TS
12546}
12547
b00c7218 12548static void gen_rdhwr(DisasContext *ctx, int rt, int rd, int sel)
26ebe468
NF
12549{
12550 TCGv t0;
12551
b3167288
RH
12552#if !defined(CONFIG_USER_ONLY)
12553 /* The Linux kernel will emulate rdhwr if it's not supported natively.
12554 Therefore only check the ISA in system mode. */
d75c135e 12555 check_insn(ctx, ISA_MIPS32R2);
b3167288 12556#endif
26ebe468
NF
12557 t0 = tcg_temp_new();
12558
12559 switch (rd) {
12560 case 0:
895c2d04 12561 gen_helper_rdhwr_cpunum(t0, cpu_env);
26ebe468
NF
12562 gen_store_gpr(t0, rt);
12563 break;
12564 case 1:
895c2d04 12565 gen_helper_rdhwr_synci_step(t0, cpu_env);
26ebe468
NF
12566 gen_store_gpr(t0, rt);
12567 break;
12568 case 2:
eeb3bba8 12569 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
d673a68d
JH
12570 gen_io_start();
12571 }
895c2d04 12572 gen_helper_rdhwr_cc(t0, cpu_env);
eeb3bba8 12573 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
d673a68d
JH
12574 gen_io_end();
12575 }
26ebe468 12576 gen_store_gpr(t0, rt);
d673a68d 12577 /* Break the TB to be able to take timer interrupts immediately
b28425ba 12578 after reading count. DISAS_STOP isn't sufficient, we need to ensure
d673a68d 12579 we break completely out of translated code. */
eeb3bba8
EC
12580 gen_save_pc(ctx->base.pc_next + 4);
12581 ctx->base.is_jmp = DISAS_EXIT;
26ebe468
NF
12582 break;
12583 case 3:
895c2d04 12584 gen_helper_rdhwr_ccres(t0, cpu_env);
26ebe468
NF
12585 gen_store_gpr(t0, rt);
12586 break;
b00c7218
YK
12587 case 4:
12588 check_insn(ctx, ISA_MIPS32R6);
12589 if (sel != 0) {
12590 /* Performance counter registers are not implemented other than
12591 * control register 0.
12592 */
12593 generate_exception(ctx, EXCP_RI);
12594 }
12595 gen_helper_rdhwr_performance(t0, cpu_env);
12596 gen_store_gpr(t0, rt);
12597 break;
12598 case 5:
12599 check_insn(ctx, ISA_MIPS32R6);
12600 gen_helper_rdhwr_xnp(t0, cpu_env);
12601 gen_store_gpr(t0, rt);
12602 break;
26ebe468
NF
12603 case 29:
12604#if defined(CONFIG_USER_ONLY)
d279279e
PJ
12605 tcg_gen_ld_tl(t0, cpu_env,
12606 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
26ebe468
NF
12607 gen_store_gpr(t0, rt);
12608 break;
12609#else
d279279e
PJ
12610 if ((ctx->hflags & MIPS_HFLAG_CP0) ||
12611 (ctx->hflags & MIPS_HFLAG_HWRENA_ULR)) {
12612 tcg_gen_ld_tl(t0, cpu_env,
12613 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
12614 gen_store_gpr(t0, rt);
12615 } else {
9c708c7f 12616 generate_exception_end(ctx, EXCP_RI);
d279279e
PJ
12617 }
12618 break;
26ebe468
NF
12619#endif
12620 default: /* Invalid */
12621 MIPS_INVAL("rdhwr");
9c708c7f 12622 generate_exception_end(ctx, EXCP_RI);
26ebe468
NF
12623 break;
12624 }
12625 tcg_temp_free(t0);
12626}
12627
a5f53390
LA
12628static inline void clear_branch_hflags(DisasContext *ctx)
12629{
12630 ctx->hflags &= ~MIPS_HFLAG_BMASK;
eeb3bba8 12631 if (ctx->base.is_jmp == DISAS_NEXT) {
a5f53390
LA
12632 save_cpu_state(ctx, 0);
12633 } else {
12634 /* it is not safe to save ctx->hflags as hflags may be changed
12635 in execution time by the instruction in delay / forbidden slot. */
12636 tcg_gen_andi_i32(hflags, hflags, ~MIPS_HFLAG_BMASK);
12637 }
12638}
12639
31837be3 12640static void gen_branch(DisasContext *ctx, int insn_bytes)
c9602061
NF
12641{
12642 if (ctx->hflags & MIPS_HFLAG_BMASK) {
364d4831 12643 int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
c9602061 12644 /* Branches completion */
a5f53390 12645 clear_branch_hflags(ctx);
eeb3bba8 12646 ctx->base.is_jmp = DISAS_NORETURN;
c9602061 12647 /* FIXME: Need to clear can_do_io. */
364d4831 12648 switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
339cd2a8 12649 case MIPS_HFLAG_FBNSLOT:
eeb3bba8 12650 gen_goto_tb(ctx, 0, ctx->base.pc_next + insn_bytes);
339cd2a8 12651 break;
c9602061
NF
12652 case MIPS_HFLAG_B:
12653 /* unconditional branch */
364d4831
NF
12654 if (proc_hflags & MIPS_HFLAG_BX) {
12655 tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
12656 }
c9602061
NF
12657 gen_goto_tb(ctx, 0, ctx->btarget);
12658 break;
12659 case MIPS_HFLAG_BL:
12660 /* blikely taken case */
c9602061
NF
12661 gen_goto_tb(ctx, 0, ctx->btarget);
12662 break;
12663 case MIPS_HFLAG_BC:
12664 /* Conditional branch */
c9602061 12665 {
42a268c2 12666 TCGLabel *l1 = gen_new_label();
c9602061
NF
12667
12668 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
eeb3bba8 12669 gen_goto_tb(ctx, 1, ctx->base.pc_next + insn_bytes);
c9602061
NF
12670 gen_set_label(l1);
12671 gen_goto_tb(ctx, 0, ctx->btarget);
12672 }
12673 break;
12674 case MIPS_HFLAG_BR:
12675 /* unconditional branch to register */
d75c135e 12676 if (ctx->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
364d4831
NF
12677 TCGv t0 = tcg_temp_new();
12678 TCGv_i32 t1 = tcg_temp_new_i32();
12679
12680 tcg_gen_andi_tl(t0, btarget, 0x1);
12681 tcg_gen_trunc_tl_i32(t1, t0);
12682 tcg_temp_free(t0);
12683 tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
12684 tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
12685 tcg_gen_or_i32(hflags, hflags, t1);
12686 tcg_temp_free_i32(t1);
12687
12688 tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
12689 } else {
12690 tcg_gen_mov_tl(cpu_PC, btarget);
12691 }
eeb3bba8 12692 if (ctx->base.singlestep_enabled) {
c9602061 12693 save_cpu_state(ctx, 0);
9c708c7f 12694 gen_helper_raise_exception_debug(cpu_env);
c9602061 12695 }
7f11636d 12696 tcg_gen_lookup_and_goto_ptr();
c9602061
NF
12697 break;
12698 default:
a5f53390
LA
12699 fprintf(stderr, "unknown branch 0x%x\n", proc_hflags);
12700 abort();
c9602061
NF
12701 }
12702 }
12703}
12704
6893f074
YK
12705/* Compact Branches */
12706static void gen_compute_compact_branch(DisasContext *ctx, uint32_t opc,
12707 int rs, int rt, int32_t offset)
12708{
12709 int bcond_compute = 0;
12710 TCGv t0 = tcg_temp_new();
12711 TCGv t1 = tcg_temp_new();
65935f07 12712 int m16_lowbit = (ctx->hflags & MIPS_HFLAG_M16) != 0;
6893f074
YK
12713
12714 if (ctx->hflags & MIPS_HFLAG_BMASK) {
12715#ifdef MIPS_DEBUG_DISAS
12716 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
eeb3bba8 12717 "\n", ctx->base.pc_next);
6893f074 12718#endif
9c708c7f 12719 generate_exception_end(ctx, EXCP_RI);
6893f074
YK
12720 goto out;
12721 }
12722
12723 /* Load needed operands and calculate btarget */
12724 switch (opc) {
12725 /* compact branch */
12726 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
12727 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
12728 gen_load_gpr(t0, rs);
12729 gen_load_gpr(t1, rt);
12730 bcond_compute = 1;
eeb3bba8 12731 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
6893f074
YK
12732 if (rs <= rt && rs == 0) {
12733 /* OPC_BEQZALC, OPC_BNEZALC */
eeb3bba8 12734 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
6893f074
YK
12735 }
12736 break;
12737 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
12738 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
12739 gen_load_gpr(t0, rs);
12740 gen_load_gpr(t1, rt);
12741 bcond_compute = 1;
eeb3bba8 12742 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
6893f074
YK
12743 break;
12744 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
12745 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
12746 if (rs == 0 || rs == rt) {
12747 /* OPC_BLEZALC, OPC_BGEZALC */
12748 /* OPC_BGTZALC, OPC_BLTZALC */
eeb3bba8 12749 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
6893f074
YK
12750 }
12751 gen_load_gpr(t0, rs);
12752 gen_load_gpr(t1, rt);
12753 bcond_compute = 1;
eeb3bba8 12754 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
6893f074
YK
12755 break;
12756 case OPC_BC:
12757 case OPC_BALC:
eeb3bba8 12758 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
6893f074
YK
12759 break;
12760 case OPC_BEQZC:
12761 case OPC_BNEZC:
12762 if (rs != 0) {
12763 /* OPC_BEQZC, OPC_BNEZC */
12764 gen_load_gpr(t0, rs);
12765 bcond_compute = 1;
eeb3bba8 12766 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
6893f074
YK
12767 } else {
12768 /* OPC_JIC, OPC_JIALC */
12769 TCGv tbase = tcg_temp_new();
12770 TCGv toffset = tcg_temp_new();
12771
12772 gen_load_gpr(tbase, rt);
12773 tcg_gen_movi_tl(toffset, offset);
12774 gen_op_addr_add(ctx, btarget, tbase, toffset);
12775 tcg_temp_free(tbase);
12776 tcg_temp_free(toffset);
12777 }
12778 break;
12779 default:
12780 MIPS_INVAL("Compact branch/jump");
9c708c7f 12781 generate_exception_end(ctx, EXCP_RI);
6893f074
YK
12782 goto out;
12783 }
12784
12785 if (bcond_compute == 0) {
12786 /* Uncoditional compact branch */
12787 switch (opc) {
12788 case OPC_JIALC:
eeb3bba8 12789 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
6893f074
YK
12790 /* Fallthrough */
12791 case OPC_JIC:
12792 ctx->hflags |= MIPS_HFLAG_BR;
12793 break;
12794 case OPC_BALC:
eeb3bba8 12795 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
6893f074
YK
12796 /* Fallthrough */
12797 case OPC_BC:
12798 ctx->hflags |= MIPS_HFLAG_B;
12799 break;
12800 default:
12801 MIPS_INVAL("Compact branch/jump");
9c708c7f 12802 generate_exception_end(ctx, EXCP_RI);
6893f074
YK
12803 goto out;
12804 }
12805
12806 /* Generating branch here as compact branches don't have delay slot */
12807 gen_branch(ctx, 4);
12808 } else {
12809 /* Conditional compact branch */
12810 TCGLabel *fs = gen_new_label();
12811 save_cpu_state(ctx, 0);
12812
12813 switch (opc) {
12814 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
12815 if (rs == 0 && rt != 0) {
12816 /* OPC_BLEZALC */
12817 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
12818 } else if (rs != 0 && rt != 0 && rs == rt) {
12819 /* OPC_BGEZALC */
12820 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
12821 } else {
12822 /* OPC_BGEUC */
12823 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU), t0, t1, fs);
12824 }
12825 break;
12826 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
12827 if (rs == 0 && rt != 0) {
12828 /* OPC_BGTZALC */
12829 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
12830 } else if (rs != 0 && rt != 0 && rs == rt) {
12831 /* OPC_BLTZALC */
12832 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
12833 } else {
12834 /* OPC_BLTUC */
12835 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU), t0, t1, fs);
12836 }
12837 break;
12838 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
12839 if (rs == 0 && rt != 0) {
12840 /* OPC_BLEZC */
12841 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
12842 } else if (rs != 0 && rt != 0 && rs == rt) {
12843 /* OPC_BGEZC */
12844 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
12845 } else {
12846 /* OPC_BGEC */
12847 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE), t0, t1, fs);
12848 }
12849 break;
12850 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
12851 if (rs == 0 && rt != 0) {
12852 /* OPC_BGTZC */
12853 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
12854 } else if (rs != 0 && rt != 0 && rs == rt) {
12855 /* OPC_BLTZC */
12856 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
12857 } else {
12858 /* OPC_BLTC */
12859 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT), t0, t1, fs);
12860 }
12861 break;
12862 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
12863 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
12864 if (rs >= rt) {
12865 /* OPC_BOVC, OPC_BNVC */
12866 TCGv t2 = tcg_temp_new();
12867 TCGv t3 = tcg_temp_new();
12868 TCGv t4 = tcg_temp_new();
12869 TCGv input_overflow = tcg_temp_new();
12870
12871 gen_load_gpr(t0, rs);
12872 gen_load_gpr(t1, rt);
12873 tcg_gen_ext32s_tl(t2, t0);
12874 tcg_gen_setcond_tl(TCG_COND_NE, input_overflow, t2, t0);
12875 tcg_gen_ext32s_tl(t3, t1);
12876 tcg_gen_setcond_tl(TCG_COND_NE, t4, t3, t1);
12877 tcg_gen_or_tl(input_overflow, input_overflow, t4);
12878
12879 tcg_gen_add_tl(t4, t2, t3);
12880 tcg_gen_ext32s_tl(t4, t4);
12881 tcg_gen_xor_tl(t2, t2, t3);
12882 tcg_gen_xor_tl(t3, t4, t3);
12883 tcg_gen_andc_tl(t2, t3, t2);
12884 tcg_gen_setcondi_tl(TCG_COND_LT, t4, t2, 0);
12885 tcg_gen_or_tl(t4, t4, input_overflow);
12886 if (opc == OPC_BOVC) {
12887 /* OPC_BOVC */
12888 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t4, 0, fs);
12889 } else {
12890 /* OPC_BNVC */
12891 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t4, 0, fs);
12892 }
12893 tcg_temp_free(input_overflow);
12894 tcg_temp_free(t4);
12895 tcg_temp_free(t3);
12896 tcg_temp_free(t2);
12897 } else if (rs < rt && rs == 0) {
12898 /* OPC_BEQZALC, OPC_BNEZALC */
12899 if (opc == OPC_BEQZALC) {
12900 /* OPC_BEQZALC */
12901 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t1, 0, fs);
12902 } else {
12903 /* OPC_BNEZALC */
12904 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t1, 0, fs);
12905 }
12906 } else {
12907 /* OPC_BEQC, OPC_BNEC */
12908 if (opc == OPC_BEQC) {
12909 /* OPC_BEQC */
12910 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_EQ), t0, t1, fs);
12911 } else {
12912 /* OPC_BNEC */
12913 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_NE), t0, t1, fs);
12914 }
12915 }
12916 break;
12917 case OPC_BEQZC:
12918 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t0, 0, fs);
12919 break;
12920 case OPC_BNEZC:
12921 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t0, 0, fs);
12922 break;
12923 default:
12924 MIPS_INVAL("Compact conditional branch/jump");
9c708c7f 12925 generate_exception_end(ctx, EXCP_RI);
6893f074
YK
12926 goto out;
12927 }
12928
12929 /* Generating branch here as compact branches don't have delay slot */
12930 gen_goto_tb(ctx, 1, ctx->btarget);
12931 gen_set_label(fs);
12932
12933 ctx->hflags |= MIPS_HFLAG_FBNSLOT;
6893f074
YK
12934 }
12935
12936out:
12937 tcg_temp_free(t0);
12938 tcg_temp_free(t1);
12939}
12940
7a387fff 12941/* ISA extensions (ASEs) */
6af0bf9c 12942/* MIPS16 extension to MIPS32 */
6ea219d0
NF
12943
12944/* MIPS16 major opcodes */
12945enum {
12946 M16_OPC_ADDIUSP = 0x00,
12947 M16_OPC_ADDIUPC = 0x01,
12948 M16_OPC_B = 0x02,
12949 M16_OPC_JAL = 0x03,
12950 M16_OPC_BEQZ = 0x04,
12951 M16_OPC_BNEQZ = 0x05,
12952 M16_OPC_SHIFT = 0x06,
12953 M16_OPC_LD = 0x07,
12954 M16_OPC_RRIA = 0x08,
12955 M16_OPC_ADDIU8 = 0x09,
12956 M16_OPC_SLTI = 0x0a,
12957 M16_OPC_SLTIU = 0x0b,
12958 M16_OPC_I8 = 0x0c,
12959 M16_OPC_LI = 0x0d,
12960 M16_OPC_CMPI = 0x0e,
12961 M16_OPC_SD = 0x0f,
12962 M16_OPC_LB = 0x10,
12963 M16_OPC_LH = 0x11,
12964 M16_OPC_LWSP = 0x12,
12965 M16_OPC_LW = 0x13,
12966 M16_OPC_LBU = 0x14,
12967 M16_OPC_LHU = 0x15,
12968 M16_OPC_LWPC = 0x16,
12969 M16_OPC_LWU = 0x17,
12970 M16_OPC_SB = 0x18,
12971 M16_OPC_SH = 0x19,
12972 M16_OPC_SWSP = 0x1a,
12973 M16_OPC_SW = 0x1b,
12974 M16_OPC_RRR = 0x1c,
12975 M16_OPC_RR = 0x1d,
12976 M16_OPC_EXTEND = 0x1e,
12977 M16_OPC_I64 = 0x1f
12978};
12979
12980/* I8 funct field */
12981enum {
12982 I8_BTEQZ = 0x0,
12983 I8_BTNEZ = 0x1,
12984 I8_SWRASP = 0x2,
12985 I8_ADJSP = 0x3,
12986 I8_SVRS = 0x4,
12987 I8_MOV32R = 0x5,
12988 I8_MOVR32 = 0x7
12989};
12990
12991/* RRR f field */
12992enum {
12993 RRR_DADDU = 0x0,
12994 RRR_ADDU = 0x1,
12995 RRR_DSUBU = 0x2,
12996 RRR_SUBU = 0x3
12997};
12998
12999/* RR funct field */
13000enum {
13001 RR_JR = 0x00,
13002 RR_SDBBP = 0x01,
13003 RR_SLT = 0x02,
13004 RR_SLTU = 0x03,
13005 RR_SLLV = 0x04,
13006 RR_BREAK = 0x05,
13007 RR_SRLV = 0x06,
13008 RR_SRAV = 0x07,
13009 RR_DSRL = 0x08,
13010 RR_CMP = 0x0a,
13011 RR_NEG = 0x0b,
13012 RR_AND = 0x0c,
13013 RR_OR = 0x0d,
13014 RR_XOR = 0x0e,
13015 RR_NOT = 0x0f,
13016 RR_MFHI = 0x10,
13017 RR_CNVT = 0x11,
13018 RR_MFLO = 0x12,
13019 RR_DSRA = 0x13,
13020 RR_DSLLV = 0x14,
13021 RR_DSRLV = 0x16,
13022 RR_DSRAV = 0x17,
13023 RR_MULT = 0x18,
13024 RR_MULTU = 0x19,
13025 RR_DIV = 0x1a,
13026 RR_DIVU = 0x1b,
13027 RR_DMULT = 0x1c,
13028 RR_DMULTU = 0x1d,
13029 RR_DDIV = 0x1e,
13030 RR_DDIVU = 0x1f
13031};
13032
13033/* I64 funct field */
13034enum {
13035 I64_LDSP = 0x0,
13036 I64_SDSP = 0x1,
13037 I64_SDRASP = 0x2,
13038 I64_DADJSP = 0x3,
13039 I64_LDPC = 0x4,
364d4831 13040 I64_DADDIU5 = 0x5,
6ea219d0
NF
13041 I64_DADDIUPC = 0x6,
13042 I64_DADDIUSP = 0x7
13043};
13044
13045/* RR ry field for CNVT */
13046enum {
13047 RR_RY_CNVT_ZEB = 0x0,
13048 RR_RY_CNVT_ZEH = 0x1,
13049 RR_RY_CNVT_ZEW = 0x2,
13050 RR_RY_CNVT_SEB = 0x4,
13051 RR_RY_CNVT_SEH = 0x5,
13052 RR_RY_CNVT_SEW = 0x6,
13053};
13054
364d4831
NF
13055static int xlat (int r)
13056{
13057 static int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
13058
13059 return map[r];
13060}
13061
13062static void gen_mips16_save (DisasContext *ctx,
13063 int xsregs, int aregs,
13064 int do_ra, int do_s0, int do_s1,
13065 int framesize)
13066{
13067 TCGv t0 = tcg_temp_new();
13068 TCGv t1 = tcg_temp_new();
c48245f0 13069 TCGv t2 = tcg_temp_new();
364d4831
NF
13070 int args, astatic;
13071
13072 switch (aregs) {
13073 case 0:
13074 case 1:
13075 case 2:
13076 case 3:
13077 case 11:
13078 args = 0;
13079 break;
13080 case 4:
13081 case 5:
13082 case 6:
13083 case 7:
13084 args = 1;
13085 break;
13086 case 8:
13087 case 9:
13088 case 10:
13089 args = 2;
13090 break;
13091 case 12:
13092 case 13:
13093 args = 3;
13094 break;
13095 case 14:
13096 args = 4;
13097 break;
13098 default:
9c708c7f 13099 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
13100 return;
13101 }
13102
13103 switch (args) {
13104 case 4:
13105 gen_base_offset_addr(ctx, t0, 29, 12);
13106 gen_load_gpr(t1, 7);
5f68f5ae 13107 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
364d4831
NF
13108 /* Fall through */
13109 case 3:
13110 gen_base_offset_addr(ctx, t0, 29, 8);
13111 gen_load_gpr(t1, 6);
5f68f5ae 13112 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
364d4831
NF
13113 /* Fall through */
13114 case 2:
13115 gen_base_offset_addr(ctx, t0, 29, 4);
13116 gen_load_gpr(t1, 5);
5f68f5ae 13117 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
364d4831
NF
13118 /* Fall through */
13119 case 1:
13120 gen_base_offset_addr(ctx, t0, 29, 0);
13121 gen_load_gpr(t1, 4);
5f68f5ae 13122 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
364d4831
NF
13123 }
13124
13125 gen_load_gpr(t0, 29);
13126
5f68f5ae 13127#define DECR_AND_STORE(reg) do { \
c48245f0
MR
13128 tcg_gen_movi_tl(t2, -4); \
13129 gen_op_addr_add(ctx, t0, t0, t2); \
5f68f5ae
AJ
13130 gen_load_gpr(t1, reg); \
13131 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); \
364d4831
NF
13132 } while (0)
13133
13134 if (do_ra) {
13135 DECR_AND_STORE(31);
13136 }
13137
13138 switch (xsregs) {
13139 case 7:
13140 DECR_AND_STORE(30);
13141 /* Fall through */
13142 case 6:
13143 DECR_AND_STORE(23);
13144 /* Fall through */
13145 case 5:
13146 DECR_AND_STORE(22);
13147 /* Fall through */
13148 case 4:
13149 DECR_AND_STORE(21);
13150 /* Fall through */
13151 case 3:
13152 DECR_AND_STORE(20);
13153 /* Fall through */
13154 case 2:
13155 DECR_AND_STORE(19);
13156 /* Fall through */
13157 case 1:
13158 DECR_AND_STORE(18);
13159 }
13160
13161 if (do_s1) {
13162 DECR_AND_STORE(17);
13163 }
13164 if (do_s0) {
13165 DECR_AND_STORE(16);
13166 }
13167
13168 switch (aregs) {
13169 case 0:
13170 case 4:
13171 case 8:
13172 case 12:
13173 case 14:
13174 astatic = 0;
13175 break;
13176 case 1:
13177 case 5:
13178 case 9:
13179 case 13:
13180 astatic = 1;
13181 break;
13182 case 2:
13183 case 6:
13184 case 10:
13185 astatic = 2;
13186 break;
13187 case 3:
13188 case 7:
13189 astatic = 3;
13190 break;
13191 case 11:
13192 astatic = 4;
13193 break;
13194 default:
9c708c7f 13195 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
13196 return;
13197 }
13198
13199 if (astatic > 0) {
13200 DECR_AND_STORE(7);
13201 if (astatic > 1) {
13202 DECR_AND_STORE(6);
13203 if (astatic > 2) {
13204 DECR_AND_STORE(5);
13205 if (astatic > 3) {
13206 DECR_AND_STORE(4);
13207 }
13208 }
13209 }
13210 }
13211#undef DECR_AND_STORE
13212
c48245f0
MR
13213 tcg_gen_movi_tl(t2, -framesize);
13214 gen_op_addr_add(ctx, cpu_gpr[29], cpu_gpr[29], t2);
364d4831
NF
13215 tcg_temp_free(t0);
13216 tcg_temp_free(t1);
c48245f0 13217 tcg_temp_free(t2);
364d4831
NF
13218}
13219
13220static void gen_mips16_restore (DisasContext *ctx,
13221 int xsregs, int aregs,
13222 int do_ra, int do_s0, int do_s1,
13223 int framesize)
13224{
13225 int astatic;
13226 TCGv t0 = tcg_temp_new();
13227 TCGv t1 = tcg_temp_new();
c48245f0 13228 TCGv t2 = tcg_temp_new();
364d4831 13229
c48245f0
MR
13230 tcg_gen_movi_tl(t2, framesize);
13231 gen_op_addr_add(ctx, t0, cpu_gpr[29], t2);
364d4831 13232
5f68f5ae 13233#define DECR_AND_LOAD(reg) do { \
c48245f0
MR
13234 tcg_gen_movi_tl(t2, -4); \
13235 gen_op_addr_add(ctx, t0, t0, t2); \
5f68f5ae
AJ
13236 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL); \
13237 gen_store_gpr(t1, reg); \
364d4831
NF
13238 } while (0)
13239
13240 if (do_ra) {
13241 DECR_AND_LOAD(31);
13242 }
13243
13244 switch (xsregs) {
13245 case 7:
13246 DECR_AND_LOAD(30);
13247 /* Fall through */
13248 case 6:
13249 DECR_AND_LOAD(23);
13250 /* Fall through */
13251 case 5:
13252 DECR_AND_LOAD(22);
13253 /* Fall through */
13254 case 4:
13255 DECR_AND_LOAD(21);
13256 /* Fall through */
13257 case 3:
13258 DECR_AND_LOAD(20);
13259 /* Fall through */
13260 case 2:
13261 DECR_AND_LOAD(19);
13262 /* Fall through */
13263 case 1:
13264 DECR_AND_LOAD(18);
13265 }
13266
13267 if (do_s1) {
13268 DECR_AND_LOAD(17);
13269 }
13270 if (do_s0) {
13271 DECR_AND_LOAD(16);
13272 }
13273
13274 switch (aregs) {
13275 case 0:
13276 case 4:
13277 case 8:
13278 case 12:
13279 case 14:
13280 astatic = 0;
13281 break;
13282 case 1:
13283 case 5:
13284 case 9:
13285 case 13:
13286 astatic = 1;
13287 break;
13288 case 2:
13289 case 6:
13290 case 10:
13291 astatic = 2;
13292 break;
13293 case 3:
13294 case 7:
13295 astatic = 3;
13296 break;
13297 case 11:
13298 astatic = 4;
13299 break;
13300 default:
9c708c7f 13301 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
13302 return;
13303 }
13304
13305 if (astatic > 0) {
13306 DECR_AND_LOAD(7);
13307 if (astatic > 1) {
13308 DECR_AND_LOAD(6);
13309 if (astatic > 2) {
13310 DECR_AND_LOAD(5);
13311 if (astatic > 3) {
13312 DECR_AND_LOAD(4);
13313 }
13314 }
13315 }
13316 }
13317#undef DECR_AND_LOAD
13318
c48245f0
MR
13319 tcg_gen_movi_tl(t2, framesize);
13320 gen_op_addr_add(ctx, cpu_gpr[29], cpu_gpr[29], t2);
364d4831
NF
13321 tcg_temp_free(t0);
13322 tcg_temp_free(t1);
c48245f0 13323 tcg_temp_free(t2);
364d4831
NF
13324}
13325
13326static void gen_addiupc (DisasContext *ctx, int rx, int imm,
13327 int is_64_bit, int extended)
13328{
13329 TCGv t0;
13330
13331 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9c708c7f 13332 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
13333 return;
13334 }
13335
13336 t0 = tcg_temp_new();
13337
13338 tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
13339 tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
13340 if (!is_64_bit) {
13341 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
13342 }
13343
13344 tcg_temp_free(t0);
13345}
13346
0d74a222
LA
13347static void gen_cache_operation(DisasContext *ctx, uint32_t op, int base,
13348 int16_t offset)
13349{
13350 TCGv_i32 t0 = tcg_const_i32(op);
13351 TCGv t1 = tcg_temp_new();
13352 gen_base_offset_addr(ctx, t1, base, offset);
13353 gen_helper_cache(cpu_env, t1, t0);
13354}
13355
364d4831 13356#if defined(TARGET_MIPS64)
d75c135e 13357static void decode_i64_mips16 (DisasContext *ctx,
364d4831
NF
13358 int ry, int funct, int16_t offset,
13359 int extended)
13360{
13361 switch (funct) {
13362 case I64_LDSP:
d9224450 13363 check_insn(ctx, ISA_MIPS3);
364d4831
NF
13364 check_mips_64(ctx);
13365 offset = extended ? offset : offset << 3;
d75c135e 13366 gen_ld(ctx, OPC_LD, ry, 29, offset);
364d4831
NF
13367 break;
13368 case I64_SDSP:
d9224450 13369 check_insn(ctx, ISA_MIPS3);
364d4831
NF
13370 check_mips_64(ctx);
13371 offset = extended ? offset : offset << 3;
5c13fdfd 13372 gen_st(ctx, OPC_SD, ry, 29, offset);
364d4831
NF
13373 break;
13374 case I64_SDRASP:
d9224450 13375 check_insn(ctx, ISA_MIPS3);
364d4831
NF
13376 check_mips_64(ctx);
13377 offset = extended ? offset : (ctx->opcode & 0xff) << 3;
5c13fdfd 13378 gen_st(ctx, OPC_SD, 31, 29, offset);
364d4831
NF
13379 break;
13380 case I64_DADJSP:
d9224450 13381 check_insn(ctx, ISA_MIPS3);
364d4831
NF
13382 check_mips_64(ctx);
13383 offset = extended ? offset : ((int8_t)ctx->opcode) << 3;
d75c135e 13384 gen_arith_imm(ctx, OPC_DADDIU, 29, 29, offset);
364d4831
NF
13385 break;
13386 case I64_LDPC:
d9224450
MR
13387 check_insn(ctx, ISA_MIPS3);
13388 check_mips_64(ctx);
364d4831 13389 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9c708c7f 13390 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
13391 } else {
13392 offset = extended ? offset : offset << 3;
d75c135e 13393 gen_ld(ctx, OPC_LDPC, ry, 0, offset);
364d4831
NF
13394 }
13395 break;
13396 case I64_DADDIU5:
d9224450 13397 check_insn(ctx, ISA_MIPS3);
364d4831
NF
13398 check_mips_64(ctx);
13399 offset = extended ? offset : ((int8_t)(offset << 3)) >> 3;
d75c135e 13400 gen_arith_imm(ctx, OPC_DADDIU, ry, ry, offset);
364d4831
NF
13401 break;
13402 case I64_DADDIUPC:
d9224450 13403 check_insn(ctx, ISA_MIPS3);
364d4831
NF
13404 check_mips_64(ctx);
13405 offset = extended ? offset : offset << 2;
13406 gen_addiupc(ctx, ry, offset, 1, extended);
13407 break;
13408 case I64_DADDIUSP:
d9224450 13409 check_insn(ctx, ISA_MIPS3);
364d4831
NF
13410 check_mips_64(ctx);
13411 offset = extended ? offset : offset << 2;
d75c135e 13412 gen_arith_imm(ctx, OPC_DADDIU, ry, 29, offset);
364d4831
NF
13413 break;
13414 }
13415}
13416#endif
13417
240ce26a 13418static int decode_extended_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
364d4831 13419{
eeb3bba8 13420 int extend = cpu_lduw_code(env, ctx->base.pc_next + 2);
364d4831
NF
13421 int op, rx, ry, funct, sa;
13422 int16_t imm, offset;
13423
13424 ctx->opcode = (ctx->opcode << 16) | extend;
13425 op = (ctx->opcode >> 11) & 0x1f;
13426 sa = (ctx->opcode >> 22) & 0x1f;
13427 funct = (ctx->opcode >> 8) & 0x7;
13428 rx = xlat((ctx->opcode >> 8) & 0x7);
13429 ry = xlat((ctx->opcode >> 5) & 0x7);
13430 offset = imm = (int16_t) (((ctx->opcode >> 16) & 0x1f) << 11
13431 | ((ctx->opcode >> 21) & 0x3f) << 5
13432 | (ctx->opcode & 0x1f));
13433
13434 /* The extended opcodes cleverly reuse the opcodes from their 16-bit
13435 counterparts. */
13436 switch (op) {
13437 case M16_OPC_ADDIUSP:
d75c135e 13438 gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
364d4831
NF
13439 break;
13440 case M16_OPC_ADDIUPC:
13441 gen_addiupc(ctx, rx, imm, 0, 1);
13442 break;
13443 case M16_OPC_B:
b231c103 13444 gen_compute_branch(ctx, OPC_BEQ, 4, 0, 0, offset << 1, 0);
364d4831
NF
13445 /* No delay slot, so just process as a normal instruction */
13446 break;
13447 case M16_OPC_BEQZ:
b231c103 13448 gen_compute_branch(ctx, OPC_BEQ, 4, rx, 0, offset << 1, 0);
364d4831
NF
13449 /* No delay slot, so just process as a normal instruction */
13450 break;
13451 case M16_OPC_BNEQZ:
b231c103 13452 gen_compute_branch(ctx, OPC_BNE, 4, rx, 0, offset << 1, 0);
364d4831
NF
13453 /* No delay slot, so just process as a normal instruction */
13454 break;
13455 case M16_OPC_SHIFT:
13456 switch (ctx->opcode & 0x3) {
13457 case 0x0:
d75c135e 13458 gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
364d4831
NF
13459 break;
13460 case 0x1:
13461#if defined(TARGET_MIPS64)
13462 check_mips_64(ctx);
d75c135e 13463 gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
364d4831 13464#else
9c708c7f 13465 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
13466#endif
13467 break;
13468 case 0x2:
d75c135e 13469 gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
364d4831
NF
13470 break;
13471 case 0x3:
d75c135e 13472 gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
364d4831
NF
13473 break;
13474 }
13475 break;
13476#if defined(TARGET_MIPS64)
13477 case M16_OPC_LD:
d9224450 13478 check_insn(ctx, ISA_MIPS3);
d75de749 13479 check_mips_64(ctx);
d75c135e 13480 gen_ld(ctx, OPC_LD, ry, rx, offset);
364d4831
NF
13481 break;
13482#endif
13483 case M16_OPC_RRIA:
13484 imm = ctx->opcode & 0xf;
13485 imm = imm | ((ctx->opcode >> 20) & 0x7f) << 4;
13486 imm = imm | ((ctx->opcode >> 16) & 0xf) << 11;
13487 imm = (int16_t) (imm << 1) >> 1;
13488 if ((ctx->opcode >> 4) & 0x1) {
13489#if defined(TARGET_MIPS64)
13490 check_mips_64(ctx);
d75c135e 13491 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
364d4831 13492#else
9c708c7f 13493 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
13494#endif
13495 } else {
d75c135e 13496 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
364d4831
NF
13497 }
13498 break;
13499 case M16_OPC_ADDIU8:
d75c135e 13500 gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
364d4831
NF
13501 break;
13502 case M16_OPC_SLTI:
d75c135e 13503 gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
364d4831
NF
13504 break;
13505 case M16_OPC_SLTIU:
d75c135e 13506 gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
364d4831
NF
13507 break;
13508 case M16_OPC_I8:
13509 switch (funct) {
13510 case I8_BTEQZ:
b231c103 13511 gen_compute_branch(ctx, OPC_BEQ, 4, 24, 0, offset << 1, 0);
364d4831
NF
13512 break;
13513 case I8_BTNEZ:
b231c103 13514 gen_compute_branch(ctx, OPC_BNE, 4, 24, 0, offset << 1, 0);
364d4831
NF
13515 break;
13516 case I8_SWRASP:
5c13fdfd 13517 gen_st(ctx, OPC_SW, 31, 29, imm);
364d4831
NF
13518 break;
13519 case I8_ADJSP:
d75c135e 13520 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm);
364d4831
NF
13521 break;
13522 case I8_SVRS:
d9224450 13523 check_insn(ctx, ISA_MIPS32);
364d4831
NF
13524 {
13525 int xsregs = (ctx->opcode >> 24) & 0x7;
13526 int aregs = (ctx->opcode >> 16) & 0xf;
13527 int do_ra = (ctx->opcode >> 6) & 0x1;
13528 int do_s0 = (ctx->opcode >> 5) & 0x1;
13529 int do_s1 = (ctx->opcode >> 4) & 0x1;
13530 int framesize = (((ctx->opcode >> 20) & 0xf) << 4
13531 | (ctx->opcode & 0xf)) << 3;
13532
13533 if (ctx->opcode & (1 << 7)) {
13534 gen_mips16_save(ctx, xsregs, aregs,
13535 do_ra, do_s0, do_s1,
13536 framesize);
13537 } else {
13538 gen_mips16_restore(ctx, xsregs, aregs,
13539 do_ra, do_s0, do_s1,
13540 framesize);
13541 }
13542 }
13543 break;
13544 default:
9c708c7f 13545 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
13546 break;
13547 }
13548 break;
13549 case M16_OPC_LI:
13550 tcg_gen_movi_tl(cpu_gpr[rx], (uint16_t) imm);
13551 break;
13552 case M16_OPC_CMPI:
13553 tcg_gen_xori_tl(cpu_gpr[24], cpu_gpr[rx], (uint16_t) imm);
13554 break;
13555#if defined(TARGET_MIPS64)
13556 case M16_OPC_SD:
d9224450
MR
13557 check_insn(ctx, ISA_MIPS3);
13558 check_mips_64(ctx);
5c13fdfd 13559 gen_st(ctx, OPC_SD, ry, rx, offset);
364d4831
NF
13560 break;
13561#endif
13562 case M16_OPC_LB:
d75c135e 13563 gen_ld(ctx, OPC_LB, ry, rx, offset);
364d4831
NF
13564 break;
13565 case M16_OPC_LH:
d75c135e 13566 gen_ld(ctx, OPC_LH, ry, rx, offset);
364d4831
NF
13567 break;
13568 case M16_OPC_LWSP:
d75c135e 13569 gen_ld(ctx, OPC_LW, rx, 29, offset);
364d4831
NF
13570 break;
13571 case M16_OPC_LW:
d75c135e 13572 gen_ld(ctx, OPC_LW, ry, rx, offset);
364d4831
NF
13573 break;
13574 case M16_OPC_LBU:
d75c135e 13575 gen_ld(ctx, OPC_LBU, ry, rx, offset);
364d4831
NF
13576 break;
13577 case M16_OPC_LHU:
d75c135e 13578 gen_ld(ctx, OPC_LHU, ry, rx, offset);
364d4831
NF
13579 break;
13580 case M16_OPC_LWPC:
d75c135e 13581 gen_ld(ctx, OPC_LWPC, rx, 0, offset);
364d4831
NF
13582 break;
13583#if defined(TARGET_MIPS64)
13584 case M16_OPC_LWU:
d9224450
MR
13585 check_insn(ctx, ISA_MIPS3);
13586 check_mips_64(ctx);
d75c135e 13587 gen_ld(ctx, OPC_LWU, ry, rx, offset);
364d4831
NF
13588 break;
13589#endif
13590 case M16_OPC_SB:
5c13fdfd 13591 gen_st(ctx, OPC_SB, ry, rx, offset);
364d4831
NF
13592 break;
13593 case M16_OPC_SH:
5c13fdfd 13594 gen_st(ctx, OPC_SH, ry, rx, offset);
364d4831
NF
13595 break;
13596 case M16_OPC_SWSP:
5c13fdfd 13597 gen_st(ctx, OPC_SW, rx, 29, offset);
364d4831
NF
13598 break;
13599 case M16_OPC_SW:
5c13fdfd 13600 gen_st(ctx, OPC_SW, ry, rx, offset);
364d4831
NF
13601 break;
13602#if defined(TARGET_MIPS64)
13603 case M16_OPC_I64:
d75c135e 13604 decode_i64_mips16(ctx, ry, funct, offset, 1);
364d4831
NF
13605 break;
13606#endif
13607 default:
9c708c7f 13608 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
13609 break;
13610 }
13611
13612 return 4;
13613}
13614
3b3c1694
LA
13615static inline bool is_uhi(int sdbbp_code)
13616{
13617#ifdef CONFIG_USER_ONLY
13618 return false;
13619#else
13620 return semihosting_enabled() && sdbbp_code == 1;
13621#endif
13622}
13623
240ce26a 13624static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
364d4831
NF
13625{
13626 int rx, ry;
13627 int sa;
13628 int op, cnvt_op, op1, offset;
13629 int funct;
13630 int n_bytes;
13631
13632 op = (ctx->opcode >> 11) & 0x1f;
13633 sa = (ctx->opcode >> 2) & 0x7;
13634 sa = sa == 0 ? 8 : sa;
13635 rx = xlat((ctx->opcode >> 8) & 0x7);
13636 cnvt_op = (ctx->opcode >> 5) & 0x7;
13637 ry = xlat((ctx->opcode >> 5) & 0x7);
13638 op1 = offset = ctx->opcode & 0x1f;
13639
13640 n_bytes = 2;
13641
13642 switch (op) {
13643 case M16_OPC_ADDIUSP:
13644 {
13645 int16_t imm = ((uint8_t) ctx->opcode) << 2;
13646
d75c135e 13647 gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
364d4831
NF
13648 }
13649 break;
13650 case M16_OPC_ADDIUPC:
13651 gen_addiupc(ctx, rx, ((uint8_t) ctx->opcode) << 2, 0, 0);
13652 break;
13653 case M16_OPC_B:
13654 offset = (ctx->opcode & 0x7ff) << 1;
13655 offset = (int16_t)(offset << 4) >> 4;
b231c103 13656 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, offset, 0);
364d4831
NF
13657 /* No delay slot, so just process as a normal instruction */
13658 break;
13659 case M16_OPC_JAL:
eeb3bba8 13660 offset = cpu_lduw_code(env, ctx->base.pc_next + 2);
364d4831
NF
13661 offset = (((ctx->opcode & 0x1f) << 21)
13662 | ((ctx->opcode >> 5) & 0x1f) << 16
13663 | offset) << 2;
b231c103
YK
13664 op = ((ctx->opcode >> 10) & 0x1) ? OPC_JALX : OPC_JAL;
13665 gen_compute_branch(ctx, op, 4, rx, ry, offset, 2);
364d4831 13666 n_bytes = 4;
364d4831
NF
13667 break;
13668 case M16_OPC_BEQZ:
b231c103
YK
13669 gen_compute_branch(ctx, OPC_BEQ, 2, rx, 0,
13670 ((int8_t)ctx->opcode) << 1, 0);
364d4831
NF
13671 /* No delay slot, so just process as a normal instruction */
13672 break;
13673 case M16_OPC_BNEQZ:
b231c103
YK
13674 gen_compute_branch(ctx, OPC_BNE, 2, rx, 0,
13675 ((int8_t)ctx->opcode) << 1, 0);
364d4831
NF
13676 /* No delay slot, so just process as a normal instruction */
13677 break;
13678 case M16_OPC_SHIFT:
13679 switch (ctx->opcode & 0x3) {
13680 case 0x0:
d75c135e 13681 gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
364d4831
NF
13682 break;
13683 case 0x1:
13684#if defined(TARGET_MIPS64)
d9224450 13685 check_insn(ctx, ISA_MIPS3);
364d4831 13686 check_mips_64(ctx);
d75c135e 13687 gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
364d4831 13688#else
9c708c7f 13689 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
13690#endif
13691 break;
13692 case 0x2:
d75c135e 13693 gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
364d4831
NF
13694 break;
13695 case 0x3:
d75c135e 13696 gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
364d4831
NF
13697 break;
13698 }
13699 break;
13700#if defined(TARGET_MIPS64)
13701 case M16_OPC_LD:
d9224450 13702 check_insn(ctx, ISA_MIPS3);
364d4831 13703 check_mips_64(ctx);
d75c135e 13704 gen_ld(ctx, OPC_LD, ry, rx, offset << 3);
364d4831
NF
13705 break;
13706#endif
13707 case M16_OPC_RRIA:
13708 {
13709 int16_t imm = (int8_t)((ctx->opcode & 0xf) << 4) >> 4;
13710
13711 if ((ctx->opcode >> 4) & 1) {
13712#if defined(TARGET_MIPS64)
d9224450 13713 check_insn(ctx, ISA_MIPS3);
364d4831 13714 check_mips_64(ctx);
d75c135e 13715 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
364d4831 13716#else
9c708c7f 13717 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
13718#endif
13719 } else {
d75c135e 13720 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
364d4831
NF
13721 }
13722 }
13723 break;
13724 case M16_OPC_ADDIU8:
13725 {
13726 int16_t imm = (int8_t) ctx->opcode;
13727
d75c135e 13728 gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
364d4831
NF
13729 }
13730 break;
13731 case M16_OPC_SLTI:
13732 {
13733 int16_t imm = (uint8_t) ctx->opcode;
d75c135e 13734 gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
364d4831
NF
13735 }
13736 break;
13737 case M16_OPC_SLTIU:
13738 {
13739 int16_t imm = (uint8_t) ctx->opcode;
d75c135e 13740 gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
364d4831
NF
13741 }
13742 break;
13743 case M16_OPC_I8:
13744 {
13745 int reg32;
13746
13747 funct = (ctx->opcode >> 8) & 0x7;
13748 switch (funct) {
13749 case I8_BTEQZ:
13750 gen_compute_branch(ctx, OPC_BEQ, 2, 24, 0,
b231c103 13751 ((int8_t)ctx->opcode) << 1, 0);
364d4831
NF
13752 break;
13753 case I8_BTNEZ:
13754 gen_compute_branch(ctx, OPC_BNE, 2, 24, 0,
b231c103 13755 ((int8_t)ctx->opcode) << 1, 0);
364d4831
NF
13756 break;
13757 case I8_SWRASP:
5c13fdfd 13758 gen_st(ctx, OPC_SW, 31, 29, (ctx->opcode & 0xff) << 2);
364d4831
NF
13759 break;
13760 case I8_ADJSP:
d75c135e 13761 gen_arith_imm(ctx, OPC_ADDIU, 29, 29,
364d4831
NF
13762 ((int8_t)ctx->opcode) << 3);
13763 break;
13764 case I8_SVRS:
d9224450 13765 check_insn(ctx, ISA_MIPS32);
364d4831
NF
13766 {
13767 int do_ra = ctx->opcode & (1 << 6);
13768 int do_s0 = ctx->opcode & (1 << 5);
13769 int do_s1 = ctx->opcode & (1 << 4);
13770 int framesize = ctx->opcode & 0xf;
13771
13772 if (framesize == 0) {
13773 framesize = 128;
13774 } else {
13775 framesize = framesize << 3;
13776 }
13777
13778 if (ctx->opcode & (1 << 7)) {
13779 gen_mips16_save(ctx, 0, 0,
13780 do_ra, do_s0, do_s1, framesize);
13781 } else {
13782 gen_mips16_restore(ctx, 0, 0,
13783 do_ra, do_s0, do_s1, framesize);
13784 }
13785 }
13786 break;
13787 case I8_MOV32R:
13788 {
13789 int rz = xlat(ctx->opcode & 0x7);
13790
13791 reg32 = (((ctx->opcode >> 3) & 0x3) << 3) |
13792 ((ctx->opcode >> 5) & 0x7);
d75c135e 13793 gen_arith(ctx, OPC_ADDU, reg32, rz, 0);
364d4831
NF
13794 }
13795 break;
13796 case I8_MOVR32:
13797 reg32 = ctx->opcode & 0x1f;
d75c135e 13798 gen_arith(ctx, OPC_ADDU, ry, reg32, 0);
364d4831
NF
13799 break;
13800 default:
9c708c7f 13801 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
13802 break;
13803 }
13804 }
13805 break;
13806 case M16_OPC_LI:
13807 {
13808 int16_t imm = (uint8_t) ctx->opcode;
13809
d75c135e 13810 gen_arith_imm(ctx, OPC_ADDIU, rx, 0, imm);
364d4831
NF
13811 }
13812 break;
13813 case M16_OPC_CMPI:
13814 {
13815 int16_t imm = (uint8_t) ctx->opcode;
d75c135e 13816 gen_logic_imm(ctx, OPC_XORI, 24, rx, imm);
364d4831
NF
13817 }
13818 break;
13819#if defined(TARGET_MIPS64)
13820 case M16_OPC_SD:
d9224450 13821 check_insn(ctx, ISA_MIPS3);
364d4831 13822 check_mips_64(ctx);
5c13fdfd 13823 gen_st(ctx, OPC_SD, ry, rx, offset << 3);
364d4831
NF
13824 break;
13825#endif
13826 case M16_OPC_LB:
d75c135e 13827 gen_ld(ctx, OPC_LB, ry, rx, offset);
364d4831
NF
13828 break;
13829 case M16_OPC_LH:
d75c135e 13830 gen_ld(ctx, OPC_LH, ry, rx, offset << 1);
364d4831
NF
13831 break;
13832 case M16_OPC_LWSP:
d75c135e 13833 gen_ld(ctx, OPC_LW, rx, 29, ((uint8_t)ctx->opcode) << 2);
364d4831
NF
13834 break;
13835 case M16_OPC_LW:
d75c135e 13836 gen_ld(ctx, OPC_LW, ry, rx, offset << 2);
364d4831
NF
13837 break;
13838 case M16_OPC_LBU:
d75c135e 13839 gen_ld(ctx, OPC_LBU, ry, rx, offset);
364d4831
NF
13840 break;
13841 case M16_OPC_LHU:
d75c135e 13842 gen_ld(ctx, OPC_LHU, ry, rx, offset << 1);
364d4831
NF
13843 break;
13844 case M16_OPC_LWPC:
d75c135e 13845 gen_ld(ctx, OPC_LWPC, rx, 0, ((uint8_t)ctx->opcode) << 2);
364d4831
NF
13846 break;
13847#if defined (TARGET_MIPS64)
13848 case M16_OPC_LWU:
d9224450 13849 check_insn(ctx, ISA_MIPS3);
364d4831 13850 check_mips_64(ctx);
d75c135e 13851 gen_ld(ctx, OPC_LWU, ry, rx, offset << 2);
364d4831
NF
13852 break;
13853#endif
13854 case M16_OPC_SB:
5c13fdfd 13855 gen_st(ctx, OPC_SB, ry, rx, offset);
364d4831
NF
13856 break;
13857 case M16_OPC_SH:
5c13fdfd 13858 gen_st(ctx, OPC_SH, ry, rx, offset << 1);
364d4831
NF
13859 break;
13860 case M16_OPC_SWSP:
5c13fdfd 13861 gen_st(ctx, OPC_SW, rx, 29, ((uint8_t)ctx->opcode) << 2);
364d4831
NF
13862 break;
13863 case M16_OPC_SW:
5c13fdfd 13864 gen_st(ctx, OPC_SW, ry, rx, offset << 2);
364d4831
NF
13865 break;
13866 case M16_OPC_RRR:
13867 {
13868 int rz = xlat((ctx->opcode >> 2) & 0x7);
13869 int mips32_op;
13870
13871 switch (ctx->opcode & 0x3) {
13872 case RRR_ADDU:
13873 mips32_op = OPC_ADDU;
13874 break;
13875 case RRR_SUBU:
13876 mips32_op = OPC_SUBU;
13877 break;
13878#if defined(TARGET_MIPS64)
13879 case RRR_DADDU:
13880 mips32_op = OPC_DADDU;
d9224450 13881 check_insn(ctx, ISA_MIPS3);
364d4831
NF
13882 check_mips_64(ctx);
13883 break;
13884 case RRR_DSUBU:
13885 mips32_op = OPC_DSUBU;
d9224450 13886 check_insn(ctx, ISA_MIPS3);
364d4831
NF
13887 check_mips_64(ctx);
13888 break;
13889#endif
13890 default:
9c708c7f 13891 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
13892 goto done;
13893 }
13894
d75c135e 13895 gen_arith(ctx, mips32_op, rz, rx, ry);
364d4831
NF
13896 done:
13897 ;
13898 }
13899 break;
13900 case M16_OPC_RR:
13901 switch (op1) {
13902 case RR_JR:
13903 {
13904 int nd = (ctx->opcode >> 7) & 0x1;
13905 int link = (ctx->opcode >> 6) & 0x1;
13906 int ra = (ctx->opcode >> 5) & 0x1;
13907
d9224450
MR
13908 if (nd) {
13909 check_insn(ctx, ISA_MIPS32);
13910 }
13911
364d4831 13912 if (link) {
b231c103 13913 op = OPC_JALR;
364d4831
NF
13914 } else {
13915 op = OPC_JR;
13916 }
13917
b231c103
YK
13918 gen_compute_branch(ctx, op, 2, ra ? 31 : rx, 31, 0,
13919 (nd ? 0 : 2));
364d4831
NF
13920 }
13921 break;
13922 case RR_SDBBP:
3b3c1694
LA
13923 if (is_uhi(extract32(ctx->opcode, 5, 6))) {
13924 gen_helper_do_semihosting(cpu_env);
13925 } else {
13926 /* XXX: not clear which exception should be raised
13927 * when in debug mode...
13928 */
13929 check_insn(ctx, ISA_MIPS32);
9c708c7f 13930 generate_exception_end(ctx, EXCP_DBp);
3b3c1694 13931 }
364d4831
NF
13932 break;
13933 case RR_SLT:
d75c135e 13934 gen_slt(ctx, OPC_SLT, 24, rx, ry);
364d4831
NF
13935 break;
13936 case RR_SLTU:
d75c135e 13937 gen_slt(ctx, OPC_SLTU, 24, rx, ry);
364d4831
NF
13938 break;
13939 case RR_BREAK:
9c708c7f 13940 generate_exception_end(ctx, EXCP_BREAK);
364d4831
NF
13941 break;
13942 case RR_SLLV:
d75c135e 13943 gen_shift(ctx, OPC_SLLV, ry, rx, ry);
364d4831
NF
13944 break;
13945 case RR_SRLV:
d75c135e 13946 gen_shift(ctx, OPC_SRLV, ry, rx, ry);
364d4831
NF
13947 break;
13948 case RR_SRAV:
d75c135e 13949 gen_shift(ctx, OPC_SRAV, ry, rx, ry);
364d4831
NF
13950 break;
13951#if defined (TARGET_MIPS64)
13952 case RR_DSRL:
d9224450 13953 check_insn(ctx, ISA_MIPS3);
364d4831 13954 check_mips_64(ctx);
d75c135e 13955 gen_shift_imm(ctx, OPC_DSRL, ry, ry, sa);
364d4831
NF
13956 break;
13957#endif
13958 case RR_CMP:
d75c135e 13959 gen_logic(ctx, OPC_XOR, 24, rx, ry);
364d4831
NF
13960 break;
13961 case RR_NEG:
d75c135e 13962 gen_arith(ctx, OPC_SUBU, rx, 0, ry);
364d4831
NF
13963 break;
13964 case RR_AND:
d75c135e 13965 gen_logic(ctx, OPC_AND, rx, rx, ry);
364d4831
NF
13966 break;
13967 case RR_OR:
d75c135e 13968 gen_logic(ctx, OPC_OR, rx, rx, ry);
364d4831
NF
13969 break;
13970 case RR_XOR:
d75c135e 13971 gen_logic(ctx, OPC_XOR, rx, rx, ry);
364d4831
NF
13972 break;
13973 case RR_NOT:
d75c135e 13974 gen_logic(ctx, OPC_NOR, rx, ry, 0);
364d4831
NF
13975 break;
13976 case RR_MFHI:
26135ead 13977 gen_HILO(ctx, OPC_MFHI, 0, rx);
364d4831
NF
13978 break;
13979 case RR_CNVT:
d9224450 13980 check_insn(ctx, ISA_MIPS32);
364d4831
NF
13981 switch (cnvt_op) {
13982 case RR_RY_CNVT_ZEB:
13983 tcg_gen_ext8u_tl(cpu_gpr[rx], cpu_gpr[rx]);
13984 break;
13985 case RR_RY_CNVT_ZEH:
13986 tcg_gen_ext16u_tl(cpu_gpr[rx], cpu_gpr[rx]);
13987 break;
13988 case RR_RY_CNVT_SEB:
13989 tcg_gen_ext8s_tl(cpu_gpr[rx], cpu_gpr[rx]);
13990 break;
13991 case RR_RY_CNVT_SEH:
13992 tcg_gen_ext16s_tl(cpu_gpr[rx], cpu_gpr[rx]);
13993 break;
13994#if defined (TARGET_MIPS64)
13995 case RR_RY_CNVT_ZEW:
d9224450 13996 check_insn(ctx, ISA_MIPS64);
364d4831
NF
13997 check_mips_64(ctx);
13998 tcg_gen_ext32u_tl(cpu_gpr[rx], cpu_gpr[rx]);
13999 break;
14000 case RR_RY_CNVT_SEW:
d9224450 14001 check_insn(ctx, ISA_MIPS64);
364d4831
NF
14002 check_mips_64(ctx);
14003 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
14004 break;
14005#endif
14006 default:
9c708c7f 14007 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
14008 break;
14009 }
14010 break;
14011 case RR_MFLO:
26135ead 14012 gen_HILO(ctx, OPC_MFLO, 0, rx);
364d4831
NF
14013 break;
14014#if defined (TARGET_MIPS64)
14015 case RR_DSRA:
d9224450 14016 check_insn(ctx, ISA_MIPS3);
364d4831 14017 check_mips_64(ctx);
d75c135e 14018 gen_shift_imm(ctx, OPC_DSRA, ry, ry, sa);
364d4831
NF
14019 break;
14020 case RR_DSLLV:
d9224450 14021 check_insn(ctx, ISA_MIPS3);
364d4831 14022 check_mips_64(ctx);
d75c135e 14023 gen_shift(ctx, OPC_DSLLV, ry, rx, ry);
364d4831
NF
14024 break;
14025 case RR_DSRLV:
d9224450 14026 check_insn(ctx, ISA_MIPS3);
364d4831 14027 check_mips_64(ctx);
d75c135e 14028 gen_shift(ctx, OPC_DSRLV, ry, rx, ry);
364d4831
NF
14029 break;
14030 case RR_DSRAV:
d9224450 14031 check_insn(ctx, ISA_MIPS3);
364d4831 14032 check_mips_64(ctx);
d75c135e 14033 gen_shift(ctx, OPC_DSRAV, ry, rx, ry);
364d4831
NF
14034 break;
14035#endif
14036 case RR_MULT:
26135ead 14037 gen_muldiv(ctx, OPC_MULT, 0, rx, ry);
364d4831
NF
14038 break;
14039 case RR_MULTU:
26135ead 14040 gen_muldiv(ctx, OPC_MULTU, 0, rx, ry);
364d4831
NF
14041 break;
14042 case RR_DIV:
26135ead 14043 gen_muldiv(ctx, OPC_DIV, 0, rx, ry);
364d4831
NF
14044 break;
14045 case RR_DIVU:
26135ead 14046 gen_muldiv(ctx, OPC_DIVU, 0, rx, ry);
364d4831
NF
14047 break;
14048#if defined (TARGET_MIPS64)
14049 case RR_DMULT:
d9224450 14050 check_insn(ctx, ISA_MIPS3);
364d4831 14051 check_mips_64(ctx);
26135ead 14052 gen_muldiv(ctx, OPC_DMULT, 0, rx, ry);
364d4831
NF
14053 break;
14054 case RR_DMULTU:
d9224450 14055 check_insn(ctx, ISA_MIPS3);
364d4831 14056 check_mips_64(ctx);
26135ead 14057 gen_muldiv(ctx, OPC_DMULTU, 0, rx, ry);
364d4831
NF
14058 break;
14059 case RR_DDIV:
d9224450 14060 check_insn(ctx, ISA_MIPS3);
364d4831 14061 check_mips_64(ctx);
26135ead 14062 gen_muldiv(ctx, OPC_DDIV, 0, rx, ry);
364d4831
NF
14063 break;
14064 case RR_DDIVU:
d9224450 14065 check_insn(ctx, ISA_MIPS3);
364d4831 14066 check_mips_64(ctx);
26135ead 14067 gen_muldiv(ctx, OPC_DDIVU, 0, rx, ry);
364d4831
NF
14068 break;
14069#endif
14070 default:
9c708c7f 14071 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
14072 break;
14073 }
14074 break;
14075 case M16_OPC_EXTEND:
240ce26a 14076 decode_extended_mips16_opc(env, ctx);
364d4831
NF
14077 n_bytes = 4;
14078 break;
14079#if defined(TARGET_MIPS64)
14080 case M16_OPC_I64:
14081 funct = (ctx->opcode >> 8) & 0x7;
d75c135e 14082 decode_i64_mips16(ctx, ry, funct, offset, 0);
364d4831
NF
14083 break;
14084#endif
14085 default:
9c708c7f 14086 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
14087 break;
14088 }
14089
14090 return n_bytes;
14091}
14092
211da992 14093/* microMIPS extension to MIPS32/MIPS64 */
6af0bf9c 14094
211da992
CWR
14095/*
14096 * microMIPS32/microMIPS64 major opcodes
14097 *
14098 * 1. MIPS Architecture for Programmers Volume II-B:
14099 * The microMIPS32 Instruction Set (Revision 3.05)
14100 *
14101 * Table 6.2 microMIPS32 Encoding of Major Opcode Field
14102 *
14103 * 2. MIPS Architecture For Programmers Volume II-A:
14104 * The MIPS64 Instruction Set (Revision 3.51)
14105 */
6af0bf9c 14106
3c824109
NF
14107enum {
14108 POOL32A = 0x00,
14109 POOL16A = 0x01,
14110 LBU16 = 0x02,
14111 MOVE16 = 0x03,
14112 ADDI32 = 0x04,
3a1f4268
YK
14113 R6_LUI = 0x04,
14114 AUI = 0x04,
3c824109
NF
14115 LBU32 = 0x05,
14116 SB32 = 0x06,
14117 LB32 = 0x07,
14118
14119 POOL32B = 0x08,
14120 POOL16B = 0x09,
14121 LHU16 = 0x0a,
14122 ANDI16 = 0x0b,
14123 ADDIU32 = 0x0c,
14124 LHU32 = 0x0d,
14125 SH32 = 0x0e,
14126 LH32 = 0x0f,
14127
14128 POOL32I = 0x10,
14129 POOL16C = 0x11,
14130 LWSP16 = 0x12,
14131 POOL16D = 0x13,
14132 ORI32 = 0x14,
14133 POOL32F = 0x15,
211da992
CWR
14134 POOL32S = 0x16, /* MIPS64 */
14135 DADDIU32 = 0x17, /* MIPS64 */
3c824109
NF
14136
14137 POOL32C = 0x18,
14138 LWGP16 = 0x19,
14139 LW16 = 0x1a,
14140 POOL16E = 0x1b,
14141 XORI32 = 0x1c,
14142 JALS32 = 0x1d,
3a1f4268
YK
14143 BOVC = 0x1d,
14144 BEQC = 0x1d,
14145 BEQZALC = 0x1d,
3c824109 14146 ADDIUPC = 0x1e,
3a1f4268
YK
14147 PCREL = 0x1e,
14148 BNVC = 0x1f,
14149 BNEC = 0x1f,
14150 BNEZALC = 0x1f,
3c824109 14151
3a1f4268
YK
14152 R6_BEQZC = 0x20,
14153 JIC = 0x20,
3c824109
NF
14154 POOL16F = 0x21,
14155 SB16 = 0x22,
14156 BEQZ16 = 0x23,
3a1f4268 14157 BEQZC16 = 0x23,
3c824109
NF
14158 SLTI32 = 0x24,
14159 BEQ32 = 0x25,
3a1f4268 14160 BC = 0x25,
3c824109
NF
14161 SWC132 = 0x26,
14162 LWC132 = 0x27,
14163
3a1f4268 14164 /* 0x29 is reserved */
3c824109 14165 RES_29 = 0x29,
3a1f4268
YK
14166 R6_BNEZC = 0x28,
14167 JIALC = 0x28,
3c824109
NF
14168 SH16 = 0x2a,
14169 BNEZ16 = 0x2b,
3a1f4268 14170 BNEZC16 = 0x2b,
3c824109
NF
14171 SLTIU32 = 0x2c,
14172 BNE32 = 0x2d,
3a1f4268 14173 BALC = 0x2d,
3c824109
NF
14174 SDC132 = 0x2e,
14175 LDC132 = 0x2f,
14176
3a1f4268 14177 /* 0x31 is reserved */
3c824109 14178 RES_31 = 0x31,
3a1f4268
YK
14179 BLEZALC = 0x30,
14180 BGEZALC = 0x30,
14181 BGEUC = 0x30,
3c824109
NF
14182 SWSP16 = 0x32,
14183 B16 = 0x33,
3a1f4268 14184 BC16 = 0x33,
3c824109
NF
14185 ANDI32 = 0x34,
14186 J32 = 0x35,
3a1f4268
YK
14187 BGTZC = 0x35,
14188 BLTZC = 0x35,
14189 BLTC = 0x35,
211da992
CWR
14190 SD32 = 0x36, /* MIPS64 */
14191 LD32 = 0x37, /* MIPS64 */
3c824109 14192
3a1f4268 14193 /* 0x39 is reserved */
3c824109 14194 RES_39 = 0x39,
3a1f4268
YK
14195 BGTZALC = 0x38,
14196 BLTZALC = 0x38,
14197 BLTUC = 0x38,
3c824109
NF
14198 SW16 = 0x3a,
14199 LI16 = 0x3b,
14200 JALX32 = 0x3c,
14201 JAL32 = 0x3d,
3a1f4268
YK
14202 BLEZC = 0x3d,
14203 BGEZC = 0x3d,
14204 BGEC = 0x3d,
3c824109
NF
14205 SW32 = 0x3e,
14206 LW32 = 0x3f
14207};
14208
3a1f4268
YK
14209/* PCREL Instructions perform PC-Relative address calculation. bits 20..16 */
14210enum {
14211 ADDIUPC_00 = 0x00,
c38a1d52
AR
14212 ADDIUPC_01 = 0x01,
14213 ADDIUPC_02 = 0x02,
14214 ADDIUPC_03 = 0x03,
14215 ADDIUPC_04 = 0x04,
14216 ADDIUPC_05 = 0x05,
14217 ADDIUPC_06 = 0x06,
3a1f4268
YK
14218 ADDIUPC_07 = 0x07,
14219 AUIPC = 0x1e,
14220 ALUIPC = 0x1f,
14221 LWPC_08 = 0x08,
c38a1d52
AR
14222 LWPC_09 = 0x09,
14223 LWPC_0A = 0x0A,
14224 LWPC_0B = 0x0B,
14225 LWPC_0C = 0x0C,
14226 LWPC_0D = 0x0D,
14227 LWPC_0E = 0x0E,
3a1f4268
YK
14228 LWPC_0F = 0x0F,
14229};
14230
3c824109
NF
14231/* POOL32A encoding of minor opcode field */
14232
14233enum {
14234 /* These opcodes are distinguished only by bits 9..6; those bits are
14235 * what are recorded below. */
14236 SLL32 = 0x0,
14237 SRL32 = 0x1,
14238 SRA = 0x2,
14239 ROTR = 0x3,
3a1f4268
YK
14240 SELEQZ = 0x5,
14241 SELNEZ = 0x6,
b00c7218 14242 R6_RDHWR = 0x7,
3c824109
NF
14243
14244 SLLV = 0x0,
14245 SRLV = 0x1,
14246 SRAV = 0x2,
14247 ROTRV = 0x3,
14248 ADD = 0x4,
14249 ADDU32 = 0x5,
14250 SUB = 0x6,
14251 SUBU32 = 0x7,
14252 MUL = 0x8,
14253 AND = 0x9,
14254 OR32 = 0xa,
14255 NOR = 0xb,
14256 XOR32 = 0xc,
14257 SLT = 0xd,
14258 SLTU = 0xe,
14259
14260 MOVN = 0x0,
3a1f4268 14261 R6_MUL = 0x0,
3c824109 14262 MOVZ = 0x1,
3a1f4268
YK
14263 MUH = 0x1,
14264 MULU = 0x2,
14265 MUHU = 0x3,
3c824109 14266 LWXS = 0x4,
3a1f4268
YK
14267 R6_DIV = 0x4,
14268 MOD = 0x5,
14269 R6_DIVU = 0x6,
14270 MODU = 0x7,
3c824109
NF
14271
14272 /* The following can be distinguished by their lower 6 bits. */
dbd8af98 14273 BREAK32 = 0x07,
3c824109 14274 INS = 0x0c,
3a1f4268
YK
14275 LSA = 0x0f,
14276 ALIGN = 0x1f,
3c824109 14277 EXT = 0x2c,
bb238210
YK
14278 POOL32AXF = 0x3c,
14279 SIGRIE = 0x3f
3c824109
NF
14280};
14281
14282/* POOL32AXF encoding of minor opcode field extension */
14283
d132c79f
CWR
14284/*
14285 * 1. MIPS Architecture for Programmers Volume II-B:
14286 * The microMIPS32 Instruction Set (Revision 3.05)
14287 *
14288 * Table 6.5 POOL32Axf Encoding of Minor Opcode Extension Field
14289 *
14290 * 2. MIPS Architecture for Programmers VolumeIV-e:
14291 * The MIPS DSP Application-Specific Extension
14292 * to the microMIPS32 Architecture (Revision 2.34)
14293 *
14294 * Table 5.5 POOL32Axf Encoding of Minor Opcode Extension Field
14295 */
14296
3c824109
NF
14297enum {
14298 /* bits 11..6 */
14299 TEQ = 0x00,
14300 TGE = 0x08,
14301 TGEU = 0x10,
14302 TLT = 0x20,
14303 TLTU = 0x28,
14304 TNE = 0x30,
14305
14306 MFC0 = 0x03,
14307 MTC0 = 0x0b,
14308
d132c79f
CWR
14309 /* begin of microMIPS32 DSP */
14310
3c824109
NF
14311 /* bits 13..12 for 0x01 */
14312 MFHI_ACC = 0x0,
14313 MFLO_ACC = 0x1,
14314 MTHI_ACC = 0x2,
14315 MTLO_ACC = 0x3,
14316
14317 /* bits 13..12 for 0x2a */
14318 MADD_ACC = 0x0,
14319 MADDU_ACC = 0x1,
14320 MSUB_ACC = 0x2,
14321 MSUBU_ACC = 0x3,
14322
14323 /* bits 13..12 for 0x32 */
14324 MULT_ACC = 0x0,
6801038b 14325 MULTU_ACC = 0x1,
3c824109 14326
d132c79f
CWR
14327 /* end of microMIPS32 DSP */
14328
3c824109 14329 /* bits 15..12 for 0x2c */
3a1f4268 14330 BITSWAP = 0x0,
3c824109
NF
14331 SEB = 0x2,
14332 SEH = 0x3,
14333 CLO = 0x4,
14334 CLZ = 0x5,
14335 RDHWR = 0x6,
14336 WSBH = 0x7,
14337 MULT = 0x8,
14338 MULTU = 0x9,
14339 DIV = 0xa,
14340 DIVU = 0xb,
14341 MADD = 0xc,
14342 MADDU = 0xd,
14343 MSUB = 0xe,
14344 MSUBU = 0xf,
14345
14346 /* bits 15..12 for 0x34 */
14347 MFC2 = 0x4,
14348 MTC2 = 0x5,
14349 MFHC2 = 0x8,
14350 MTHC2 = 0x9,
14351 CFC2 = 0xc,
14352 CTC2 = 0xd,
14353
14354 /* bits 15..12 for 0x3c */
14355 JALR = 0x0,
14356 JR = 0x0, /* alias */
3a1f4268
YK
14357 JALRC = 0x0,
14358 JRC = 0x0,
3c824109 14359 JALR_HB = 0x1,
3a1f4268 14360 JALRC_HB = 0x1,
3c824109
NF
14361 JALRS = 0x4,
14362 JALRS_HB = 0x5,
14363
14364 /* bits 15..12 for 0x05 */
14365 RDPGPR = 0xe,
14366 WRPGPR = 0xf,
14367
14368 /* bits 15..12 for 0x0d */
14369 TLBP = 0x0,
14370 TLBR = 0x1,
14371 TLBWI = 0x2,
14372 TLBWR = 0x3,
e60ec063
YK
14373 TLBINV = 0x4,
14374 TLBINVF = 0x5,
3c824109
NF
14375 WAIT = 0x9,
14376 IRET = 0xd,
14377 DERET = 0xe,
14378 ERET = 0xf,
14379
14380 /* bits 15..12 for 0x15 */
14381 DMT = 0x0,
14382 DVPE = 0x1,
14383 EMT = 0x2,
14384 EVPE = 0x3,
14385
14386 /* bits 15..12 for 0x1d */
14387 DI = 0x4,
14388 EI = 0x5,
14389
14390 /* bits 15..12 for 0x2d */
14391 SYNC = 0x6,
14392 SYSCALL = 0x8,
14393 SDBBP = 0xd,
14394
14395 /* bits 15..12 for 0x35 */
14396 MFHI32 = 0x0,
14397 MFLO32 = 0x1,
14398 MTHI32 = 0x2,
14399 MTLO32 = 0x3,
14400};
14401
14402/* POOL32B encoding of minor opcode field (bits 15..12) */
14403
14404enum {
14405 LWC2 = 0x0,
14406 LWP = 0x1,
14407 LDP = 0x4,
14408 LWM32 = 0x5,
14409 CACHE = 0x6,
14410 LDM = 0x7,
14411 SWC2 = 0x8,
14412 SWP = 0x9,
14413 SDP = 0xc,
14414 SWM32 = 0xd,
14415 SDM = 0xf
14416};
14417
14418/* POOL32C encoding of minor opcode field (bits 15..12) */
14419
14420enum {
14421 LWL = 0x0,
14422 SWL = 0x8,
14423 LWR = 0x1,
14424 SWR = 0x9,
14425 PREF = 0x2,
8fffc646 14426 ST_EVA = 0xa,
3c824109
NF
14427 LL = 0x3,
14428 SC = 0xb,
14429 LDL = 0x4,
14430 SDL = 0xc,
14431 LDR = 0x5,
14432 SDR = 0xd,
8fffc646 14433 LD_EVA = 0x6,
3c824109
NF
14434 LWU = 0xe,
14435 LLD = 0x7,
14436 SCD = 0xf
14437};
14438
8fffc646
JH
14439/* POOL32C LD-EVA encoding of minor opcode field (bits 11..9) */
14440
14441enum {
14442 LBUE = 0x0,
14443 LHUE = 0x1,
14444 LWLE = 0x2,
14445 LWRE = 0x3,
14446 LBE = 0x4,
14447 LHE = 0x5,
14448 LLE = 0x6,
14449 LWE = 0x7,
14450};
14451
14452/* POOL32C ST-EVA encoding of minor opcode field (bits 11..9) */
14453
14454enum {
14455 SWLE = 0x0,
14456 SWRE = 0x1,
14457 PREFE = 0x2,
14458 CACHEE = 0x3,
14459 SBE = 0x4,
14460 SHE = 0x5,
14461 SCE = 0x6,
14462 SWE = 0x7,
14463};
14464
3c824109
NF
14465/* POOL32F encoding of minor opcode field (bits 5..0) */
14466
14467enum {
14468 /* These are the bit 7..6 values */
14469 ADD_FMT = 0x0,
3c824109
NF
14470
14471 SUB_FMT = 0x1,
3c824109
NF
14472
14473 MUL_FMT = 0x2,
14474
14475 DIV_FMT = 0x3,
14476
14477 /* These are the bit 8..6 values */
3a1f4268 14478 MOVN_FMT = 0x0,
3c824109
NF
14479 RSQRT2_FMT = 0x0,
14480 MOVF_FMT = 0x0,
3a1f4268
YK
14481 RINT_FMT = 0x0,
14482 SELNEZ_FMT = 0x0,
3c824109 14483
3a1f4268 14484 MOVZ_FMT = 0x1,
3c824109
NF
14485 LWXC1 = 0x1,
14486 MOVT_FMT = 0x1,
3a1f4268
YK
14487 CLASS_FMT = 0x1,
14488 SELEQZ_FMT = 0x1,
3c824109
NF
14489
14490 PLL_PS = 0x2,
14491 SWXC1 = 0x2,
3a1f4268 14492 SEL_FMT = 0x2,
3c824109
NF
14493
14494 PLU_PS = 0x3,
14495 LDXC1 = 0x3,
14496
3a1f4268 14497 MOVN_FMT_04 = 0x4,
3c824109
NF
14498 PUL_PS = 0x4,
14499 SDXC1 = 0x4,
14500 RECIP2_FMT = 0x4,
14501
3a1f4268 14502 MOVZ_FMT_05 = 0x05,
3c824109
NF
14503 PUU_PS = 0x5,
14504 LUXC1 = 0x5,
14505
14506 CVT_PS_S = 0x6,
14507 SUXC1 = 0x6,
14508 ADDR_PS = 0x6,
14509 PREFX = 0x6,
3a1f4268 14510 MADDF_FMT = 0x6,
3c824109
NF
14511
14512 MULR_PS = 0x7,
3a1f4268 14513 MSUBF_FMT = 0x7,
3c824109
NF
14514
14515 MADD_S = 0x01,
14516 MADD_D = 0x09,
14517 MADD_PS = 0x11,
14518 ALNV_PS = 0x19,
14519 MSUB_S = 0x21,
14520 MSUB_D = 0x29,
14521 MSUB_PS = 0x31,
14522
14523 NMADD_S = 0x02,
14524 NMADD_D = 0x0a,
14525 NMADD_PS = 0x12,
14526 NMSUB_S = 0x22,
14527 NMSUB_D = 0x2a,
14528 NMSUB_PS = 0x32,
14529
3a1f4268
YK
14530 MIN_FMT = 0x3,
14531 MAX_FMT = 0xb,
14532 MINA_FMT = 0x23,
14533 MAXA_FMT = 0x2b,
3c824109
NF
14534 POOL32FXF = 0x3b,
14535
14536 CABS_COND_FMT = 0x1c, /* MIPS3D */
3a1f4268
YK
14537 C_COND_FMT = 0x3c,
14538
14539 CMP_CONDN_S = 0x5,
14540 CMP_CONDN_D = 0x15
3c824109
NF
14541};
14542
14543/* POOL32Fxf encoding of minor opcode extension field */
14544
14545enum {
14546 CVT_L = 0x04,
14547 RSQRT_FMT = 0x08,
14548 FLOOR_L = 0x0c,
14549 CVT_PW_PS = 0x1c,
14550 CVT_W = 0x24,
14551 SQRT_FMT = 0x28,
14552 FLOOR_W = 0x2c,
14553 CVT_PS_PW = 0x3c,
14554 CFC1 = 0x40,
14555 RECIP_FMT = 0x48,
14556 CEIL_L = 0x4c,
14557 CTC1 = 0x60,
14558 CEIL_W = 0x6c,
14559 MFC1 = 0x80,
14560 CVT_S_PL = 0x84,
14561 TRUNC_L = 0x8c,
14562 MTC1 = 0xa0,
14563 CVT_S_PU = 0xa4,
14564 TRUNC_W = 0xac,
14565 MFHC1 = 0xc0,
14566 ROUND_L = 0xcc,
14567 MTHC1 = 0xe0,
14568 ROUND_W = 0xec,
14569
14570 MOV_FMT = 0x01,
14571 MOVF = 0x05,
14572 ABS_FMT = 0x0d,
14573 RSQRT1_FMT = 0x1d,
14574 MOVT = 0x25,
14575 NEG_FMT = 0x2d,
14576 CVT_D = 0x4d,
14577 RECIP1_FMT = 0x5d,
14578 CVT_S = 0x6d
14579};
14580
14581/* POOL32I encoding of minor opcode field (bits 25..21) */
14582
14583enum {
14584 BLTZ = 0x00,
14585 BLTZAL = 0x01,
14586 BGEZ = 0x02,
14587 BGEZAL = 0x03,
14588 BLEZ = 0x04,
14589 BNEZC = 0x05,
14590 BGTZ = 0x06,
14591 BEQZC = 0x07,
14592 TLTI = 0x08,
3a1f4268 14593 BC1EQZC = 0x08,
3c824109 14594 TGEI = 0x09,
3a1f4268 14595 BC1NEZC = 0x09,
3c824109 14596 TLTIU = 0x0a,
3a1f4268 14597 BC2EQZC = 0x0a,
3c824109 14598 TGEIU = 0x0b,
3a1f4268 14599 BC2NEZC = 0x0a,
3c824109 14600 TNEI = 0x0c,
3a1f4268 14601 R6_SYNCI = 0x0c,
3c824109
NF
14602 LUI = 0x0d,
14603 TEQI = 0x0e,
14604 SYNCI = 0x10,
14605 BLTZALS = 0x11,
14606 BGEZALS = 0x13,
14607 BC2F = 0x14,
14608 BC2T = 0x15,
14609 BPOSGE64 = 0x1a,
14610 BPOSGE32 = 0x1b,
14611 /* These overlap and are distinguished by bit16 of the instruction */
14612 BC1F = 0x1c,
14613 BC1T = 0x1d,
14614 BC1ANY2F = 0x1c,
14615 BC1ANY2T = 0x1d,
14616 BC1ANY4F = 0x1e,
14617 BC1ANY4T = 0x1f
14618};
14619
14620/* POOL16A encoding of minor opcode field */
14621
14622enum {
14623 ADDU16 = 0x0,
14624 SUBU16 = 0x1
14625};
14626
14627/* POOL16B encoding of minor opcode field */
14628
14629enum {
14630 SLL16 = 0x0,
14631 SRL16 = 0x1
14632};
14633
14634/* POOL16C encoding of minor opcode field */
14635
14636enum {
14637 NOT16 = 0x00,
14638 XOR16 = 0x04,
14639 AND16 = 0x08,
14640 OR16 = 0x0c,
14641 LWM16 = 0x10,
14642 SWM16 = 0x14,
14643 JR16 = 0x18,
14644 JRC16 = 0x1a,
14645 JALR16 = 0x1c,
14646 JALR16S = 0x1e,
14647 MFHI16 = 0x20,
14648 MFLO16 = 0x24,
14649 BREAK16 = 0x28,
14650 SDBBP16 = 0x2c,
14651 JRADDIUSP = 0x30
14652};
14653
3a1f4268
YK
14654/* R6 POOL16C encoding of minor opcode field (bits 0..5) */
14655
14656enum {
14657 R6_NOT16 = 0x00,
14658 R6_AND16 = 0x01,
14659 R6_LWM16 = 0x02,
14660 R6_JRC16 = 0x03,
14661 MOVEP = 0x04,
c38a1d52
AR
14662 MOVEP_05 = 0x05,
14663 MOVEP_06 = 0x06,
3a1f4268
YK
14664 MOVEP_07 = 0x07,
14665 R6_XOR16 = 0x08,
14666 R6_OR16 = 0x09,
14667 R6_SWM16 = 0x0a,
14668 JALRC16 = 0x0b,
14669 MOVEP_0C = 0x0c,
c38a1d52
AR
14670 MOVEP_0D = 0x0d,
14671 MOVEP_0E = 0x0e,
3a1f4268
YK
14672 MOVEP_0F = 0x0f,
14673 JRCADDIUSP = 0x13,
14674 R6_BREAK16 = 0x1b,
14675 R6_SDBBP16 = 0x3b
14676};
14677
3c824109
NF
14678/* POOL16D encoding of minor opcode field */
14679
14680enum {
14681 ADDIUS5 = 0x0,
14682 ADDIUSP = 0x1
14683};
14684
14685/* POOL16E encoding of minor opcode field */
14686
14687enum {
14688 ADDIUR2 = 0x0,
14689 ADDIUR1SP = 0x1
14690};
14691
14692static int mmreg (int r)
14693{
14694 static const int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
14695
14696 return map[r];
14697}
14698
14699/* Used for 16-bit store instructions. */
14700static int mmreg2 (int r)
14701{
14702 static const int map[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
14703
14704 return map[r];
14705}
14706
14707#define uMIPS_RD(op) ((op >> 7) & 0x7)
14708#define uMIPS_RS(op) ((op >> 4) & 0x7)
14709#define uMIPS_RS2(op) uMIPS_RS(op)
14710#define uMIPS_RS1(op) ((op >> 1) & 0x7)
14711#define uMIPS_RD5(op) ((op >> 5) & 0x1f)
14712#define uMIPS_RS5(op) (op & 0x1f)
14713
14714/* Signed immediate */
14715#define SIMM(op, start, width) \
14716 ((int32_t)(((op >> start) & ((~0U) >> (32-width))) \
14717 << (32-width)) \
14718 >> (32-width))
14719/* Zero-extended immediate */
14720#define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
14721
d75c135e 14722static void gen_addiur1sp(DisasContext *ctx)
3c824109
NF
14723{
14724 int rd = mmreg(uMIPS_RD(ctx->opcode));
14725
d75c135e 14726 gen_arith_imm(ctx, OPC_ADDIU, rd, 29, ((ctx->opcode >> 1) & 0x3f) << 2);
3c824109
NF
14727}
14728
d75c135e 14729static void gen_addiur2(DisasContext *ctx)
3c824109
NF
14730{
14731 static const int decoded_imm[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
14732 int rd = mmreg(uMIPS_RD(ctx->opcode));
14733 int rs = mmreg(uMIPS_RS(ctx->opcode));
14734
d75c135e 14735 gen_arith_imm(ctx, OPC_ADDIU, rd, rs, decoded_imm[ZIMM(ctx->opcode, 1, 3)]);
3c824109
NF
14736}
14737
d75c135e 14738static void gen_addiusp(DisasContext *ctx)
3c824109
NF
14739{
14740 int encoded = ZIMM(ctx->opcode, 1, 9);
14741 int decoded;
14742
14743 if (encoded <= 1) {
14744 decoded = 256 + encoded;
14745 } else if (encoded <= 255) {
14746 decoded = encoded;
14747 } else if (encoded <= 509) {
14748 decoded = encoded - 512;
14749 } else {
14750 decoded = encoded - 768;
14751 }
14752
d75c135e 14753 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, decoded << 2);
3c824109
NF
14754}
14755
d75c135e 14756static void gen_addius5(DisasContext *ctx)
3c824109
NF
14757{
14758 int imm = SIMM(ctx->opcode, 1, 4);
14759 int rd = (ctx->opcode >> 5) & 0x1f;
14760
d75c135e 14761 gen_arith_imm(ctx, OPC_ADDIU, rd, rd, imm);
3c824109
NF
14762}
14763
d75c135e 14764static void gen_andi16(DisasContext *ctx)
3c824109
NF
14765{
14766 static const int decoded_imm[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
14767 31, 32, 63, 64, 255, 32768, 65535 };
14768 int rd = mmreg(uMIPS_RD(ctx->opcode));
14769 int rs = mmreg(uMIPS_RS(ctx->opcode));
14770 int encoded = ZIMM(ctx->opcode, 0, 4);
14771
d75c135e 14772 gen_logic_imm(ctx, OPC_ANDI, rd, rs, decoded_imm[encoded]);
3c824109
NF
14773}
14774
14775static void gen_ldst_multiple (DisasContext *ctx, uint32_t opc, int reglist,
14776 int base, int16_t offset)
14777{
14778 TCGv t0, t1;
14779 TCGv_i32 t2;
14780
14781 if (ctx->hflags & MIPS_HFLAG_BMASK) {
9c708c7f 14782 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
14783 return;
14784 }
14785
14786 t0 = tcg_temp_new();
14787
14788 gen_base_offset_addr(ctx, t0, base, offset);
14789
14790 t1 = tcg_const_tl(reglist);
14791 t2 = tcg_const_i32(ctx->mem_idx);
6af0bf9c 14792
3c824109
NF
14793 save_cpu_state(ctx, 1);
14794 switch (opc) {
14795 case LWM32:
895c2d04 14796 gen_helper_lwm(cpu_env, t0, t1, t2);
3c824109
NF
14797 break;
14798 case SWM32:
895c2d04 14799 gen_helper_swm(cpu_env, t0, t1, t2);
3c824109
NF
14800 break;
14801#ifdef TARGET_MIPS64
14802 case LDM:
895c2d04 14803 gen_helper_ldm(cpu_env, t0, t1, t2);
3c824109
NF
14804 break;
14805 case SDM:
895c2d04 14806 gen_helper_sdm(cpu_env, t0, t1, t2);
3c824109 14807 break;
6af0bf9c 14808#endif
3c824109 14809 }
3c824109 14810 tcg_temp_free(t0);
33087598 14811 tcg_temp_free(t1);
3c824109
NF
14812 tcg_temp_free_i32(t2);
14813}
6af0bf9c 14814
3c824109 14815
240ce26a 14816static void gen_pool16c_insn(DisasContext *ctx)
6af0bf9c 14817{
3c824109
NF
14818 int rd = mmreg((ctx->opcode >> 3) & 0x7);
14819 int rs = mmreg(ctx->opcode & 0x7);
6af0bf9c 14820
3c824109
NF
14821 switch (((ctx->opcode) >> 4) & 0x3f) {
14822 case NOT16 + 0:
14823 case NOT16 + 1:
14824 case NOT16 + 2:
14825 case NOT16 + 3:
d75c135e 14826 gen_logic(ctx, OPC_NOR, rd, rs, 0);
3c824109
NF
14827 break;
14828 case XOR16 + 0:
14829 case XOR16 + 1:
14830 case XOR16 + 2:
14831 case XOR16 + 3:
d75c135e 14832 gen_logic(ctx, OPC_XOR, rd, rd, rs);
3c824109
NF
14833 break;
14834 case AND16 + 0:
14835 case AND16 + 1:
14836 case AND16 + 2:
14837 case AND16 + 3:
d75c135e 14838 gen_logic(ctx, OPC_AND, rd, rd, rs);
3c824109
NF
14839 break;
14840 case OR16 + 0:
14841 case OR16 + 1:
14842 case OR16 + 2:
14843 case OR16 + 3:
d75c135e 14844 gen_logic(ctx, OPC_OR, rd, rd, rs);
3c824109
NF
14845 break;
14846 case LWM16 + 0:
14847 case LWM16 + 1:
14848 case LWM16 + 2:
14849 case LWM16 + 3:
14850 {
14851 static const int lwm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
14852 int offset = ZIMM(ctx->opcode, 0, 4);
14853
14854 gen_ldst_multiple(ctx, LWM32, lwm_convert[(ctx->opcode >> 4) & 0x3],
14855 29, offset << 2);
14856 }
14857 break;
14858 case SWM16 + 0:
14859 case SWM16 + 1:
14860 case SWM16 + 2:
14861 case SWM16 + 3:
14862 {
14863 static const int swm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
14864 int offset = ZIMM(ctx->opcode, 0, 4);
14865
14866 gen_ldst_multiple(ctx, SWM32, swm_convert[(ctx->opcode >> 4) & 0x3],
14867 29, offset << 2);
14868 }
14869 break;
14870 case JR16 + 0:
14871 case JR16 + 1:
14872 {
14873 int reg = ctx->opcode & 0x1f;
14874
b231c103 14875 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 4);
3c824109 14876 }
3c824109
NF
14877 break;
14878 case JRC16 + 0:
14879 case JRC16 + 1:
14880 {
14881 int reg = ctx->opcode & 0x1f;
b231c103 14882 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 0);
3c824109
NF
14883 /* Let normal delay slot handling in our caller take us
14884 to the branch target. */
14885 }
14886 break;
14887 case JALR16 + 0:
14888 case JALR16 + 1:
b231c103
YK
14889 gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 4);
14890 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14891 break;
3c824109
NF
14892 case JALR16S + 0:
14893 case JALR16S + 1:
b231c103
YK
14894 gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 2);
14895 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
3c824109
NF
14896 break;
14897 case MFHI16 + 0:
14898 case MFHI16 + 1:
26135ead 14899 gen_HILO(ctx, OPC_MFHI, 0, uMIPS_RS5(ctx->opcode));
3c824109
NF
14900 break;
14901 case MFLO16 + 0:
14902 case MFLO16 + 1:
26135ead 14903 gen_HILO(ctx, OPC_MFLO, 0, uMIPS_RS5(ctx->opcode));
3c824109
NF
14904 break;
14905 case BREAK16:
9c708c7f 14906 generate_exception_end(ctx, EXCP_BREAK);
3c824109
NF
14907 break;
14908 case SDBBP16:
3b3c1694
LA
14909 if (is_uhi(extract32(ctx->opcode, 0, 4))) {
14910 gen_helper_do_semihosting(cpu_env);
14911 } else {
14912 /* XXX: not clear which exception should be raised
14913 * when in debug mode...
14914 */
14915 check_insn(ctx, ISA_MIPS32);
9c708c7f 14916 generate_exception_end(ctx, EXCP_DBp);
3b3c1694 14917 }
3c824109
NF
14918 break;
14919 case JRADDIUSP + 0:
14920 case JRADDIUSP + 1:
14921 {
14922 int imm = ZIMM(ctx->opcode, 0, 5);
b231c103 14923 gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0, 0);
d75c135e 14924 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
3c824109
NF
14925 /* Let normal delay slot handling in our caller take us
14926 to the branch target. */
14927 }
14928 break;
14929 default:
9c708c7f 14930 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
14931 break;
14932 }
14933}
14934
ed7ce6c0
YK
14935static inline void gen_movep(DisasContext *ctx, int enc_dest, int enc_rt,
14936 int enc_rs)
14937{
14938 int rd, rs, re, rt;
14939 static const int rd_enc[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
14940 static const int re_enc[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
14941 static const int rs_rt_enc[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
14942 rd = rd_enc[enc_dest];
14943 re = re_enc[enc_dest];
14944 rs = rs_rt_enc[enc_rs];
14945 rt = rs_rt_enc[enc_rt];
14946 if (rs) {
14947 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
14948 } else {
14949 tcg_gen_movi_tl(cpu_gpr[rd], 0);
14950 }
14951 if (rt) {
14952 tcg_gen_mov_tl(cpu_gpr[re], cpu_gpr[rt]);
14953 } else {
14954 tcg_gen_movi_tl(cpu_gpr[re], 0);
14955 }
14956}
14957
14958static void gen_pool16c_r6_insn(DisasContext *ctx)
14959{
14960 int rt = mmreg((ctx->opcode >> 7) & 0x7);
14961 int rs = mmreg((ctx->opcode >> 4) & 0x7);
14962
14963 switch (ctx->opcode & 0xf) {
14964 case R6_NOT16:
14965 gen_logic(ctx, OPC_NOR, rt, rs, 0);
14966 break;
14967 case R6_AND16:
14968 gen_logic(ctx, OPC_AND, rt, rt, rs);
14969 break;
14970 case R6_LWM16:
14971 {
14972 int lwm_converted = 0x11 + extract32(ctx->opcode, 8, 2);
14973 int offset = extract32(ctx->opcode, 4, 4);
14974 gen_ldst_multiple(ctx, LWM32, lwm_converted, 29, offset << 2);
14975 }
14976 break;
14977 case R6_JRC16: /* JRCADDIUSP */
14978 if ((ctx->opcode >> 4) & 1) {
14979 /* JRCADDIUSP */
14980 int imm = extract32(ctx->opcode, 5, 5);
14981 gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0, 0);
14982 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
14983 } else {
14984 /* JRC16 */
e1555d7d 14985 rs = extract32(ctx->opcode, 5, 5);
ed7ce6c0
YK
14986 gen_compute_branch(ctx, OPC_JR, 2, rs, 0, 0, 0);
14987 }
14988 break;
c38a1d52
AR
14989 case MOVEP:
14990 case MOVEP_05:
14991 case MOVEP_06:
14992 case MOVEP_07:
14993 case MOVEP_0C:
14994 case MOVEP_0D:
14995 case MOVEP_0E:
14996 case MOVEP_0F:
ed7ce6c0
YK
14997 {
14998 int enc_dest = uMIPS_RD(ctx->opcode);
14999 int enc_rt = uMIPS_RS2(ctx->opcode);
15000 int enc_rs = (ctx->opcode & 3) | ((ctx->opcode >> 1) & 4);
15001 gen_movep(ctx, enc_dest, enc_rt, enc_rs);
15002 }
15003 break;
15004 case R6_XOR16:
15005 gen_logic(ctx, OPC_XOR, rt, rt, rs);
15006 break;
15007 case R6_OR16:
15008 gen_logic(ctx, OPC_OR, rt, rt, rs);
15009 break;
15010 case R6_SWM16:
15011 {
15012 int swm_converted = 0x11 + extract32(ctx->opcode, 8, 2);
15013 int offset = extract32(ctx->opcode, 4, 4);
15014 gen_ldst_multiple(ctx, SWM32, swm_converted, 29, offset << 2);
15015 }
15016 break;
15017 case JALRC16: /* BREAK16, SDBBP16 */
15018 switch (ctx->opcode & 0x3f) {
15019 case JALRC16:
15020 case JALRC16 + 0x20:
15021 /* JALRC16 */
15022 gen_compute_branch(ctx, OPC_JALR, 2, (ctx->opcode >> 5) & 0x1f,
15023 31, 0, 0);
15024 break;
15025 case R6_BREAK16:
15026 /* BREAK16 */
15027 generate_exception(ctx, EXCP_BREAK);
15028 break;
15029 case R6_SDBBP16:
15030 /* SDBBP16 */
060ebfef
LA
15031 if (is_uhi(extract32(ctx->opcode, 6, 4))) {
15032 gen_helper_do_semihosting(cpu_env);
ed7ce6c0 15033 } else {
060ebfef
LA
15034 if (ctx->hflags & MIPS_HFLAG_SBRI) {
15035 generate_exception(ctx, EXCP_RI);
15036 } else {
15037 generate_exception(ctx, EXCP_DBp);
15038 }
ed7ce6c0
YK
15039 }
15040 break;
15041 }
15042 break;
15043 default:
15044 generate_exception(ctx, EXCP_RI);
15045 break;
15046 }
15047}
15048
3c824109
NF
15049static void gen_ldxs (DisasContext *ctx, int base, int index, int rd)
15050{
15051 TCGv t0 = tcg_temp_new();
15052 TCGv t1 = tcg_temp_new();
15053
15054 gen_load_gpr(t0, base);
15055
15056 if (index != 0) {
15057 gen_load_gpr(t1, index);
15058 tcg_gen_shli_tl(t1, t1, 2);
15059 gen_op_addr_add(ctx, t0, t1, t0);
15060 }
15061
5f68f5ae 15062 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
3c824109
NF
15063 gen_store_gpr(t1, rd);
15064
15065 tcg_temp_free(t0);
15066 tcg_temp_free(t1);
15067}
15068
15069static void gen_ldst_pair (DisasContext *ctx, uint32_t opc, int rd,
15070 int base, int16_t offset)
15071{
3c824109
NF
15072 TCGv t0, t1;
15073
36c6711b 15074 if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31) {
9c708c7f 15075 generate_exception_end(ctx, EXCP_RI);
d796321b
FB
15076 return;
15077 }
15078
3c824109
NF
15079 t0 = tcg_temp_new();
15080 t1 = tcg_temp_new();
8e9ade68 15081
3c824109
NF
15082 gen_base_offset_addr(ctx, t0, base, offset);
15083
15084 switch (opc) {
15085 case LWP:
36c6711b 15086 if (rd == base) {
9c708c7f 15087 generate_exception_end(ctx, EXCP_RI);
36c6711b
EJ
15088 return;
15089 }
5f68f5ae 15090 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
3c824109
NF
15091 gen_store_gpr(t1, rd);
15092 tcg_gen_movi_tl(t1, 4);
15093 gen_op_addr_add(ctx, t0, t0, t1);
5f68f5ae 15094 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
3c824109 15095 gen_store_gpr(t1, rd+1);
3c824109
NF
15096 break;
15097 case SWP:
3c824109 15098 gen_load_gpr(t1, rd);
5f68f5ae 15099 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
3c824109
NF
15100 tcg_gen_movi_tl(t1, 4);
15101 gen_op_addr_add(ctx, t0, t0, t1);
15102 gen_load_gpr(t1, rd+1);
5f68f5ae 15103 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
3c824109
NF
15104 break;
15105#ifdef TARGET_MIPS64
15106 case LDP:
36c6711b 15107 if (rd == base) {
9c708c7f 15108 generate_exception_end(ctx, EXCP_RI);
36c6711b
EJ
15109 return;
15110 }
5f68f5ae 15111 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
3c824109
NF
15112 gen_store_gpr(t1, rd);
15113 tcg_gen_movi_tl(t1, 8);
15114 gen_op_addr_add(ctx, t0, t0, t1);
5f68f5ae 15115 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
3c824109 15116 gen_store_gpr(t1, rd+1);
3c824109
NF
15117 break;
15118 case SDP:
3c824109 15119 gen_load_gpr(t1, rd);
5f68f5ae 15120 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
3c824109
NF
15121 tcg_gen_movi_tl(t1, 8);
15122 gen_op_addr_add(ctx, t0, t0, t1);
15123 gen_load_gpr(t1, rd+1);
5f68f5ae 15124 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
3c824109
NF
15125 break;
15126#endif
6af0bf9c 15127 }
3c824109
NF
15128 tcg_temp_free(t0);
15129 tcg_temp_free(t1);
15130}
618b0fe9 15131
d208ac0c
LA
15132static void gen_sync(int stype)
15133{
15134 TCGBar tcg_mo = TCG_BAR_SC;
15135
15136 switch (stype) {
15137 case 0x4: /* SYNC_WMB */
15138 tcg_mo |= TCG_MO_ST_ST;
15139 break;
15140 case 0x10: /* SYNC_MB */
15141 tcg_mo |= TCG_MO_ALL;
15142 break;
15143 case 0x11: /* SYNC_ACQUIRE */
15144 tcg_mo |= TCG_MO_LD_LD | TCG_MO_LD_ST;
15145 break;
15146 case 0x12: /* SYNC_RELEASE */
15147 tcg_mo |= TCG_MO_ST_ST | TCG_MO_LD_ST;
15148 break;
15149 case 0x13: /* SYNC_RMB */
15150 tcg_mo |= TCG_MO_LD_LD;
15151 break;
15152 default:
15153 tcg_mo |= TCG_MO_ALL;
15154 break;
15155 }
15156
15157 tcg_gen_mb(tcg_mo);
15158}
15159
240ce26a 15160static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
3c824109
NF
15161{
15162 int extension = (ctx->opcode >> 6) & 0x3f;
15163 int minor = (ctx->opcode >> 12) & 0xf;
15164 uint32_t mips32_op;
15165
15166 switch (extension) {
15167 case TEQ:
15168 mips32_op = OPC_TEQ;
15169 goto do_trap;
15170 case TGE:
15171 mips32_op = OPC_TGE;
15172 goto do_trap;
15173 case TGEU:
15174 mips32_op = OPC_TGEU;
15175 goto do_trap;
15176 case TLT:
15177 mips32_op = OPC_TLT;
15178 goto do_trap;
15179 case TLTU:
15180 mips32_op = OPC_TLTU;
15181 goto do_trap;
15182 case TNE:
15183 mips32_op = OPC_TNE;
15184 do_trap:
15185 gen_trap(ctx, mips32_op, rs, rt, -1);
15186 break;
15187#ifndef CONFIG_USER_ONLY
15188 case MFC0:
15189 case MFC0 + 32:
2e15497c 15190 check_cp0_enabled(ctx);
3c824109
NF
15191 if (rt == 0) {
15192 /* Treat as NOP. */
15193 break;
15194 }
d75c135e 15195 gen_mfc0(ctx, cpu_gpr[rt], rs, (ctx->opcode >> 11) & 0x7);
3c824109
NF
15196 break;
15197 case MTC0:
15198 case MTC0 + 32:
2e15497c 15199 check_cp0_enabled(ctx);
3c824109
NF
15200 {
15201 TCGv t0 = tcg_temp_new();
618b0fe9 15202
3c824109 15203 gen_load_gpr(t0, rt);
d75c135e 15204 gen_mtc0(ctx, t0, rs, (ctx->opcode >> 11) & 0x7);
3c824109
NF
15205 tcg_temp_free(t0);
15206 }
15207 break;
15208#endif
a1fc6246
LA
15209 case 0x2a:
15210 switch (minor & 3) {
15211 case MADD_ACC:
15212 gen_muldiv(ctx, OPC_MADD, (ctx->opcode >> 14) & 3, rs, rt);
15213 break;
15214 case MADDU_ACC:
15215 gen_muldiv(ctx, OPC_MADDU, (ctx->opcode >> 14) & 3, rs, rt);
15216 break;
15217 case MSUB_ACC:
15218 gen_muldiv(ctx, OPC_MSUB, (ctx->opcode >> 14) & 3, rs, rt);
15219 break;
15220 case MSUBU_ACC:
15221 gen_muldiv(ctx, OPC_MSUBU, (ctx->opcode >> 14) & 3, rs, rt);
15222 break;
15223 default:
15224 goto pool32axf_invalid;
15225 }
15226 break;
15227 case 0x32:
15228 switch (minor & 3) {
15229 case MULT_ACC:
15230 gen_muldiv(ctx, OPC_MULT, (ctx->opcode >> 14) & 3, rs, rt);
15231 break;
15232 case MULTU_ACC:
15233 gen_muldiv(ctx, OPC_MULTU, (ctx->opcode >> 14) & 3, rs, rt);
15234 break;
15235 default:
15236 goto pool32axf_invalid;
15237 }
15238 break;
3c824109
NF
15239 case 0x2c:
15240 switch (minor) {
e0332095
YK
15241 case BITSWAP:
15242 check_insn(ctx, ISA_MIPS32R6);
15243 gen_bitswap(ctx, OPC_BITSWAP, rs, rt);
15244 break;
3c824109
NF
15245 case SEB:
15246 gen_bshfl(ctx, OPC_SEB, rs, rt);
15247 break;
15248 case SEH:
15249 gen_bshfl(ctx, OPC_SEH, rs, rt);
15250 break;
15251 case CLO:
15252 mips32_op = OPC_CLO;
15253 goto do_cl;
15254 case CLZ:
15255 mips32_op = OPC_CLZ;
15256 do_cl:
d75c135e 15257 check_insn(ctx, ISA_MIPS32);
3c824109
NF
15258 gen_cl(ctx, mips32_op, rt, rs);
15259 break;
15260 case RDHWR:
b00c7218
YK
15261 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15262 gen_rdhwr(ctx, rt, rs, 0);
3c824109
NF
15263 break;
15264 case WSBH:
15265 gen_bshfl(ctx, OPC_WSBH, rs, rt);
15266 break;
15267 case MULT:
9e8f441a 15268 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 15269 mips32_op = OPC_MULT;
26135ead 15270 goto do_mul;
3c824109 15271 case MULTU:
9e8f441a 15272 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 15273 mips32_op = OPC_MULTU;
26135ead 15274 goto do_mul;
3c824109 15275 case DIV:
9e8f441a 15276 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 15277 mips32_op = OPC_DIV;
26135ead 15278 goto do_div;
3c824109 15279 case DIVU:
9e8f441a 15280 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 15281 mips32_op = OPC_DIVU;
26135ead
RS
15282 goto do_div;
15283 do_div:
15284 check_insn(ctx, ISA_MIPS32);
15285 gen_muldiv(ctx, mips32_op, 0, rs, rt);
15286 break;
3c824109 15287 case MADD:
9e8f441a 15288 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 15289 mips32_op = OPC_MADD;
26135ead 15290 goto do_mul;
3c824109 15291 case MADDU:
9e8f441a 15292 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 15293 mips32_op = OPC_MADDU;
26135ead 15294 goto do_mul;
3c824109 15295 case MSUB:
9e8f441a 15296 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 15297 mips32_op = OPC_MSUB;
26135ead 15298 goto do_mul;
3c824109 15299 case MSUBU:
9e8f441a 15300 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 15301 mips32_op = OPC_MSUBU;
26135ead 15302 do_mul:
d75c135e 15303 check_insn(ctx, ISA_MIPS32);
a1fc6246 15304 gen_muldiv(ctx, mips32_op, 0, rs, rt);
3c824109
NF
15305 break;
15306 default:
15307 goto pool32axf_invalid;
15308 }
15309 break;
15310 case 0x34:
15311 switch (minor) {
15312 case MFC2:
15313 case MTC2:
15314 case MFHC2:
15315 case MTHC2:
15316 case CFC2:
15317 case CTC2:
15318 generate_exception_err(ctx, EXCP_CpU, 2);
15319 break;
15320 default:
15321 goto pool32axf_invalid;
15322 }
15323 break;
15324 case 0x3c:
15325 switch (minor) {
65935f07
YK
15326 case JALR: /* JALRC */
15327 case JALR_HB: /* JALRC_HB */
15328 if (ctx->insn_flags & ISA_MIPS32R6) {
15329 /* JALRC, JALRC_HB */
15330 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 0);
15331 } else {
15332 /* JALR, JALR_HB */
15333 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 4);
15334 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
15335 }
3c824109
NF
15336 break;
15337 case JALRS:
15338 case JALRS_HB:
9e8f441a 15339 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
15340 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 2);
15341 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
3c824109
NF
15342 break;
15343 default:
15344 goto pool32axf_invalid;
15345 }
15346 break;
15347 case 0x05:
15348 switch (minor) {
15349 case RDPGPR:
2e15497c 15350 check_cp0_enabled(ctx);
d75c135e 15351 check_insn(ctx, ISA_MIPS32R2);
1bf5902d 15352 gen_load_srsgpr(rs, rt);
3c824109
NF
15353 break;
15354 case WRPGPR:
2e15497c 15355 check_cp0_enabled(ctx);
d75c135e 15356 check_insn(ctx, ISA_MIPS32R2);
1bf5902d 15357 gen_store_srsgpr(rs, rt);
3c824109
NF
15358 break;
15359 default:
15360 goto pool32axf_invalid;
15361 }
15362 break;
15363#ifndef CONFIG_USER_ONLY
15364 case 0x0d:
15365 switch (minor) {
15366 case TLBP:
15367 mips32_op = OPC_TLBP;
15368 goto do_cp0;
15369 case TLBR:
15370 mips32_op = OPC_TLBR;
15371 goto do_cp0;
15372 case TLBWI:
15373 mips32_op = OPC_TLBWI;
15374 goto do_cp0;
15375 case TLBWR:
15376 mips32_op = OPC_TLBWR;
15377 goto do_cp0;
e60ec063
YK
15378 case TLBINV:
15379 mips32_op = OPC_TLBINV;
15380 goto do_cp0;
15381 case TLBINVF:
15382 mips32_op = OPC_TLBINVF;
15383 goto do_cp0;
3c824109
NF
15384 case WAIT:
15385 mips32_op = OPC_WAIT;
15386 goto do_cp0;
15387 case DERET:
15388 mips32_op = OPC_DERET;
15389 goto do_cp0;
15390 case ERET:
15391 mips32_op = OPC_ERET;
15392 do_cp0:
15393 gen_cp0(env, ctx, mips32_op, rt, rs);
15394 break;
15395 default:
15396 goto pool32axf_invalid;
15397 }
15398 break;
15399 case 0x1d:
15400 switch (minor) {
15401 case DI:
2e15497c 15402 check_cp0_enabled(ctx);
3c824109
NF
15403 {
15404 TCGv t0 = tcg_temp_new();
15405
15406 save_cpu_state(ctx, 1);
895c2d04 15407 gen_helper_di(t0, cpu_env);
3c824109
NF
15408 gen_store_gpr(t0, rs);
15409 /* Stop translation as we may have switched the execution mode */
eeb3bba8 15410 ctx->base.is_jmp = DISAS_STOP;
3c824109
NF
15411 tcg_temp_free(t0);
15412 }
15413 break;
15414 case EI:
2e15497c 15415 check_cp0_enabled(ctx);
3c824109
NF
15416 {
15417 TCGv t0 = tcg_temp_new();
15418
15419 save_cpu_state(ctx, 1);
895c2d04 15420 gen_helper_ei(t0, cpu_env);
3c824109 15421 gen_store_gpr(t0, rs);
b28425ba 15422 /* DISAS_STOP isn't sufficient, we need to ensure we break out
b74cddcb 15423 of translated code to check for pending interrupts. */
eeb3bba8
EC
15424 gen_save_pc(ctx->base.pc_next + 4);
15425 ctx->base.is_jmp = DISAS_EXIT;
3c824109
NF
15426 tcg_temp_free(t0);
15427 }
15428 break;
15429 default:
15430 goto pool32axf_invalid;
15431 }
15432 break;
15433#endif
15434 case 0x2d:
15435 switch (minor) {
15436 case SYNC:
d208ac0c 15437 gen_sync(extract32(ctx->opcode, 16, 5));
3c824109
NF
15438 break;
15439 case SYSCALL:
9c708c7f 15440 generate_exception_end(ctx, EXCP_SYSCALL);
3c824109
NF
15441 break;
15442 case SDBBP:
3b3c1694
LA
15443 if (is_uhi(extract32(ctx->opcode, 16, 10))) {
15444 gen_helper_do_semihosting(cpu_env);
15445 } else {
15446 check_insn(ctx, ISA_MIPS32);
e0332095 15447 if (ctx->hflags & MIPS_HFLAG_SBRI) {
9c708c7f 15448 generate_exception_end(ctx, EXCP_RI);
e0332095 15449 } else {
9c708c7f 15450 generate_exception_end(ctx, EXCP_DBp);
e0332095 15451 }
3b3c1694 15452 }
3c824109
NF
15453 break;
15454 default:
15455 goto pool32axf_invalid;
15456 }
15457 break;
a1fc6246 15458 case 0x01:
26135ead 15459 switch (minor & 3) {
a1fc6246 15460 case MFHI_ACC:
26135ead 15461 gen_HILO(ctx, OPC_MFHI, minor >> 2, rs);
3c824109 15462 break;
a1fc6246 15463 case MFLO_ACC:
26135ead 15464 gen_HILO(ctx, OPC_MFLO, minor >> 2, rs);
3c824109 15465 break;
a1fc6246 15466 case MTHI_ACC:
26135ead 15467 gen_HILO(ctx, OPC_MTHI, minor >> 2, rs);
3c824109 15468 break;
a1fc6246 15469 case MTLO_ACC:
26135ead 15470 gen_HILO(ctx, OPC_MTLO, minor >> 2, rs);
3c824109
NF
15471 break;
15472 default:
15473 goto pool32axf_invalid;
15474 }
15475 break;
a1fc6246 15476 case 0x35:
9e8f441a 15477 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a1fc6246
LA
15478 switch (minor) {
15479 case MFHI32:
15480 gen_HILO(ctx, OPC_MFHI, 0, rs);
15481 break;
15482 case MFLO32:
15483 gen_HILO(ctx, OPC_MFLO, 0, rs);
15484 break;
15485 case MTHI32:
15486 gen_HILO(ctx, OPC_MTHI, 0, rs);
15487 break;
15488 case MTLO32:
15489 gen_HILO(ctx, OPC_MTLO, 0, rs);
15490 break;
15491 default:
15492 goto pool32axf_invalid;
15493 }
15494 break;
3c824109
NF
15495 default:
15496 pool32axf_invalid:
15497 MIPS_INVAL("pool32axf");
9c708c7f 15498 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
15499 break;
15500 }
15501}
15502
15503/* Values for microMIPS fmt field. Variable-width, depending on which
15504 formats the instruction supports. */
15505
15506enum {
15507 FMT_SD_S = 0,
15508 FMT_SD_D = 1,
15509
15510 FMT_SDPS_S = 0,
15511 FMT_SDPS_D = 1,
15512 FMT_SDPS_PS = 2,
15513
15514 FMT_SWL_S = 0,
15515 FMT_SWL_W = 1,
15516 FMT_SWL_L = 2,
15517
15518 FMT_DWL_D = 0,
15519 FMT_DWL_W = 1,
15520 FMT_DWL_L = 2
15521};
15522
d75c135e 15523static void gen_pool32fxf(DisasContext *ctx, int rt, int rs)
3c824109
NF
15524{
15525 int extension = (ctx->opcode >> 6) & 0x3ff;
15526 uint32_t mips32_op;
15527
15528#define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
15529#define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
15530#define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
15531
15532 switch (extension) {
15533 case FLOAT_1BIT_FMT(CFC1, 0):
15534 mips32_op = OPC_CFC1;
15535 goto do_cp1;
15536 case FLOAT_1BIT_FMT(CTC1, 0):
15537 mips32_op = OPC_CTC1;
15538 goto do_cp1;
15539 case FLOAT_1BIT_FMT(MFC1, 0):
15540 mips32_op = OPC_MFC1;
15541 goto do_cp1;
15542 case FLOAT_1BIT_FMT(MTC1, 0):
15543 mips32_op = OPC_MTC1;
15544 goto do_cp1;
15545 case FLOAT_1BIT_FMT(MFHC1, 0):
15546 mips32_op = OPC_MFHC1;
15547 goto do_cp1;
15548 case FLOAT_1BIT_FMT(MTHC1, 0):
15549 mips32_op = OPC_MTHC1;
15550 do_cp1:
15551 gen_cp1(ctx, mips32_op, rt, rs);
15552 break;
15553
15554 /* Reciprocal square root */
15555 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_S):
15556 mips32_op = OPC_RSQRT_S;
15557 goto do_unaryfp;
15558 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_D):
15559 mips32_op = OPC_RSQRT_D;
15560 goto do_unaryfp;
15561
15562 /* Square root */
15563 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_S):
15564 mips32_op = OPC_SQRT_S;
15565 goto do_unaryfp;
15566 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_D):
15567 mips32_op = OPC_SQRT_D;
15568 goto do_unaryfp;
15569
15570 /* Reciprocal */
15571 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_S):
15572 mips32_op = OPC_RECIP_S;
15573 goto do_unaryfp;
15574 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_D):
15575 mips32_op = OPC_RECIP_D;
15576 goto do_unaryfp;
15577
15578 /* Floor */
15579 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_S):
15580 mips32_op = OPC_FLOOR_L_S;
15581 goto do_unaryfp;
15582 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_D):
15583 mips32_op = OPC_FLOOR_L_D;
15584 goto do_unaryfp;
15585 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_S):
15586 mips32_op = OPC_FLOOR_W_S;
15587 goto do_unaryfp;
15588 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_D):
15589 mips32_op = OPC_FLOOR_W_D;
15590 goto do_unaryfp;
15591
15592 /* Ceiling */
15593 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_S):
15594 mips32_op = OPC_CEIL_L_S;
15595 goto do_unaryfp;
15596 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_D):
15597 mips32_op = OPC_CEIL_L_D;
15598 goto do_unaryfp;
15599 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_S):
15600 mips32_op = OPC_CEIL_W_S;
15601 goto do_unaryfp;
15602 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_D):
15603 mips32_op = OPC_CEIL_W_D;
15604 goto do_unaryfp;
15605
15606 /* Truncation */
15607 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_S):
15608 mips32_op = OPC_TRUNC_L_S;
15609 goto do_unaryfp;
15610 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_D):
15611 mips32_op = OPC_TRUNC_L_D;
15612 goto do_unaryfp;
15613 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_S):
15614 mips32_op = OPC_TRUNC_W_S;
15615 goto do_unaryfp;
15616 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_D):
15617 mips32_op = OPC_TRUNC_W_D;
15618 goto do_unaryfp;
15619
15620 /* Round */
15621 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_S):
15622 mips32_op = OPC_ROUND_L_S;
15623 goto do_unaryfp;
15624 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_D):
15625 mips32_op = OPC_ROUND_L_D;
15626 goto do_unaryfp;
15627 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_S):
15628 mips32_op = OPC_ROUND_W_S;
15629 goto do_unaryfp;
15630 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_D):
15631 mips32_op = OPC_ROUND_W_D;
15632 goto do_unaryfp;
15633
15634 /* Integer to floating-point conversion */
15635 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_S):
15636 mips32_op = OPC_CVT_L_S;
15637 goto do_unaryfp;
15638 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_D):
15639 mips32_op = OPC_CVT_L_D;
15640 goto do_unaryfp;
15641 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_S):
15642 mips32_op = OPC_CVT_W_S;
15643 goto do_unaryfp;
15644 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_D):
15645 mips32_op = OPC_CVT_W_D;
15646 goto do_unaryfp;
15647
15648 /* Paired-foo conversions */
15649 case FLOAT_1BIT_FMT(CVT_S_PL, 0):
15650 mips32_op = OPC_CVT_S_PL;
15651 goto do_unaryfp;
15652 case FLOAT_1BIT_FMT(CVT_S_PU, 0):
15653 mips32_op = OPC_CVT_S_PU;
15654 goto do_unaryfp;
15655 case FLOAT_1BIT_FMT(CVT_PW_PS, 0):
15656 mips32_op = OPC_CVT_PW_PS;
15657 goto do_unaryfp;
15658 case FLOAT_1BIT_FMT(CVT_PS_PW, 0):
15659 mips32_op = OPC_CVT_PS_PW;
15660 goto do_unaryfp;
15661
15662 /* Floating-point moves */
15663 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_S):
15664 mips32_op = OPC_MOV_S;
15665 goto do_unaryfp;
15666 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_D):
15667 mips32_op = OPC_MOV_D;
15668 goto do_unaryfp;
15669 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_PS):
15670 mips32_op = OPC_MOV_PS;
15671 goto do_unaryfp;
15672
15673 /* Absolute value */
15674 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_S):
15675 mips32_op = OPC_ABS_S;
15676 goto do_unaryfp;
15677 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_D):
15678 mips32_op = OPC_ABS_D;
15679 goto do_unaryfp;
15680 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_PS):
15681 mips32_op = OPC_ABS_PS;
15682 goto do_unaryfp;
15683
15684 /* Negation */
15685 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_S):
15686 mips32_op = OPC_NEG_S;
15687 goto do_unaryfp;
15688 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_D):
15689 mips32_op = OPC_NEG_D;
15690 goto do_unaryfp;
15691 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_PS):
15692 mips32_op = OPC_NEG_PS;
15693 goto do_unaryfp;
15694
15695 /* Reciprocal square root step */
15696 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_S):
15697 mips32_op = OPC_RSQRT1_S;
15698 goto do_unaryfp;
15699 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_D):
15700 mips32_op = OPC_RSQRT1_D;
15701 goto do_unaryfp;
15702 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_PS):
15703 mips32_op = OPC_RSQRT1_PS;
15704 goto do_unaryfp;
15705
15706 /* Reciprocal step */
15707 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_S):
15708 mips32_op = OPC_RECIP1_S;
15709 goto do_unaryfp;
15710 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_D):
15711 mips32_op = OPC_RECIP1_S;
15712 goto do_unaryfp;
15713 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_PS):
15714 mips32_op = OPC_RECIP1_PS;
15715 goto do_unaryfp;
15716
15717 /* Conversions from double */
15718 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_S):
15719 mips32_op = OPC_CVT_D_S;
15720 goto do_unaryfp;
15721 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_W):
15722 mips32_op = OPC_CVT_D_W;
15723 goto do_unaryfp;
15724 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_L):
15725 mips32_op = OPC_CVT_D_L;
15726 goto do_unaryfp;
15727
15728 /* Conversions from single */
15729 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_D):
15730 mips32_op = OPC_CVT_S_D;
15731 goto do_unaryfp;
15732 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_W):
15733 mips32_op = OPC_CVT_S_W;
15734 goto do_unaryfp;
15735 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_L):
15736 mips32_op = OPC_CVT_S_L;
15737 do_unaryfp:
15738 gen_farith(ctx, mips32_op, -1, rs, rt, 0);
15739 break;
15740
15741 /* Conditional moves on floating-point codes */
15742 case COND_FLOAT_MOV(MOVT, 0):
15743 case COND_FLOAT_MOV(MOVT, 1):
15744 case COND_FLOAT_MOV(MOVT, 2):
15745 case COND_FLOAT_MOV(MOVT, 3):
15746 case COND_FLOAT_MOV(MOVT, 4):
15747 case COND_FLOAT_MOV(MOVT, 5):
15748 case COND_FLOAT_MOV(MOVT, 6):
15749 case COND_FLOAT_MOV(MOVT, 7):
9e8f441a 15750 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
15751 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 1);
15752 break;
15753 case COND_FLOAT_MOV(MOVF, 0):
15754 case COND_FLOAT_MOV(MOVF, 1):
15755 case COND_FLOAT_MOV(MOVF, 2):
15756 case COND_FLOAT_MOV(MOVF, 3):
15757 case COND_FLOAT_MOV(MOVF, 4):
15758 case COND_FLOAT_MOV(MOVF, 5):
15759 case COND_FLOAT_MOV(MOVF, 6):
15760 case COND_FLOAT_MOV(MOVF, 7):
9e8f441a 15761 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
15762 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 0);
15763 break;
15764 default:
15765 MIPS_INVAL("pool32fxf");
9c708c7f 15766 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
15767 break;
15768 }
15769}
15770
f60eeb0c 15771static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx)
3c824109
NF
15772{
15773 int32_t offset;
15774 uint16_t insn;
15775 int rt, rs, rd, rr;
15776 int16_t imm;
8fffc646 15777 uint32_t op, minor, minor2, mips32_op;
3c824109
NF
15778 uint32_t cond, fmt, cc;
15779
eeb3bba8 15780 insn = cpu_lduw_code(env, ctx->base.pc_next + 2);
3c824109
NF
15781 ctx->opcode = (ctx->opcode << 16) | insn;
15782
15783 rt = (ctx->opcode >> 21) & 0x1f;
15784 rs = (ctx->opcode >> 16) & 0x1f;
15785 rd = (ctx->opcode >> 11) & 0x1f;
15786 rr = (ctx->opcode >> 6) & 0x1f;
15787 imm = (int16_t) ctx->opcode;
15788
15789 op = (ctx->opcode >> 26) & 0x3f;
15790 switch (op) {
15791 case POOL32A:
15792 minor = ctx->opcode & 0x3f;
15793 switch (minor) {
15794 case 0x00:
15795 minor = (ctx->opcode >> 6) & 0xf;
15796 switch (minor) {
15797 case SLL32:
15798 mips32_op = OPC_SLL;
15799 goto do_shifti;
15800 case SRA:
15801 mips32_op = OPC_SRA;
15802 goto do_shifti;
15803 case SRL32:
15804 mips32_op = OPC_SRL;
15805 goto do_shifti;
15806 case ROTR:
15807 mips32_op = OPC_ROTR;
15808 do_shifti:
d75c135e 15809 gen_shift_imm(ctx, mips32_op, rt, rs, rd);
3c824109 15810 break;
e0332095
YK
15811 case SELEQZ:
15812 check_insn(ctx, ISA_MIPS32R6);
15813 gen_cond_move(ctx, OPC_SELEQZ, rd, rs, rt);
15814 break;
15815 case SELNEZ:
15816 check_insn(ctx, ISA_MIPS32R6);
15817 gen_cond_move(ctx, OPC_SELNEZ, rd, rs, rt);
15818 break;
b00c7218
YK
15819 case R6_RDHWR:
15820 check_insn(ctx, ISA_MIPS32R6);
15821 gen_rdhwr(ctx, rt, rs, extract32(ctx->opcode, 11, 3));
15822 break;
3c824109
NF
15823 default:
15824 goto pool32a_invalid;
15825 }
15826 break;
15827 case 0x10:
15828 minor = (ctx->opcode >> 6) & 0xf;
15829 switch (minor) {
15830 /* Arithmetic */
15831 case ADD:
15832 mips32_op = OPC_ADD;
15833 goto do_arith;
15834 case ADDU32:
15835 mips32_op = OPC_ADDU;
15836 goto do_arith;
15837 case SUB:
15838 mips32_op = OPC_SUB;
15839 goto do_arith;
15840 case SUBU32:
15841 mips32_op = OPC_SUBU;
15842 goto do_arith;
15843 case MUL:
9e8f441a 15844 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
15845 mips32_op = OPC_MUL;
15846 do_arith:
d75c135e 15847 gen_arith(ctx, mips32_op, rd, rs, rt);
3c824109
NF
15848 break;
15849 /* Shifts */
15850 case SLLV:
15851 mips32_op = OPC_SLLV;
15852 goto do_shift;
15853 case SRLV:
15854 mips32_op = OPC_SRLV;
15855 goto do_shift;
15856 case SRAV:
15857 mips32_op = OPC_SRAV;
15858 goto do_shift;
15859 case ROTRV:
15860 mips32_op = OPC_ROTRV;
15861 do_shift:
d75c135e 15862 gen_shift(ctx, mips32_op, rd, rs, rt);
3c824109
NF
15863 break;
15864 /* Logical operations */
15865 case AND:
15866 mips32_op = OPC_AND;
15867 goto do_logic;
15868 case OR32:
15869 mips32_op = OPC_OR;
15870 goto do_logic;
15871 case NOR:
15872 mips32_op = OPC_NOR;
15873 goto do_logic;
15874 case XOR32:
15875 mips32_op = OPC_XOR;
15876 do_logic:
d75c135e 15877 gen_logic(ctx, mips32_op, rd, rs, rt);
3c824109
NF
15878 break;
15879 /* Set less than */
15880 case SLT:
15881 mips32_op = OPC_SLT;
15882 goto do_slt;
15883 case SLTU:
15884 mips32_op = OPC_SLTU;
15885 do_slt:
d75c135e 15886 gen_slt(ctx, mips32_op, rd, rs, rt);
3c824109
NF
15887 break;
15888 default:
15889 goto pool32a_invalid;
15890 }
15891 break;
15892 case 0x18:
15893 minor = (ctx->opcode >> 6) & 0xf;
15894 switch (minor) {
15895 /* Conditional moves */
e0332095
YK
15896 case MOVN: /* MUL */
15897 if (ctx->insn_flags & ISA_MIPS32R6) {
15898 /* MUL */
15899 gen_r6_muldiv(ctx, R6_OPC_MUL, rd, rs, rt);
15900 } else {
15901 /* MOVN */
15902 gen_cond_move(ctx, OPC_MOVN, rd, rs, rt);
15903 }
15904 break;
15905 case MOVZ: /* MUH */
15906 if (ctx->insn_flags & ISA_MIPS32R6) {
15907 /* MUH */
15908 gen_r6_muldiv(ctx, R6_OPC_MUH, rd, rs, rt);
15909 } else {
15910 /* MOVZ */
15911 gen_cond_move(ctx, OPC_MOVZ, rd, rs, rt);
15912 }
15913 break;
15914 case MULU:
15915 check_insn(ctx, ISA_MIPS32R6);
15916 gen_r6_muldiv(ctx, R6_OPC_MULU, rd, rs, rt);
15917 break;
15918 case MUHU:
15919 check_insn(ctx, ISA_MIPS32R6);
15920 gen_r6_muldiv(ctx, R6_OPC_MUHU, rd, rs, rt);
15921 break;
15922 case LWXS: /* DIV */
15923 if (ctx->insn_flags & ISA_MIPS32R6) {
15924 /* DIV */
15925 gen_r6_muldiv(ctx, R6_OPC_DIV, rd, rs, rt);
15926 } else {
15927 /* LWXS */
15928 gen_ldxs(ctx, rs, rt, rd);
15929 }
15930 break;
15931 case MOD:
15932 check_insn(ctx, ISA_MIPS32R6);
15933 gen_r6_muldiv(ctx, R6_OPC_MOD, rd, rs, rt);
15934 break;
15935 case R6_DIVU:
15936 check_insn(ctx, ISA_MIPS32R6);
15937 gen_r6_muldiv(ctx, R6_OPC_DIVU, rd, rs, rt);
3c824109 15938 break;
e0332095
YK
15939 case MODU:
15940 check_insn(ctx, ISA_MIPS32R6);
15941 gen_r6_muldiv(ctx, R6_OPC_MODU, rd, rs, rt);
3c824109
NF
15942 break;
15943 default:
15944 goto pool32a_invalid;
15945 }
15946 break;
15947 case INS:
15948 gen_bitops(ctx, OPC_INS, rt, rs, rr, rd);
15949 return;
e0332095
YK
15950 case LSA:
15951 check_insn(ctx, ISA_MIPS32R6);
15952 gen_lsa(ctx, OPC_LSA, rd, rs, rt,
15953 extract32(ctx->opcode, 9, 2));
15954 break;
15955 case ALIGN:
15956 check_insn(ctx, ISA_MIPS32R6);
821f2008 15957 gen_align(ctx, 32, rd, rs, rt, extract32(ctx->opcode, 9, 2));
e0332095 15958 break;
3c824109
NF
15959 case EXT:
15960 gen_bitops(ctx, OPC_EXT, rt, rs, rr, rd);
15961 return;
15962 case POOL32AXF:
240ce26a 15963 gen_pool32axf(env, ctx, rt, rs);
3c824109 15964 break;
dbd8af98 15965 case BREAK32:
9c708c7f 15966 generate_exception_end(ctx, EXCP_BREAK);
3c824109 15967 break;
bb238210
YK
15968 case SIGRIE:
15969 check_insn(ctx, ISA_MIPS32R6);
15970 generate_exception_end(ctx, EXCP_RI);
15971 break;
3c824109
NF
15972 default:
15973 pool32a_invalid:
15974 MIPS_INVAL("pool32a");
9c708c7f 15975 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
15976 break;
15977 }
15978 break;
15979 case POOL32B:
15980 minor = (ctx->opcode >> 12) & 0xf;
15981 switch (minor) {
15982 case CACHE:
2e15497c 15983 check_cp0_enabled(ctx);
0d74a222
LA
15984 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
15985 gen_cache_operation(ctx, rt, rs, imm);
15986 }
3c824109
NF
15987 break;
15988 case LWC2:
15989 case SWC2:
15990 /* COP2: Not implemented. */
15991 generate_exception_err(ctx, EXCP_CpU, 2);
15992 break;
3c824109
NF
15993#ifdef TARGET_MIPS64
15994 case LDP:
15995 case SDP:
d9224450
MR
15996 check_insn(ctx, ISA_MIPS3);
15997 check_mips_64(ctx);
3c824109 15998#endif
146dd620 15999 /* fall through */
d9224450
MR
16000 case LWP:
16001 case SWP:
3c824109
NF
16002 gen_ldst_pair(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
16003 break;
3c824109
NF
16004#ifdef TARGET_MIPS64
16005 case LDM:
16006 case SDM:
d9224450
MR
16007 check_insn(ctx, ISA_MIPS3);
16008 check_mips_64(ctx);
3c824109 16009#endif
146dd620 16010 /* fall through */
d9224450
MR
16011 case LWM32:
16012 case SWM32:
3c824109
NF
16013 gen_ldst_multiple(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
16014 break;
16015 default:
16016 MIPS_INVAL("pool32b");
9c708c7f 16017 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
16018 break;
16019 }
16020 break;
16021 case POOL32F:
5ab5c041 16022 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
3c824109
NF
16023 minor = ctx->opcode & 0x3f;
16024 check_cp1_enabled(ctx);
16025 switch (minor) {
16026 case ALNV_PS:
9e8f441a 16027 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
16028 mips32_op = OPC_ALNV_PS;
16029 goto do_madd;
16030 case MADD_S:
9e8f441a 16031 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
16032 mips32_op = OPC_MADD_S;
16033 goto do_madd;
16034 case MADD_D:
9e8f441a 16035 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
16036 mips32_op = OPC_MADD_D;
16037 goto do_madd;
16038 case MADD_PS:
9e8f441a 16039 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
16040 mips32_op = OPC_MADD_PS;
16041 goto do_madd;
16042 case MSUB_S:
9e8f441a 16043 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
16044 mips32_op = OPC_MSUB_S;
16045 goto do_madd;
16046 case MSUB_D:
9e8f441a 16047 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
16048 mips32_op = OPC_MSUB_D;
16049 goto do_madd;
16050 case MSUB_PS:
9e8f441a 16051 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
16052 mips32_op = OPC_MSUB_PS;
16053 goto do_madd;
16054 case NMADD_S:
9e8f441a 16055 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
16056 mips32_op = OPC_NMADD_S;
16057 goto do_madd;
16058 case NMADD_D:
9e8f441a 16059 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
16060 mips32_op = OPC_NMADD_D;
16061 goto do_madd;
16062 case NMADD_PS:
9e8f441a 16063 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
16064 mips32_op = OPC_NMADD_PS;
16065 goto do_madd;
16066 case NMSUB_S:
9e8f441a 16067 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
16068 mips32_op = OPC_NMSUB_S;
16069 goto do_madd;
16070 case NMSUB_D:
9e8f441a 16071 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
16072 mips32_op = OPC_NMSUB_D;
16073 goto do_madd;
16074 case NMSUB_PS:
9e8f441a 16075 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
16076 mips32_op = OPC_NMSUB_PS;
16077 do_madd:
16078 gen_flt3_arith(ctx, mips32_op, rd, rr, rs, rt);
16079 break;
16080 case CABS_COND_FMT:
9e8f441a 16081 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
16082 cond = (ctx->opcode >> 6) & 0xf;
16083 cc = (ctx->opcode >> 13) & 0x7;
16084 fmt = (ctx->opcode >> 10) & 0x3;
16085 switch (fmt) {
16086 case 0x0:
16087 gen_cmpabs_s(ctx, cond, rt, rs, cc);
16088 break;
16089 case 0x1:
16090 gen_cmpabs_d(ctx, cond, rt, rs, cc);
16091 break;
16092 case 0x2:
16093 gen_cmpabs_ps(ctx, cond, rt, rs, cc);
16094 break;
16095 default:
16096 goto pool32f_invalid;
16097 }
16098 break;
16099 case C_COND_FMT:
9e8f441a 16100 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
16101 cond = (ctx->opcode >> 6) & 0xf;
16102 cc = (ctx->opcode >> 13) & 0x7;
16103 fmt = (ctx->opcode >> 10) & 0x3;
16104 switch (fmt) {
16105 case 0x0:
16106 gen_cmp_s(ctx, cond, rt, rs, cc);
16107 break;
16108 case 0x1:
16109 gen_cmp_d(ctx, cond, rt, rs, cc);
16110 break;
16111 case 0x2:
16112 gen_cmp_ps(ctx, cond, rt, rs, cc);
16113 break;
16114 default:
16115 goto pool32f_invalid;
16116 }
16117 break;
2a24a7ba
YK
16118 case CMP_CONDN_S:
16119 check_insn(ctx, ISA_MIPS32R6);
16120 gen_r6_cmp_s(ctx, (ctx->opcode >> 6) & 0x1f, rt, rs, rd);
16121 break;
16122 case CMP_CONDN_D:
16123 check_insn(ctx, ISA_MIPS32R6);
16124 gen_r6_cmp_d(ctx, (ctx->opcode >> 6) & 0x1f, rt, rs, rd);
16125 break;
3c824109 16126 case POOL32FXF:
d75c135e 16127 gen_pool32fxf(ctx, rt, rs);
3c824109
NF
16128 break;
16129 case 0x00:
16130 /* PLL foo */
16131 switch ((ctx->opcode >> 6) & 0x7) {
16132 case PLL_PS:
16133 mips32_op = OPC_PLL_PS;
16134 goto do_ps;
16135 case PLU_PS:
16136 mips32_op = OPC_PLU_PS;
16137 goto do_ps;
16138 case PUL_PS:
16139 mips32_op = OPC_PUL_PS;
16140 goto do_ps;
16141 case PUU_PS:
16142 mips32_op = OPC_PUU_PS;
16143 goto do_ps;
16144 case CVT_PS_S:
9e8f441a 16145 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
16146 mips32_op = OPC_CVT_PS_S;
16147 do_ps:
16148 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
16149 break;
16150 default:
16151 goto pool32f_invalid;
16152 }
16153 break;
2a24a7ba
YK
16154 case MIN_FMT:
16155 check_insn(ctx, ISA_MIPS32R6);
16156 switch ((ctx->opcode >> 9) & 0x3) {
16157 case FMT_SDPS_S:
16158 gen_farith(ctx, OPC_MIN_S, rt, rs, rd, 0);
16159 break;
16160 case FMT_SDPS_D:
16161 gen_farith(ctx, OPC_MIN_D, rt, rs, rd, 0);
16162 break;
16163 default:
16164 goto pool32f_invalid;
16165 }
16166 break;
3c824109
NF
16167 case 0x08:
16168 /* [LS][WDU]XC1 */
16169 switch ((ctx->opcode >> 6) & 0x7) {
16170 case LWXC1:
9e8f441a 16171 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
16172 mips32_op = OPC_LWXC1;
16173 goto do_ldst_cp1;
16174 case SWXC1:
9e8f441a 16175 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
16176 mips32_op = OPC_SWXC1;
16177 goto do_ldst_cp1;
16178 case LDXC1:
9e8f441a 16179 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
16180 mips32_op = OPC_LDXC1;
16181 goto do_ldst_cp1;
16182 case SDXC1:
9e8f441a 16183 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
16184 mips32_op = OPC_SDXC1;
16185 goto do_ldst_cp1;
16186 case LUXC1:
9e8f441a 16187 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
16188 mips32_op = OPC_LUXC1;
16189 goto do_ldst_cp1;
16190 case SUXC1:
9e8f441a 16191 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
16192 mips32_op = OPC_SUXC1;
16193 do_ldst_cp1:
16194 gen_flt3_ldst(ctx, mips32_op, rd, rd, rt, rs);
16195 break;
16196 default:
16197 goto pool32f_invalid;
16198 }
16199 break;
2a24a7ba
YK
16200 case MAX_FMT:
16201 check_insn(ctx, ISA_MIPS32R6);
16202 switch ((ctx->opcode >> 9) & 0x3) {
16203 case FMT_SDPS_S:
16204 gen_farith(ctx, OPC_MAX_S, rt, rs, rd, 0);
16205 break;
16206 case FMT_SDPS_D:
16207 gen_farith(ctx, OPC_MAX_D, rt, rs, rd, 0);
16208 break;
16209 default:
16210 goto pool32f_invalid;
16211 }
16212 break;
3c824109
NF
16213 case 0x18:
16214 /* 3D insns */
9e8f441a 16215 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
16216 fmt = (ctx->opcode >> 9) & 0x3;
16217 switch ((ctx->opcode >> 6) & 0x7) {
16218 case RSQRT2_FMT:
16219 switch (fmt) {
16220 case FMT_SDPS_S:
16221 mips32_op = OPC_RSQRT2_S;
16222 goto do_3d;
16223 case FMT_SDPS_D:
16224 mips32_op = OPC_RSQRT2_D;
16225 goto do_3d;
16226 case FMT_SDPS_PS:
16227 mips32_op = OPC_RSQRT2_PS;
16228 goto do_3d;
16229 default:
16230 goto pool32f_invalid;
16231 }
16232 break;
16233 case RECIP2_FMT:
16234 switch (fmt) {
16235 case FMT_SDPS_S:
16236 mips32_op = OPC_RECIP2_S;
16237 goto do_3d;
16238 case FMT_SDPS_D:
16239 mips32_op = OPC_RECIP2_D;
16240 goto do_3d;
16241 case FMT_SDPS_PS:
16242 mips32_op = OPC_RECIP2_PS;
16243 goto do_3d;
16244 default:
16245 goto pool32f_invalid;
16246 }
16247 break;
16248 case ADDR_PS:
16249 mips32_op = OPC_ADDR_PS;
16250 goto do_3d;
16251 case MULR_PS:
16252 mips32_op = OPC_MULR_PS;
16253 do_3d:
16254 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
16255 break;
16256 default:
16257 goto pool32f_invalid;
16258 }
16259 break;
16260 case 0x20:
2a24a7ba 16261 /* MOV[FT].fmt, PREFX, RINT.fmt, CLASS.fmt*/
3c824109
NF
16262 cc = (ctx->opcode >> 13) & 0x7;
16263 fmt = (ctx->opcode >> 9) & 0x3;
16264 switch ((ctx->opcode >> 6) & 0x7) {
2a24a7ba
YK
16265 case MOVF_FMT: /* RINT_FMT */
16266 if (ctx->insn_flags & ISA_MIPS32R6) {
16267 /* RINT_FMT */
16268 switch (fmt) {
16269 case FMT_SDPS_S:
16270 gen_farith(ctx, OPC_RINT_S, 0, rt, rs, 0);
16271 break;
16272 case FMT_SDPS_D:
16273 gen_farith(ctx, OPC_RINT_D, 0, rt, rs, 0);
16274 break;
16275 default:
16276 goto pool32f_invalid;
16277 }
16278 } else {
16279 /* MOVF_FMT */
16280 switch (fmt) {
16281 case FMT_SDPS_S:
16282 gen_movcf_s(ctx, rs, rt, cc, 0);
16283 break;
16284 case FMT_SDPS_D:
16285 gen_movcf_d(ctx, rs, rt, cc, 0);
16286 break;
16287 case FMT_SDPS_PS:
16288 check_ps(ctx);
16289 gen_movcf_ps(ctx, rs, rt, cc, 0);
16290 break;
16291 default:
16292 goto pool32f_invalid;
16293 }
3c824109
NF
16294 }
16295 break;
2a24a7ba
YK
16296 case MOVT_FMT: /* CLASS_FMT */
16297 if (ctx->insn_flags & ISA_MIPS32R6) {
16298 /* CLASS_FMT */
16299 switch (fmt) {
16300 case FMT_SDPS_S:
16301 gen_farith(ctx, OPC_CLASS_S, 0, rt, rs, 0);
16302 break;
16303 case FMT_SDPS_D:
16304 gen_farith(ctx, OPC_CLASS_D, 0, rt, rs, 0);
16305 break;
16306 default:
16307 goto pool32f_invalid;
16308 }
16309 } else {
16310 /* MOVT_FMT */
16311 switch (fmt) {
16312 case FMT_SDPS_S:
16313 gen_movcf_s(ctx, rs, rt, cc, 1);
16314 break;
16315 case FMT_SDPS_D:
16316 gen_movcf_d(ctx, rs, rt, cc, 1);
16317 break;
16318 case FMT_SDPS_PS:
16319 check_ps(ctx);
16320 gen_movcf_ps(ctx, rs, rt, cc, 1);
16321 break;
16322 default:
16323 goto pool32f_invalid;
16324 }
3c824109
NF
16325 }
16326 break;
16327 case PREFX:
9e8f441a 16328 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
16329 break;
16330 default:
16331 goto pool32f_invalid;
16332 }
16333 break;
16334#define FINSN_3ARG_SDPS(prfx) \
16335 switch ((ctx->opcode >> 8) & 0x3) { \
16336 case FMT_SDPS_S: \
16337 mips32_op = OPC_##prfx##_S; \
16338 goto do_fpop; \
16339 case FMT_SDPS_D: \
16340 mips32_op = OPC_##prfx##_D; \
16341 goto do_fpop; \
16342 case FMT_SDPS_PS: \
e29c9628 16343 check_ps(ctx); \
3c824109
NF
16344 mips32_op = OPC_##prfx##_PS; \
16345 goto do_fpop; \
16346 default: \
16347 goto pool32f_invalid; \
16348 }
2a24a7ba
YK
16349 case MINA_FMT:
16350 check_insn(ctx, ISA_MIPS32R6);
16351 switch ((ctx->opcode >> 9) & 0x3) {
16352 case FMT_SDPS_S:
16353 gen_farith(ctx, OPC_MINA_S, rt, rs, rd, 0);
16354 break;
16355 case FMT_SDPS_D:
16356 gen_farith(ctx, OPC_MINA_D, rt, rs, rd, 0);
16357 break;
16358 default:
16359 goto pool32f_invalid;
16360 }
16361 break;
16362 case MAXA_FMT:
16363 check_insn(ctx, ISA_MIPS32R6);
16364 switch ((ctx->opcode >> 9) & 0x3) {
16365 case FMT_SDPS_S:
16366 gen_farith(ctx, OPC_MAXA_S, rt, rs, rd, 0);
16367 break;
16368 case FMT_SDPS_D:
16369 gen_farith(ctx, OPC_MAXA_D, rt, rs, rd, 0);
16370 break;
16371 default:
16372 goto pool32f_invalid;
16373 }
16374 break;
3c824109
NF
16375 case 0x30:
16376 /* regular FP ops */
16377 switch ((ctx->opcode >> 6) & 0x3) {
16378 case ADD_FMT:
16379 FINSN_3ARG_SDPS(ADD);
16380 break;
16381 case SUB_FMT:
16382 FINSN_3ARG_SDPS(SUB);
16383 break;
16384 case MUL_FMT:
16385 FINSN_3ARG_SDPS(MUL);
16386 break;
16387 case DIV_FMT:
16388 fmt = (ctx->opcode >> 8) & 0x3;
16389 if (fmt == 1) {
16390 mips32_op = OPC_DIV_D;
16391 } else if (fmt == 0) {
16392 mips32_op = OPC_DIV_S;
16393 } else {
16394 goto pool32f_invalid;
16395 }
16396 goto do_fpop;
16397 default:
16398 goto pool32f_invalid;
16399 }
16400 break;
16401 case 0x38:
16402 /* cmovs */
2a24a7ba 16403 switch ((ctx->opcode >> 6) & 0x7) {
fdac60cd 16404 case MOVN_FMT: /* SELEQZ_FMT */
2a24a7ba 16405 if (ctx->insn_flags & ISA_MIPS32R6) {
fdac60cd 16406 /* SELEQZ_FMT */
2a24a7ba
YK
16407 switch ((ctx->opcode >> 9) & 0x3) {
16408 case FMT_SDPS_S:
fdac60cd 16409 gen_sel_s(ctx, OPC_SELEQZ_S, rd, rt, rs);
2a24a7ba
YK
16410 break;
16411 case FMT_SDPS_D:
fdac60cd 16412 gen_sel_d(ctx, OPC_SELEQZ_D, rd, rt, rs);
2a24a7ba
YK
16413 break;
16414 default:
16415 goto pool32f_invalid;
16416 }
16417 } else {
16418 /* MOVN_FMT */
16419 FINSN_3ARG_SDPS(MOVN);
16420 }
16421 break;
16422 case MOVN_FMT_04:
16423 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
16424 FINSN_3ARG_SDPS(MOVN);
16425 break;
fdac60cd 16426 case MOVZ_FMT: /* SELNEZ_FMT */
2a24a7ba 16427 if (ctx->insn_flags & ISA_MIPS32R6) {
fdac60cd 16428 /* SELNEZ_FMT */
2a24a7ba
YK
16429 switch ((ctx->opcode >> 9) & 0x3) {
16430 case FMT_SDPS_S:
fdac60cd 16431 gen_sel_s(ctx, OPC_SELNEZ_S, rd, rt, rs);
2a24a7ba
YK
16432 break;
16433 case FMT_SDPS_D:
fdac60cd 16434 gen_sel_d(ctx, OPC_SELNEZ_D, rd, rt, rs);
2a24a7ba
YK
16435 break;
16436 default:
16437 goto pool32f_invalid;
16438 }
16439 } else {
16440 /* MOVZ_FMT */
16441 FINSN_3ARG_SDPS(MOVZ);
16442 }
16443 break;
16444 case MOVZ_FMT_05:
16445 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
16446 FINSN_3ARG_SDPS(MOVZ);
16447 break;
2a24a7ba
YK
16448 case SEL_FMT:
16449 check_insn(ctx, ISA_MIPS32R6);
16450 switch ((ctx->opcode >> 9) & 0x3) {
16451 case FMT_SDPS_S:
16452 gen_sel_s(ctx, OPC_SEL_S, rd, rt, rs);
16453 break;
16454 case FMT_SDPS_D:
16455 gen_sel_d(ctx, OPC_SEL_D, rd, rt, rs);
16456 break;
16457 default:
16458 goto pool32f_invalid;
16459 }
16460 break;
16461 case MADDF_FMT:
16462 check_insn(ctx, ISA_MIPS32R6);
16463 switch ((ctx->opcode >> 9) & 0x3) {
16464 case FMT_SDPS_S:
16465 mips32_op = OPC_MADDF_S;
16466 goto do_fpop;
16467 case FMT_SDPS_D:
16468 mips32_op = OPC_MADDF_D;
16469 goto do_fpop;
16470 default:
16471 goto pool32f_invalid;
16472 }
16473 break;
16474 case MSUBF_FMT:
16475 check_insn(ctx, ISA_MIPS32R6);
16476 switch ((ctx->opcode >> 9) & 0x3) {
16477 case FMT_SDPS_S:
16478 mips32_op = OPC_MSUBF_S;
16479 goto do_fpop;
16480 case FMT_SDPS_D:
16481 mips32_op = OPC_MSUBF_D;
16482 goto do_fpop;
16483 default:
16484 goto pool32f_invalid;
16485 }
16486 break;
3c824109
NF
16487 default:
16488 goto pool32f_invalid;
16489 }
16490 break;
16491 do_fpop:
16492 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
16493 break;
16494 default:
16495 pool32f_invalid:
16496 MIPS_INVAL("pool32f");
9c708c7f 16497 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
16498 break;
16499 }
16500 } else {
16501 generate_exception_err(ctx, EXCP_CpU, 1);
16502 }
16503 break;
16504 case POOL32I:
16505 minor = (ctx->opcode >> 21) & 0x1f;
16506 switch (minor) {
16507 case BLTZ:
9e8f441a 16508 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
16509 gen_compute_branch(ctx, OPC_BLTZ, 4, rs, -1, imm << 1, 4);
16510 break;
3c824109 16511 case BLTZAL:
9e8f441a 16512 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
16513 gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 4);
16514 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16515 break;
3c824109 16516 case BLTZALS:
9e8f441a 16517 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
16518 gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 2);
16519 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16520 break;
3c824109 16521 case BGEZ:
9e8f441a 16522 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
16523 gen_compute_branch(ctx, OPC_BGEZ, 4, rs, -1, imm << 1, 4);
16524 break;
3c824109 16525 case BGEZAL:
9e8f441a 16526 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
16527 gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 4);
16528 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16529 break;
3c824109 16530 case BGEZALS:
9e8f441a 16531 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
16532 gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 2);
16533 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16534 break;
3c824109 16535 case BLEZ:
9e8f441a 16536 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
16537 gen_compute_branch(ctx, OPC_BLEZ, 4, rs, -1, imm << 1, 4);
16538 break;
3c824109 16539 case BGTZ:
9e8f441a 16540 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103 16541 gen_compute_branch(ctx, OPC_BGTZ, 4, rs, -1, imm << 1, 4);
3c824109
NF
16542 break;
16543
16544 /* Traps */
65935f07
YK
16545 case TLTI: /* BC1EQZC */
16546 if (ctx->insn_flags & ISA_MIPS32R6) {
16547 /* BC1EQZC */
16548 check_cp1_enabled(ctx);
16549 gen_compute_branch1_r6(ctx, OPC_BC1EQZ, rs, imm << 1, 0);
16550 } else {
16551 /* TLTI */
16552 mips32_op = OPC_TLTI;
16553 goto do_trapi;
16554 }
16555 break;
16556 case TGEI: /* BC1NEZC */
16557 if (ctx->insn_flags & ISA_MIPS32R6) {
16558 /* BC1NEZC */
16559 check_cp1_enabled(ctx);
16560 gen_compute_branch1_r6(ctx, OPC_BC1NEZ, rs, imm << 1, 0);
16561 } else {
16562 /* TGEI */
16563 mips32_op = OPC_TGEI;
16564 goto do_trapi;
16565 }
16566 break;
3c824109 16567 case TLTIU:
9e8f441a 16568 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
16569 mips32_op = OPC_TLTIU;
16570 goto do_trapi;
16571 case TGEIU:
9e8f441a 16572 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
16573 mips32_op = OPC_TGEIU;
16574 goto do_trapi;
3b4a5489
YK
16575 case TNEI: /* SYNCI */
16576 if (ctx->insn_flags & ISA_MIPS32R6) {
16577 /* SYNCI */
16578 /* Break the TB to be able to sync copied instructions
16579 immediately */
eeb3bba8 16580 ctx->base.is_jmp = DISAS_STOP;
3b4a5489
YK
16581 } else {
16582 /* TNEI */
16583 mips32_op = OPC_TNEI;
16584 goto do_trapi;
16585 }
16586 break;
3c824109 16587 case TEQI:
9e8f441a 16588 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
16589 mips32_op = OPC_TEQI;
16590 do_trapi:
16591 gen_trap(ctx, mips32_op, rs, -1, imm);
16592 break;
16593
16594 case BNEZC:
16595 case BEQZC:
9e8f441a 16596 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 16597 gen_compute_branch(ctx, minor == BNEZC ? OPC_BNE : OPC_BEQ,
b231c103 16598 4, rs, 0, imm << 1, 0);
3c824109
NF
16599 /* Compact branches don't have a delay slot, so just let
16600 the normal delay slot handling take us to the branch
16601 target. */
16602 break;
16603 case LUI:
9e8f441a 16604 check_insn_opc_removed(ctx, ISA_MIPS32R6);
5e88759a 16605 gen_logic_imm(ctx, OPC_LUI, rs, 0, imm);
3c824109
NF
16606 break;
16607 case SYNCI:
9e8f441a 16608 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a83bddd6
DZ
16609 /* Break the TB to be able to sync copied instructions
16610 immediately */
eeb3bba8 16611 ctx->base.is_jmp = DISAS_STOP;
3c824109
NF
16612 break;
16613 case BC2F:
16614 case BC2T:
9e8f441a 16615 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
16616 /* COP2: Not implemented. */
16617 generate_exception_err(ctx, EXCP_CpU, 2);
16618 break;
16619 case BC1F:
9e8f441a 16620 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
16621 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1FANY2 : OPC_BC1F;
16622 goto do_cp1branch;
16623 case BC1T:
9e8f441a 16624 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
16625 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1TANY2 : OPC_BC1T;
16626 goto do_cp1branch;
16627 case BC1ANY4F:
9e8f441a 16628 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
16629 mips32_op = OPC_BC1FANY4;
16630 goto do_cp1mips3d;
16631 case BC1ANY4T:
9e8f441a 16632 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
16633 mips32_op = OPC_BC1TANY4;
16634 do_cp1mips3d:
16635 check_cop1x(ctx);
d75c135e 16636 check_insn(ctx, ASE_MIPS3D);
3c824109
NF
16637 /* Fall through */
16638 do_cp1branch:
272f458d
MR
16639 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
16640 check_cp1_enabled(ctx);
16641 gen_compute_branch1(ctx, mips32_op,
16642 (ctx->opcode >> 18) & 0x7, imm << 1);
16643 } else {
16644 generate_exception_err(ctx, EXCP_CpU, 1);
16645 }
3c824109
NF
16646 break;
16647 case BPOSGE64:
16648 case BPOSGE32:
16649 /* MIPS DSP: not implemented */
16650 /* Fall through */
16651 default:
16652 MIPS_INVAL("pool32i");
9c708c7f 16653 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
16654 break;
16655 }
16656 break;
16657 case POOL32C:
16658 minor = (ctx->opcode >> 12) & 0xf;
3b4a5489
YK
16659 offset = sextract32(ctx->opcode, 0,
16660 (ctx->insn_flags & ISA_MIPS32R6) ? 9 : 12);
3c824109
NF
16661 switch (minor) {
16662 case LWL:
9e8f441a 16663 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 16664 mips32_op = OPC_LWL;
5c13fdfd 16665 goto do_ld_lr;
3c824109 16666 case SWL:
9e8f441a 16667 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 16668 mips32_op = OPC_SWL;
5c13fdfd 16669 goto do_st_lr;
3c824109 16670 case LWR:
9e8f441a 16671 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 16672 mips32_op = OPC_LWR;
5c13fdfd 16673 goto do_ld_lr;
3c824109 16674 case SWR:
9e8f441a 16675 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 16676 mips32_op = OPC_SWR;
5c13fdfd 16677 goto do_st_lr;
3c824109
NF
16678#if defined(TARGET_MIPS64)
16679 case LDL:
d9224450
MR
16680 check_insn(ctx, ISA_MIPS3);
16681 check_mips_64(ctx);
9e8f441a 16682 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 16683 mips32_op = OPC_LDL;
5c13fdfd 16684 goto do_ld_lr;
3c824109 16685 case SDL:
d9224450
MR
16686 check_insn(ctx, ISA_MIPS3);
16687 check_mips_64(ctx);
9e8f441a 16688 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 16689 mips32_op = OPC_SDL;
5c13fdfd 16690 goto do_st_lr;
3c824109 16691 case LDR:
d9224450
MR
16692 check_insn(ctx, ISA_MIPS3);
16693 check_mips_64(ctx);
9e8f441a 16694 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 16695 mips32_op = OPC_LDR;
5c13fdfd 16696 goto do_ld_lr;
3c824109 16697 case SDR:
d9224450
MR
16698 check_insn(ctx, ISA_MIPS3);
16699 check_mips_64(ctx);
9e8f441a 16700 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 16701 mips32_op = OPC_SDR;
5c13fdfd 16702 goto do_st_lr;
3c824109 16703 case LWU:
d9224450
MR
16704 check_insn(ctx, ISA_MIPS3);
16705 check_mips_64(ctx);
3c824109 16706 mips32_op = OPC_LWU;
5c13fdfd 16707 goto do_ld_lr;
3c824109 16708 case LLD:
d9224450
MR
16709 check_insn(ctx, ISA_MIPS3);
16710 check_mips_64(ctx);
3c824109 16711 mips32_op = OPC_LLD;
5c13fdfd 16712 goto do_ld_lr;
3c824109
NF
16713#endif
16714 case LL:
16715 mips32_op = OPC_LL;
5c13fdfd
AJ
16716 goto do_ld_lr;
16717 do_ld_lr:
3b4a5489 16718 gen_ld(ctx, mips32_op, rt, rs, offset);
5c13fdfd
AJ
16719 break;
16720 do_st_lr:
8fffc646 16721 gen_st(ctx, mips32_op, rt, rs, offset);
3c824109
NF
16722 break;
16723 case SC:
3b4a5489 16724 gen_st_cond(ctx, OPC_SC, rt, rs, offset);
3c824109
NF
16725 break;
16726#if defined(TARGET_MIPS64)
16727 case SCD:
d9224450
MR
16728 check_insn(ctx, ISA_MIPS3);
16729 check_mips_64(ctx);
3b4a5489 16730 gen_st_cond(ctx, OPC_SCD, rt, rs, offset);
3c824109
NF
16731 break;
16732#endif
8fffc646
JH
16733 case LD_EVA:
16734 if (!ctx->eva) {
16735 MIPS_INVAL("pool32c ld-eva");
16736 generate_exception_end(ctx, EXCP_RI);
16737 break;
16738 }
16739 check_cp0_enabled(ctx);
16740
16741 minor2 = (ctx->opcode >> 9) & 0x7;
16742 offset = sextract32(ctx->opcode, 0, 9);
16743 switch (minor2) {
16744 case LBUE:
16745 mips32_op = OPC_LBUE;
16746 goto do_ld_lr;
16747 case LHUE:
16748 mips32_op = OPC_LHUE;
16749 goto do_ld_lr;
16750 case LWLE:
16751 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16752 mips32_op = OPC_LWLE;
16753 goto do_ld_lr;
16754 case LWRE:
16755 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16756 mips32_op = OPC_LWRE;
16757 goto do_ld_lr;
16758 case LBE:
16759 mips32_op = OPC_LBE;
16760 goto do_ld_lr;
16761 case LHE:
16762 mips32_op = OPC_LHE;
16763 goto do_ld_lr;
16764 case LLE:
16765 mips32_op = OPC_LLE;
16766 goto do_ld_lr;
16767 case LWE:
16768 mips32_op = OPC_LWE;
16769 goto do_ld_lr;
16770 };
16771 break;
16772 case ST_EVA:
16773 if (!ctx->eva) {
16774 MIPS_INVAL("pool32c st-eva");
16775 generate_exception_end(ctx, EXCP_RI);
16776 break;
16777 }
16778 check_cp0_enabled(ctx);
16779
16780 minor2 = (ctx->opcode >> 9) & 0x7;
16781 offset = sextract32(ctx->opcode, 0, 9);
16782 switch (minor2) {
16783 case SWLE:
16784 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16785 mips32_op = OPC_SWLE;
16786 goto do_st_lr;
16787 case SWRE:
16788 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16789 mips32_op = OPC_SWRE;
16790 goto do_st_lr;
16791 case PREFE:
16792 /* Treat as no-op */
16793 if ((ctx->insn_flags & ISA_MIPS32R6) && (rt >= 24)) {
16794 /* hint codes 24-31 are reserved and signal RI */
16795 generate_exception(ctx, EXCP_RI);
16796 }
16797 break;
16798 case CACHEE:
16799 /* Treat as no-op */
16800 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
16801 gen_cache_operation(ctx, rt, rs, offset);
16802 }
16803 break;
16804 case SBE:
16805 mips32_op = OPC_SBE;
16806 goto do_st_lr;
16807 case SHE:
16808 mips32_op = OPC_SHE;
16809 goto do_st_lr;
16810 case SCE:
16811 gen_st_cond(ctx, OPC_SCE, rt, rs, offset);
16812 break;
16813 case SWE:
16814 mips32_op = OPC_SWE;
16815 goto do_st_lr;
16816 };
16817 break;
3c824109
NF
16818 case PREF:
16819 /* Treat as no-op */
3b4a5489
YK
16820 if ((ctx->insn_flags & ISA_MIPS32R6) && (rt >= 24)) {
16821 /* hint codes 24-31 are reserved and signal RI */
16822 generate_exception(ctx, EXCP_RI);
16823 }
3c824109
NF
16824 break;
16825 default:
16826 MIPS_INVAL("pool32c");
9c708c7f 16827 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
16828 break;
16829 }
16830 break;
ab39ee45
YK
16831 case ADDI32: /* AUI, LUI */
16832 if (ctx->insn_flags & ISA_MIPS32R6) {
16833 /* AUI, LUI */
16834 gen_logic_imm(ctx, OPC_LUI, rt, rs, imm);
16835 } else {
16836 /* ADDI32 */
16837 mips32_op = OPC_ADDI;
16838 goto do_addi;
16839 }
16840 break;
3c824109
NF
16841 case ADDIU32:
16842 mips32_op = OPC_ADDIU;
16843 do_addi:
d75c135e 16844 gen_arith_imm(ctx, mips32_op, rt, rs, imm);
3c824109
NF
16845 break;
16846
16847 /* Logical operations */
16848 case ORI32:
16849 mips32_op = OPC_ORI;
16850 goto do_logici;
16851 case XORI32:
16852 mips32_op = OPC_XORI;
16853 goto do_logici;
16854 case ANDI32:
16855 mips32_op = OPC_ANDI;
16856 do_logici:
d75c135e 16857 gen_logic_imm(ctx, mips32_op, rt, rs, imm);
3c824109
NF
16858 break;
16859
16860 /* Set less than immediate */
16861 case SLTI32:
16862 mips32_op = OPC_SLTI;
16863 goto do_slti;
16864 case SLTIU32:
16865 mips32_op = OPC_SLTIU;
16866 do_slti:
d75c135e 16867 gen_slt_imm(ctx, mips32_op, rt, rs, imm);
3c824109
NF
16868 break;
16869 case JALX32:
9e8f441a 16870 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 16871 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
b231c103
YK
16872 gen_compute_branch(ctx, OPC_JALX, 4, rt, rs, offset, 4);
16873 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
3c824109 16874 break;
65935f07
YK
16875 case JALS32: /* BOVC, BEQC, BEQZALC */
16876 if (ctx->insn_flags & ISA_MIPS32R6) {
16877 if (rs >= rt) {
16878 /* BOVC */
16879 mips32_op = OPC_BOVC;
16880 } else if (rs < rt && rs == 0) {
16881 /* BEQZALC */
16882 mips32_op = OPC_BEQZALC;
16883 } else {
16884 /* BEQC */
16885 mips32_op = OPC_BEQC;
16886 }
16887 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
16888 } else {
16889 /* JALS32 */
16890 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 1;
16891 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs, offset, 2);
16892 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16893 }
3c824109 16894 break;
65935f07
YK
16895 case BEQ32: /* BC */
16896 if (ctx->insn_flags & ISA_MIPS32R6) {
16897 /* BC */
16898 gen_compute_compact_branch(ctx, OPC_BC, 0, 0,
16899 sextract32(ctx->opcode << 1, 0, 27));
16900 } else {
16901 /* BEQ32 */
16902 gen_compute_branch(ctx, OPC_BEQ, 4, rt, rs, imm << 1, 4);
16903 }
3c824109 16904 break;
65935f07
YK
16905 case BNE32: /* BALC */
16906 if (ctx->insn_flags & ISA_MIPS32R6) {
16907 /* BALC */
16908 gen_compute_compact_branch(ctx, OPC_BALC, 0, 0,
16909 sextract32(ctx->opcode << 1, 0, 27));
16910 } else {
16911 /* BNE32 */
16912 gen_compute_branch(ctx, OPC_BNE, 4, rt, rs, imm << 1, 4);
16913 }
3c824109 16914 break;
65935f07
YK
16915 case J32: /* BGTZC, BLTZC, BLTC */
16916 if (ctx->insn_flags & ISA_MIPS32R6) {
16917 if (rs == 0 && rt != 0) {
16918 /* BGTZC */
16919 mips32_op = OPC_BGTZC;
16920 } else if (rs != 0 && rt != 0 && rs == rt) {
16921 /* BLTZC */
16922 mips32_op = OPC_BLTZC;
16923 } else {
16924 /* BLTC */
16925 mips32_op = OPC_BLTC;
16926 }
16927 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
16928 } else {
16929 /* J32 */
16930 gen_compute_branch(ctx, OPC_J, 4, rt, rs,
16931 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
16932 }
3c824109 16933 break;
65935f07
YK
16934 case JAL32: /* BLEZC, BGEZC, BGEC */
16935 if (ctx->insn_flags & ISA_MIPS32R6) {
16936 if (rs == 0 && rt != 0) {
16937 /* BLEZC */
16938 mips32_op = OPC_BLEZC;
16939 } else if (rs != 0 && rt != 0 && rs == rt) {
16940 /* BGEZC */
16941 mips32_op = OPC_BGEZC;
16942 } else {
16943 /* BGEC */
16944 mips32_op = OPC_BGEC;
16945 }
16946 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
16947 } else {
16948 /* JAL32 */
16949 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs,
16950 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
16951 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16952 }
3c824109
NF
16953 break;
16954 /* Floating point (COP1) */
16955 case LWC132:
16956 mips32_op = OPC_LWC1;
16957 goto do_cop1;
16958 case LDC132:
16959 mips32_op = OPC_LDC1;
16960 goto do_cop1;
16961 case SWC132:
16962 mips32_op = OPC_SWC1;
16963 goto do_cop1;
16964 case SDC132:
16965 mips32_op = OPC_SDC1;
16966 do_cop1:
5ab5c041 16967 gen_cop1_ldst(ctx, mips32_op, rt, rs, imm);
3c824109 16968 break;
ab39ee45
YK
16969 case ADDIUPC: /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
16970 if (ctx->insn_flags & ISA_MIPS32R6) {
16971 /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
16972 switch ((ctx->opcode >> 16) & 0x1f) {
c38a1d52
AR
16973 case ADDIUPC_00:
16974 case ADDIUPC_01:
16975 case ADDIUPC_02:
16976 case ADDIUPC_03:
16977 case ADDIUPC_04:
16978 case ADDIUPC_05:
16979 case ADDIUPC_06:
16980 case ADDIUPC_07:
eeb3bba8 16981 gen_pcrel(ctx, OPC_ADDIUPC, ctx->base.pc_next & ~0x3, rt);
ab39ee45
YK
16982 break;
16983 case AUIPC:
eeb3bba8 16984 gen_pcrel(ctx, OPC_AUIPC, ctx->base.pc_next, rt);
ab39ee45
YK
16985 break;
16986 case ALUIPC:
eeb3bba8 16987 gen_pcrel(ctx, OPC_ALUIPC, ctx->base.pc_next, rt);
ab39ee45 16988 break;
c38a1d52
AR
16989 case LWPC_08:
16990 case LWPC_09:
16991 case LWPC_0A:
16992 case LWPC_0B:
16993 case LWPC_0C:
16994 case LWPC_0D:
16995 case LWPC_0E:
16996 case LWPC_0F:
eeb3bba8 16997 gen_pcrel(ctx, R6_OPC_LWPC, ctx->base.pc_next & ~0x3, rt);
ab39ee45
YK
16998 break;
16999 default:
17000 generate_exception(ctx, EXCP_RI);
17001 break;
17002 }
17003 } else {
17004 /* ADDIUPC */
3c824109 17005 int reg = mmreg(ZIMM(ctx->opcode, 23, 3));
e1555d7d 17006 offset = SIMM(ctx->opcode, 0, 23) << 2;
3c824109
NF
17007
17008 gen_addiupc(ctx, reg, offset, 0, 0);
17009 }
17010 break;
65935f07
YK
17011 case BNVC: /* BNEC, BNEZALC */
17012 check_insn(ctx, ISA_MIPS32R6);
17013 if (rs >= rt) {
17014 /* BNVC */
17015 mips32_op = OPC_BNVC;
17016 } else if (rs < rt && rs == 0) {
17017 /* BNEZALC */
17018 mips32_op = OPC_BNEZALC;
17019 } else {
17020 /* BNEC */
17021 mips32_op = OPC_BNEC;
17022 }
17023 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
17024 break;
17025 case R6_BNEZC: /* JIALC */
17026 check_insn(ctx, ISA_MIPS32R6);
17027 if (rt != 0) {
17028 /* BNEZC */
17029 gen_compute_compact_branch(ctx, OPC_BNEZC, rt, 0,
17030 sextract32(ctx->opcode << 1, 0, 22));
17031 } else {
17032 /* JIALC */
17033 gen_compute_compact_branch(ctx, OPC_JIALC, 0, rs, imm);
17034 }
17035 break;
17036 case R6_BEQZC: /* JIC */
17037 check_insn(ctx, ISA_MIPS32R6);
17038 if (rt != 0) {
17039 /* BEQZC */
17040 gen_compute_compact_branch(ctx, OPC_BEQZC, rt, 0,
17041 sextract32(ctx->opcode << 1, 0, 22));
17042 } else {
17043 /* JIC */
17044 gen_compute_compact_branch(ctx, OPC_JIC, 0, rs, imm);
17045 }
17046 break;
17047 case BLEZALC: /* BGEZALC, BGEUC */
17048 check_insn(ctx, ISA_MIPS32R6);
17049 if (rs == 0 && rt != 0) {
17050 /* BLEZALC */
17051 mips32_op = OPC_BLEZALC;
17052 } else if (rs != 0 && rt != 0 && rs == rt) {
17053 /* BGEZALC */
17054 mips32_op = OPC_BGEZALC;
17055 } else {
17056 /* BGEUC */
17057 mips32_op = OPC_BGEUC;
17058 }
17059 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
17060 break;
17061 case BGTZALC: /* BLTZALC, BLTUC */
17062 check_insn(ctx, ISA_MIPS32R6);
17063 if (rs == 0 && rt != 0) {
17064 /* BGTZALC */
17065 mips32_op = OPC_BGTZALC;
17066 } else if (rs != 0 && rt != 0 && rs == rt) {
17067 /* BLTZALC */
17068 mips32_op = OPC_BLTZALC;
17069 } else {
17070 /* BLTUC */
17071 mips32_op = OPC_BLTUC;
17072 }
17073 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
17074 break;
3c824109
NF
17075 /* Loads and stores */
17076 case LB32:
17077 mips32_op = OPC_LB;
5c13fdfd 17078 goto do_ld;
3c824109
NF
17079 case LBU32:
17080 mips32_op = OPC_LBU;
5c13fdfd 17081 goto do_ld;
3c824109
NF
17082 case LH32:
17083 mips32_op = OPC_LH;
5c13fdfd 17084 goto do_ld;
3c824109
NF
17085 case LHU32:
17086 mips32_op = OPC_LHU;
5c13fdfd 17087 goto do_ld;
3c824109
NF
17088 case LW32:
17089 mips32_op = OPC_LW;
5c13fdfd 17090 goto do_ld;
3c824109
NF
17091#ifdef TARGET_MIPS64
17092 case LD32:
d9224450
MR
17093 check_insn(ctx, ISA_MIPS3);
17094 check_mips_64(ctx);
3c824109 17095 mips32_op = OPC_LD;
5c13fdfd 17096 goto do_ld;
3c824109 17097 case SD32:
d9224450
MR
17098 check_insn(ctx, ISA_MIPS3);
17099 check_mips_64(ctx);
3c824109 17100 mips32_op = OPC_SD;
5c13fdfd 17101 goto do_st;
3c824109
NF
17102#endif
17103 case SB32:
17104 mips32_op = OPC_SB;
5c13fdfd 17105 goto do_st;
3c824109
NF
17106 case SH32:
17107 mips32_op = OPC_SH;
5c13fdfd 17108 goto do_st;
3c824109
NF
17109 case SW32:
17110 mips32_op = OPC_SW;
5c13fdfd
AJ
17111 goto do_st;
17112 do_ld:
d75c135e 17113 gen_ld(ctx, mips32_op, rt, rs, imm);
5c13fdfd
AJ
17114 break;
17115 do_st:
17116 gen_st(ctx, mips32_op, rt, rs, imm);
3c824109
NF
17117 break;
17118 default:
9c708c7f 17119 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
17120 break;
17121 }
17122}
17123
240ce26a 17124static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx)
3c824109
NF
17125{
17126 uint32_t op;
17127
17128 /* make sure instructions are on a halfword boundary */
eeb3bba8
EC
17129 if (ctx->base.pc_next & 0x1) {
17130 env->CP0_BadVAddr = ctx->base.pc_next;
9c708c7f 17131 generate_exception_end(ctx, EXCP_AdEL);
3c824109
NF
17132 return 2;
17133 }
17134
17135 op = (ctx->opcode >> 10) & 0x3f;
17136 /* Enforce properly-sized instructions in a delay slot */
b231c103
YK
17137 if (ctx->hflags & MIPS_HFLAG_BDS_STRICT) {
17138 switch (op & 0x7) { /* MSB-3..MSB-5 */
17139 case 0:
17140 /* POOL32A, POOL32B, POOL32I, POOL32C */
17141 case 4:
17142 /* ADDI32, ADDIU32, ORI32, XORI32, SLTI32, SLTIU32, ANDI32, JALX32 */
17143 case 5:
17144 /* LBU32, LHU32, POOL32F, JALS32, BEQ32, BNE32, J32, JAL32 */
17145 case 6:
17146 /* SB32, SH32, ADDIUPC, SWC132, SDC132, SW32 */
17147 case 7:
17148 /* LB32, LH32, LWC132, LDC132, LW32 */
17149 if (ctx->hflags & MIPS_HFLAG_BDS16) {
9c708c7f 17150 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
17151 return 2;
17152 }
17153 break;
b231c103
YK
17154 case 1:
17155 /* POOL16A, POOL16B, POOL16C, LWGP16, POOL16F */
17156 case 2:
17157 /* LBU16, LHU16, LWSP16, LW16, SB16, SH16, SWSP16, SW16 */
17158 case 3:
17159 /* MOVE16, ANDI16, POOL16D, POOL16E, BEQZ16, BNEZ16, B16, LI16 */
17160 if (ctx->hflags & MIPS_HFLAG_BDS32) {
9c708c7f 17161 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
17162 return 2;
17163 }
17164 break;
3c824109
NF
17165 }
17166 }
b231c103 17167
3c824109
NF
17168 switch (op) {
17169 case POOL16A:
17170 {
17171 int rd = mmreg(uMIPS_RD(ctx->opcode));
17172 int rs1 = mmreg(uMIPS_RS1(ctx->opcode));
17173 int rs2 = mmreg(uMIPS_RS2(ctx->opcode));
17174 uint32_t opc = 0;
17175
17176 switch (ctx->opcode & 0x1) {
17177 case ADDU16:
17178 opc = OPC_ADDU;
17179 break;
17180 case SUBU16:
17181 opc = OPC_SUBU;
17182 break;
17183 }
ed7ce6c0
YK
17184 if (ctx->insn_flags & ISA_MIPS32R6) {
17185 /* In the Release 6 the register number location in
17186 * the instruction encoding has changed.
17187 */
17188 gen_arith(ctx, opc, rs1, rd, rs2);
17189 } else {
17190 gen_arith(ctx, opc, rd, rs1, rs2);
17191 }
3c824109
NF
17192 }
17193 break;
17194 case POOL16B:
17195 {
17196 int rd = mmreg(uMIPS_RD(ctx->opcode));
17197 int rs = mmreg(uMIPS_RS(ctx->opcode));
17198 int amount = (ctx->opcode >> 1) & 0x7;
17199 uint32_t opc = 0;
17200 amount = amount == 0 ? 8 : amount;
17201
17202 switch (ctx->opcode & 0x1) {
17203 case SLL16:
17204 opc = OPC_SLL;
17205 break;
17206 case SRL16:
17207 opc = OPC_SRL;
17208 break;
17209 }
17210
d75c135e 17211 gen_shift_imm(ctx, opc, rd, rs, amount);
3c824109
NF
17212 }
17213 break;
17214 case POOL16C:
ed7ce6c0
YK
17215 if (ctx->insn_flags & ISA_MIPS32R6) {
17216 gen_pool16c_r6_insn(ctx);
17217 } else {
17218 gen_pool16c_insn(ctx);
17219 }
3c824109
NF
17220 break;
17221 case LWGP16:
17222 {
17223 int rd = mmreg(uMIPS_RD(ctx->opcode));
17224 int rb = 28; /* GP */
17225 int16_t offset = SIMM(ctx->opcode, 0, 7) << 2;
17226
d75c135e 17227 gen_ld(ctx, OPC_LW, rd, rb, offset);
3c824109
NF
17228 }
17229 break;
17230 case POOL16F:
9e8f441a 17231 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 17232 if (ctx->opcode & 1) {
9c708c7f 17233 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
17234 } else {
17235 /* MOVEP */
17236 int enc_dest = uMIPS_RD(ctx->opcode);
17237 int enc_rt = uMIPS_RS2(ctx->opcode);
17238 int enc_rs = uMIPS_RS1(ctx->opcode);
ed7ce6c0 17239 gen_movep(ctx, enc_dest, enc_rt, enc_rs);
3c824109
NF
17240 }
17241 break;
17242 case LBU16:
17243 {
17244 int rd = mmreg(uMIPS_RD(ctx->opcode));
17245 int rb = mmreg(uMIPS_RS(ctx->opcode));
17246 int16_t offset = ZIMM(ctx->opcode, 0, 4);
17247 offset = (offset == 0xf ? -1 : offset);
17248
d75c135e 17249 gen_ld(ctx, OPC_LBU, rd, rb, offset);
3c824109
NF
17250 }
17251 break;
17252 case LHU16:
17253 {
17254 int rd = mmreg(uMIPS_RD(ctx->opcode));
17255 int rb = mmreg(uMIPS_RS(ctx->opcode));
17256 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
17257
d75c135e 17258 gen_ld(ctx, OPC_LHU, rd, rb, offset);
3c824109
NF
17259 }
17260 break;
17261 case LWSP16:
17262 {
17263 int rd = (ctx->opcode >> 5) & 0x1f;
17264 int rb = 29; /* SP */
17265 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
17266
d75c135e 17267 gen_ld(ctx, OPC_LW, rd, rb, offset);
3c824109
NF
17268 }
17269 break;
17270 case LW16:
17271 {
17272 int rd = mmreg(uMIPS_RD(ctx->opcode));
17273 int rb = mmreg(uMIPS_RS(ctx->opcode));
17274 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
17275
d75c135e 17276 gen_ld(ctx, OPC_LW, rd, rb, offset);
3c824109
NF
17277 }
17278 break;
17279 case SB16:
17280 {
17281 int rd = mmreg2(uMIPS_RD(ctx->opcode));
17282 int rb = mmreg(uMIPS_RS(ctx->opcode));
17283 int16_t offset = ZIMM(ctx->opcode, 0, 4);
17284
5c13fdfd 17285 gen_st(ctx, OPC_SB, rd, rb, offset);
3c824109
NF
17286 }
17287 break;
17288 case SH16:
17289 {
17290 int rd = mmreg2(uMIPS_RD(ctx->opcode));
17291 int rb = mmreg(uMIPS_RS(ctx->opcode));
17292 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
17293
5c13fdfd 17294 gen_st(ctx, OPC_SH, rd, rb, offset);
3c824109
NF
17295 }
17296 break;
17297 case SWSP16:
17298 {
17299 int rd = (ctx->opcode >> 5) & 0x1f;
17300 int rb = 29; /* SP */
17301 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
17302
5c13fdfd 17303 gen_st(ctx, OPC_SW, rd, rb, offset);
3c824109
NF
17304 }
17305 break;
17306 case SW16:
17307 {
17308 int rd = mmreg2(uMIPS_RD(ctx->opcode));
17309 int rb = mmreg(uMIPS_RS(ctx->opcode));
17310 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
17311
5c13fdfd 17312 gen_st(ctx, OPC_SW, rd, rb, offset);
3c824109
NF
17313 }
17314 break;
17315 case MOVE16:
17316 {
17317 int rd = uMIPS_RD5(ctx->opcode);
17318 int rs = uMIPS_RS5(ctx->opcode);
17319
7215d7e7 17320 gen_arith(ctx, OPC_ADDU, rd, rs, 0);
3c824109
NF
17321 }
17322 break;
17323 case ANDI16:
d75c135e 17324 gen_andi16(ctx);
3c824109
NF
17325 break;
17326 case POOL16D:
17327 switch (ctx->opcode & 0x1) {
17328 case ADDIUS5:
d75c135e 17329 gen_addius5(ctx);
3c824109
NF
17330 break;
17331 case ADDIUSP:
d75c135e 17332 gen_addiusp(ctx);
3c824109
NF
17333 break;
17334 }
17335 break;
17336 case POOL16E:
17337 switch (ctx->opcode & 0x1) {
17338 case ADDIUR2:
d75c135e 17339 gen_addiur2(ctx);
3c824109
NF
17340 break;
17341 case ADDIUR1SP:
d75c135e 17342 gen_addiur1sp(ctx);
3c824109
NF
17343 break;
17344 }
17345 break;
65935f07 17346 case B16: /* BC16 */
3c824109 17347 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0,
65935f07
YK
17348 sextract32(ctx->opcode, 0, 10) << 1,
17349 (ctx->insn_flags & ISA_MIPS32R6) ? 0 : 4);
3c824109 17350 break;
65935f07
YK
17351 case BNEZ16: /* BNEZC16 */
17352 case BEQZ16: /* BEQZC16 */
3c824109
NF
17353 gen_compute_branch(ctx, op == BNEZ16 ? OPC_BNE : OPC_BEQ, 2,
17354 mmreg(uMIPS_RD(ctx->opcode)),
65935f07
YK
17355 0, sextract32(ctx->opcode, 0, 7) << 1,
17356 (ctx->insn_flags & ISA_MIPS32R6) ? 0 : 4);
17357
3c824109
NF
17358 break;
17359 case LI16:
17360 {
17361 int reg = mmreg(uMIPS_RD(ctx->opcode));
17362 int imm = ZIMM(ctx->opcode, 0, 7);
17363
17364 imm = (imm == 0x7f ? -1 : imm);
17365 tcg_gen_movi_tl(cpu_gpr[reg], imm);
17366 }
17367 break;
3c824109 17368 case RES_29:
3c824109 17369 case RES_31:
3c824109 17370 case RES_39:
9c708c7f 17371 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
17372 break;
17373 default:
f60eeb0c 17374 decode_micromips32_opc(env, ctx);
3c824109
NF
17375 return 4;
17376 }
17377
17378 return 2;
17379}
17380
261c95a0
YK
17381/*
17382 *
17383 * nanoMIPS opcodes
17384 *
17385 */
17386
17387/* MAJOR, P16, and P32 pools opcodes */
17388enum {
17389 NM_P_ADDIU = 0x00,
17390 NM_ADDIUPC = 0x01,
17391 NM_MOVE_BALC = 0x02,
17392 NM_P16_MV = 0x04,
17393 NM_LW16 = 0x05,
17394 NM_BC16 = 0x06,
17395 NM_P16_SR = 0x07,
17396
17397 NM_POOL32A = 0x08,
17398 NM_P_BAL = 0x0a,
17399 NM_P16_SHIFT = 0x0c,
17400 NM_LWSP16 = 0x0d,
17401 NM_BALC16 = 0x0e,
17402 NM_P16_4X4 = 0x0f,
17403
17404 NM_P_GP_W = 0x10,
17405 NM_P_GP_BH = 0x11,
17406 NM_P_J = 0x12,
17407 NM_P16C = 0x14,
17408 NM_LWGP16 = 0x15,
17409 NM_P16_LB = 0x17,
17410
17411 NM_P48I = 0x18,
17412 NM_P16_A1 = 0x1c,
17413 NM_LW4X4 = 0x1d,
17414 NM_P16_LH = 0x1f,
17415
17416 NM_P_U12 = 0x20,
17417 NM_P_LS_U12 = 0x21,
17418 NM_P_BR1 = 0x22,
17419 NM_P16_A2 = 0x24,
17420 NM_SW16 = 0x25,
17421 NM_BEQZC16 = 0x26,
17422
17423 NM_POOL32F = 0x28,
17424 NM_P_LS_S9 = 0x29,
17425 NM_P_BR2 = 0x2a,
17426
17427 NM_P16_ADDU = 0x2c,
17428 NM_SWSP16 = 0x2d,
17429 NM_BNEZC16 = 0x2e,
17430 NM_MOVEP = 0x2f,
17431
17432 NM_POOL32S = 0x30,
17433 NM_P_BRI = 0x32,
17434 NM_LI16 = 0x34,
17435 NM_SWGP16 = 0x35,
17436 NM_P16_BR = 0x36,
17437
17438 NM_P_LUI = 0x38,
17439 NM_ANDI16 = 0x3c,
17440 NM_SW4X4 = 0x3d,
17441 NM_MOVEPREV = 0x3f,
17442};
17443
17444/* POOL32A instruction pool */
17445enum {
17446 NM_POOL32A0 = 0x00,
17447 NM_SPECIAL2 = 0x01,
17448 NM_COP2_1 = 0x02,
17449 NM_UDI = 0x03,
17450 NM_POOL32A5 = 0x05,
17451 NM_POOL32A7 = 0x07,
17452};
17453
17454/* P.GP.W instruction pool */
17455enum {
17456 NM_ADDIUGP_W = 0x00,
17457 NM_LWGP = 0x02,
17458 NM_SWGP = 0x03,
17459};
17460
17461/* P48I instruction pool */
17462enum {
17463 NM_LI48 = 0x00,
17464 NM_ADDIU48 = 0x01,
17465 NM_ADDIUGP48 = 0x02,
17466 NM_ADDIUPC48 = 0x03,
17467 NM_LWPC48 = 0x0b,
17468 NM_SWPC48 = 0x0f,
17469};
17470
17471/* P.U12 instruction pool */
17472enum {
17473 NM_ORI = 0x00,
17474 NM_XORI = 0x01,
17475 NM_ANDI = 0x02,
17476 NM_P_SR = 0x03,
17477 NM_SLTI = 0x04,
17478 NM_SLTIU = 0x05,
17479 NM_SEQI = 0x06,
17480 NM_ADDIUNEG = 0x08,
17481 NM_P_SHIFT = 0x0c,
17482 NM_P_ROTX = 0x0d,
17483 NM_P_INS = 0x0e,
17484 NM_P_EXT = 0x0f,
17485};
17486
17487/* POOL32F instruction pool */
17488enum {
17489 NM_POOL32F_0 = 0x00,
17490 NM_POOL32F_3 = 0x03,
17491 NM_POOL32F_5 = 0x05,
17492};
17493
17494/* POOL32S instruction pool */
17495enum {
17496 NM_POOL32S_0 = 0x00,
17497 NM_POOL32S_4 = 0x04,
17498};
17499
17500/* P.LUI instruction pool */
17501enum {
17502 NM_LUI = 0x00,
17503 NM_ALUIPC = 0x01,
17504};
17505
17506/* P.GP.BH instruction pool */
17507enum {
17508 NM_LBGP = 0x00,
17509 NM_SBGP = 0x01,
17510 NM_LBUGP = 0x02,
17511 NM_ADDIUGP_B = 0x03,
17512 NM_P_GP_LH = 0x04,
17513 NM_P_GP_SH = 0x05,
17514 NM_P_GP_CP1 = 0x06,
17515};
17516
17517/* P.LS.U12 instruction pool */
17518enum {
17519 NM_LB = 0x00,
17520 NM_SB = 0x01,
17521 NM_LBU = 0x02,
17522 NM_P_PREFU12 = 0x03,
17523 NM_LH = 0x04,
17524 NM_SH = 0x05,
17525 NM_LHU = 0x06,
17526 NM_LWU = 0x07,
17527 NM_LW = 0x08,
17528 NM_SW = 0x09,
17529 NM_LWC1 = 0x0a,
17530 NM_SWC1 = 0x0b,
17531 NM_LDC1 = 0x0e,
17532 NM_SDC1 = 0x0f,
17533};
17534
17535/* P.LS.S9 instruction pool */
17536enum {
17537 NM_P_LS_S0 = 0x00,
17538 NM_P_LS_S1 = 0x01,
17539 NM_P_LS_E0 = 0x02,
17540 NM_P_LS_WM = 0x04,
17541 NM_P_LS_UAWM = 0x05,
17542};
17543
17544/* P.BAL instruction pool */
17545enum {
17546 NM_BC = 0x00,
17547 NM_BALC = 0x01,
17548};
17549
17550/* P.J instruction pool */
17551enum {
17552 NM_JALRC = 0x00,
17553 NM_JALRC_HB = 0x01,
17554 NM_P_BALRSC = 0x08,
17555};
17556
17557/* P.BR1 instruction pool */
17558enum {
17559 NM_BEQC = 0x00,
17560 NM_P_BR3A = 0x01,
17561 NM_BGEC = 0x02,
17562 NM_BGEUC = 0x03,
17563};
17564
17565/* P.BR2 instruction pool */
17566enum {
17567 NM_BNEC = 0x00,
17568 NM_BLTC = 0x02,
17569 NM_BLTUC = 0x03,
17570};
17571
17572/* P.BRI instruction pool */
17573enum {
17574 NM_BEQIC = 0x00,
17575 NM_BBEQZC = 0x01,
17576 NM_BGEIC = 0x02,
17577 NM_BGEIUC = 0x03,
17578 NM_BNEIC = 0x04,
17579 NM_BBNEZC = 0x05,
17580 NM_BLTIC = 0x06,
17581 NM_BLTIUC = 0x07,
17582};
17583
17584/* P16.SHIFT instruction pool */
17585enum {
17586 NM_SLL16 = 0x00,
17587 NM_SRL16 = 0x01,
17588};
17589
17590/* POOL16C instruction pool */
17591enum {
17592 NM_POOL16C_0 = 0x00,
17593 NM_LWXS16 = 0x01,
17594};
17595
17596/* P16.A1 instruction pool */
17597enum {
17598 NM_ADDIUR1SP = 0x01,
17599};
17600
17601/* P16.A2 instruction pool */
17602enum {
17603 NM_ADDIUR2 = 0x00,
17604 NM_P_ADDIURS5 = 0x01,
17605};
17606
17607/* P16.ADDU instruction pool */
17608enum {
17609 NM_ADDU16 = 0x00,
17610 NM_SUBU16 = 0x01,
17611};
17612
17613/* P16.SR instruction pool */
17614enum {
17615 NM_SAVE16 = 0x00,
17616 NM_RESTORE_JRC16 = 0x01,
17617};
17618
17619/* P16.4X4 instruction pool */
17620enum {
17621 NM_ADDU4X4 = 0x00,
17622 NM_MUL4X4 = 0x01,
17623};
17624
17625/* P16.LB instruction pool */
17626enum {
17627 NM_LB16 = 0x00,
17628 NM_SB16 = 0x01,
17629 NM_LBU16 = 0x02,
17630};
17631
17632/* P16.LH instruction pool */
17633enum {
17634 NM_LH16 = 0x00,
17635 NM_SH16 = 0x01,
17636 NM_LHU16 = 0x02,
17637};
17638
17639/* P.RI instruction pool */
17640enum {
17641 NM_SIGRIE = 0x00,
17642 NM_P_SYSCALL = 0x01,
17643 NM_BREAK = 0x02,
17644 NM_SDBBP = 0x03,
17645};
17646
17647/* POOL32A0 instruction pool */
17648enum {
17649 NM_P_TRAP = 0x00,
17650 NM_SEB = 0x01,
17651 NM_SLLV = 0x02,
17652 NM_MUL = 0x03,
17653 NM_MFC0 = 0x06,
17654 NM_MFHC0 = 0x07,
17655 NM_SEH = 0x09,
17656 NM_SRLV = 0x0a,
17657 NM_MUH = 0x0b,
17658 NM_MTC0 = 0x0e,
17659 NM_MTHC0 = 0x0f,
17660 NM_SRAV = 0x12,
17661 NM_MULU = 0x13,
17662 NM_ROTRV = 0x1a,
17663 NM_MUHU = 0x1b,
17664 NM_ADD = 0x22,
17665 NM_DIV = 0x23,
17666 NM_ADDU = 0x2a,
17667 NM_MOD = 0x2b,
17668 NM_SUB = 0x32,
17669 NM_DIVU = 0x33,
17670 NM_RDHWR = 0x38,
17671 NM_SUBU = 0x3a,
17672 NM_MODU = 0x3b,
17673 NM_P_CMOVE = 0x42,
17674 NM_FORK = 0x45,
17675 NM_MFTR = 0x46,
17676 NM_MFHTR = 0x47,
17677 NM_AND = 0x4a,
17678 NM_YIELD = 0x4d,
17679 NM_MTTR = 0x4e,
17680 NM_MTHTR = 0x4f,
17681 NM_OR = 0x52,
17682 NM_D_E_MT_VPE = 0x56,
17683 NM_NOR = 0x5a,
17684 NM_XOR = 0x62,
17685 NM_SLT = 0x6a,
17686 NM_P_SLTU = 0x72,
17687 NM_SOV = 0x7a,
17688};
17689
ba1e8117
AM
17690/* CRC32 instruction pool */
17691enum {
17692 NM_CRC32B = 0x00,
17693 NM_CRC32H = 0x01,
17694 NM_CRC32W = 0x02,
17695 NM_CRC32CB = 0x04,
17696 NM_CRC32CH = 0x05,
17697 NM_CRC32CW = 0x06,
17698};
17699
b3979b6f
SM
17700/* POOL32A5 instruction pool */
17701enum {
17702 NM_CMP_EQ_PH = 0x00,
17703 NM_CMP_LT_PH = 0x08,
17704 NM_CMP_LE_PH = 0x10,
17705 NM_CMPGU_EQ_QB = 0x18,
17706 NM_CMPGU_LT_QB = 0x20,
17707 NM_CMPGU_LE_QB = 0x28,
17708 NM_CMPGDU_EQ_QB = 0x30,
17709 NM_CMPGDU_LT_QB = 0x38,
17710 NM_CMPGDU_LE_QB = 0x40,
17711 NM_CMPU_EQ_QB = 0x48,
17712 NM_CMPU_LT_QB = 0x50,
17713 NM_CMPU_LE_QB = 0x58,
17714 NM_ADDQ_S_W = 0x60,
17715 NM_SUBQ_S_W = 0x68,
17716 NM_ADDSC = 0x70,
17717 NM_ADDWC = 0x78,
17718
17719 NM_ADDQ_S_PH = 0x01,
17720 NM_ADDQH_R_PH = 0x09,
17721 NM_ADDQH_R_W = 0x11,
17722 NM_ADDU_S_QB = 0x19,
17723 NM_ADDU_S_PH = 0x21,
17724 NM_ADDUH_R_QB = 0x29,
17725 NM_SHRAV_R_PH = 0x31,
17726 NM_SHRAV_R_QB = 0x39,
17727 NM_SUBQ_S_PH = 0x41,
17728 NM_SUBQH_R_PH = 0x49,
17729 NM_SUBQH_R_W = 0x51,
17730 NM_SUBU_S_QB = 0x59,
17731 NM_SUBU_S_PH = 0x61,
17732 NM_SUBUH_R_QB = 0x69,
17733 NM_SHLLV_S_PH = 0x71,
17734 NM_PRECR_SRA_R_PH_W = 0x79,
17735
17736 NM_MULEU_S_PH_QBL = 0x12,
17737 NM_MULEU_S_PH_QBR = 0x1a,
17738 NM_MULQ_RS_PH = 0x22,
17739 NM_MULQ_S_PH = 0x2a,
17740 NM_MULQ_RS_W = 0x32,
17741 NM_MULQ_S_W = 0x3a,
17742 NM_APPEND = 0x42,
17743 NM_MODSUB = 0x52,
17744 NM_SHRAV_R_W = 0x5a,
17745 NM_SHRLV_PH = 0x62,
17746 NM_SHRLV_QB = 0x6a,
17747 NM_SHLLV_QB = 0x72,
17748 NM_SHLLV_S_W = 0x7a,
17749
17750 NM_SHILO = 0x03,
17751
17752 NM_MULEQ_S_W_PHL = 0x04,
17753 NM_MULEQ_S_W_PHR = 0x0c,
17754
17755 NM_MUL_S_PH = 0x05,
17756 NM_PRECR_QB_PH = 0x0d,
17757 NM_PRECRQ_QB_PH = 0x15,
17758 NM_PRECRQ_PH_W = 0x1d,
17759 NM_PRECRQ_RS_PH_W = 0x25,
17760 NM_PRECRQU_S_QB_PH = 0x2d,
17761 NM_PACKRL_PH = 0x35,
17762 NM_PICK_QB = 0x3d,
17763 NM_PICK_PH = 0x45,
17764
17765 NM_SHRA_R_W = 0x5e,
17766 NM_SHRA_R_PH = 0x66,
17767 NM_SHLL_S_PH = 0x76,
17768 NM_SHLL_S_W = 0x7e,
17769
17770 NM_REPL_PH = 0x07
17771};
17772
261c95a0
YK
17773/* POOL32A7 instruction pool */
17774enum {
17775 NM_P_LSX = 0x00,
17776 NM_LSA = 0x01,
17777 NM_EXTW = 0x03,
17778 NM_POOL32AXF = 0x07,
17779};
17780
17781/* P.SR instruction pool */
17782enum {
17783 NM_PP_SR = 0x00,
17784 NM_P_SR_F = 0x01,
17785};
17786
17787/* P.SHIFT instruction pool */
17788enum {
17789 NM_P_SLL = 0x00,
17790 NM_SRL = 0x02,
17791 NM_SRA = 0x04,
17792 NM_ROTR = 0x06,
17793};
17794
17795/* P.ROTX instruction pool */
17796enum {
17797 NM_ROTX = 0x00,
17798};
17799
17800/* P.INS instruction pool */
17801enum {
17802 NM_INS = 0x00,
17803};
17804
17805/* P.EXT instruction pool */
17806enum {
17807 NM_EXT = 0x00,
17808};
17809
17810/* POOL32F_0 (fmt) instruction pool */
17811enum {
17812 NM_RINT_S = 0x04,
17813 NM_RINT_D = 0x44,
17814 NM_ADD_S = 0x06,
17815 NM_SELEQZ_S = 0x07,
17816 NM_SELEQZ_D = 0x47,
17817 NM_CLASS_S = 0x0c,
17818 NM_CLASS_D = 0x4c,
17819 NM_SUB_S = 0x0e,
17820 NM_SELNEZ_S = 0x0f,
17821 NM_SELNEZ_D = 0x4f,
17822 NM_MUL_S = 0x16,
17823 NM_SEL_S = 0x17,
17824 NM_SEL_D = 0x57,
17825 NM_DIV_S = 0x1e,
17826 NM_ADD_D = 0x26,
17827 NM_SUB_D = 0x2e,
17828 NM_MUL_D = 0x36,
17829 NM_MADDF_S = 0x37,
17830 NM_MADDF_D = 0x77,
17831 NM_DIV_D = 0x3e,
17832 NM_MSUBF_S = 0x3f,
17833 NM_MSUBF_D = 0x7f,
17834};
17835
17836/* POOL32F_3 instruction pool */
17837enum {
17838 NM_MIN_FMT = 0x00,
17839 NM_MAX_FMT = 0x01,
17840 NM_MINA_FMT = 0x04,
17841 NM_MAXA_FMT = 0x05,
17842 NM_POOL32FXF = 0x07,
17843};
17844
17845/* POOL32F_5 instruction pool */
17846enum {
17847 NM_CMP_CONDN_S = 0x00,
17848 NM_CMP_CONDN_D = 0x02,
17849};
17850
17851/* P.GP.LH instruction pool */
17852enum {
17853 NM_LHGP = 0x00,
17854 NM_LHUGP = 0x01,
17855};
17856
17857/* P.GP.SH instruction pool */
17858enum {
17859 NM_SHGP = 0x00,
17860};
17861
17862/* P.GP.CP1 instruction pool */
17863enum {
17864 NM_LWC1GP = 0x00,
17865 NM_SWC1GP = 0x01,
17866 NM_LDC1GP = 0x02,
17867 NM_SDC1GP = 0x03,
17868};
17869
17870/* P.LS.S0 instruction pool */
17871enum {
17872 NM_LBS9 = 0x00,
17873 NM_LHS9 = 0x04,
17874 NM_LWS9 = 0x08,
17875 NM_LDS9 = 0x0c,
17876
17877 NM_SBS9 = 0x01,
17878 NM_SHS9 = 0x05,
17879 NM_SWS9 = 0x09,
17880 NM_SDS9 = 0x0d,
17881
17882 NM_LBUS9 = 0x02,
17883 NM_LHUS9 = 0x06,
17884 NM_LWC1S9 = 0x0a,
17885 NM_LDC1S9 = 0x0e,
17886
17887 NM_P_PREFS9 = 0x03,
17888 NM_LWUS9 = 0x07,
17889 NM_SWC1S9 = 0x0b,
17890 NM_SDC1S9 = 0x0f,
17891};
17892
17893/* P.LS.S1 instruction pool */
17894enum {
17895 NM_ASET_ACLR = 0x02,
17896 NM_UALH = 0x04,
17897 NM_UASH = 0x05,
17898 NM_CACHE = 0x07,
17899 NM_P_LL = 0x0a,
17900 NM_P_SC = 0x0b,
17901};
17902
0d30b3bb
DN
17903/* P.LS.E0 instruction pool */
17904enum {
17905 NM_LBE = 0x00,
17906 NM_SBE = 0x01,
17907 NM_LBUE = 0x02,
17908 NM_P_PREFE = 0x03,
17909 NM_LHE = 0x04,
17910 NM_SHE = 0x05,
17911 NM_LHUE = 0x06,
17912 NM_CACHEE = 0x07,
17913 NM_LWE = 0x08,
17914 NM_SWE = 0x09,
17915 NM_P_LLE = 0x0a,
17916 NM_P_SCE = 0x0b,
17917};
17918
17919/* P.PREFE instruction pool */
17920enum {
17921 NM_SYNCIE = 0x00,
17922 NM_PREFE = 0x01,
17923};
17924
17925/* P.LLE instruction pool */
17926enum {
17927 NM_LLE = 0x00,
17928 NM_LLWPE = 0x01,
17929};
17930
17931/* P.SCE instruction pool */
17932enum {
17933 NM_SCE = 0x00,
17934 NM_SCWPE = 0x01,
17935};
17936
261c95a0
YK
17937/* P.LS.WM instruction pool */
17938enum {
17939 NM_LWM = 0x00,
17940 NM_SWM = 0x01,
17941};
17942
17943/* P.LS.UAWM instruction pool */
17944enum {
17945 NM_UALWM = 0x00,
17946 NM_UASWM = 0x01,
17947};
17948
17949/* P.BR3A instruction pool */
17950enum {
17951 NM_BC1EQZC = 0x00,
17952 NM_BC1NEZC = 0x01,
17953 NM_BC2EQZC = 0x02,
17954 NM_BC2NEZC = 0x03,
17955 NM_BPOSGE32C = 0x04,
17956};
17957
17958/* P16.RI instruction pool */
17959enum {
17960 NM_P16_SYSCALL = 0x01,
17961 NM_BREAK16 = 0x02,
17962 NM_SDBBP16 = 0x03,
17963};
17964
17965/* POOL16C_0 instruction pool */
17966enum {
17967 NM_POOL16C_00 = 0x00,
17968};
17969
17970/* P16.JRC instruction pool */
17971enum {
17972 NM_JRC = 0x00,
17973 NM_JALRC16 = 0x01,
17974};
17975
17976/* P.SYSCALL instruction pool */
17977enum {
17978 NM_SYSCALL = 0x00,
17979 NM_HYPCALL = 0x01,
17980};
17981
17982/* P.TRAP instruction pool */
17983enum {
17984 NM_TEQ = 0x00,
17985 NM_TNE = 0x01,
17986};
17987
17988/* P.CMOVE instruction pool */
17989enum {
17990 NM_MOVZ = 0x00,
17991 NM_MOVN = 0x01,
17992};
17993
17994/* POOL32Axf instruction pool */
17995enum {
b3979b6f
SM
17996 NM_POOL32AXF_1 = 0x01,
17997 NM_POOL32AXF_2 = 0x02,
261c95a0
YK
17998 NM_POOL32AXF_4 = 0x04,
17999 NM_POOL32AXF_5 = 0x05,
b3979b6f
SM
18000 NM_POOL32AXF_7 = 0x07,
18001};
18002
18003/* POOL32Axf_1 instruction pool */
18004enum {
18005 NM_POOL32AXF_1_0 = 0x00,
18006 NM_POOL32AXF_1_1 = 0x01,
18007 NM_POOL32AXF_1_3 = 0x03,
18008 NM_POOL32AXF_1_4 = 0x04,
18009 NM_POOL32AXF_1_5 = 0x05,
18010 NM_POOL32AXF_1_7 = 0x07,
18011};
18012
18013/* POOL32Axf_2 instruction pool */
18014enum {
18015 NM_POOL32AXF_2_0_7 = 0x00,
18016 NM_POOL32AXF_2_8_15 = 0x01,
18017 NM_POOL32AXF_2_16_23 = 0x02,
18018 NM_POOL32AXF_2_24_31 = 0x03,
18019};
18020
18021/* POOL32Axf_7 instruction pool */
18022enum {
18023 NM_SHRA_R_QB = 0x0,
18024 NM_SHRL_PH = 0x1,
18025 NM_REPL_QB = 0x2,
18026};
18027
18028/* POOL32Axf_1_0 instruction pool */
18029enum {
18030 NM_MFHI = 0x0,
18031 NM_MFLO = 0x1,
18032 NM_MTHI = 0x2,
18033 NM_MTLO = 0x3,
18034};
18035
18036/* POOL32Axf_1_1 instruction pool */
18037enum {
18038 NM_MTHLIP = 0x0,
18039 NM_SHILOV = 0x1,
18040};
18041
18042/* POOL32Axf_1_3 instruction pool */
18043enum {
18044 NM_RDDSP = 0x0,
18045 NM_WRDSP = 0x1,
18046 NM_EXTP = 0x2,
18047 NM_EXTPDP = 0x3,
18048};
18049
18050/* POOL32Axf_1_4 instruction pool */
18051enum {
18052 NM_SHLL_QB = 0x0,
18053 NM_SHRL_QB = 0x1,
18054};
18055
18056/* POOL32Axf_1_5 instruction pool */
18057enum {
18058 NM_MAQ_S_W_PHR = 0x0,
18059 NM_MAQ_S_W_PHL = 0x1,
18060 NM_MAQ_SA_W_PHR = 0x2,
18061 NM_MAQ_SA_W_PHL = 0x3,
18062};
18063
18064/* POOL32Axf_1_7 instruction pool */
18065enum {
18066 NM_EXTR_W = 0x0,
18067 NM_EXTR_R_W = 0x1,
18068 NM_EXTR_RS_W = 0x2,
18069 NM_EXTR_S_H = 0x3,
18070};
18071
18072/* POOL32Axf_2_0_7 instruction pool */
18073enum {
18074 NM_DPA_W_PH = 0x0,
18075 NM_DPAQ_S_W_PH = 0x1,
18076 NM_DPS_W_PH = 0x2,
18077 NM_DPSQ_S_W_PH = 0x3,
18078 NM_BALIGN = 0x4,
18079 NM_MADD = 0x5,
18080 NM_MULT = 0x6,
18081 NM_EXTRV_W = 0x7,
18082};
18083
18084/* POOL32Axf_2_8_15 instruction pool */
18085enum {
18086 NM_DPAX_W_PH = 0x0,
18087 NM_DPAQ_SA_L_W = 0x1,
18088 NM_DPSX_W_PH = 0x2,
18089 NM_DPSQ_SA_L_W = 0x3,
18090 NM_MADDU = 0x5,
18091 NM_MULTU = 0x6,
18092 NM_EXTRV_R_W = 0x7,
18093};
18094
18095/* POOL32Axf_2_16_23 instruction pool */
18096enum {
18097 NM_DPAU_H_QBL = 0x0,
18098 NM_DPAQX_S_W_PH = 0x1,
18099 NM_DPSU_H_QBL = 0x2,
18100 NM_DPSQX_S_W_PH = 0x3,
18101 NM_EXTPV = 0x4,
18102 NM_MSUB = 0x5,
18103 NM_MULSA_W_PH = 0x6,
18104 NM_EXTRV_RS_W = 0x7,
18105};
18106
18107/* POOL32Axf_2_24_31 instruction pool */
18108enum {
18109 NM_DPAU_H_QBR = 0x0,
18110 NM_DPAQX_SA_W_PH = 0x1,
18111 NM_DPSU_H_QBR = 0x2,
18112 NM_DPSQX_SA_W_PH = 0x3,
18113 NM_EXTPDPV = 0x4,
18114 NM_MSUBU = 0x5,
18115 NM_MULSAQ_S_W_PH = 0x6,
18116 NM_EXTRV_S_H = 0x7,
261c95a0
YK
18117};
18118
18119/* POOL32Axf_{4, 5} instruction pool */
18120enum {
18121 NM_CLO = 0x25,
18122 NM_CLZ = 0x2d,
18123
18124 NM_TLBP = 0x01,
18125 NM_TLBR = 0x09,
18126 NM_TLBWI = 0x11,
18127 NM_TLBWR = 0x19,
18128 NM_TLBINV = 0x03,
18129 NM_TLBINVF = 0x0b,
18130 NM_DI = 0x23,
18131 NM_EI = 0x2b,
18132 NM_RDPGPR = 0x70,
18133 NM_WRPGPR = 0x78,
18134 NM_WAIT = 0x61,
18135 NM_DERET = 0x71,
18136 NM_ERETX = 0x79,
b3979b6f
SM
18137
18138 /* nanoMIPS DSP instructions */
18139 NM_ABSQ_S_QB = 0x00,
18140 NM_ABSQ_S_PH = 0x08,
18141 NM_ABSQ_S_W = 0x10,
18142 NM_PRECEQ_W_PHL = 0x28,
18143 NM_PRECEQ_W_PHR = 0x30,
18144 NM_PRECEQU_PH_QBL = 0x38,
18145 NM_PRECEQU_PH_QBR = 0x48,
18146 NM_PRECEU_PH_QBL = 0x58,
18147 NM_PRECEU_PH_QBR = 0x68,
18148 NM_PRECEQU_PH_QBLA = 0x39,
18149 NM_PRECEQU_PH_QBRA = 0x49,
18150 NM_PRECEU_PH_QBLA = 0x59,
18151 NM_PRECEU_PH_QBRA = 0x69,
18152 NM_REPLV_PH = 0x01,
18153 NM_REPLV_QB = 0x09,
18154 NM_BITREV = 0x18,
18155 NM_INSV = 0x20,
18156 NM_RADDU_W_QB = 0x78,
18157
18158 NM_BITSWAP = 0x05,
18159 NM_WSBH = 0x3d,
261c95a0
YK
18160};
18161
18162/* PP.SR instruction pool */
18163enum {
18164 NM_SAVE = 0x00,
18165 NM_RESTORE = 0x02,
18166 NM_RESTORE_JRC = 0x03,
18167};
18168
18169/* P.SR.F instruction pool */
18170enum {
18171 NM_SAVEF = 0x00,
18172 NM_RESTOREF = 0x01,
18173};
18174
18175/* P16.SYSCALL instruction pool */
18176enum {
18177 NM_SYSCALL16 = 0x00,
18178 NM_HYPCALL16 = 0x01,
18179};
18180
18181/* POOL16C_00 instruction pool */
18182enum {
18183 NM_NOT16 = 0x00,
18184 NM_XOR16 = 0x01,
18185 NM_AND16 = 0x02,
18186 NM_OR16 = 0x03,
18187};
18188
18189/* PP.LSX and PP.LSXS instruction pool */
18190enum {
18191 NM_LBX = 0x00,
18192 NM_LHX = 0x04,
18193 NM_LWX = 0x08,
18194 NM_LDX = 0x0c,
18195
18196 NM_SBX = 0x01,
18197 NM_SHX = 0x05,
18198 NM_SWX = 0x09,
18199 NM_SDX = 0x0d,
18200
18201 NM_LBUX = 0x02,
18202 NM_LHUX = 0x06,
18203 NM_LWC1X = 0x0a,
18204 NM_LDC1X = 0x0e,
18205
18206 NM_LWUX = 0x07,
18207 NM_SWC1X = 0x0b,
18208 NM_SDC1X = 0x0f,
18209
18210 NM_LHXS = 0x04,
18211 NM_LWXS = 0x08,
18212 NM_LDXS = 0x0c,
18213
18214 NM_SHXS = 0x05,
18215 NM_SWXS = 0x09,
18216 NM_SDXS = 0x0d,
18217
18218 NM_LHUXS = 0x06,
18219 NM_LWC1XS = 0x0a,
18220 NM_LDC1XS = 0x0e,
18221
18222 NM_LWUXS = 0x07,
18223 NM_SWC1XS = 0x0b,
18224 NM_SDC1XS = 0x0f,
18225};
18226
18227/* ERETx instruction pool */
18228enum {
18229 NM_ERET = 0x00,
18230 NM_ERETNC = 0x01,
18231};
18232
18233/* POOL32FxF_{0, 1} insturction pool */
18234enum {
18235 NM_CFC1 = 0x40,
18236 NM_CTC1 = 0x60,
18237 NM_MFC1 = 0x80,
18238 NM_MTC1 = 0xa0,
18239 NM_MFHC1 = 0xc0,
18240 NM_MTHC1 = 0xe0,
18241
18242 NM_CVT_S_PL = 0x84,
18243 NM_CVT_S_PU = 0xa4,
18244
18245 NM_CVT_L_S = 0x004,
18246 NM_CVT_L_D = 0x104,
18247 NM_CVT_W_S = 0x024,
18248 NM_CVT_W_D = 0x124,
18249
18250 NM_RSQRT_S = 0x008,
18251 NM_RSQRT_D = 0x108,
18252
18253 NM_SQRT_S = 0x028,
18254 NM_SQRT_D = 0x128,
18255
18256 NM_RECIP_S = 0x048,
18257 NM_RECIP_D = 0x148,
18258
18259 NM_FLOOR_L_S = 0x00c,
18260 NM_FLOOR_L_D = 0x10c,
18261
18262 NM_FLOOR_W_S = 0x02c,
18263 NM_FLOOR_W_D = 0x12c,
18264
18265 NM_CEIL_L_S = 0x04c,
18266 NM_CEIL_L_D = 0x14c,
18267 NM_CEIL_W_S = 0x06c,
18268 NM_CEIL_W_D = 0x16c,
18269 NM_TRUNC_L_S = 0x08c,
18270 NM_TRUNC_L_D = 0x18c,
18271 NM_TRUNC_W_S = 0x0ac,
18272 NM_TRUNC_W_D = 0x1ac,
18273 NM_ROUND_L_S = 0x0cc,
18274 NM_ROUND_L_D = 0x1cc,
18275 NM_ROUND_W_S = 0x0ec,
18276 NM_ROUND_W_D = 0x1ec,
18277
18278 NM_MOV_S = 0x01,
18279 NM_MOV_D = 0x81,
18280 NM_ABS_S = 0x0d,
18281 NM_ABS_D = 0x8d,
18282 NM_NEG_S = 0x2d,
18283 NM_NEG_D = 0xad,
18284 NM_CVT_D_S = 0x04d,
18285 NM_CVT_D_W = 0x0cd,
18286 NM_CVT_D_L = 0x14d,
18287 NM_CVT_S_D = 0x06d,
18288 NM_CVT_S_W = 0x0ed,
18289 NM_CVT_S_L = 0x16d,
18290};
18291
18292/* P.LL instruction pool */
18293enum {
18294 NM_LL = 0x00,
18295 NM_LLWP = 0x01,
18296};
18297
18298/* P.SC instruction pool */
18299enum {
18300 NM_SC = 0x00,
18301 NM_SCWP = 0x01,
18302};
18303
18304/* P.DVP instruction pool */
18305enum {
18306 NM_DVP = 0x00,
18307 NM_EVP = 0x01,
18308};
18309
c533c0f4
AM
18310
18311/*
18312 *
18313 * nanoMIPS decoding engine
18314 *
18315 */
18316
6bfa9f4c
AM
18317
18318/* extraction utilities */
18319
18320#define NANOMIPS_EXTRACT_RD(op) ((op >> 7) & 0x7)
18321#define NANOMIPS_EXTRACT_RS(op) ((op >> 4) & 0x7)
18322#define NANOMIPS_EXTRACT_RS2(op) uMIPS_RS(op)
18323#define NANOMIPS_EXTRACT_RS1(op) ((op >> 1) & 0x7)
18324#define NANOMIPS_EXTRACT_RD5(op) ((op >> 5) & 0x1f)
18325#define NANOMIPS_EXTRACT_RS5(op) (op & 0x1f)
18326
ea4ca3c2
YK
18327/* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr3'). */
18328static inline int decode_gpr_gpr3(int r)
18329{
18330 static const int map[] = { 16, 17, 18, 19, 4, 5, 6, 7 };
18331
18332 return map[r & 0x7];
18333}
18334
8bdb7029
YK
18335/* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr3.src.store'). */
18336static inline int decode_gpr_gpr3_src_store(int r)
18337{
18338 static const int map[] = { 0, 17, 18, 19, 4, 5, 6, 7 };
18339
18340 return map[r & 0x7];
18341}
18342
ea4ca3c2
YK
18343/* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr4'). */
18344static inline int decode_gpr_gpr4(int r)
18345{
18346 static const int map[] = { 8, 9, 10, 11, 4, 5, 6, 7,
18347 16, 17, 18, 19, 20, 21, 22, 23 };
18348
18349 return map[r & 0xf];
18350}
18351
8bdb7029
YK
18352/* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr4.zero'). */
18353static inline int decode_gpr_gpr4_zero(int r)
18354{
18355 static const int map[] = { 8, 9, 10, 0, 4, 5, 6, 7,
18356 16, 17, 18, 19, 20, 21, 22, 23 };
18357
18358 return map[r & 0xf];
18359}
18360
6bfa9f4c 18361
80845edf
YK
18362/* extraction utilities */
18363
18364#define NANOMIPS_EXTRACT_RD(op) ((op >> 7) & 0x7)
18365#define NANOMIPS_EXTRACT_RS(op) ((op >> 4) & 0x7)
18366#define NANOMIPS_EXTRACT_RS2(op) uMIPS_RS(op)
18367#define NANOMIPS_EXTRACT_RS1(op) ((op >> 1) & 0x7)
18368#define NANOMIPS_EXTRACT_RD5(op) ((op >> 5) & 0x1f)
18369#define NANOMIPS_EXTRACT_RS5(op) (op & 0x1f)
18370
18371
bf0718c5
SM
18372static void gen_adjust_sp(DisasContext *ctx, int u)
18373{
18374 gen_op_addr_addi(ctx, cpu_gpr[29], cpu_gpr[29], u);
18375}
18376
18377static void gen_save(DisasContext *ctx, uint8_t rt, uint8_t count,
18378 uint8_t gp, uint16_t u)
18379{
18380 int counter = 0;
18381 TCGv va = tcg_temp_new();
18382 TCGv t0 = tcg_temp_new();
18383
18384 while (counter != count) {
18385 bool use_gp = gp && (counter == count - 1);
18386 int this_rt = use_gp ? 28 : (rt & 0x10) | ((rt + counter) & 0x1f);
18387 int this_offset = -((counter + 1) << 2);
18388 gen_base_offset_addr(ctx, va, 29, this_offset);
18389 gen_load_gpr(t0, this_rt);
18390 tcg_gen_qemu_st_tl(t0, va, ctx->mem_idx,
18391 (MO_TEUL | ctx->default_tcg_memop_mask));
18392 counter++;
18393 }
18394
18395 /* adjust stack pointer */
18396 gen_adjust_sp(ctx, -u);
18397
18398 tcg_temp_free(t0);
18399 tcg_temp_free(va);
18400}
18401
18402static void gen_restore(DisasContext *ctx, uint8_t rt, uint8_t count,
18403 uint8_t gp, uint16_t u)
18404{
18405 int counter = 0;
18406 TCGv va = tcg_temp_new();
18407 TCGv t0 = tcg_temp_new();
18408
18409 while (counter != count) {
18410 bool use_gp = gp && (counter == count - 1);
18411 int this_rt = use_gp ? 28 : (rt & 0x10) | ((rt + counter) & 0x1f);
18412 int this_offset = u - ((counter + 1) << 2);
18413 gen_base_offset_addr(ctx, va, 29, this_offset);
18414 tcg_gen_qemu_ld_tl(t0, va, ctx->mem_idx, MO_TESL |
18415 ctx->default_tcg_memop_mask);
18416 tcg_gen_ext32s_tl(t0, t0);
18417 gen_store_gpr(t0, this_rt);
18418 counter++;
18419 }
18420
18421 /* adjust stack pointer */
18422 gen_adjust_sp(ctx, u);
18423
18424 tcg_temp_free(t0);
18425 tcg_temp_free(va);
18426}
18427
80845edf
YK
18428static void gen_pool16c_nanomips_insn(DisasContext *ctx)
18429{
18430 int rt = decode_gpr_gpr3(NANOMIPS_EXTRACT_RD(ctx->opcode));
18431 int rs = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS(ctx->opcode));
18432
18433 switch (extract32(ctx->opcode, 2, 2)) {
18434 case NM_NOT16:
18435 gen_logic(ctx, OPC_NOR, rt, rs, 0);
18436 break;
18437 case NM_AND16:
18438 gen_logic(ctx, OPC_AND, rt, rt, rs);
18439 break;
18440 case NM_XOR16:
18441 gen_logic(ctx, OPC_XOR, rt, rt, rs);
18442 break;
18443 case NM_OR16:
18444 gen_logic(ctx, OPC_OR, rt, rt, rs);
18445 break;
18446 }
18447}
18448
0a1a6ed7 18449static void gen_pool32a0_nanomips_insn(CPUMIPSState *env, DisasContext *ctx)
e0cf0e65
YK
18450{
18451 int rt = extract32(ctx->opcode, 21, 5);
18452 int rs = extract32(ctx->opcode, 16, 5);
18453 int rd = extract32(ctx->opcode, 11, 5);
18454
18455 switch (extract32(ctx->opcode, 3, 7)) {
18456 case NM_P_TRAP:
18457 switch (extract32(ctx->opcode, 10, 1)) {
18458 case NM_TEQ:
fb32f8c8 18459 check_nms(ctx);
e0cf0e65
YK
18460 gen_trap(ctx, OPC_TEQ, rs, rt, -1);
18461 break;
18462 case NM_TNE:
fb32f8c8 18463 check_nms(ctx);
e0cf0e65
YK
18464 gen_trap(ctx, OPC_TNE, rs, rt, -1);
18465 break;
18466 }
18467 break;
18468 case NM_RDHWR:
fb32f8c8 18469 check_nms(ctx);
e0cf0e65
YK
18470 gen_rdhwr(ctx, rt, rs, extract32(ctx->opcode, 11, 3));
18471 break;
18472 case NM_SEB:
fb32f8c8 18473 check_nms(ctx);
e0cf0e65
YK
18474 gen_bshfl(ctx, OPC_SEB, rs, rt);
18475 break;
18476 case NM_SEH:
18477 gen_bshfl(ctx, OPC_SEH, rs, rt);
18478 break;
18479 case NM_SLLV:
18480 gen_shift(ctx, OPC_SLLV, rd, rt, rs);
18481 break;
18482 case NM_SRLV:
18483 gen_shift(ctx, OPC_SRLV, rd, rt, rs);
18484 break;
18485 case NM_SRAV:
18486 gen_shift(ctx, OPC_SRAV, rd, rt, rs);
18487 break;
18488 case NM_ROTRV:
18489 gen_shift(ctx, OPC_ROTRV, rd, rt, rs);
18490 break;
18491 case NM_ADD:
18492 gen_arith(ctx, OPC_ADD, rd, rs, rt);
18493 break;
18494 case NM_ADDU:
18495 gen_arith(ctx, OPC_ADDU, rd, rs, rt);
18496 break;
18497 case NM_SUB:
fb32f8c8 18498 check_nms(ctx);
e0cf0e65
YK
18499 gen_arith(ctx, OPC_SUB, rd, rs, rt);
18500 break;
18501 case NM_SUBU:
18502 gen_arith(ctx, OPC_SUBU, rd, rs, rt);
18503 break;
18504 case NM_P_CMOVE:
18505 switch (extract32(ctx->opcode, 10, 1)) {
18506 case NM_MOVZ:
18507 gen_cond_move(ctx, OPC_MOVZ, rd, rs, rt);
18508 break;
18509 case NM_MOVN:
18510 gen_cond_move(ctx, OPC_MOVN, rd, rs, rt);
18511 break;
18512 }
18513 break;
18514 case NM_AND:
18515 gen_logic(ctx, OPC_AND, rd, rs, rt);
18516 break;
18517 case NM_OR:
18518 gen_logic(ctx, OPC_OR, rd, rs, rt);
18519 break;
18520 case NM_NOR:
18521 gen_logic(ctx, OPC_NOR, rd, rs, rt);
18522 break;
18523 case NM_XOR:
18524 gen_logic(ctx, OPC_XOR, rd, rs, rt);
18525 break;
18526 case NM_SLT:
18527 gen_slt(ctx, OPC_SLT, rd, rs, rt);
18528 break;
18529 case NM_P_SLTU:
18530 if (rd == 0) {
18531 /* P_DVP */
18532#ifndef CONFIG_USER_ONLY
18533 TCGv t0 = tcg_temp_new();
18534 switch (extract32(ctx->opcode, 10, 1)) {
18535 case NM_DVP:
18536 if (ctx->vp) {
18537 check_cp0_enabled(ctx);
18538 gen_helper_dvp(t0, cpu_env);
18539 gen_store_gpr(t0, rt);
18540 }
18541 break;
18542 case NM_EVP:
18543 if (ctx->vp) {
18544 check_cp0_enabled(ctx);
18545 gen_helper_evp(t0, cpu_env);
18546 gen_store_gpr(t0, rt);
18547 }
18548 break;
18549 }
18550 tcg_temp_free(t0);
18551#endif
18552 } else {
18553 gen_slt(ctx, OPC_SLTU, rd, rs, rt);
18554 }
18555 break;
18556 case NM_SOV:
18557 {
18558 TCGv t0 = tcg_temp_new();
18559 TCGv t1 = tcg_temp_new();
18560 TCGv t2 = tcg_temp_new();
18561
18562 gen_load_gpr(t1, rs);
18563 gen_load_gpr(t2, rt);
18564 tcg_gen_add_tl(t0, t1, t2);
18565 tcg_gen_ext32s_tl(t0, t0);
18566 tcg_gen_xor_tl(t1, t1, t2);
18567 tcg_gen_xor_tl(t2, t0, t2);
18568 tcg_gen_andc_tl(t1, t2, t1);
18569
18570 /* operands of same sign, result different sign */
18571 tcg_gen_setcondi_tl(TCG_COND_LT, t0, t1, 0);
18572 gen_store_gpr(t0, rd);
18573
18574 tcg_temp_free(t0);
18575 tcg_temp_free(t1);
18576 tcg_temp_free(t2);
18577 }
18578 break;
18579 case NM_MUL:
18580 gen_r6_muldiv(ctx, R6_OPC_MUL, rd, rs, rt);
18581 break;
18582 case NM_MUH:
18583 gen_r6_muldiv(ctx, R6_OPC_MUH, rd, rs, rt);
18584 break;
18585 case NM_MULU:
18586 gen_r6_muldiv(ctx, R6_OPC_MULU, rd, rs, rt);
18587 break;
18588 case NM_MUHU:
18589 gen_r6_muldiv(ctx, R6_OPC_MUHU, rd, rs, rt);
18590 break;
18591 case NM_DIV:
18592 gen_r6_muldiv(ctx, R6_OPC_DIV, rd, rs, rt);
18593 break;
18594 case NM_MOD:
18595 gen_r6_muldiv(ctx, R6_OPC_MOD, rd, rs, rt);
18596 break;
18597 case NM_DIVU:
18598 gen_r6_muldiv(ctx, R6_OPC_DIVU, rd, rs, rt);
18599 break;
18600 case NM_MODU:
18601 gen_r6_muldiv(ctx, R6_OPC_MODU, rd, rs, rt);
18602 break;
18603#ifndef CONFIG_USER_ONLY
18604 case NM_MFC0:
18605 check_cp0_enabled(ctx);
18606 if (rt == 0) {
18607 /* Treat as NOP. */
18608 break;
18609 }
18610 gen_mfc0(ctx, cpu_gpr[rt], rs, extract32(ctx->opcode, 11, 3));
18611 break;
18612 case NM_MTC0:
18613 check_cp0_enabled(ctx);
18614 {
18615 TCGv t0 = tcg_temp_new();
18616
18617 gen_load_gpr(t0, rt);
18618 gen_mtc0(ctx, t0, rs, extract32(ctx->opcode, 11, 3));
18619 tcg_temp_free(t0);
18620 }
18621 break;
0a1a6ed7
SM
18622 case NM_D_E_MT_VPE:
18623 {
18624 uint8_t sc = extract32(ctx->opcode, 10, 1);
18625 TCGv t0 = tcg_temp_new();
18626
18627 switch (sc) {
18628 case 0:
18629 if (rs == 1) {
18630 /* DMT */
18631 check_cp0_mt(ctx);
18632 gen_helper_dmt(t0);
18633 gen_store_gpr(t0, rt);
18634 } else if (rs == 0) {
18635 /* DVPE */
18636 check_cp0_mt(ctx);
18637 gen_helper_dvpe(t0, cpu_env);
18638 gen_store_gpr(t0, rt);
18639 } else {
18640 generate_exception_end(ctx, EXCP_RI);
18641 }
18642 break;
18643 case 1:
18644 if (rs == 1) {
18645 /* EMT */
18646 check_cp0_mt(ctx);
18647 gen_helper_emt(t0);
18648 gen_store_gpr(t0, rt);
18649 } else if (rs == 0) {
18650 /* EVPE */
18651 check_cp0_mt(ctx);
18652 gen_helper_evpe(t0, cpu_env);
18653 gen_store_gpr(t0, rt);
18654 } else {
18655 generate_exception_end(ctx, EXCP_RI);
18656 }
18657 break;
18658 }
18659
18660 tcg_temp_free(t0);
18661 }
18662 break;
18663 case NM_FORK:
18664 check_mt(ctx);
18665 {
18666 TCGv t0 = tcg_temp_new();
18667 TCGv t1 = tcg_temp_new();
18668
18669 gen_load_gpr(t0, rt);
18670 gen_load_gpr(t1, rs);
18671 gen_helper_fork(t0, t1);
18672 tcg_temp_free(t0);
18673 tcg_temp_free(t1);
18674 }
18675 break;
18676 case NM_MFTR:
18677 case NM_MFHTR:
18678 check_cp0_enabled(ctx);
18679 if (rd == 0) {
18680 /* Treat as NOP. */
18681 return;
18682 }
18683 gen_mftr(env, ctx, rs, rt, extract32(ctx->opcode, 10, 1),
18684 extract32(ctx->opcode, 11, 5), extract32(ctx->opcode, 3, 1));
18685 break;
18686 case NM_MTTR:
18687 case NM_MTHTR:
18688 check_cp0_enabled(ctx);
18689 gen_mttr(env, ctx, rs, rt, extract32(ctx->opcode, 10, 1),
18690 extract32(ctx->opcode, 11, 5), extract32(ctx->opcode, 3, 1));
18691 break;
18692 case NM_YIELD:
18693 check_mt(ctx);
18694 {
18695 TCGv t0 = tcg_temp_new();
18696
18697 gen_load_gpr(t0, rs);
18698 gen_helper_yield(t0, cpu_env, t0);
18699 gen_store_gpr(t0, rt);
18700 tcg_temp_free(t0);
18701 }
18702 break;
e0cf0e65
YK
18703#endif
18704 default:
18705 generate_exception_end(ctx, EXCP_RI);
18706 break;
18707 }
18708}
18709
2ed42efa
SM
18710/* dsp */
18711static void gen_pool32axf_1_5_nanomips_insn(DisasContext *ctx, uint32_t opc,
18712 int ret, int v1, int v2)
18713{
18714 TCGv_i32 t0;
18715 TCGv v0_t;
18716 TCGv v1_t;
18717
18718 t0 = tcg_temp_new_i32();
18719
18720 v0_t = tcg_temp_new();
18721 v1_t = tcg_temp_new();
18722
18723 tcg_gen_movi_i32(t0, v2 >> 3);
18724
18725 gen_load_gpr(v0_t, ret);
18726 gen_load_gpr(v1_t, v1);
18727
18728 switch (opc) {
18729 case NM_MAQ_S_W_PHR:
18730 check_dsp(ctx);
18731 gen_helper_maq_s_w_phr(t0, v1_t, v0_t, cpu_env);
18732 break;
18733 case NM_MAQ_S_W_PHL:
18734 check_dsp(ctx);
18735 gen_helper_maq_s_w_phl(t0, v1_t, v0_t, cpu_env);
18736 break;
18737 case NM_MAQ_SA_W_PHR:
18738 check_dsp(ctx);
18739 gen_helper_maq_sa_w_phr(t0, v1_t, v0_t, cpu_env);
18740 break;
18741 case NM_MAQ_SA_W_PHL:
18742 check_dsp(ctx);
18743 gen_helper_maq_sa_w_phl(t0, v1_t, v0_t, cpu_env);
18744 break;
18745 default:
18746 generate_exception_end(ctx, EXCP_RI);
18747 break;
18748 }
18749
18750 tcg_temp_free_i32(t0);
18751
18752 tcg_temp_free(v0_t);
18753 tcg_temp_free(v1_t);
18754}
18755
18756
18757static void gen_pool32axf_1_nanomips_insn(DisasContext *ctx, uint32_t opc,
18758 int ret, int v1, int v2)
18759{
18760 int16_t imm;
18761 TCGv t0 = tcg_temp_new();
18762 TCGv t1 = tcg_temp_new();
18763 TCGv v0_t = tcg_temp_new();
18764
18765 gen_load_gpr(v0_t, v1);
18766
18767 switch (opc) {
18768 case NM_POOL32AXF_1_0:
18769 check_dsp(ctx);
18770 switch (extract32(ctx->opcode, 12, 2)) {
18771 case NM_MFHI:
18772 gen_HILO(ctx, OPC_MFHI, v2 >> 3, ret);
18773 break;
18774 case NM_MFLO:
18775 gen_HILO(ctx, OPC_MFLO, v2 >> 3, ret);
18776 break;
18777 case NM_MTHI:
18778 gen_HILO(ctx, OPC_MTHI, v2 >> 3, v1);
18779 break;
18780 case NM_MTLO:
18781 gen_HILO(ctx, OPC_MTLO, v2 >> 3, v1);
18782 break;
18783 }
18784 break;
18785 case NM_POOL32AXF_1_1:
18786 check_dsp(ctx);
18787 switch (extract32(ctx->opcode, 12, 2)) {
18788 case NM_MTHLIP:
18789 tcg_gen_movi_tl(t0, v2);
18790 gen_helper_mthlip(t0, v0_t, cpu_env);
18791 break;
18792 case NM_SHILOV:
18793 tcg_gen_movi_tl(t0, v2 >> 3);
18794 gen_helper_shilo(t0, v0_t, cpu_env);
18795 break;
18796 default:
18797 generate_exception_end(ctx, EXCP_RI);
18798 break;
18799 }
18800 break;
18801 case NM_POOL32AXF_1_3:
18802 check_dsp(ctx);
18803 imm = extract32(ctx->opcode, 14, 7);
18804 switch (extract32(ctx->opcode, 12, 2)) {
18805 case NM_RDDSP:
18806 tcg_gen_movi_tl(t0, imm);
18807 gen_helper_rddsp(t0, t0, cpu_env);
18808 gen_store_gpr(t0, ret);
18809 break;
18810 case NM_WRDSP:
18811 gen_load_gpr(t0, ret);
18812 tcg_gen_movi_tl(t1, imm);
18813 gen_helper_wrdsp(t0, t1, cpu_env);
18814 break;
18815 case NM_EXTP:
18816 tcg_gen_movi_tl(t0, v2 >> 3);
18817 tcg_gen_movi_tl(t1, v1);
18818 gen_helper_extp(t0, t0, t1, cpu_env);
18819 gen_store_gpr(t0, ret);
18820 break;
18821 case NM_EXTPDP:
18822 tcg_gen_movi_tl(t0, v2 >> 3);
18823 tcg_gen_movi_tl(t1, v1);
18824 gen_helper_extpdp(t0, t0, t1, cpu_env);
18825 gen_store_gpr(t0, ret);
18826 break;
18827 }
18828 break;
18829 case NM_POOL32AXF_1_4:
18830 check_dsp(ctx);
18831 tcg_gen_movi_tl(t0, v2 >> 2);
18832 switch (extract32(ctx->opcode, 12, 1)) {
18833 case NM_SHLL_QB:
18834 gen_helper_shll_qb(t0, t0, v0_t, cpu_env);
18835 gen_store_gpr(t0, ret);
18836 break;
18837 case NM_SHRL_QB:
18838 gen_helper_shrl_qb(t0, t0, v0_t);
18839 gen_store_gpr(t0, ret);
18840 break;
18841 }
18842 break;
18843 case NM_POOL32AXF_1_5:
18844 opc = extract32(ctx->opcode, 12, 2);
18845 gen_pool32axf_1_5_nanomips_insn(ctx, opc, ret, v1, v2);
18846 break;
18847 case NM_POOL32AXF_1_7:
18848 check_dsp(ctx);
18849 tcg_gen_movi_tl(t0, v2 >> 3);
18850 tcg_gen_movi_tl(t1, v1);
18851 switch (extract32(ctx->opcode, 12, 2)) {
18852 case NM_EXTR_W:
18853 gen_helper_extr_w(t0, t0, t1, cpu_env);
18854 gen_store_gpr(t0, ret);
18855 break;
18856 case NM_EXTR_R_W:
18857 gen_helper_extr_r_w(t0, t0, t1, cpu_env);
18858 gen_store_gpr(t0, ret);
18859 break;
18860 case NM_EXTR_RS_W:
18861 gen_helper_extr_rs_w(t0, t0, t1, cpu_env);
18862 gen_store_gpr(t0, ret);
18863 break;
18864 case NM_EXTR_S_H:
18865 gen_helper_extr_s_h(t0, t0, t1, cpu_env);
18866 gen_store_gpr(t0, ret);
18867 break;
18868 }
18869 break;
18870 default:
18871 generate_exception_end(ctx, EXCP_RI);
18872 break;
18873 }
18874
18875 tcg_temp_free(t0);
18876 tcg_temp_free(t1);
18877 tcg_temp_free(v0_t);
18878}
18879
8b3698b2
SM
18880static void gen_pool32axf_2_multiply(DisasContext *ctx, uint32_t opc,
18881 TCGv v0, TCGv v1, int rd)
18882{
18883 TCGv_i32 t0;
18884
18885 t0 = tcg_temp_new_i32();
18886
18887 tcg_gen_movi_i32(t0, rd >> 3);
18888
18889 switch (opc) {
18890 case NM_POOL32AXF_2_0_7:
18891 switch (extract32(ctx->opcode, 9, 3)) {
18892 case NM_DPA_W_PH:
908f6be1 18893 check_dsp_r2(ctx);
8b3698b2
SM
18894 gen_helper_dpa_w_ph(t0, v1, v0, cpu_env);
18895 break;
18896 case NM_DPAQ_S_W_PH:
18897 check_dsp(ctx);
18898 gen_helper_dpaq_s_w_ph(t0, v1, v0, cpu_env);
18899 break;
18900 case NM_DPS_W_PH:
908f6be1 18901 check_dsp_r2(ctx);
8b3698b2
SM
18902 gen_helper_dps_w_ph(t0, v1, v0, cpu_env);
18903 break;
18904 case NM_DPSQ_S_W_PH:
18905 check_dsp(ctx);
18906 gen_helper_dpsq_s_w_ph(t0, v1, v0, cpu_env);
18907 break;
18908 default:
18909 generate_exception_end(ctx, EXCP_RI);
18910 break;
18911 }
18912 break;
18913 case NM_POOL32AXF_2_8_15:
18914 switch (extract32(ctx->opcode, 9, 3)) {
18915 case NM_DPAX_W_PH:
908f6be1 18916 check_dsp_r2(ctx);
8b3698b2
SM
18917 gen_helper_dpax_w_ph(t0, v0, v1, cpu_env);
18918 break;
18919 case NM_DPAQ_SA_L_W:
18920 check_dsp(ctx);
18921 gen_helper_dpaq_sa_l_w(t0, v0, v1, cpu_env);
18922 break;
18923 case NM_DPSX_W_PH:
908f6be1 18924 check_dsp_r2(ctx);
8b3698b2
SM
18925 gen_helper_dpsx_w_ph(t0, v0, v1, cpu_env);
18926 break;
18927 case NM_DPSQ_SA_L_W:
18928 check_dsp(ctx);
18929 gen_helper_dpsq_sa_l_w(t0, v0, v1, cpu_env);
18930 break;
18931 default:
18932 generate_exception_end(ctx, EXCP_RI);
18933 break;
18934 }
18935 break;
18936 case NM_POOL32AXF_2_16_23:
18937 switch (extract32(ctx->opcode, 9, 3)) {
18938 case NM_DPAU_H_QBL:
18939 check_dsp(ctx);
18940 gen_helper_dpau_h_qbl(t0, v0, v1, cpu_env);
18941 break;
18942 case NM_DPAQX_S_W_PH:
908f6be1 18943 check_dsp_r2(ctx);
8b3698b2
SM
18944 gen_helper_dpaqx_s_w_ph(t0, v0, v1, cpu_env);
18945 break;
18946 case NM_DPSU_H_QBL:
18947 check_dsp(ctx);
18948 gen_helper_dpsu_h_qbl(t0, v0, v1, cpu_env);
18949 break;
18950 case NM_DPSQX_S_W_PH:
908f6be1 18951 check_dsp_r2(ctx);
8b3698b2
SM
18952 gen_helper_dpsqx_s_w_ph(t0, v0, v1, cpu_env);
18953 break;
18954 case NM_MULSA_W_PH:
908f6be1 18955 check_dsp_r2(ctx);
8b3698b2
SM
18956 gen_helper_mulsa_w_ph(t0, v0, v1, cpu_env);
18957 break;
18958 default:
18959 generate_exception_end(ctx, EXCP_RI);
18960 break;
18961 }
18962 break;
18963 case NM_POOL32AXF_2_24_31:
18964 switch (extract32(ctx->opcode, 9, 3)) {
18965 case NM_DPAU_H_QBR:
18966 check_dsp(ctx);
18967 gen_helper_dpau_h_qbr(t0, v1, v0, cpu_env);
18968 break;
18969 case NM_DPAQX_SA_W_PH:
908f6be1 18970 check_dsp_r2(ctx);
8b3698b2
SM
18971 gen_helper_dpaqx_sa_w_ph(t0, v1, v0, cpu_env);
18972 break;
18973 case NM_DPSU_H_QBR:
18974 check_dsp(ctx);
18975 gen_helper_dpsu_h_qbr(t0, v1, v0, cpu_env);
18976 break;
18977 case NM_DPSQX_SA_W_PH:
908f6be1 18978 check_dsp_r2(ctx);
8b3698b2
SM
18979 gen_helper_dpsqx_sa_w_ph(t0, v1, v0, cpu_env);
18980 break;
18981 case NM_MULSAQ_S_W_PH:
18982 check_dsp(ctx);
18983 gen_helper_mulsaq_s_w_ph(t0, v1, v0, cpu_env);
18984 break;
18985 default:
18986 generate_exception_end(ctx, EXCP_RI);
18987 break;
18988 }
18989 break;
18990 default:
18991 generate_exception_end(ctx, EXCP_RI);
18992 break;
18993 }
18994
18995 tcg_temp_free_i32(t0);
18996}
18997
18998static void gen_pool32axf_2_nanomips_insn(DisasContext *ctx, uint32_t opc,
18999 int rt, int rs, int rd)
19000{
19001 int ret = rt;
19002 TCGv t0 = tcg_temp_new();
19003 TCGv t1 = tcg_temp_new();
19004 TCGv v0_t = tcg_temp_new();
19005 TCGv v1_t = tcg_temp_new();
19006
19007 gen_load_gpr(v0_t, rt);
19008 gen_load_gpr(v1_t, rs);
19009
19010 switch (opc) {
19011 case NM_POOL32AXF_2_0_7:
19012 switch (extract32(ctx->opcode, 9, 3)) {
19013 case NM_DPA_W_PH:
19014 case NM_DPAQ_S_W_PH:
19015 case NM_DPS_W_PH:
19016 case NM_DPSQ_S_W_PH:
19017 gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
19018 break;
19019 case NM_BALIGN:
908f6be1 19020 check_dsp_r2(ctx);
8b3698b2
SM
19021 if (rt != 0) {
19022 gen_load_gpr(t0, rs);
19023 rd &= 3;
19024 if (rd != 0 && rd != 2) {
19025 tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 8 * rd);
19026 tcg_gen_ext32u_tl(t0, t0);
19027 tcg_gen_shri_tl(t0, t0, 8 * (4 - rd));
19028 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
19029 }
19030 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
19031 }
19032 break;
19033 case NM_MADD:
19034 check_dsp(ctx);
19035 {
19036 int acc = extract32(ctx->opcode, 14, 2);
19037 TCGv_i64 t2 = tcg_temp_new_i64();
19038 TCGv_i64 t3 = tcg_temp_new_i64();
19039
19040 gen_load_gpr(t0, rt);
19041 gen_load_gpr(t1, rs);
19042 tcg_gen_ext_tl_i64(t2, t0);
19043 tcg_gen_ext_tl_i64(t3, t1);
19044 tcg_gen_mul_i64(t2, t2, t3);
19045 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
19046 tcg_gen_add_i64(t2, t2, t3);
19047 tcg_temp_free_i64(t3);
19048 gen_move_low32(cpu_LO[acc], t2);
19049 gen_move_high32(cpu_HI[acc], t2);
19050 tcg_temp_free_i64(t2);
19051 }
19052 break;
19053 case NM_MULT:
19054 check_dsp(ctx);
19055 {
19056 int acc = extract32(ctx->opcode, 14, 2);
19057 TCGv_i32 t2 = tcg_temp_new_i32();
19058 TCGv_i32 t3 = tcg_temp_new_i32();
19059
19060 gen_load_gpr(t0, rs);
19061 gen_load_gpr(t1, rt);
19062 tcg_gen_trunc_tl_i32(t2, t0);
19063 tcg_gen_trunc_tl_i32(t3, t1);
19064 tcg_gen_muls2_i32(t2, t3, t2, t3);
19065 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
19066 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
19067 tcg_temp_free_i32(t2);
19068 tcg_temp_free_i32(t3);
19069 }
19070 break;
19071 case NM_EXTRV_W:
19072 check_dsp(ctx);
19073 gen_load_gpr(v1_t, rs);
19074 tcg_gen_movi_tl(t0, rd >> 3);
19075 gen_helper_extr_w(t0, t0, v1_t, cpu_env);
19076 gen_store_gpr(t0, ret);
19077 break;
19078 }
19079 break;
19080 case NM_POOL32AXF_2_8_15:
19081 switch (extract32(ctx->opcode, 9, 3)) {
19082 case NM_DPAX_W_PH:
19083 case NM_DPAQ_SA_L_W:
19084 case NM_DPSX_W_PH:
19085 case NM_DPSQ_SA_L_W:
19086 gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
19087 break;
19088 case NM_MADDU:
19089 check_dsp(ctx);
19090 {
19091 int acc = extract32(ctx->opcode, 14, 2);
19092 TCGv_i64 t2 = tcg_temp_new_i64();
19093 TCGv_i64 t3 = tcg_temp_new_i64();
19094
19095 gen_load_gpr(t0, rs);
19096 gen_load_gpr(t1, rt);
19097 tcg_gen_ext32u_tl(t0, t0);
19098 tcg_gen_ext32u_tl(t1, t1);
19099 tcg_gen_extu_tl_i64(t2, t0);
19100 tcg_gen_extu_tl_i64(t3, t1);
19101 tcg_gen_mul_i64(t2, t2, t3);
19102 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
19103 tcg_gen_add_i64(t2, t2, t3);
19104 tcg_temp_free_i64(t3);
19105 gen_move_low32(cpu_LO[acc], t2);
19106 gen_move_high32(cpu_HI[acc], t2);
19107 tcg_temp_free_i64(t2);
19108 }
19109 break;
19110 case NM_MULTU:
19111 check_dsp(ctx);
19112 {
19113 int acc = extract32(ctx->opcode, 14, 2);
19114 TCGv_i32 t2 = tcg_temp_new_i32();
19115 TCGv_i32 t3 = tcg_temp_new_i32();
19116
19117 gen_load_gpr(t0, rs);
19118 gen_load_gpr(t1, rt);
19119 tcg_gen_trunc_tl_i32(t2, t0);
19120 tcg_gen_trunc_tl_i32(t3, t1);
19121 tcg_gen_mulu2_i32(t2, t3, t2, t3);
19122 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
19123 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
19124 tcg_temp_free_i32(t2);
19125 tcg_temp_free_i32(t3);
19126 }
19127 break;
19128 case NM_EXTRV_R_W:
19129 check_dsp(ctx);
19130 tcg_gen_movi_tl(t0, rd >> 3);
19131 gen_helper_extr_r_w(t0, t0, v1_t, cpu_env);
19132 gen_store_gpr(t0, ret);
19133 break;
19134 default:
19135 generate_exception_end(ctx, EXCP_RI);
19136 break;
19137 }
19138 break;
19139 case NM_POOL32AXF_2_16_23:
19140 switch (extract32(ctx->opcode, 9, 3)) {
19141 case NM_DPAU_H_QBL:
19142 case NM_DPAQX_S_W_PH:
19143 case NM_DPSU_H_QBL:
19144 case NM_DPSQX_S_W_PH:
19145 case NM_MULSA_W_PH:
19146 gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
19147 break;
19148 case NM_EXTPV:
19149 check_dsp(ctx);
19150 tcg_gen_movi_tl(t0, rd >> 3);
19151 gen_helper_extp(t0, t0, v1_t, cpu_env);
19152 gen_store_gpr(t0, ret);
19153 break;
19154 case NM_MSUB:
19155 check_dsp(ctx);
19156 {
19157 int acc = extract32(ctx->opcode, 14, 2);
19158 TCGv_i64 t2 = tcg_temp_new_i64();
19159 TCGv_i64 t3 = tcg_temp_new_i64();
19160
19161 gen_load_gpr(t0, rs);
19162 gen_load_gpr(t1, rt);
19163 tcg_gen_ext_tl_i64(t2, t0);
19164 tcg_gen_ext_tl_i64(t3, t1);
19165 tcg_gen_mul_i64(t2, t2, t3);
19166 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
19167 tcg_gen_sub_i64(t2, t3, t2);
19168 tcg_temp_free_i64(t3);
19169 gen_move_low32(cpu_LO[acc], t2);
19170 gen_move_high32(cpu_HI[acc], t2);
19171 tcg_temp_free_i64(t2);
19172 }
19173 break;
19174 case NM_EXTRV_RS_W:
19175 check_dsp(ctx);
19176 tcg_gen_movi_tl(t0, rd >> 3);
19177 gen_helper_extr_rs_w(t0, t0, v1_t, cpu_env);
19178 gen_store_gpr(t0, ret);
19179 break;
19180 }
19181 break;
19182 case NM_POOL32AXF_2_24_31:
19183 switch (extract32(ctx->opcode, 9, 3)) {
19184 case NM_DPAU_H_QBR:
19185 case NM_DPAQX_SA_W_PH:
19186 case NM_DPSU_H_QBR:
19187 case NM_DPSQX_SA_W_PH:
19188 case NM_MULSAQ_S_W_PH:
19189 gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
19190 break;
19191 case NM_EXTPDPV:
19192 check_dsp(ctx);
19193 tcg_gen_movi_tl(t0, rd >> 3);
19194 gen_helper_extpdp(t0, t0, v1_t, cpu_env);
19195 gen_store_gpr(t0, ret);
19196 break;
19197 case NM_MSUBU:
19198 check_dsp(ctx);
19199 {
19200 int acc = extract32(ctx->opcode, 14, 2);
19201 TCGv_i64 t2 = tcg_temp_new_i64();
19202 TCGv_i64 t3 = tcg_temp_new_i64();
19203
19204 gen_load_gpr(t0, rs);
19205 gen_load_gpr(t1, rt);
19206 tcg_gen_ext32u_tl(t0, t0);
19207 tcg_gen_ext32u_tl(t1, t1);
19208 tcg_gen_extu_tl_i64(t2, t0);
19209 tcg_gen_extu_tl_i64(t3, t1);
19210 tcg_gen_mul_i64(t2, t2, t3);
19211 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
19212 tcg_gen_sub_i64(t2, t3, t2);
19213 tcg_temp_free_i64(t3);
19214 gen_move_low32(cpu_LO[acc], t2);
19215 gen_move_high32(cpu_HI[acc], t2);
19216 tcg_temp_free_i64(t2);
19217 }
19218 break;
19219 case NM_EXTRV_S_H:
19220 check_dsp(ctx);
19221 tcg_gen_movi_tl(t0, rd >> 3);
19222 gen_helper_extr_s_h(t0, t0, v0_t, cpu_env);
19223 gen_store_gpr(t0, ret);
19224 break;
19225 }
19226 break;
19227 default:
19228 generate_exception_end(ctx, EXCP_RI);
19229 break;
19230 }
19231
19232 tcg_temp_free(t0);
19233 tcg_temp_free(t1);
19234
19235 tcg_temp_free(v0_t);
19236 tcg_temp_free(v1_t);
19237}
19238
4c75c985
SM
19239static void gen_pool32axf_4_nanomips_insn(DisasContext *ctx, uint32_t opc,
19240 int rt, int rs)
19241{
19242 int ret = rt;
19243 TCGv t0 = tcg_temp_new();
19244 TCGv v0_t = tcg_temp_new();
19245
19246 gen_load_gpr(v0_t, rs);
19247
19248 switch (opc) {
19249 case NM_ABSQ_S_QB:
908f6be1 19250 check_dsp_r2(ctx);
4c75c985
SM
19251 gen_helper_absq_s_qb(v0_t, v0_t, cpu_env);
19252 gen_store_gpr(v0_t, ret);
19253 break;
19254 case NM_ABSQ_S_PH:
19255 check_dsp(ctx);
19256 gen_helper_absq_s_ph(v0_t, v0_t, cpu_env);
19257 gen_store_gpr(v0_t, ret);
19258 break;
19259 case NM_ABSQ_S_W:
19260 check_dsp(ctx);
19261 gen_helper_absq_s_w(v0_t, v0_t, cpu_env);
19262 gen_store_gpr(v0_t, ret);
19263 break;
19264 case NM_PRECEQ_W_PHL:
19265 check_dsp(ctx);
19266 tcg_gen_andi_tl(v0_t, v0_t, 0xFFFF0000);
19267 tcg_gen_ext32s_tl(v0_t, v0_t);
19268 gen_store_gpr(v0_t, ret);
19269 break;
19270 case NM_PRECEQ_W_PHR:
19271 check_dsp(ctx);
19272 tcg_gen_andi_tl(v0_t, v0_t, 0x0000FFFF);
19273 tcg_gen_shli_tl(v0_t, v0_t, 16);
19274 tcg_gen_ext32s_tl(v0_t, v0_t);
19275 gen_store_gpr(v0_t, ret);
19276 break;
19277 case NM_PRECEQU_PH_QBL:
19278 check_dsp(ctx);
19279 gen_helper_precequ_ph_qbl(v0_t, v0_t);
19280 gen_store_gpr(v0_t, ret);
19281 break;
19282 case NM_PRECEQU_PH_QBR:
19283 check_dsp(ctx);
19284 gen_helper_precequ_ph_qbr(v0_t, v0_t);
19285 gen_store_gpr(v0_t, ret);
19286 break;
19287 case NM_PRECEQU_PH_QBLA:
19288 check_dsp(ctx);
19289 gen_helper_precequ_ph_qbla(v0_t, v0_t);
19290 gen_store_gpr(v0_t, ret);
19291 break;
19292 case NM_PRECEQU_PH_QBRA:
19293 check_dsp(ctx);
19294 gen_helper_precequ_ph_qbra(v0_t, v0_t);
19295 gen_store_gpr(v0_t, ret);
19296 break;
19297 case NM_PRECEU_PH_QBL:
19298 check_dsp(ctx);
19299 gen_helper_preceu_ph_qbl(v0_t, v0_t);
19300 gen_store_gpr(v0_t, ret);
19301 break;
19302 case NM_PRECEU_PH_QBR:
19303 check_dsp(ctx);
19304 gen_helper_preceu_ph_qbr(v0_t, v0_t);
19305 gen_store_gpr(v0_t, ret);
19306 break;
19307 case NM_PRECEU_PH_QBLA:
19308 check_dsp(ctx);
19309 gen_helper_preceu_ph_qbla(v0_t, v0_t);
19310 gen_store_gpr(v0_t, ret);
19311 break;
19312 case NM_PRECEU_PH_QBRA:
19313 check_dsp(ctx);
19314 gen_helper_preceu_ph_qbra(v0_t, v0_t);
19315 gen_store_gpr(v0_t, ret);
19316 break;
19317 case NM_REPLV_PH:
19318 check_dsp(ctx);
19319 tcg_gen_ext16u_tl(v0_t, v0_t);
19320 tcg_gen_shli_tl(t0, v0_t, 16);
19321 tcg_gen_or_tl(v0_t, v0_t, t0);
19322 tcg_gen_ext32s_tl(v0_t, v0_t);
19323 gen_store_gpr(v0_t, ret);
19324 break;
19325 case NM_REPLV_QB:
19326 check_dsp(ctx);
19327 tcg_gen_ext8u_tl(v0_t, v0_t);
19328 tcg_gen_shli_tl(t0, v0_t, 8);
19329 tcg_gen_or_tl(v0_t, v0_t, t0);
19330 tcg_gen_shli_tl(t0, v0_t, 16);
19331 tcg_gen_or_tl(v0_t, v0_t, t0);
19332 tcg_gen_ext32s_tl(v0_t, v0_t);
19333 gen_store_gpr(v0_t, ret);
19334 break;
19335 case NM_BITREV:
19336 check_dsp(ctx);
19337 gen_helper_bitrev(v0_t, v0_t);
19338 gen_store_gpr(v0_t, ret);
19339 break;
19340 case NM_INSV:
19341 check_dsp(ctx);
19342 {
19343 TCGv tv0 = tcg_temp_new();
19344
19345 gen_load_gpr(tv0, rt);
19346 gen_helper_insv(v0_t, cpu_env, v0_t, tv0);
19347 gen_store_gpr(v0_t, ret);
19348 tcg_temp_free(tv0);
19349 }
19350 break;
19351 case NM_RADDU_W_QB:
19352 check_dsp(ctx);
19353 gen_helper_raddu_w_qb(v0_t, v0_t);
19354 gen_store_gpr(v0_t, ret);
19355 break;
19356 case NM_BITSWAP:
19357 gen_bitswap(ctx, OPC_BITSWAP, ret, rs);
19358 break;
19359 case NM_CLO:
fb32f8c8 19360 check_nms(ctx);
4c75c985
SM
19361 gen_cl(ctx, OPC_CLO, ret, rs);
19362 break;
19363 case NM_CLZ:
fb32f8c8 19364 check_nms(ctx);
4c75c985
SM
19365 gen_cl(ctx, OPC_CLZ, ret, rs);
19366 break;
19367 case NM_WSBH:
19368 gen_bshfl(ctx, OPC_WSBH, ret, rs);
19369 break;
19370 default:
19371 generate_exception_end(ctx, EXCP_RI);
19372 break;
19373 }
19374
19375 tcg_temp_free(v0_t);
19376 tcg_temp_free(t0);
19377}
19378
0b591184
SM
19379static void gen_pool32axf_7_nanomips_insn(DisasContext *ctx, uint32_t opc,
19380 int rt, int rs, int rd)
19381{
19382 TCGv t0 = tcg_temp_new();
19383 TCGv rs_t = tcg_temp_new();
19384
19385 gen_load_gpr(rs_t, rs);
19386
19387 switch (opc) {
19388 case NM_SHRA_R_QB:
908f6be1 19389 check_dsp_r2(ctx);
0b591184
SM
19390 tcg_gen_movi_tl(t0, rd >> 2);
19391 switch (extract32(ctx->opcode, 12, 1)) {
19392 case 0:
19393 /* NM_SHRA_QB */
19394 gen_helper_shra_qb(t0, t0, rs_t);
19395 gen_store_gpr(t0, rt);
19396 break;
19397 case 1:
19398 /* NM_SHRA_R_QB */
19399 gen_helper_shra_r_qb(t0, t0, rs_t);
19400 gen_store_gpr(t0, rt);
19401 break;
19402 }
19403 break;
19404 case NM_SHRL_PH:
908f6be1 19405 check_dsp_r2(ctx);
0b591184
SM
19406 tcg_gen_movi_tl(t0, rd >> 1);
19407 gen_helper_shrl_ph(t0, t0, rs_t);
19408 gen_store_gpr(t0, rt);
19409 break;
19410 case NM_REPL_QB:
19411 check_dsp(ctx);
19412 {
19413 int16_t imm;
19414 target_long result;
19415 imm = extract32(ctx->opcode, 13, 8);
19416 result = (uint32_t)imm << 24 |
19417 (uint32_t)imm << 16 |
19418 (uint32_t)imm << 8 |
19419 (uint32_t)imm;
19420 result = (int32_t)result;
19421 tcg_gen_movi_tl(t0, result);
19422 gen_store_gpr(t0, rt);
19423 }
19424 break;
19425 default:
19426 generate_exception_end(ctx, EXCP_RI);
19427 break;
19428 }
19429 tcg_temp_free(t0);
19430 tcg_temp_free(rs_t);
19431}
19432
2ed42efa 19433
64224187
YK
19434static void gen_pool32axf_nanomips_insn(CPUMIPSState *env, DisasContext *ctx)
19435{
64224187
YK
19436 int rt = extract32(ctx->opcode, 21, 5);
19437 int rs = extract32(ctx->opcode, 16, 5);
2ed42efa 19438 int rd = extract32(ctx->opcode, 11, 5);
64224187
YK
19439
19440 switch (extract32(ctx->opcode, 6, 3)) {
2ed42efa
SM
19441 case NM_POOL32AXF_1:
19442 {
19443 int32_t op1 = extract32(ctx->opcode, 9, 3);
19444 gen_pool32axf_1_nanomips_insn(ctx, op1, rt, rs, rd);
19445 }
19446 break;
19447 case NM_POOL32AXF_2:
8b3698b2
SM
19448 {
19449 int32_t op1 = extract32(ctx->opcode, 12, 2);
19450 gen_pool32axf_2_nanomips_insn(ctx, op1, rt, rs, rd);
19451 }
2ed42efa 19452 break;
64224187 19453 case NM_POOL32AXF_4:
4c75c985
SM
19454 {
19455 int32_t op1 = extract32(ctx->opcode, 9, 7);
19456 gen_pool32axf_4_nanomips_insn(ctx, op1, rt, rs);
19457 }
2ed42efa 19458 break;
64224187
YK
19459 case NM_POOL32AXF_5:
19460 switch (extract32(ctx->opcode, 9, 7)) {
19461#ifndef CONFIG_USER_ONLY
19462 case NM_TLBP:
19463 gen_cp0(env, ctx, OPC_TLBP, 0, 0);
19464 break;
19465 case NM_TLBR:
19466 gen_cp0(env, ctx, OPC_TLBR, 0, 0);
19467 break;
19468 case NM_TLBWI:
19469 gen_cp0(env, ctx, OPC_TLBWI, 0, 0);
19470 break;
19471 case NM_TLBWR:
19472 gen_cp0(env, ctx, OPC_TLBWR, 0, 0);
19473 break;
19474 case NM_TLBINV:
19475 gen_cp0(env, ctx, OPC_TLBINV, 0, 0);
19476 break;
19477 case NM_TLBINVF:
19478 gen_cp0(env, ctx, OPC_TLBINVF, 0, 0);
19479 break;
19480 case NM_DI:
19481 check_cp0_enabled(ctx);
19482 {
19483 TCGv t0 = tcg_temp_new();
19484
19485 save_cpu_state(ctx, 1);
19486 gen_helper_di(t0, cpu_env);
19487 gen_store_gpr(t0, rt);
19488 /* Stop translation as we may have switched the execution mode */
19489 ctx->base.is_jmp = DISAS_STOP;
19490 tcg_temp_free(t0);
19491 }
19492 break;
19493 case NM_EI:
19494 check_cp0_enabled(ctx);
19495 {
19496 TCGv t0 = tcg_temp_new();
19497
19498 save_cpu_state(ctx, 1);
19499 gen_helper_ei(t0, cpu_env);
19500 gen_store_gpr(t0, rt);
19501 /* Stop translation as we may have switched the execution mode */
19502 ctx->base.is_jmp = DISAS_STOP;
19503 tcg_temp_free(t0);
19504 }
19505 break;
19506 case NM_RDPGPR:
19507 gen_load_srsgpr(rs, rt);
19508 break;
19509 case NM_WRPGPR:
19510 gen_store_srsgpr(rs, rt);
19511 break;
19512 case NM_WAIT:
19513 gen_cp0(env, ctx, OPC_WAIT, 0, 0);
19514 break;
19515 case NM_DERET:
19516 gen_cp0(env, ctx, OPC_DERET, 0, 0);
19517 break;
19518 case NM_ERETX:
19519 gen_cp0(env, ctx, OPC_ERET, 0, 0);
19520 break;
19521#endif
19522 default:
19523 generate_exception_end(ctx, EXCP_RI);
19524 break;
19525 }
19526 break;
2ed42efa 19527 case NM_POOL32AXF_7:
0b591184
SM
19528 {
19529 int32_t op1 = extract32(ctx->opcode, 9, 3);
19530 gen_pool32axf_7_nanomips_insn(ctx, op1, rt, rs, rd);
19531 }
2ed42efa 19532 break;
64224187
YK
19533 default:
19534 generate_exception_end(ctx, EXCP_RI);
19535 break;
19536 }
19537}
19538
11d0fc10
SM
19539/* Immediate Value Compact Branches */
19540static void gen_compute_imm_branch(DisasContext *ctx, uint32_t opc,
19541 int rt, int32_t imm, int32_t offset)
19542{
19543 TCGCond cond;
19544 int bcond_compute = 0;
19545 TCGv t0 = tcg_temp_new();
19546 TCGv t1 = tcg_temp_new();
19547
19548 gen_load_gpr(t0, rt);
19549 tcg_gen_movi_tl(t1, imm);
19550 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
19551
19552 /* Load needed operands and calculate btarget */
19553 switch (opc) {
19554 case NM_BEQIC:
19555 if (rt == 0 && imm == 0) {
19556 /* Unconditional branch */
19557 } else if (rt == 0 && imm != 0) {
19558 /* Treat as NOP */
19559 goto out;
19560 } else {
19561 bcond_compute = 1;
19562 cond = TCG_COND_EQ;
19563 }
19564 break;
19565 case NM_BBEQZC:
19566 case NM_BBNEZC:
fb32f8c8 19567 check_nms(ctx);
11d0fc10
SM
19568 if (imm >= 32 && !(ctx->hflags & MIPS_HFLAG_64)) {
19569 generate_exception_end(ctx, EXCP_RI);
19570 goto out;
19571 } else if (rt == 0 && opc == NM_BBEQZC) {
19572 /* Unconditional branch */
19573 } else if (rt == 0 && opc == NM_BBNEZC) {
19574 /* Treat as NOP */
19575 goto out;
19576 } else {
19577 tcg_gen_shri_tl(t0, t0, imm);
19578 tcg_gen_andi_tl(t0, t0, 1);
19579 tcg_gen_movi_tl(t1, 0);
19580 bcond_compute = 1;
19581 if (opc == NM_BBEQZC) {
19582 cond = TCG_COND_EQ;
19583 } else {
19584 cond = TCG_COND_NE;
19585 }
19586 }
19587 break;
19588 case NM_BNEIC:
19589 if (rt == 0 && imm == 0) {
19590 /* Treat as NOP */
19591 goto out;
19592 } else if (rt == 0 && imm != 0) {
19593 /* Unconditional branch */
19594 } else {
19595 bcond_compute = 1;
19596 cond = TCG_COND_NE;
19597 }
19598 break;
19599 case NM_BGEIC:
19600 if (rt == 0 && imm == 0) {
19601 /* Unconditional branch */
19602 } else {
19603 bcond_compute = 1;
19604 cond = TCG_COND_GE;
19605 }
19606 break;
19607 case NM_BLTIC:
19608 bcond_compute = 1;
19609 cond = TCG_COND_LT;
19610 break;
19611 case NM_BGEIUC:
19612 if (rt == 0 && imm == 0) {
19613 /* Unconditional branch */
19614 } else {
19615 bcond_compute = 1;
19616 cond = TCG_COND_GEU;
19617 }
19618 break;
19619 case NM_BLTIUC:
19620 bcond_compute = 1;
19621 cond = TCG_COND_LTU;
19622 break;
19623 default:
19624 MIPS_INVAL("Immediate Value Compact branch");
19625 generate_exception_end(ctx, EXCP_RI);
19626 goto out;
19627 }
19628
19629 if (bcond_compute == 0) {
19630 /* Uncoditional compact branch */
19631 gen_goto_tb(ctx, 0, ctx->btarget);
19632 } else {
19633 /* Conditional compact branch */
19634 TCGLabel *fs = gen_new_label();
19635
19636 tcg_gen_brcond_tl(tcg_invert_cond(cond), t0, t1, fs);
19637
19638 gen_goto_tb(ctx, 1, ctx->btarget);
19639 gen_set_label(fs);
19640
19641 gen_goto_tb(ctx, 0, ctx->base.pc_next + 4);
19642 }
19643
19644out:
19645 tcg_temp_free(t0);
19646 tcg_temp_free(t1);
19647}
19648
19649/* P.BALRSC type nanoMIPS R6 branches: BALRSC and BRSC */
19650static void gen_compute_nanomips_pbalrsc_branch(DisasContext *ctx, int rs,
19651 int rt)
19652{
19653 TCGv t0 = tcg_temp_new();
19654 TCGv t1 = tcg_temp_new();
19655
19656 /* load rs */
19657 gen_load_gpr(t0, rs);
19658
19659 /* link */
19660 if (rt != 0) {
19661 tcg_gen_movi_tl(cpu_gpr[rt], ctx->base.pc_next + 4);
19662 }
19663
19664 /* calculate btarget */
19665 tcg_gen_shli_tl(t0, t0, 1);
19666 tcg_gen_movi_tl(t1, ctx->base.pc_next + 4);
19667 gen_op_addr_add(ctx, btarget, t1, t0);
19668
19669 /* unconditional branch to register */
19670 tcg_gen_mov_tl(cpu_PC, btarget);
19671 tcg_gen_lookup_and_goto_ptr();
19672
19673 tcg_temp_free(t0);
19674 tcg_temp_free(t1);
19675}
19676
19677/* nanoMIPS Branches */
19678static void gen_compute_compact_branch_nm(DisasContext *ctx, uint32_t opc,
19679 int rs, int rt, int32_t offset)
19680{
19681 int bcond_compute = 0;
19682 TCGv t0 = tcg_temp_new();
19683 TCGv t1 = tcg_temp_new();
19684
19685 /* Load needed operands and calculate btarget */
19686 switch (opc) {
19687 /* compact branch */
19688 case OPC_BGEC:
19689 case OPC_BLTC:
19690 gen_load_gpr(t0, rs);
19691 gen_load_gpr(t1, rt);
19692 bcond_compute = 1;
19693 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
19694 break;
19695 case OPC_BGEUC:
19696 case OPC_BLTUC:
19697 if (rs == 0 || rs == rt) {
19698 /* OPC_BLEZALC, OPC_BGEZALC */
19699 /* OPC_BGTZALC, OPC_BLTZALC */
19700 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4);
19701 }
19702 gen_load_gpr(t0, rs);
19703 gen_load_gpr(t1, rt);
19704 bcond_compute = 1;
19705 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
19706 break;
19707 case OPC_BC:
19708 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
19709 break;
19710 case OPC_BEQZC:
19711 if (rs != 0) {
19712 /* OPC_BEQZC, OPC_BNEZC */
19713 gen_load_gpr(t0, rs);
19714 bcond_compute = 1;
19715 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
19716 } else {
19717 /* OPC_JIC, OPC_JIALC */
19718 TCGv tbase = tcg_temp_new();
19719 TCGv toffset = tcg_temp_new();
19720
19721 gen_load_gpr(tbase, rt);
19722 tcg_gen_movi_tl(toffset, offset);
19723 gen_op_addr_add(ctx, btarget, tbase, toffset);
19724 tcg_temp_free(tbase);
19725 tcg_temp_free(toffset);
19726 }
19727 break;
19728 default:
19729 MIPS_INVAL("Compact branch/jump");
19730 generate_exception_end(ctx, EXCP_RI);
19731 goto out;
19732 }
19733
19734 if (bcond_compute == 0) {
19735 /* Uncoditional compact branch */
19736 switch (opc) {
19737 case OPC_BC:
19738 gen_goto_tb(ctx, 0, ctx->btarget);
19739 break;
19740 default:
19741 MIPS_INVAL("Compact branch/jump");
19742 generate_exception_end(ctx, EXCP_RI);
19743 goto out;
19744 }
19745 } else {
19746 /* Conditional compact branch */
19747 TCGLabel *fs = gen_new_label();
19748
19749 switch (opc) {
19750 case OPC_BGEUC:
19751 if (rs == 0 && rt != 0) {
19752 /* OPC_BLEZALC */
19753 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
19754 } else if (rs != 0 && rt != 0 && rs == rt) {
19755 /* OPC_BGEZALC */
19756 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
19757 } else {
19758 /* OPC_BGEUC */
19759 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU), t0, t1, fs);
19760 }
19761 break;
19762 case OPC_BLTUC:
19763 if (rs == 0 && rt != 0) {
19764 /* OPC_BGTZALC */
19765 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
19766 } else if (rs != 0 && rt != 0 && rs == rt) {
19767 /* OPC_BLTZALC */
19768 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
19769 } else {
19770 /* OPC_BLTUC */
19771 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU), t0, t1, fs);
19772 }
19773 break;
19774 case OPC_BGEC:
19775 if (rs == 0 && rt != 0) {
19776 /* OPC_BLEZC */
19777 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
19778 } else if (rs != 0 && rt != 0 && rs == rt) {
19779 /* OPC_BGEZC */
19780 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
19781 } else {
19782 /* OPC_BGEC */
19783 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE), t0, t1, fs);
19784 }
19785 break;
19786 case OPC_BLTC:
19787 if (rs == 0 && rt != 0) {
19788 /* OPC_BGTZC */
19789 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
19790 } else if (rs != 0 && rt != 0 && rs == rt) {
19791 /* OPC_BLTZC */
19792 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
19793 } else {
19794 /* OPC_BLTC */
19795 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT), t0, t1, fs);
19796 }
19797 break;
19798 case OPC_BEQZC:
19799 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t0, 0, fs);
19800 break;
19801 default:
19802 MIPS_INVAL("Compact conditional branch/jump");
19803 generate_exception_end(ctx, EXCP_RI);
19804 goto out;
19805 }
19806
19807 /* Generating branch here as compact branches don't have delay slot */
19808 gen_goto_tb(ctx, 1, ctx->btarget);
19809 gen_set_label(fs);
19810
19811 gen_goto_tb(ctx, 0, ctx->base.pc_next + 4);
19812 }
19813
19814out:
19815 tcg_temp_free(t0);
19816 tcg_temp_free(t1);
19817}
19818
19819
19820/* nanoMIPS CP1 Branches */
19821static void gen_compute_branch_cp1_nm(DisasContext *ctx, uint32_t op,
19822 int32_t ft, int32_t offset)
19823{
19824 target_ulong btarget;
19825 TCGv_i64 t0 = tcg_temp_new_i64();
19826
19827 gen_load_fpr64(ctx, t0, ft);
19828 tcg_gen_andi_i64(t0, t0, 1);
19829
19830 btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
19831
19832 switch (op) {
19833 case NM_BC1EQZC:
19834 tcg_gen_xori_i64(t0, t0, 1);
19835 ctx->hflags |= MIPS_HFLAG_BC;
19836 break;
19837 case NM_BC1NEZC:
19838 /* t0 already set */
19839 ctx->hflags |= MIPS_HFLAG_BC;
19840 break;
19841 default:
19842 MIPS_INVAL("cp1 cond branch");
19843 generate_exception_end(ctx, EXCP_RI);
19844 goto out;
19845 }
19846
19847 tcg_gen_trunc_i64_tl(bcond, t0);
19848
19849 ctx->btarget = btarget;
19850
19851out:
19852 tcg_temp_free_i64(t0);
19853}
19854
eac52664
YK
19855
19856static void gen_p_lsx(DisasContext *ctx, int rd, int rs, int rt)
19857{
19858 TCGv t0, t1;
19859 t0 = tcg_temp_new();
19860 t1 = tcg_temp_new();
19861
19862 gen_load_gpr(t0, rs);
19863 gen_load_gpr(t1, rt);
19864
19865 if ((extract32(ctx->opcode, 6, 1)) == 1) {
19866 /* PP.LSXS instructions require shifting */
19867 switch (extract32(ctx->opcode, 7, 4)) {
eac52664 19868 case NM_SHXS:
fb32f8c8
DN
19869 check_nms(ctx);
19870 case NM_LHXS:
eac52664
YK
19871 case NM_LHUXS:
19872 tcg_gen_shli_tl(t0, t0, 1);
19873 break;
eac52664 19874 case NM_SWXS:
fb32f8c8
DN
19875 check_nms(ctx);
19876 case NM_LWXS:
eac52664
YK
19877 case NM_LWC1XS:
19878 case NM_SWC1XS:
19879 tcg_gen_shli_tl(t0, t0, 2);
19880 break;
19881 case NM_LDC1XS:
19882 case NM_SDC1XS:
19883 tcg_gen_shli_tl(t0, t0, 3);
19884 break;
19885 }
19886 }
19887 gen_op_addr_add(ctx, t0, t0, t1);
19888
19889 switch (extract32(ctx->opcode, 7, 4)) {
19890 case NM_LBX:
19891 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
19892 MO_SB);
19893 gen_store_gpr(t0, rd);
19894 break;
19895 case NM_LHX:
19896 /*case NM_LHXS:*/
19897 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
19898 MO_TESW);
19899 gen_store_gpr(t0, rd);
19900 break;
19901 case NM_LWX:
19902 /*case NM_LWXS:*/
19903 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
19904 MO_TESL);
19905 gen_store_gpr(t0, rd);
19906 break;
19907 case NM_LBUX:
19908 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
19909 MO_UB);
19910 gen_store_gpr(t0, rd);
19911 break;
19912 case NM_LHUX:
19913 /*case NM_LHUXS:*/
19914 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
19915 MO_TEUW);
19916 gen_store_gpr(t0, rd);
19917 break;
19918 case NM_SBX:
fb32f8c8 19919 check_nms(ctx);
eac52664
YK
19920 gen_load_gpr(t1, rd);
19921 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx,
19922 MO_8);
19923 break;
19924 case NM_SHX:
19925 /*case NM_SHXS:*/
fb32f8c8 19926 check_nms(ctx);
eac52664
YK
19927 gen_load_gpr(t1, rd);
19928 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx,
19929 MO_TEUW);
19930 break;
19931 case NM_SWX:
19932 /*case NM_SWXS:*/
fb32f8c8 19933 check_nms(ctx);
eac52664
YK
19934 gen_load_gpr(t1, rd);
19935 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx,
19936 MO_TEUL);
19937 break;
19938 case NM_LWC1X:
19939 /*case NM_LWC1XS:*/
19940 case NM_LDC1X:
19941 /*case NM_LDC1XS:*/
19942 case NM_SWC1X:
19943 /*case NM_SWC1XS:*/
19944 case NM_SDC1X:
19945 /*case NM_SDC1XS:*/
19946 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
19947 check_cp1_enabled(ctx);
19948 switch (extract32(ctx->opcode, 7, 4)) {
19949 case NM_LWC1X:
19950 /*case NM_LWC1XS:*/
19951 gen_flt_ldst(ctx, OPC_LWC1, rd, t0);
19952 break;
19953 case NM_LDC1X:
19954 /*case NM_LDC1XS:*/
19955 gen_flt_ldst(ctx, OPC_LDC1, rd, t0);
19956 break;
19957 case NM_SWC1X:
19958 /*case NM_SWC1XS:*/
19959 gen_flt_ldst(ctx, OPC_SWC1, rd, t0);
19960 break;
19961 case NM_SDC1X:
19962 /*case NM_SDC1XS:*/
19963 gen_flt_ldst(ctx, OPC_SDC1, rd, t0);
19964 break;
19965 }
19966 } else {
19967 generate_exception_err(ctx, EXCP_CpU, 1);
19968 }
19969 break;
19970 default:
19971 generate_exception_end(ctx, EXCP_RI);
19972 break;
19973 }
19974
19975 tcg_temp_free(t0);
19976 tcg_temp_free(t1);
19977}
19978
579b8ea9
YK
19979static void gen_pool32f_nanomips_insn(DisasContext *ctx)
19980{
19981 int rt, rs, rd;
19982
19983 rt = extract32(ctx->opcode, 21, 5);
19984 rs = extract32(ctx->opcode, 16, 5);
19985 rd = extract32(ctx->opcode, 11, 5);
19986
19987 if (!(ctx->CP0_Config1 & (1 << CP0C1_FP))) {
19988 generate_exception_end(ctx, EXCP_RI);
19989 return;
19990 }
19991 check_cp1_enabled(ctx);
19992 switch (extract32(ctx->opcode, 0, 3)) {
19993 case NM_POOL32F_0:
19994 switch (extract32(ctx->opcode, 3, 7)) {
19995 case NM_RINT_S:
19996 gen_farith(ctx, OPC_RINT_S, 0, rt, rs, 0);
19997 break;
19998 case NM_RINT_D:
19999 gen_farith(ctx, OPC_RINT_D, 0, rt, rs, 0);
20000 break;
20001 case NM_CLASS_S:
20002 gen_farith(ctx, OPC_CLASS_S, 0, rt, rs, 0);
20003 break;
20004 case NM_CLASS_D:
20005 gen_farith(ctx, OPC_CLASS_D, 0, rt, rs, 0);
20006 break;
20007 case NM_ADD_S:
20008 gen_farith(ctx, OPC_ADD_S, rt, rs, rd, 0);
20009 break;
20010 case NM_ADD_D:
20011 gen_farith(ctx, OPC_ADD_D, rt, rs, rd, 0);
20012 break;
20013 case NM_SUB_S:
20014 gen_farith(ctx, OPC_SUB_S, rt, rs, rd, 0);
20015 break;
20016 case NM_SUB_D:
20017 gen_farith(ctx, OPC_SUB_D, rt, rs, rd, 0);
20018 break;
20019 case NM_MUL_S:
20020 gen_farith(ctx, OPC_MUL_S, rt, rs, rd, 0);
20021 break;
20022 case NM_MUL_D:
20023 gen_farith(ctx, OPC_MUL_D, rt, rs, rd, 0);
20024 break;
20025 case NM_DIV_S:
20026 gen_farith(ctx, OPC_DIV_S, rt, rs, rd, 0);
20027 break;
20028 case NM_DIV_D:
20029 gen_farith(ctx, OPC_DIV_D, rt, rs, rd, 0);
20030 break;
20031 case NM_SELEQZ_S:
20032 gen_sel_s(ctx, OPC_SELEQZ_S, rd, rt, rs);
20033 break;
20034 case NM_SELEQZ_D:
20035 gen_sel_d(ctx, OPC_SELEQZ_D, rd, rt, rs);
20036 break;
20037 case NM_SELNEZ_S:
20038 gen_sel_s(ctx, OPC_SELNEZ_S, rd, rt, rs);
20039 break;
20040 case NM_SELNEZ_D:
20041 gen_sel_d(ctx, OPC_SELNEZ_D, rd, rt, rs);
20042 break;
20043 case NM_SEL_S:
20044 gen_sel_s(ctx, OPC_SEL_S, rd, rt, rs);
20045 break;
20046 case NM_SEL_D:
20047 gen_sel_d(ctx, OPC_SEL_D, rd, rt, rs);
20048 break;
20049 case NM_MADDF_S:
20050 gen_farith(ctx, OPC_MADDF_S, rt, rs, rd, 0);
20051 break;
20052 case NM_MADDF_D:
20053 gen_farith(ctx, OPC_MADDF_D, rt, rs, rd, 0);
20054 break;
20055 case NM_MSUBF_S:
20056 gen_farith(ctx, OPC_MSUBF_S, rt, rs, rd, 0);
20057 break;
20058 case NM_MSUBF_D:
20059 gen_farith(ctx, OPC_MSUBF_D, rt, rs, rd, 0);
20060 break;
20061 default:
20062 generate_exception_end(ctx, EXCP_RI);
20063 break;
20064 }
20065 break;
20066 case NM_POOL32F_3:
20067 switch (extract32(ctx->opcode, 3, 3)) {
20068 case NM_MIN_FMT:
20069 switch (extract32(ctx->opcode, 9, 1)) {
20070 case FMT_SDPS_S:
20071 gen_farith(ctx, OPC_MIN_S, rt, rs, rd, 0);
20072 break;
20073 case FMT_SDPS_D:
20074 gen_farith(ctx, OPC_MIN_D, rt, rs, rd, 0);
20075 break;
20076 }
20077 break;
20078 case NM_MAX_FMT:
20079 switch (extract32(ctx->opcode, 9, 1)) {
20080 case FMT_SDPS_S:
20081 gen_farith(ctx, OPC_MAX_S, rt, rs, rd, 0);
20082 break;
20083 case FMT_SDPS_D:
20084 gen_farith(ctx, OPC_MAX_D, rt, rs, rd, 0);
20085 break;
20086 }
20087 break;
20088 case NM_MINA_FMT:
20089 switch (extract32(ctx->opcode, 9, 1)) {
20090 case FMT_SDPS_S:
20091 gen_farith(ctx, OPC_MINA_S, rt, rs, rd, 0);
20092 break;
20093 case FMT_SDPS_D:
20094 gen_farith(ctx, OPC_MINA_D, rt, rs, rd, 0);
20095 break;
20096 }
20097 break;
20098 case NM_MAXA_FMT:
20099 switch (extract32(ctx->opcode, 9, 1)) {
20100 case FMT_SDPS_S:
20101 gen_farith(ctx, OPC_MAXA_S, rt, rs, rd, 0);
20102 break;
20103 case FMT_SDPS_D:
20104 gen_farith(ctx, OPC_MAXA_D, rt, rs, rd, 0);
20105 break;
20106 }
20107 break;
20108 case NM_POOL32FXF:
20109 switch (extract32(ctx->opcode, 6, 8)) {
20110 case NM_CFC1:
20111 gen_cp1(ctx, OPC_CFC1, rt, rs);
20112 break;
20113 case NM_CTC1:
20114 gen_cp1(ctx, OPC_CTC1, rt, rs);
20115 break;
20116 case NM_MFC1:
20117 gen_cp1(ctx, OPC_MFC1, rt, rs);
20118 break;
20119 case NM_MTC1:
20120 gen_cp1(ctx, OPC_MTC1, rt, rs);
20121 break;
20122 case NM_MFHC1:
20123 gen_cp1(ctx, OPC_MFHC1, rt, rs);
20124 break;
20125 case NM_MTHC1:
20126 gen_cp1(ctx, OPC_MTHC1, rt, rs);
20127 break;
20128 case NM_CVT_S_PL:
20129 gen_farith(ctx, OPC_CVT_S_PL, -1, rs, rt, 0);
20130 break;
20131 case NM_CVT_S_PU:
20132 gen_farith(ctx, OPC_CVT_S_PU, -1, rs, rt, 0);
20133 break;
20134 default:
20135 switch (extract32(ctx->opcode, 6, 9)) {
20136 case NM_CVT_L_S:
20137 gen_farith(ctx, OPC_CVT_L_S, -1, rs, rt, 0);
20138 break;
20139 case NM_CVT_L_D:
20140 gen_farith(ctx, OPC_CVT_L_D, -1, rs, rt, 0);
20141 break;
20142 case NM_CVT_W_S:
20143 gen_farith(ctx, OPC_CVT_W_S, -1, rs, rt, 0);
20144 break;
20145 case NM_CVT_W_D:
20146 gen_farith(ctx, OPC_CVT_W_D, -1, rs, rt, 0);
20147 break;
20148 case NM_RSQRT_S:
20149 gen_farith(ctx, OPC_RSQRT_S, -1, rs, rt, 0);
20150 break;
20151 case NM_RSQRT_D:
20152 gen_farith(ctx, OPC_RSQRT_D, -1, rs, rt, 0);
20153 break;
20154 case NM_SQRT_S:
20155 gen_farith(ctx, OPC_SQRT_S, -1, rs, rt, 0);
20156 break;
20157 case NM_SQRT_D:
20158 gen_farith(ctx, OPC_SQRT_D, -1, rs, rt, 0);
20159 break;
20160 case NM_RECIP_S:
20161 gen_farith(ctx, OPC_RECIP_S, -1, rs, rt, 0);
20162 break;
20163 case NM_RECIP_D:
20164 gen_farith(ctx, OPC_RECIP_D, -1, rs, rt, 0);
20165 break;
20166 case NM_FLOOR_L_S:
20167 gen_farith(ctx, OPC_FLOOR_L_S, -1, rs, rt, 0);
20168 break;
20169 case NM_FLOOR_L_D:
20170 gen_farith(ctx, OPC_FLOOR_L_D, -1, rs, rt, 0);
20171 break;
20172 case NM_FLOOR_W_S:
20173 gen_farith(ctx, OPC_FLOOR_W_S, -1, rs, rt, 0);
20174 break;
20175 case NM_FLOOR_W_D:
20176 gen_farith(ctx, OPC_FLOOR_W_D, -1, rs, rt, 0);
20177 break;
20178 case NM_CEIL_L_S:
20179 gen_farith(ctx, OPC_CEIL_L_S, -1, rs, rt, 0);
20180 break;
20181 case NM_CEIL_L_D:
20182 gen_farith(ctx, OPC_CEIL_L_D, -1, rs, rt, 0);
20183 break;
20184 case NM_CEIL_W_S:
20185 gen_farith(ctx, OPC_CEIL_W_S, -1, rs, rt, 0);
20186 break;
20187 case NM_CEIL_W_D:
20188 gen_farith(ctx, OPC_CEIL_W_D, -1, rs, rt, 0);
20189 break;
20190 case NM_TRUNC_L_S:
20191 gen_farith(ctx, OPC_TRUNC_L_S, -1, rs, rt, 0);
20192 break;
20193 case NM_TRUNC_L_D:
20194 gen_farith(ctx, OPC_TRUNC_L_D, -1, rs, rt, 0);
20195 break;
20196 case NM_TRUNC_W_S:
20197 gen_farith(ctx, OPC_TRUNC_W_S, -1, rs, rt, 0);
20198 break;
20199 case NM_TRUNC_W_D:
20200 gen_farith(ctx, OPC_TRUNC_W_D, -1, rs, rt, 0);
20201 break;
20202 case NM_ROUND_L_S:
20203 gen_farith(ctx, OPC_ROUND_L_S, -1, rs, rt, 0);
20204 break;
20205 case NM_ROUND_L_D:
20206 gen_farith(ctx, OPC_ROUND_L_D, -1, rs, rt, 0);
20207 break;
20208 case NM_ROUND_W_S:
20209 gen_farith(ctx, OPC_ROUND_W_S, -1, rs, rt, 0);
20210 break;
20211 case NM_ROUND_W_D:
20212 gen_farith(ctx, OPC_ROUND_W_D, -1, rs, rt, 0);
20213 break;
20214 case NM_MOV_S:
20215 gen_farith(ctx, OPC_MOV_S, -1, rs, rt, 0);
20216 break;
20217 case NM_MOV_D:
20218 gen_farith(ctx, OPC_MOV_D, -1, rs, rt, 0);
20219 break;
20220 case NM_ABS_S:
20221 gen_farith(ctx, OPC_ABS_S, -1, rs, rt, 0);
20222 break;
20223 case NM_ABS_D:
20224 gen_farith(ctx, OPC_ABS_D, -1, rs, rt, 0);
20225 break;
20226 case NM_NEG_S:
20227 gen_farith(ctx, OPC_NEG_S, -1, rs, rt, 0);
20228 break;
20229 case NM_NEG_D:
20230 gen_farith(ctx, OPC_NEG_D, -1, rs, rt, 0);
20231 break;
20232 case NM_CVT_D_S:
20233 gen_farith(ctx, OPC_CVT_D_S, -1, rs, rt, 0);
20234 break;
20235 case NM_CVT_D_W:
20236 gen_farith(ctx, OPC_CVT_D_W, -1, rs, rt, 0);
20237 break;
20238 case NM_CVT_D_L:
20239 gen_farith(ctx, OPC_CVT_D_L, -1, rs, rt, 0);
20240 break;
20241 case NM_CVT_S_D:
20242 gen_farith(ctx, OPC_CVT_S_D, -1, rs, rt, 0);
20243 break;
20244 case NM_CVT_S_W:
20245 gen_farith(ctx, OPC_CVT_S_W, -1, rs, rt, 0);
20246 break;
20247 case NM_CVT_S_L:
20248 gen_farith(ctx, OPC_CVT_S_L, -1, rs, rt, 0);
20249 break;
20250 default:
20251 generate_exception_end(ctx, EXCP_RI);
20252 break;
20253 }
20254 break;
20255 }
20256 break;
20257 }
20258 break;
20259 case NM_POOL32F_5:
20260 switch (extract32(ctx->opcode, 3, 3)) {
20261 case NM_CMP_CONDN_S:
20262 gen_r6_cmp_s(ctx, extract32(ctx->opcode, 6, 5), rt, rs, rd);
20263 break;
20264 case NM_CMP_CONDN_D:
20265 gen_r6_cmp_d(ctx, extract32(ctx->opcode, 6, 5), rt, rs, rd);
20266 break;
20267 default:
20268 generate_exception_end(ctx, EXCP_RI);
20269 break;
20270 }
20271 break;
20272 default:
20273 generate_exception_end(ctx, EXCP_RI);
20274 break;
20275 }
20276}
20277
3285a3e4
SM
20278static void gen_pool32a5_nanomips_insn(DisasContext *ctx, int opc,
20279 int rd, int rs, int rt)
20280{
20281 int ret = rd;
20282 TCGv t0 = tcg_temp_new();
20283 TCGv v1_t = tcg_temp_new();
20284 TCGv v2_t = tcg_temp_new();
20285
20286 gen_load_gpr(v1_t, rs);
20287 gen_load_gpr(v2_t, rt);
20288
20289 switch (opc) {
20290 case NM_CMP_EQ_PH:
20291 check_dsp(ctx);
20292 gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
20293 break;
20294 case NM_CMP_LT_PH:
20295 check_dsp(ctx);
20296 gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
20297 break;
20298 case NM_CMP_LE_PH:
20299 check_dsp(ctx);
20300 gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
20301 break;
20302 case NM_CMPU_EQ_QB:
20303 check_dsp(ctx);
20304 gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
20305 break;
20306 case NM_CMPU_LT_QB:
20307 check_dsp(ctx);
20308 gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
20309 break;
20310 case NM_CMPU_LE_QB:
20311 check_dsp(ctx);
20312 gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
20313 break;
20314 case NM_CMPGU_EQ_QB:
20315 check_dsp(ctx);
20316 gen_helper_cmpgu_eq_qb(v1_t, v1_t, v2_t);
20317 gen_store_gpr(v1_t, ret);
20318 break;
20319 case NM_CMPGU_LT_QB:
20320 check_dsp(ctx);
20321 gen_helper_cmpgu_lt_qb(v1_t, v1_t, v2_t);
20322 gen_store_gpr(v1_t, ret);
20323 break;
20324 case NM_CMPGU_LE_QB:
20325 check_dsp(ctx);
20326 gen_helper_cmpgu_le_qb(v1_t, v1_t, v2_t);
20327 gen_store_gpr(v1_t, ret);
20328 break;
20329 case NM_CMPGDU_EQ_QB:
908f6be1 20330 check_dsp_r2(ctx);
3285a3e4
SM
20331 gen_helper_cmpgu_eq_qb(v1_t, v1_t, v2_t);
20332 tcg_gen_deposit_tl(cpu_dspctrl, cpu_dspctrl, v1_t, 24, 4);
20333 gen_store_gpr(v1_t, ret);
20334 break;
20335 case NM_CMPGDU_LT_QB:
908f6be1 20336 check_dsp_r2(ctx);
3285a3e4
SM
20337 gen_helper_cmpgu_lt_qb(v1_t, v1_t, v2_t);
20338 tcg_gen_deposit_tl(cpu_dspctrl, cpu_dspctrl, v1_t, 24, 4);
20339 gen_store_gpr(v1_t, ret);
20340 break;
20341 case NM_CMPGDU_LE_QB:
908f6be1 20342 check_dsp_r2(ctx);
3285a3e4
SM
20343 gen_helper_cmpgu_le_qb(v1_t, v1_t, v2_t);
20344 tcg_gen_deposit_tl(cpu_dspctrl, cpu_dspctrl, v1_t, 24, 4);
20345 gen_store_gpr(v1_t, ret);
20346 break;
20347 case NM_PACKRL_PH:
20348 check_dsp(ctx);
20349 gen_helper_packrl_ph(v1_t, v1_t, v2_t);
20350 gen_store_gpr(v1_t, ret);
20351 break;
20352 case NM_PICK_QB:
20353 check_dsp(ctx);
20354 gen_helper_pick_qb(v1_t, v1_t, v2_t, cpu_env);
20355 gen_store_gpr(v1_t, ret);
20356 break;
20357 case NM_PICK_PH:
20358 check_dsp(ctx);
20359 gen_helper_pick_ph(v1_t, v1_t, v2_t, cpu_env);
20360 gen_store_gpr(v1_t, ret);
20361 break;
20362 case NM_ADDQ_S_W:
20363 check_dsp(ctx);
20364 gen_helper_addq_s_w(v1_t, v1_t, v2_t, cpu_env);
20365 gen_store_gpr(v1_t, ret);
20366 break;
20367 case NM_SUBQ_S_W:
20368 check_dsp(ctx);
20369 gen_helper_subq_s_w(v1_t, v1_t, v2_t, cpu_env);
20370 gen_store_gpr(v1_t, ret);
20371 break;
20372 case NM_ADDSC:
20373 check_dsp(ctx);
20374 gen_helper_addsc(v1_t, v1_t, v2_t, cpu_env);
20375 gen_store_gpr(v1_t, ret);
20376 break;
20377 case NM_ADDWC:
20378 check_dsp(ctx);
20379 gen_helper_addwc(v1_t, v1_t, v2_t, cpu_env);
20380 gen_store_gpr(v1_t, ret);
20381 break;
20382 case NM_ADDQ_S_PH:
20383 check_dsp(ctx);
20384 switch (extract32(ctx->opcode, 10, 1)) {
20385 case 0:
20386 /* ADDQ_PH */
20387 gen_helper_addq_ph(v1_t, v1_t, v2_t, cpu_env);
20388 gen_store_gpr(v1_t, ret);
20389 break;
20390 case 1:
20391 /* ADDQ_S_PH */
20392 gen_helper_addq_s_ph(v1_t, v1_t, v2_t, cpu_env);
20393 gen_store_gpr(v1_t, ret);
20394 break;
20395 }
20396 break;
20397 case NM_ADDQH_R_PH:
908f6be1 20398 check_dsp_r2(ctx);
3285a3e4
SM
20399 switch (extract32(ctx->opcode, 10, 1)) {
20400 case 0:
20401 /* ADDQH_PH */
20402 gen_helper_addqh_ph(v1_t, v1_t, v2_t);
20403 gen_store_gpr(v1_t, ret);
20404 break;
20405 case 1:
20406 /* ADDQH_R_PH */
20407 gen_helper_addqh_r_ph(v1_t, v1_t, v2_t);
20408 gen_store_gpr(v1_t, ret);
20409 break;
20410 }
20411 break;
20412 case NM_ADDQH_R_W:
908f6be1 20413 check_dsp_r2(ctx);
3285a3e4
SM
20414 switch (extract32(ctx->opcode, 10, 1)) {
20415 case 0:
20416 /* ADDQH_W */
20417 gen_helper_addqh_w(v1_t, v1_t, v2_t);
20418 gen_store_gpr(v1_t, ret);
20419 break;
20420 case 1:
20421 /* ADDQH_R_W */
20422 gen_helper_addqh_r_w(v1_t, v1_t, v2_t);
20423 gen_store_gpr(v1_t, ret);
20424 break;
20425 }
20426 break;
20427 case NM_ADDU_S_QB:
20428 check_dsp(ctx);
20429 switch (extract32(ctx->opcode, 10, 1)) {
20430 case 0:
20431 /* ADDU_QB */
20432 gen_helper_addu_qb(v1_t, v1_t, v2_t, cpu_env);
20433 gen_store_gpr(v1_t, ret);
20434 break;
20435 case 1:
20436 /* ADDU_S_QB */
20437 gen_helper_addu_s_qb(v1_t, v1_t, v2_t, cpu_env);
20438 gen_store_gpr(v1_t, ret);
20439 break;
20440 }
20441 break;
20442 case NM_ADDU_S_PH:
908f6be1 20443 check_dsp_r2(ctx);
3285a3e4
SM
20444 switch (extract32(ctx->opcode, 10, 1)) {
20445 case 0:
20446 /* ADDU_PH */
20447 gen_helper_addu_ph(v1_t, v1_t, v2_t, cpu_env);
20448 gen_store_gpr(v1_t, ret);
20449 break;
20450 case 1:
20451 /* ADDU_S_PH */
20452 gen_helper_addu_s_ph(v1_t, v1_t, v2_t, cpu_env);
20453 gen_store_gpr(v1_t, ret);
20454 break;
20455 }
20456 break;
20457 case NM_ADDUH_R_QB:
908f6be1 20458 check_dsp_r2(ctx);
3285a3e4
SM
20459 switch (extract32(ctx->opcode, 10, 1)) {
20460 case 0:
20461 /* ADDUH_QB */
20462 gen_helper_adduh_qb(v1_t, v1_t, v2_t);
20463 gen_store_gpr(v1_t, ret);
20464 break;
20465 case 1:
20466 /* ADDUH_R_QB */
20467 gen_helper_adduh_r_qb(v1_t, v1_t, v2_t);
20468 gen_store_gpr(v1_t, ret);
20469 break;
20470 }
20471 break;
20472 case NM_SHRAV_R_PH:
20473 check_dsp(ctx);
20474 switch (extract32(ctx->opcode, 10, 1)) {
20475 case 0:
20476 /* SHRAV_PH */
20477 gen_helper_shra_ph(v1_t, v1_t, v2_t);
20478 gen_store_gpr(v1_t, ret);
20479 break;
20480 case 1:
20481 /* SHRAV_R_PH */
20482 gen_helper_shra_r_ph(v1_t, v1_t, v2_t);
20483 gen_store_gpr(v1_t, ret);
20484 break;
20485 }
20486 break;
20487 case NM_SHRAV_R_QB:
908f6be1 20488 check_dsp_r2(ctx);
3285a3e4
SM
20489 switch (extract32(ctx->opcode, 10, 1)) {
20490 case 0:
20491 /* SHRAV_QB */
20492 gen_helper_shra_qb(v1_t, v1_t, v2_t);
20493 gen_store_gpr(v1_t, ret);
20494 break;
20495 case 1:
20496 /* SHRAV_R_QB */
20497 gen_helper_shra_r_qb(v1_t, v1_t, v2_t);
20498 gen_store_gpr(v1_t, ret);
20499 break;
20500 }
20501 break;
20502 case NM_SUBQ_S_PH:
20503 check_dsp(ctx);
20504 switch (extract32(ctx->opcode, 10, 1)) {
20505 case 0:
20506 /* SUBQ_PH */
20507 gen_helper_subq_ph(v1_t, v1_t, v2_t, cpu_env);
20508 gen_store_gpr(v1_t, ret);
20509 break;
20510 case 1:
20511 /* SUBQ_S_PH */
20512 gen_helper_subq_s_ph(v1_t, v1_t, v2_t, cpu_env);
20513 gen_store_gpr(v1_t, ret);
20514 break;
20515 }
20516 break;
20517 case NM_SUBQH_R_PH:
908f6be1 20518 check_dsp_r2(ctx);
3285a3e4
SM
20519 switch (extract32(ctx->opcode, 10, 1)) {
20520 case 0:
20521 /* SUBQH_PH */
20522 gen_helper_subqh_ph(v1_t, v1_t, v2_t);
20523 gen_store_gpr(v1_t, ret);
20524 break;
20525 case 1:
20526 /* SUBQH_R_PH */
20527 gen_helper_subqh_r_ph(v1_t, v1_t, v2_t);
20528 gen_store_gpr(v1_t, ret);
20529 break;
20530 }
20531 break;
20532 case NM_SUBQH_R_W:
908f6be1 20533 check_dsp_r2(ctx);
3285a3e4
SM
20534 switch (extract32(ctx->opcode, 10, 1)) {
20535 case 0:
20536 /* SUBQH_W */
20537 gen_helper_subqh_w(v1_t, v1_t, v2_t);
20538 gen_store_gpr(v1_t, ret);
20539 break;
20540 case 1:
20541 /* SUBQH_R_W */
20542 gen_helper_subqh_r_w(v1_t, v1_t, v2_t);
20543 gen_store_gpr(v1_t, ret);
20544 break;
20545 }
20546 break;
20547 case NM_SUBU_S_QB:
20548 check_dsp(ctx);
20549 switch (extract32(ctx->opcode, 10, 1)) {
20550 case 0:
20551 /* SUBU_QB */
20552 gen_helper_subu_qb(v1_t, v1_t, v2_t, cpu_env);
20553 gen_store_gpr(v1_t, ret);
20554 break;
20555 case 1:
20556 /* SUBU_S_QB */
20557 gen_helper_subu_s_qb(v1_t, v1_t, v2_t, cpu_env);
20558 gen_store_gpr(v1_t, ret);
20559 break;
20560 }
20561 break;
20562 case NM_SUBU_S_PH:
908f6be1 20563 check_dsp_r2(ctx);
3285a3e4
SM
20564 switch (extract32(ctx->opcode, 10, 1)) {
20565 case 0:
20566 /* SUBU_PH */
20567 gen_helper_subu_ph(v1_t, v1_t, v2_t, cpu_env);
20568 gen_store_gpr(v1_t, ret);
20569 break;
20570 case 1:
20571 /* SUBU_S_PH */
20572 gen_helper_subu_s_ph(v1_t, v1_t, v2_t, cpu_env);
20573 gen_store_gpr(v1_t, ret);
20574 break;
20575 }
20576 break;
20577 case NM_SUBUH_R_QB:
908f6be1 20578 check_dsp_r2(ctx);
3285a3e4
SM
20579 switch (extract32(ctx->opcode, 10, 1)) {
20580 case 0:
20581 /* SUBUH_QB */
20582 gen_helper_subuh_qb(v1_t, v1_t, v2_t);
20583 gen_store_gpr(v1_t, ret);
20584 break;
20585 case 1:
20586 /* SUBUH_R_QB */
20587 gen_helper_subuh_r_qb(v1_t, v1_t, v2_t);
20588 gen_store_gpr(v1_t, ret);
20589 break;
20590 }
20591 break;
20592 case NM_SHLLV_S_PH:
20593 check_dsp(ctx);
20594 switch (extract32(ctx->opcode, 10, 1)) {
20595 case 0:
20596 /* SHLLV_PH */
20597 gen_helper_shll_ph(v1_t, v1_t, v2_t, cpu_env);
20598 gen_store_gpr(v1_t, ret);
20599 break;
20600 case 1:
20601 /* SHLLV_S_PH */
20602 gen_helper_shll_s_ph(v1_t, v1_t, v2_t, cpu_env);
20603 gen_store_gpr(v1_t, ret);
20604 break;
20605 }
20606 break;
20607 case NM_PRECR_SRA_R_PH_W:
908f6be1 20608 check_dsp_r2(ctx);
3285a3e4
SM
20609 switch (extract32(ctx->opcode, 10, 1)) {
20610 case 0:
20611 /* PRECR_SRA_PH_W */
20612 {
20613 TCGv_i32 sa_t = tcg_const_i32(rd);
20614 gen_helper_precr_sra_ph_w(v1_t, sa_t, v1_t,
20615 cpu_gpr[rt]);
20616 gen_store_gpr(v1_t, rt);
20617 tcg_temp_free_i32(sa_t);
20618 }
20619 break;
20620 case 1:
20621 /* PRECR_SRA_R_PH_W */
20622 {
20623 TCGv_i32 sa_t = tcg_const_i32(rd);
20624 gen_helper_precr_sra_r_ph_w(v1_t, sa_t, v1_t,
20625 cpu_gpr[rt]);
20626 gen_store_gpr(v1_t, rt);
20627 tcg_temp_free_i32(sa_t);
20628 }
20629 break;
20630 }
20631 break;
20632 case NM_MULEU_S_PH_QBL:
20633 check_dsp(ctx);
20634 gen_helper_muleu_s_ph_qbl(v1_t, v1_t, v2_t, cpu_env);
20635 gen_store_gpr(v1_t, ret);
20636 break;
20637 case NM_MULEU_S_PH_QBR:
20638 check_dsp(ctx);
20639 gen_helper_muleu_s_ph_qbr(v1_t, v1_t, v2_t, cpu_env);
20640 gen_store_gpr(v1_t, ret);
20641 break;
20642 case NM_MULQ_RS_PH:
20643 check_dsp(ctx);
20644 gen_helper_mulq_rs_ph(v1_t, v1_t, v2_t, cpu_env);
20645 gen_store_gpr(v1_t, ret);
20646 break;
20647 case NM_MULQ_S_PH:
908f6be1 20648 check_dsp_r2(ctx);
3285a3e4
SM
20649 gen_helper_mulq_s_ph(v1_t, v1_t, v2_t, cpu_env);
20650 gen_store_gpr(v1_t, ret);
20651 break;
20652 case NM_MULQ_RS_W:
908f6be1 20653 check_dsp_r2(ctx);
3285a3e4
SM
20654 gen_helper_mulq_rs_w(v1_t, v1_t, v2_t, cpu_env);
20655 gen_store_gpr(v1_t, ret);
20656 break;
20657 case NM_MULQ_S_W:
908f6be1 20658 check_dsp_r2(ctx);
3285a3e4
SM
20659 gen_helper_mulq_s_w(v1_t, v1_t, v2_t, cpu_env);
20660 gen_store_gpr(v1_t, ret);
20661 break;
20662 case NM_APPEND:
908f6be1 20663 check_dsp_r2(ctx);
3285a3e4
SM
20664 gen_load_gpr(t0, rs);
20665 if (rd != 0) {
20666 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], rd, 32 - rd);
20667 }
20668 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
20669 break;
20670 case NM_MODSUB:
20671 check_dsp(ctx);
20672 gen_helper_modsub(v1_t, v1_t, v2_t);
20673 gen_store_gpr(v1_t, ret);
20674 break;
20675 case NM_SHRAV_R_W:
20676 check_dsp(ctx);
20677 gen_helper_shra_r_w(v1_t, v1_t, v2_t);
20678 gen_store_gpr(v1_t, ret);
20679 break;
20680 case NM_SHRLV_PH:
908f6be1 20681 check_dsp_r2(ctx);
3285a3e4
SM
20682 gen_helper_shrl_ph(v1_t, v1_t, v2_t);
20683 gen_store_gpr(v1_t, ret);
20684 break;
20685 case NM_SHRLV_QB:
20686 check_dsp(ctx);
20687 gen_helper_shrl_qb(v1_t, v1_t, v2_t);
20688 gen_store_gpr(v1_t, ret);
20689 break;
20690 case NM_SHLLV_QB:
20691 check_dsp(ctx);
20692 gen_helper_shll_qb(v1_t, v1_t, v2_t, cpu_env);
20693 gen_store_gpr(v1_t, ret);
20694 break;
20695 case NM_SHLLV_S_W:
20696 check_dsp(ctx);
20697 gen_helper_shll_s_w(v1_t, v1_t, v2_t, cpu_env);
20698 gen_store_gpr(v1_t, ret);
20699 break;
20700 case NM_SHILO:
20701 check_dsp(ctx);
20702 {
20703 TCGv tv0 = tcg_temp_new();
20704 TCGv tv1 = tcg_temp_new();
20705 int16_t imm = extract32(ctx->opcode, 16, 7);
20706
20707 tcg_gen_movi_tl(tv0, rd >> 3);
20708 tcg_gen_movi_tl(tv1, imm);
20709 gen_helper_shilo(tv0, tv1, cpu_env);
20710 }
20711 break;
20712 case NM_MULEQ_S_W_PHL:
20713 check_dsp(ctx);
20714 gen_helper_muleq_s_w_phl(v1_t, v1_t, v2_t, cpu_env);
20715 gen_store_gpr(v1_t, ret);
20716 break;
20717 case NM_MULEQ_S_W_PHR:
20718 check_dsp(ctx);
20719 gen_helper_muleq_s_w_phr(v1_t, v1_t, v2_t, cpu_env);
20720 gen_store_gpr(v1_t, ret);
20721 break;
20722 case NM_MUL_S_PH:
908f6be1 20723 check_dsp_r2(ctx);
3285a3e4
SM
20724 switch (extract32(ctx->opcode, 10, 1)) {
20725 case 0:
20726 /* MUL_PH */
20727 gen_helper_mul_ph(v1_t, v1_t, v2_t, cpu_env);
20728 gen_store_gpr(v1_t, ret);
20729 break;
20730 case 1:
20731 /* MUL_S_PH */
20732 gen_helper_mul_s_ph(v1_t, v1_t, v2_t, cpu_env);
20733 gen_store_gpr(v1_t, ret);
20734 break;
20735 }
20736 break;
20737 case NM_PRECR_QB_PH:
908f6be1 20738 check_dsp_r2(ctx);
3285a3e4
SM
20739 gen_helper_precr_qb_ph(v1_t, v1_t, v2_t);
20740 gen_store_gpr(v1_t, ret);
20741 break;
20742 case NM_PRECRQ_QB_PH:
20743 check_dsp(ctx);
20744 gen_helper_precrq_qb_ph(v1_t, v1_t, v2_t);
20745 gen_store_gpr(v1_t, ret);
20746 break;
20747 case NM_PRECRQ_PH_W:
20748 check_dsp(ctx);
20749 gen_helper_precrq_ph_w(v1_t, v1_t, v2_t);
20750 gen_store_gpr(v1_t, ret);
20751 break;
20752 case NM_PRECRQ_RS_PH_W:
20753 check_dsp(ctx);
20754 gen_helper_precrq_rs_ph_w(v1_t, v1_t, v2_t, cpu_env);
20755 gen_store_gpr(v1_t, ret);
20756 break;
20757 case NM_PRECRQU_S_QB_PH:
20758 check_dsp(ctx);
20759 gen_helper_precrqu_s_qb_ph(v1_t, v1_t, v2_t, cpu_env);
20760 gen_store_gpr(v1_t, ret);
20761 break;
20762 case NM_SHRA_R_W:
20763 check_dsp(ctx);
20764 tcg_gen_movi_tl(t0, rd);
20765 gen_helper_shra_r_w(v1_t, t0, v1_t);
20766 gen_store_gpr(v1_t, rt);
20767 break;
20768 case NM_SHRA_R_PH:
20769 check_dsp(ctx);
20770 tcg_gen_movi_tl(t0, rd >> 1);
20771 switch (extract32(ctx->opcode, 10, 1)) {
20772 case 0:
20773 /* SHRA_PH */
20774 gen_helper_shra_ph(v1_t, t0, v1_t);
3285a3e4 20775 gen_store_gpr(v1_t, rt);
d5ebcbaf 20776 break;
3285a3e4
SM
20777 case 1:
20778 /* SHRA_R_PH */
20779 gen_helper_shra_r_ph(v1_t, t0, v1_t);
20780 gen_store_gpr(v1_t, rt);
20781 break;
20782 }
20783 break;
20784 case NM_SHLL_S_PH:
20785 check_dsp(ctx);
20786 tcg_gen_movi_tl(t0, rd >> 1);
20787 switch (extract32(ctx->opcode, 10, 2)) {
20788 case 0:
20789 /* SHLL_PH */
20790 gen_helper_shll_ph(v1_t, t0, v1_t, cpu_env);
20791 gen_store_gpr(v1_t, rt);
20792 break;
20793 case 2:
20794 /* SHLL_S_PH */
20795 gen_helper_shll_s_ph(v1_t, t0, v1_t, cpu_env);
20796 gen_store_gpr(v1_t, rt);
20797 break;
20798 default:
20799 generate_exception_end(ctx, EXCP_RI);
20800 break;
20801 }
20802 break;
20803 case NM_SHLL_S_W:
20804 check_dsp(ctx);
20805 tcg_gen_movi_tl(t0, rd);
20806 gen_helper_shll_s_w(v1_t, t0, v1_t, cpu_env);
20807 gen_store_gpr(v1_t, rt);
20808 break;
20809 case NM_REPL_PH:
20810 check_dsp(ctx);
20811 {
20812 int16_t imm;
20813 imm = sextract32(ctx->opcode, 11, 11);
20814 imm = (int16_t)(imm << 6) >> 6;
20815 if (rt != 0) {
20816 tcg_gen_movi_tl(cpu_gpr[rt], dup_const(MO_16, imm));
20817 }
20818 }
20819 break;
20820 default:
20821 generate_exception_end(ctx, EXCP_RI);
20822 break;
20823 }
20824}
20825
c0280983
YK
20826static int decode_nanomips_32_48_opc(CPUMIPSState *env, DisasContext *ctx)
20827{
20828 uint16_t insn;
20829 uint32_t op;
eac52664 20830 int rt, rs, rd;
c0280983
YK
20831 int offset;
20832 int imm;
20833
20834 insn = cpu_lduw_code(env, ctx->base.pc_next + 2);
20835 ctx->opcode = (ctx->opcode << 16) | insn;
20836
20837 rt = extract32(ctx->opcode, 21, 5);
20838 rs = extract32(ctx->opcode, 16, 5);
eac52664 20839 rd = extract32(ctx->opcode, 11, 5);
c0280983
YK
20840
20841 op = extract32(ctx->opcode, 26, 6);
20842 switch (op) {
20843 case NM_P_ADDIU:
20844 if (rt == 0) {
20845 /* P.RI */
20846 switch (extract32(ctx->opcode, 19, 2)) {
20847 case NM_SIGRIE:
20848 default:
20849 generate_exception_end(ctx, EXCP_RI);
20850 break;
20851 case NM_P_SYSCALL:
20852 if ((extract32(ctx->opcode, 18, 1)) == NM_SYSCALL) {
20853 generate_exception_end(ctx, EXCP_SYSCALL);
20854 } else {
20855 generate_exception_end(ctx, EXCP_RI);
20856 }
20857 break;
20858 case NM_BREAK:
20859 generate_exception_end(ctx, EXCP_BREAK);
20860 break;
20861 case NM_SDBBP:
20862 if (is_uhi(extract32(ctx->opcode, 0, 19))) {
20863 gen_helper_do_semihosting(cpu_env);
20864 } else {
20865 if (ctx->hflags & MIPS_HFLAG_SBRI) {
20866 generate_exception_end(ctx, EXCP_RI);
20867 } else {
20868 generate_exception_end(ctx, EXCP_DBp);
20869 }
20870 }
20871 break;
20872 }
20873 } else {
20874 /* NM_ADDIU */
20875 imm = extract32(ctx->opcode, 0, 16);
20876 if (rs != 0) {
20877 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm);
20878 } else {
20879 tcg_gen_movi_tl(cpu_gpr[rt], imm);
20880 }
20881 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
20882 }
20883 break;
20884 case NM_ADDIUPC:
20885 if (rt != 0) {
20886 offset = sextract32(ctx->opcode, 0, 1) << 21 |
20887 extract32(ctx->opcode, 1, 20) << 1;
20888 target_long addr = addr_add(ctx, ctx->base.pc_next + 4, offset);
20889 tcg_gen_movi_tl(cpu_gpr[rt], addr);
20890 }
20891 break;
20892 case NM_POOL32A:
e0cf0e65
YK
20893 switch (ctx->opcode & 0x07) {
20894 case NM_POOL32A0:
0a1a6ed7 20895 gen_pool32a0_nanomips_insn(env, ctx);
e0cf0e65 20896 break;
3285a3e4
SM
20897 case NM_POOL32A5:
20898 {
20899 int32_t op1 = extract32(ctx->opcode, 3, 7);
20900 gen_pool32a5_nanomips_insn(ctx, op1, rd, rs, rt);
20901 }
20902 break;
e0cf0e65 20903 case NM_POOL32A7:
64224187 20904 switch (extract32(ctx->opcode, 3, 3)) {
eac52664
YK
20905 case NM_P_LSX:
20906 gen_p_lsx(ctx, rd, rs, rt);
20907 break;
20908 case NM_LSA:
20909 /* In nanoMIPS, the shift field directly encodes the shift
20910 * amount, meaning that the supported shift values are in
20911 * the range 0 to 3 (instead of 1 to 4 in MIPSR6). */
20912 gen_lsa(ctx, OPC_LSA, rd, rs, rt,
20913 extract32(ctx->opcode, 9, 2) - 1);
20914 break;
821f2008
JH
20915 case NM_EXTW:
20916 gen_ext(ctx, 32, rd, rs, rt, extract32(ctx->opcode, 6, 5));
20917 break;
64224187
YK
20918 case NM_POOL32AXF:
20919 gen_pool32axf_nanomips_insn(env, ctx);
20920 break;
20921 default:
20922 generate_exception_end(ctx, EXCP_RI);
20923 break;
20924 }
e0cf0e65
YK
20925 break;
20926 default:
20927 generate_exception_end(ctx, EXCP_RI);
20928 break;
20929 }
c0280983
YK
20930 break;
20931 case NM_P_GP_W:
20932 switch (ctx->opcode & 0x03) {
20933 case NM_ADDIUGP_W:
20934 if (rt != 0) {
20935 offset = extract32(ctx->opcode, 0, 21);
20936 gen_op_addr_addi(ctx, cpu_gpr[rt], cpu_gpr[28], offset);
20937 }
20938 break;
20939 case NM_LWGP:
20940 gen_ld(ctx, OPC_LW, rt, 28, extract32(ctx->opcode, 2, 19) << 2);
20941 break;
20942 case NM_SWGP:
20943 gen_st(ctx, OPC_SW, rt, 28, extract32(ctx->opcode, 2, 19) << 2);
20944 break;
20945 default:
20946 generate_exception_end(ctx, EXCP_RI);
20947 break;
20948 }
20949 break;
20950 case NM_P48I:
7ef009b2
YK
20951 {
20952 insn = cpu_lduw_code(env, ctx->base.pc_next + 4);
20953 target_long addr_off = extract32(ctx->opcode, 0, 16) | insn << 16;
20954 switch (extract32(ctx->opcode, 16, 5)) {
20955 case NM_LI48:
fb32f8c8 20956 check_nms(ctx);
7ef009b2
YK
20957 if (rt != 0) {
20958 tcg_gen_movi_tl(cpu_gpr[rt], addr_off);
20959 }
20960 break;
20961 case NM_ADDIU48:
fb32f8c8 20962 check_nms(ctx);
7ef009b2
YK
20963 if (rt != 0) {
20964 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rt], addr_off);
20965 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
20966 }
20967 break;
20968 case NM_ADDIUGP48:
fb32f8c8 20969 check_nms(ctx);
7ef009b2
YK
20970 if (rt != 0) {
20971 gen_op_addr_addi(ctx, cpu_gpr[rt], cpu_gpr[28], addr_off);
20972 }
20973 break;
20974 case NM_ADDIUPC48:
fb32f8c8 20975 check_nms(ctx);
7ef009b2
YK
20976 if (rt != 0) {
20977 target_long addr = addr_add(ctx, ctx->base.pc_next + 6,
20978 addr_off);
20979
20980 tcg_gen_movi_tl(cpu_gpr[rt], addr);
20981 }
20982 break;
20983 case NM_LWPC48:
fb32f8c8 20984 check_nms(ctx);
7ef009b2
YK
20985 if (rt != 0) {
20986 TCGv t0;
20987 t0 = tcg_temp_new();
20988
20989 target_long addr = addr_add(ctx, ctx->base.pc_next + 6,
20990 addr_off);
20991
20992 tcg_gen_movi_tl(t0, addr);
20993 tcg_gen_qemu_ld_tl(cpu_gpr[rt], t0, ctx->mem_idx, MO_TESL);
20994 tcg_temp_free(t0);
20995 }
20996 break;
20997 case NM_SWPC48:
fb32f8c8 20998 check_nms(ctx);
7ef009b2
YK
20999 {
21000 TCGv t0, t1;
21001 t0 = tcg_temp_new();
21002 t1 = tcg_temp_new();
21003
21004 target_long addr = addr_add(ctx, ctx->base.pc_next + 6,
21005 addr_off);
21006
21007 tcg_gen_movi_tl(t0, addr);
21008 gen_load_gpr(t1, rt);
21009
21010 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
21011
21012 tcg_temp_free(t0);
21013 tcg_temp_free(t1);
21014 }
21015 break;
21016 default:
21017 generate_exception_end(ctx, EXCP_RI);
21018 break;
21019 }
21020 return 6;
21021 }
c0280983
YK
21022 case NM_P_U12:
21023 switch (extract32(ctx->opcode, 12, 4)) {
21024 case NM_ORI:
21025 gen_logic_imm(ctx, OPC_ORI, rt, rs, extract32(ctx->opcode, 0, 12));
21026 break;
21027 case NM_XORI:
21028 gen_logic_imm(ctx, OPC_XORI, rt, rs, extract32(ctx->opcode, 0, 12));
21029 break;
21030 case NM_ANDI:
21031 gen_logic_imm(ctx, OPC_ANDI, rt, rs, extract32(ctx->opcode, 0, 12));
21032 break;
21033 case NM_P_SR:
21034 switch (extract32(ctx->opcode, 20, 1)) {
21035 case NM_PP_SR:
21036 switch (ctx->opcode & 3) {
21037 case NM_SAVE:
21038 gen_save(ctx, rt, extract32(ctx->opcode, 16, 4),
21039 extract32(ctx->opcode, 2, 1),
21040 extract32(ctx->opcode, 3, 9) << 3);
21041 break;
21042 case NM_RESTORE:
21043 case NM_RESTORE_JRC:
21044 gen_restore(ctx, rt, extract32(ctx->opcode, 16, 4),
21045 extract32(ctx->opcode, 2, 1),
21046 extract32(ctx->opcode, 3, 9) << 3);
21047 if ((ctx->opcode & 3) == NM_RESTORE_JRC) {
21048 gen_compute_branch_nm(ctx, OPC_JR, 2, 31, 0, 0);
21049 }
21050 break;
21051 default:
21052 generate_exception_end(ctx, EXCP_RI);
21053 break;
21054 }
21055 break;
21056 case NM_P_SR_F:
21057 generate_exception_end(ctx, EXCP_RI);
21058 break;
21059 }
21060 break;
21061 case NM_SLTI:
21062 gen_slt_imm(ctx, OPC_SLTI, rt, rs, extract32(ctx->opcode, 0, 12));
21063 break;
21064 case NM_SLTIU:
21065 gen_slt_imm(ctx, OPC_SLTIU, rt, rs, extract32(ctx->opcode, 0, 12));
21066 break;
21067 case NM_SEQI:
21068 {
21069 TCGv t0 = tcg_temp_new();
21070
21071 imm = extract32(ctx->opcode, 0, 12);
21072 gen_load_gpr(t0, rs);
21073 tcg_gen_setcondi_tl(TCG_COND_EQ, t0, t0, imm);
21074 gen_store_gpr(t0, rt);
21075
21076 tcg_temp_free(t0);
21077 }
21078 break;
21079 case NM_ADDIUNEG:
21080 imm = (int16_t) extract32(ctx->opcode, 0, 12);
21081 gen_arith_imm(ctx, OPC_ADDIU, rt, rs, -imm);
21082 break;
21083 case NM_P_SHIFT:
21084 {
21085 int shift = extract32(ctx->opcode, 0, 5);
21086 switch (extract32(ctx->opcode, 5, 4)) {
21087 case NM_P_SLL:
21088 if (rt == 0 && shift == 0) {
21089 /* NOP */
21090 } else if (rt == 0 && shift == 3) {
21091 /* EHB - treat as NOP */
21092 } else if (rt == 0 && shift == 5) {
21093 /* PAUSE - treat as NOP */
21094 } else if (rt == 0 && shift == 6) {
21095 /* SYNC */
21096 gen_sync(extract32(ctx->opcode, 16, 5));
21097 } else {
21098 /* SLL */
21099 gen_shift_imm(ctx, OPC_SLL, rt, rs,
21100 extract32(ctx->opcode, 0, 5));
21101 }
21102 break;
21103 case NM_SRL:
21104 gen_shift_imm(ctx, OPC_SRL, rt, rs,
21105 extract32(ctx->opcode, 0, 5));
21106 break;
21107 case NM_SRA:
21108 gen_shift_imm(ctx, OPC_SRA, rt, rs,
21109 extract32(ctx->opcode, 0, 5));
21110 break;
21111 case NM_ROTR:
21112 gen_shift_imm(ctx, OPC_ROTR, rt, rs,
21113 extract32(ctx->opcode, 0, 5));
21114 break;
21115 }
21116 }
21117 break;
21118 case NM_P_ROTX:
fb32f8c8 21119 check_nms(ctx);
e222f506
MF
21120 if (rt != 0) {
21121 TCGv t0 = tcg_temp_new();
21122 TCGv_i32 shift = tcg_const_i32(extract32(ctx->opcode, 0, 5));
21123 TCGv_i32 shiftx = tcg_const_i32(extract32(ctx->opcode, 7, 4)
21124 << 1);
21125 TCGv_i32 stripe = tcg_const_i32(extract32(ctx->opcode, 6, 1));
21126
21127 gen_load_gpr(t0, rs);
21128 gen_helper_rotx(cpu_gpr[rt], t0, shift, shiftx, stripe);
21129 tcg_temp_free(t0);
21130
21131 tcg_temp_free_i32(shift);
21132 tcg_temp_free_i32(shiftx);
21133 tcg_temp_free_i32(stripe);
21134 }
c0280983
YK
21135 break;
21136 case NM_P_INS:
21137 switch (((ctx->opcode >> 10) & 2) |
21138 (extract32(ctx->opcode, 5, 1))) {
21139 case NM_INS:
fb32f8c8 21140 check_nms(ctx);
c0280983
YK
21141 gen_bitops(ctx, OPC_INS, rt, rs, extract32(ctx->opcode, 0, 5),
21142 extract32(ctx->opcode, 6, 5));
21143 break;
21144 default:
21145 generate_exception_end(ctx, EXCP_RI);
21146 break;
21147 }
21148 break;
21149 case NM_P_EXT:
21150 switch (((ctx->opcode >> 10) & 2) |
21151 (extract32(ctx->opcode, 5, 1))) {
21152 case NM_EXT:
fb32f8c8 21153 check_nms(ctx);
c0280983
YK
21154 gen_bitops(ctx, OPC_EXT, rt, rs, extract32(ctx->opcode, 0, 5),
21155 extract32(ctx->opcode, 6, 5));
21156 break;
21157 default:
21158 generate_exception_end(ctx, EXCP_RI);
21159 break;
21160 }
21161 break;
21162 default:
21163 generate_exception_end(ctx, EXCP_RI);
21164 break;
21165 }
21166 break;
21167 case NM_POOL32F:
579b8ea9 21168 gen_pool32f_nanomips_insn(ctx);
c0280983
YK
21169 break;
21170 case NM_POOL32S:
21171 break;
21172 case NM_P_LUI:
21173 switch (extract32(ctx->opcode, 1, 1)) {
21174 case NM_LUI:
21175 if (rt != 0) {
21176 tcg_gen_movi_tl(cpu_gpr[rt],
21177 sextract32(ctx->opcode, 0, 1) << 31 |
21178 extract32(ctx->opcode, 2, 10) << 21 |
21179 extract32(ctx->opcode, 12, 9) << 12);
21180 }
21181 break;
21182 case NM_ALUIPC:
21183 if (rt != 0) {
21184 offset = sextract32(ctx->opcode, 0, 1) << 31 |
21185 extract32(ctx->opcode, 2, 10) << 21 |
21186 extract32(ctx->opcode, 12, 9) << 12;
21187 target_long addr;
21188 addr = ~0xFFF & addr_add(ctx, ctx->base.pc_next + 4, offset);
21189 tcg_gen_movi_tl(cpu_gpr[rt], addr);
21190 }
21191 break;
21192 }
21193 break;
21194 case NM_P_GP_BH:
8f1d9b6d
YK
21195 {
21196 uint32_t u = extract32(ctx->opcode, 0, 18);
21197
21198 switch (extract32(ctx->opcode, 18, 3)) {
21199 case NM_LBGP:
21200 gen_ld(ctx, OPC_LB, rt, 28, u);
21201 break;
21202 case NM_SBGP:
21203 gen_st(ctx, OPC_SB, rt, 28, u);
21204 break;
21205 case NM_LBUGP:
21206 gen_ld(ctx, OPC_LBU, rt, 28, u);
21207 break;
21208 case NM_ADDIUGP_B:
21209 if (rt != 0) {
21210 gen_op_addr_addi(ctx, cpu_gpr[rt], cpu_gpr[28], u);
21211 }
21212 break;
21213 case NM_P_GP_LH:
21214 u &= ~1;
21215 switch (ctx->opcode & 1) {
21216 case NM_LHGP:
21217 gen_ld(ctx, OPC_LH, rt, 28, u);
21218 break;
21219 case NM_LHUGP:
21220 gen_ld(ctx, OPC_LHU, rt, 28, u);
21221 break;
21222 }
21223 break;
21224 case NM_P_GP_SH:
21225 u &= ~1;
21226 switch (ctx->opcode & 1) {
21227 case NM_SHGP:
21228 gen_st(ctx, OPC_SH, rt, 28, u);
21229 break;
21230 default:
21231 generate_exception_end(ctx, EXCP_RI);
21232 break;
21233 }
21234 break;
21235 case NM_P_GP_CP1:
21236 u &= ~0x3;
21237 switch (ctx->opcode & 0x3) {
21238 case NM_LWC1GP:
21239 gen_cop1_ldst(ctx, OPC_LWC1, rt, 28, u);
21240 break;
21241 case NM_LDC1GP:
21242 gen_cop1_ldst(ctx, OPC_LDC1, rt, 28, u);
21243 break;
21244 case NM_SWC1GP:
21245 gen_cop1_ldst(ctx, OPC_SWC1, rt, 28, u);
21246 break;
21247 case NM_SDC1GP:
21248 gen_cop1_ldst(ctx, OPC_SDC1, rt, 28, u);
21249 break;
21250 }
21251 break;
21252 default:
21253 generate_exception_end(ctx, EXCP_RI);
21254 break;
21255 }
21256 }
c0280983
YK
21257 break;
21258 case NM_P_LS_U12:
8f1d9b6d
YK
21259 {
21260 uint32_t u = extract32(ctx->opcode, 0, 12);
21261
21262 switch (extract32(ctx->opcode, 12, 4)) {
21263 case NM_P_PREFU12:
21264 if (rt == 31) {
21265 /* SYNCI */
21266 /* Break the TB to be able to sync copied instructions
21267 immediately */
21268 ctx->base.is_jmp = DISAS_STOP;
21269 } else {
21270 /* PREF */
21271 /* Treat as NOP. */
21272 }
21273 break;
21274 case NM_LB:
21275 gen_ld(ctx, OPC_LB, rt, rs, u);
21276 break;
21277 case NM_LH:
21278 gen_ld(ctx, OPC_LH, rt, rs, u);
21279 break;
21280 case NM_LW:
21281 gen_ld(ctx, OPC_LW, rt, rs, u);
21282 break;
21283 case NM_LBU:
21284 gen_ld(ctx, OPC_LBU, rt, rs, u);
21285 break;
21286 case NM_LHU:
21287 gen_ld(ctx, OPC_LHU, rt, rs, u);
21288 break;
21289 case NM_SB:
21290 gen_st(ctx, OPC_SB, rt, rs, u);
21291 break;
21292 case NM_SH:
21293 gen_st(ctx, OPC_SH, rt, rs, u);
21294 break;
21295 case NM_SW:
21296 gen_st(ctx, OPC_SW, rt, rs, u);
21297 break;
21298 case NM_LWC1:
21299 gen_cop1_ldst(ctx, OPC_LWC1, rt, rs, u);
21300 break;
21301 case NM_LDC1:
21302 gen_cop1_ldst(ctx, OPC_LDC1, rt, rs, u);
21303 break;
21304 case NM_SWC1:
21305 gen_cop1_ldst(ctx, OPC_SWC1, rt, rs, u);
21306 break;
21307 case NM_SDC1:
21308 gen_cop1_ldst(ctx, OPC_SDC1, rt, rs, u);
21309 break;
21310 default:
21311 generate_exception_end(ctx, EXCP_RI);
21312 break;
21313 }
21314 }
c0280983
YK
21315 break;
21316 case NM_P_LS_S9:
8f1d9b6d
YK
21317 {
21318 int32_t s = (sextract32(ctx->opcode, 15, 1) << 8) |
21319 extract32(ctx->opcode, 0, 8);
21320
21321 switch (extract32(ctx->opcode, 8, 3)) {
21322 case NM_P_LS_S0:
21323 switch (extract32(ctx->opcode, 11, 4)) {
21324 case NM_LBS9:
21325 gen_ld(ctx, OPC_LB, rt, rs, s);
21326 break;
21327 case NM_LHS9:
21328 gen_ld(ctx, OPC_LH, rt, rs, s);
21329 break;
21330 case NM_LWS9:
21331 gen_ld(ctx, OPC_LW, rt, rs, s);
21332 break;
21333 case NM_LBUS9:
21334 gen_ld(ctx, OPC_LBU, rt, rs, s);
21335 break;
21336 case NM_LHUS9:
21337 gen_ld(ctx, OPC_LHU, rt, rs, s);
21338 break;
21339 case NM_SBS9:
21340 gen_st(ctx, OPC_SB, rt, rs, s);
21341 break;
21342 case NM_SHS9:
21343 gen_st(ctx, OPC_SH, rt, rs, s);
21344 break;
21345 case NM_SWS9:
21346 gen_st(ctx, OPC_SW, rt, rs, s);
21347 break;
21348 case NM_LWC1S9:
21349 gen_cop1_ldst(ctx, OPC_LWC1, rt, rs, s);
21350 break;
21351 case NM_LDC1S9:
21352 gen_cop1_ldst(ctx, OPC_LDC1, rt, rs, s);
21353 break;
21354 case NM_SWC1S9:
21355 gen_cop1_ldst(ctx, OPC_SWC1, rt, rs, s);
21356 break;
21357 case NM_SDC1S9:
21358 gen_cop1_ldst(ctx, OPC_SDC1, rt, rs, s);
21359 break;
21360 case NM_P_PREFS9:
21361 if (rt == 31) {
21362 /* SYNCI */
21363 /* Break the TB to be able to sync copied instructions
21364 immediately */
21365 ctx->base.is_jmp = DISAS_STOP;
21366 } else {
21367 /* PREF */
21368 /* Treat as NOP. */
21369 }
21370 break;
21371 default:
21372 generate_exception_end(ctx, EXCP_RI);
21373 break;
21374 }
21375 break;
21376 case NM_P_LS_S1:
21377 switch (extract32(ctx->opcode, 11, 4)) {
21378 case NM_UALH:
21379 case NM_UASH:
fb32f8c8 21380 check_nms(ctx);
8f1d9b6d
YK
21381 {
21382 TCGv t0 = tcg_temp_new();
21383 TCGv t1 = tcg_temp_new();
21384
21385 gen_base_offset_addr(ctx, t0, rs, s);
21386
21387 switch (extract32(ctx->opcode, 11, 4)) {
21388 case NM_UALH:
21389 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW |
21390 MO_UNALN);
21391 gen_store_gpr(t0, rt);
21392 break;
21393 case NM_UASH:
21394 gen_load_gpr(t1, rt);
21395 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUW |
21396 MO_UNALN);
21397 break;
21398 }
21399 tcg_temp_free(t0);
21400 tcg_temp_free(t1);
21401 }
21402 break;
21403 case NM_P_LL:
21404 switch (ctx->opcode & 0x03) {
21405 case NM_LL:
21406 gen_ld(ctx, OPC_LL, rt, rs, s);
21407 break;
21408 case NM_LLWP:
0b16dcd1
AR
21409 check_xnp(ctx);
21410 gen_llwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5));
8f1d9b6d
YK
21411 break;
21412 }
21413 break;
21414 case NM_P_SC:
21415 switch (ctx->opcode & 0x03) {
21416 case NM_SC:
21417 gen_st_cond(ctx, OPC_SC, rt, rs, s);
21418 break;
21419 case NM_SCWP:
0b16dcd1
AR
21420 check_xnp(ctx);
21421 gen_scwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5));
8f1d9b6d
YK
21422 break;
21423 }
21424 break;
21425 case NM_CACHE:
21426 check_cp0_enabled(ctx);
21427 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
21428 gen_cache_operation(ctx, rt, rs, s);
21429 }
21430 break;
21431 }
21432 break;
d046a9ea
DN
21433 case NM_P_LS_E0:
21434 switch (extract32(ctx->opcode, 11, 4)) {
21435 case NM_LBE:
21436 check_eva(ctx);
21437 check_cp0_enabled(ctx);
21438 gen_ld(ctx, OPC_LBE, rt, rs, s);
21439 break;
21440 case NM_SBE:
21441 check_eva(ctx);
21442 check_cp0_enabled(ctx);
21443 gen_st(ctx, OPC_SBE, rt, rs, s);
21444 break;
21445 case NM_LBUE:
21446 check_eva(ctx);
21447 check_cp0_enabled(ctx);
21448 gen_ld(ctx, OPC_LBUE, rt, rs, s);
21449 break;
21450 case NM_P_PREFE:
21451 if (rt == 31) {
21452 /* case NM_SYNCIE */
21453 check_eva(ctx);
21454 check_cp0_enabled(ctx);
21455 /* Break the TB to be able to sync copied instructions
21456 immediately */
21457 ctx->base.is_jmp = DISAS_STOP;
21458 } else {
21459 /* case NM_PREFE */
21460 check_eva(ctx);
21461 check_cp0_enabled(ctx);
21462 /* Treat as NOP. */
21463 }
21464 break;
21465 case NM_LHE:
21466 check_eva(ctx);
21467 check_cp0_enabled(ctx);
21468 gen_ld(ctx, OPC_LHE, rt, rs, s);
21469 break;
21470 case NM_SHE:
21471 check_eva(ctx);
21472 check_cp0_enabled(ctx);
21473 gen_st(ctx, OPC_SHE, rt, rs, s);
21474 break;
21475 case NM_LHUE:
21476 check_eva(ctx);
21477 check_cp0_enabled(ctx);
21478 gen_ld(ctx, OPC_LHUE, rt, rs, s);
21479 break;
21480 case NM_CACHEE:
21481 check_nms_dl_il_sl_tl_l2c(ctx);
21482 gen_cache_operation(ctx, rt, rs, s);
21483 break;
21484 case NM_LWE:
21485 check_eva(ctx);
21486 check_cp0_enabled(ctx);
21487 gen_ld(ctx, OPC_LWE, rt, rs, s);
21488 break;
21489 case NM_SWE:
21490 check_eva(ctx);
21491 check_cp0_enabled(ctx);
21492 gen_st(ctx, OPC_SWE, rt, rs, s);
21493 break;
21494 case NM_P_LLE:
21495 switch (extract32(ctx->opcode, 2, 2)) {
21496 case NM_LLE:
21497 check_xnp(ctx);
21498 check_eva(ctx);
21499 check_cp0_enabled(ctx);
21500 gen_ld(ctx, OPC_LLE, rt, rs, s);
21501 break;
21502 case NM_LLWPE:
21503 check_xnp(ctx);
21504 check_eva(ctx);
21505 check_cp0_enabled(ctx);
21506 gen_llwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5));
2431a422 21507 break;
d046a9ea
DN
21508 default:
21509 generate_exception_end(ctx, EXCP_RI);
21510 break;
21511 }
21512 break;
21513 case NM_P_SCE:
21514 switch (extract32(ctx->opcode, 2, 2)) {
21515 case NM_SCE:
21516 check_xnp(ctx);
21517 check_eva(ctx);
21518 check_cp0_enabled(ctx);
21519 gen_st_cond(ctx, OPC_SCE, rt, rs, s);
21520 break;
21521 case NM_SCWPE:
21522 check_xnp(ctx);
21523 check_eva(ctx);
21524 check_cp0_enabled(ctx);
21525 gen_scwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5));
2431a422 21526 break;
d046a9ea
DN
21527 default:
21528 generate_exception_end(ctx, EXCP_RI);
21529 break;
21530 }
21531 break;
21532 }
21533 break;
8f1d9b6d
YK
21534 case NM_P_LS_WM:
21535 case NM_P_LS_UAWM:
fb32f8c8 21536 check_nms(ctx);
8f1d9b6d
YK
21537 {
21538 int count = extract32(ctx->opcode, 12, 3);
21539 int counter = 0;
21540
21541 offset = sextract32(ctx->opcode, 15, 1) << 8 |
21542 extract32(ctx->opcode, 0, 8);
21543 TCGv va = tcg_temp_new();
21544 TCGv t1 = tcg_temp_new();
21545 TCGMemOp memop = (extract32(ctx->opcode, 8, 3)) ==
21546 NM_P_LS_UAWM ? MO_UNALN : 0;
21547
21548 count = (count == 0) ? 8 : count;
21549 while (counter != count) {
21550 int this_rt = ((rt + counter) & 0x1f) | (rt & 0x10);
21551 int this_offset = offset + (counter << 2);
21552
21553 gen_base_offset_addr(ctx, va, rs, this_offset);
21554
21555 switch (extract32(ctx->opcode, 11, 1)) {
21556 case NM_LWM:
21557 tcg_gen_qemu_ld_tl(t1, va, ctx->mem_idx,
21558 memop | MO_TESL);
21559 gen_store_gpr(t1, this_rt);
21560 if ((this_rt == rs) &&
21561 (counter != (count - 1))) {
21562 /* UNPREDICTABLE */
21563 }
21564 break;
21565 case NM_SWM:
21566 this_rt = (rt == 0) ? 0 : this_rt;
21567 gen_load_gpr(t1, this_rt);
21568 tcg_gen_qemu_st_tl(t1, va, ctx->mem_idx,
21569 memop | MO_TEUL);
21570 break;
21571 }
21572 counter++;
21573 }
21574 tcg_temp_free(va);
21575 tcg_temp_free(t1);
21576 }
21577 break;
21578 default:
21579 generate_exception_end(ctx, EXCP_RI);
21580 break;
21581 }
21582 }
c0280983
YK
21583 break;
21584 case NM_MOVE_BALC:
fb32f8c8 21585 check_nms(ctx);
11d0fc10
SM
21586 {
21587 TCGv t0 = tcg_temp_new();
21588 int32_t s = sextract32(ctx->opcode, 0, 1) << 21 |
21589 extract32(ctx->opcode, 1, 20) << 1;
21590 rd = (extract32(ctx->opcode, 24, 1)) == 0 ? 4 : 5;
21591 rt = decode_gpr_gpr4_zero(extract32(ctx->opcode, 25, 1) << 3 |
21592 extract32(ctx->opcode, 21, 3));
21593 gen_load_gpr(t0, rt);
21594 tcg_gen_mov_tl(cpu_gpr[rd], t0);
21595 gen_compute_branch_nm(ctx, OPC_BGEZAL, 4, 0, 0, s);
21596 tcg_temp_free(t0);
21597 }
c0280983
YK
21598 break;
21599 case NM_P_BAL:
11d0fc10
SM
21600 {
21601 int32_t s = sextract32(ctx->opcode, 0, 1) << 25 |
21602 extract32(ctx->opcode, 1, 24) << 1;
21603
21604 if ((extract32(ctx->opcode, 25, 1)) == 0) {
21605 /* BC */
21606 gen_compute_branch_nm(ctx, OPC_BEQ, 4, 0, 0, s);
21607 } else {
21608 /* BALC */
21609 gen_compute_branch_nm(ctx, OPC_BGEZAL, 4, 0, 0, s);
21610 }
21611 }
c0280983
YK
21612 break;
21613 case NM_P_J:
11d0fc10
SM
21614 switch (extract32(ctx->opcode, 12, 4)) {
21615 case NM_JALRC:
21616 case NM_JALRC_HB:
21617 gen_compute_branch_nm(ctx, OPC_JALR, 4, rs, rt, 0);
21618 break;
21619 case NM_P_BALRSC:
21620 gen_compute_nanomips_pbalrsc_branch(ctx, rs, rt);
21621 break;
21622 default:
21623 generate_exception_end(ctx, EXCP_RI);
21624 break;
21625 }
c0280983
YK
21626 break;
21627 case NM_P_BR1:
11d0fc10
SM
21628 {
21629 int32_t s = sextract32(ctx->opcode, 0, 1) << 14 |
21630 extract32(ctx->opcode, 1, 13) << 1;
21631 switch (extract32(ctx->opcode, 14, 2)) {
21632 case NM_BEQC:
fb32f8c8 21633 check_nms(ctx);
11d0fc10
SM
21634 gen_compute_branch_nm(ctx, OPC_BEQ, 4, rs, rt, s);
21635 break;
21636 case NM_P_BR3A:
21637 s = sextract32(ctx->opcode, 0, 1) << 14 |
21638 extract32(ctx->opcode, 1, 13) << 1;
21639 check_cp1_enabled(ctx);
21640 switch (extract32(ctx->opcode, 16, 5)) {
21641 case NM_BC1EQZC:
21642 gen_compute_branch_cp1_nm(ctx, OPC_BC1EQZ, rt, s);
21643 break;
21644 case NM_BC1NEZC:
21645 gen_compute_branch_cp1_nm(ctx, OPC_BC1NEZ, rt, s);
21646 break;
6d033ca7 21647 case NM_BPOSGE32C:
908f6be1 21648 check_dsp_r3(ctx);
6d033ca7
SM
21649 {
21650 int32_t imm = extract32(ctx->opcode, 1, 13) |
21651 extract32(ctx->opcode, 0, 1) << 13;
21652
21653 gen_compute_branch_nm(ctx, OPC_BPOSGE32, 4, -1, -2,
21654 imm);
21655 }
21656 break;
11d0fc10
SM
21657 default:
21658 generate_exception_end(ctx, EXCP_RI);
21659 break;
21660 }
21661 break;
21662 case NM_BGEC:
21663 if (rs == rt) {
21664 gen_compute_compact_branch_nm(ctx, OPC_BC, rs, rt, s);
21665 } else {
21666 gen_compute_compact_branch_nm(ctx, OPC_BGEC, rs, rt, s);
21667 }
21668 break;
21669 case NM_BGEUC:
21670 if (rs == rt || rt == 0) {
21671 gen_compute_compact_branch_nm(ctx, OPC_BC, 0, 0, s);
21672 } else if (rs == 0) {
21673 gen_compute_compact_branch_nm(ctx, OPC_BEQZC, rt, 0, s);
21674 } else {
21675 gen_compute_compact_branch_nm(ctx, OPC_BGEUC, rs, rt, s);
21676 }
21677 break;
21678 }
21679 }
c0280983
YK
21680 break;
21681 case NM_P_BR2:
11d0fc10
SM
21682 {
21683 int32_t s = sextract32(ctx->opcode, 0, 1) << 14 |
21684 extract32(ctx->opcode, 1, 13) << 1;
21685 switch (extract32(ctx->opcode, 14, 2)) {
21686 case NM_BNEC:
fb32f8c8 21687 check_nms(ctx);
11d0fc10
SM
21688 gen_compute_branch_nm(ctx, OPC_BNE, 4, rs, rt, s);
21689 break;
21690 case NM_BLTC:
21691 if (rs != 0 && rt != 0 && rs == rt) {
21692 /* NOP */
21693 ctx->hflags |= MIPS_HFLAG_FBNSLOT;
21694 } else {
21695 gen_compute_compact_branch_nm(ctx, OPC_BLTC, rs, rt, s);
21696 }
21697 break;
21698 case NM_BLTUC:
21699 if (rs == 0 || rs == rt) {
21700 /* NOP */
21701 ctx->hflags |= MIPS_HFLAG_FBNSLOT;
21702 } else {
21703 gen_compute_compact_branch_nm(ctx, OPC_BLTUC, rs, rt, s);
21704 }
21705 break;
21706 default:
21707 generate_exception_end(ctx, EXCP_RI);
21708 break;
21709 }
21710 }
c0280983
YK
21711 break;
21712 case NM_P_BRI:
11d0fc10
SM
21713 {
21714 int32_t s = sextract32(ctx->opcode, 0, 1) << 11 |
21715 extract32(ctx->opcode, 1, 10) << 1;
21716 uint32_t u = extract32(ctx->opcode, 11, 7);
21717
21718 gen_compute_imm_branch(ctx, extract32(ctx->opcode, 18, 3),
21719 rt, u, s);
21720 }
c0280983
YK
21721 break;
21722 default:
21723 generate_exception_end(ctx, EXCP_RI);
21724 break;
21725 }
21726 return 4;
21727}
21728
c533c0f4
AM
21729static int decode_nanomips_opc(CPUMIPSState *env, DisasContext *ctx)
21730{
ea4ca3c2
YK
21731 uint32_t op;
21732 int rt = decode_gpr_gpr3(NANOMIPS_EXTRACT_RD(ctx->opcode));
21733 int rs = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS(ctx->opcode));
21734 int rd = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS1(ctx->opcode));
8bdb7029 21735 int offset;
ea4ca3c2
YK
21736 int imm;
21737
21738 /* make sure instructions are on a halfword boundary */
21739 if (ctx->base.pc_next & 0x1) {
21740 TCGv tmp = tcg_const_tl(ctx->base.pc_next);
21741 tcg_gen_st_tl(tmp, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
21742 tcg_temp_free(tmp);
21743 generate_exception_end(ctx, EXCP_AdEL);
21744 return 2;
21745 }
21746
21747 op = extract32(ctx->opcode, 10, 6);
21748 switch (op) {
21749 case NM_P16_MV:
8869ad02
YK
21750 rt = NANOMIPS_EXTRACT_RD5(ctx->opcode);
21751 if (rt != 0) {
21752 /* MOVE */
21753 rs = NANOMIPS_EXTRACT_RS5(ctx->opcode);
21754 gen_arith(ctx, OPC_ADDU, rt, rs, 0);
21755 } else {
21756 /* P16.RI */
21757 switch (extract32(ctx->opcode, 3, 2)) {
21758 case NM_P16_SYSCALL:
21759 if (extract32(ctx->opcode, 2, 1) == 0) {
21760 generate_exception_end(ctx, EXCP_SYSCALL);
21761 } else {
21762 generate_exception_end(ctx, EXCP_RI);
21763 }
21764 break;
21765 case NM_BREAK16:
21766 generate_exception_end(ctx, EXCP_BREAK);
21767 break;
21768 case NM_SDBBP16:
21769 if (is_uhi(extract32(ctx->opcode, 0, 3))) {
21770 gen_helper_do_semihosting(cpu_env);
21771 } else {
21772 if (ctx->hflags & MIPS_HFLAG_SBRI) {
21773 generate_exception_end(ctx, EXCP_RI);
21774 } else {
21775 generate_exception_end(ctx, EXCP_DBp);
21776 }
21777 }
21778 break;
21779 default:
21780 generate_exception_end(ctx, EXCP_RI);
21781 break;
21782 }
21783 }
ea4ca3c2
YK
21784 break;
21785 case NM_P16_SHIFT:
c46562fb
YK
21786 {
21787 int shift = extract32(ctx->opcode, 0, 3);
21788 uint32_t opc = 0;
21789 shift = (shift == 0) ? 8 : shift;
21790
21791 switch (extract32(ctx->opcode, 3, 1)) {
21792 case NM_SLL16:
21793 opc = OPC_SLL;
21794 break;
21795 case NM_SRL16:
21796 opc = OPC_SRL;
21797 break;
21798 }
21799 gen_shift_imm(ctx, opc, rt, rs, shift);
21800 }
ea4ca3c2
YK
21801 break;
21802 case NM_P16C:
8bdb7029
YK
21803 switch (ctx->opcode & 1) {
21804 case NM_POOL16C_0:
80845edf 21805 gen_pool16c_nanomips_insn(ctx);
8bdb7029
YK
21806 break;
21807 case NM_LWXS16:
21808 gen_ldxs(ctx, rt, rs, rd);
21809 break;
21810 }
ea4ca3c2
YK
21811 break;
21812 case NM_P16_A1:
21813 switch (extract32(ctx->opcode, 6, 1)) {
21814 case NM_ADDIUR1SP:
21815 imm = extract32(ctx->opcode, 0, 6) << 2;
21816 gen_arith_imm(ctx, OPC_ADDIU, rt, 29, imm);
21817 break;
21818 default:
21819 generate_exception_end(ctx, EXCP_RI);
21820 break;
21821 }
21822 break;
21823 case NM_P16_A2:
21824 switch (extract32(ctx->opcode, 3, 1)) {
21825 case NM_ADDIUR2:
21826 imm = extract32(ctx->opcode, 0, 3) << 2;
21827 gen_arith_imm(ctx, OPC_ADDIU, rt, rs, imm);
21828 break;
21829 case NM_P_ADDIURS5:
21830 rt = extract32(ctx->opcode, 5, 5);
21831 if (rt != 0) {
21832 /* imm = sign_extend(s[3] . s[2:0] , from_nbits = 4) */
21833 imm = (sextract32(ctx->opcode, 4, 1) << 3) |
21834 (extract32(ctx->opcode, 0, 3));
21835 gen_arith_imm(ctx, OPC_ADDIU, rt, rt, imm);
21836 }
21837 break;
21838 }
21839 break;
21840 case NM_P16_ADDU:
21841 switch (ctx->opcode & 0x1) {
21842 case NM_ADDU16:
21843 gen_arith(ctx, OPC_ADDU, rd, rs, rt);
21844 break;
21845 case NM_SUBU16:
21846 gen_arith(ctx, OPC_SUBU, rd, rs, rt);
21847 break;
21848 }
21849 break;
21850 case NM_P16_4X4:
21851 rt = (extract32(ctx->opcode, 9, 1) << 3) |
21852 extract32(ctx->opcode, 5, 3);
21853 rs = (extract32(ctx->opcode, 4, 1) << 3) |
21854 extract32(ctx->opcode, 0, 3);
21855 rt = decode_gpr_gpr4(rt);
21856 rs = decode_gpr_gpr4(rs);
21857 switch ((extract32(ctx->opcode, 7, 2) & 0x2) |
21858 (extract32(ctx->opcode, 3, 1))) {
21859 case NM_ADDU4X4:
fb32f8c8 21860 check_nms(ctx);
ea4ca3c2
YK
21861 gen_arith(ctx, OPC_ADDU, rt, rs, rt);
21862 break;
21863 case NM_MUL4X4:
fb32f8c8 21864 check_nms(ctx);
ea4ca3c2
YK
21865 gen_r6_muldiv(ctx, R6_OPC_MUL, rt, rs, rt);
21866 break;
21867 default:
21868 generate_exception_end(ctx, EXCP_RI);
21869 break;
21870 }
21871 break;
21872 case NM_LI16:
8869ad02
YK
21873 {
21874 int imm = extract32(ctx->opcode, 0, 7);
21875 imm = (imm == 0x7f ? -1 : imm);
21876 if (rt != 0) {
21877 tcg_gen_movi_tl(cpu_gpr[rt], imm);
21878 }
21879 }
ea4ca3c2
YK
21880 break;
21881 case NM_ANDI16:
80845edf
YK
21882 {
21883 uint32_t u = extract32(ctx->opcode, 0, 4);
21884 u = (u == 12) ? 0xff :
21885 (u == 13) ? 0xffff : u;
21886 gen_logic_imm(ctx, OPC_ANDI, rt, rs, u);
21887 }
ea4ca3c2
YK
21888 break;
21889 case NM_P16_LB:
8bdb7029
YK
21890 offset = extract32(ctx->opcode, 0, 2);
21891 switch (extract32(ctx->opcode, 2, 2)) {
21892 case NM_LB16:
21893 gen_ld(ctx, OPC_LB, rt, rs, offset);
21894 break;
21895 case NM_SB16:
21896 rt = decode_gpr_gpr3_src_store(
21897 NANOMIPS_EXTRACT_RD(ctx->opcode));
21898 gen_st(ctx, OPC_SB, rt, rs, offset);
21899 break;
21900 case NM_LBU16:
21901 gen_ld(ctx, OPC_LBU, rt, rs, offset);
21902 break;
21903 default:
21904 generate_exception_end(ctx, EXCP_RI);
21905 break;
21906 }
ea4ca3c2
YK
21907 break;
21908 case NM_P16_LH:
8bdb7029
YK
21909 offset = extract32(ctx->opcode, 1, 2) << 1;
21910 switch ((extract32(ctx->opcode, 3, 1) << 1) | (ctx->opcode & 1)) {
21911 case NM_LH16:
21912 gen_ld(ctx, OPC_LH, rt, rs, offset);
21913 break;
21914 case NM_SH16:
21915 rt = decode_gpr_gpr3_src_store(
21916 NANOMIPS_EXTRACT_RD(ctx->opcode));
21917 gen_st(ctx, OPC_SH, rt, rs, offset);
21918 break;
21919 case NM_LHU16:
21920 gen_ld(ctx, OPC_LHU, rt, rs, offset);
21921 break;
21922 default:
21923 generate_exception_end(ctx, EXCP_RI);
21924 break;
21925 }
ea4ca3c2
YK
21926 break;
21927 case NM_LW16:
8bdb7029
YK
21928 offset = extract32(ctx->opcode, 0, 4) << 2;
21929 gen_ld(ctx, OPC_LW, rt, rs, offset);
ea4ca3c2
YK
21930 break;
21931 case NM_LWSP16:
8bdb7029
YK
21932 rt = NANOMIPS_EXTRACT_RD5(ctx->opcode);
21933 offset = extract32(ctx->opcode, 0, 5) << 2;
21934 gen_ld(ctx, OPC_LW, rt, 29, offset);
ea4ca3c2
YK
21935 break;
21936 case NM_LW4X4:
fb32f8c8 21937 check_nms(ctx);
8bdb7029
YK
21938 rt = (extract32(ctx->opcode, 9, 1) << 3) |
21939 extract32(ctx->opcode, 5, 3);
21940 rs = (extract32(ctx->opcode, 4, 1) << 3) |
21941 extract32(ctx->opcode, 0, 3);
21942 offset = (extract32(ctx->opcode, 3, 1) << 3) |
21943 (extract32(ctx->opcode, 8, 1) << 2);
21944 rt = decode_gpr_gpr4(rt);
21945 rs = decode_gpr_gpr4(rs);
21946 gen_ld(ctx, OPC_LW, rt, rs, offset);
ea4ca3c2
YK
21947 break;
21948 case NM_SW4X4:
fb32f8c8 21949 check_nms(ctx);
8bdb7029
YK
21950 rt = (extract32(ctx->opcode, 9, 1) << 3) |
21951 extract32(ctx->opcode, 5, 3);
21952 rs = (extract32(ctx->opcode, 4, 1) << 3) |
21953 extract32(ctx->opcode, 0, 3);
21954 offset = (extract32(ctx->opcode, 3, 1) << 3) |
21955 (extract32(ctx->opcode, 8, 1) << 2);
21956 rt = decode_gpr_gpr4_zero(rt);
21957 rs = decode_gpr_gpr4(rs);
21958 gen_st(ctx, OPC_SW, rt, rs, offset);
ea4ca3c2
YK
21959 break;
21960 case NM_LWGP16:
8bdb7029
YK
21961 offset = extract32(ctx->opcode, 0, 7) << 2;
21962 gen_ld(ctx, OPC_LW, rt, 28, offset);
ea4ca3c2
YK
21963 break;
21964 case NM_SWSP16:
8bdb7029
YK
21965 rt = NANOMIPS_EXTRACT_RD5(ctx->opcode);
21966 offset = extract32(ctx->opcode, 0, 5) << 2;
21967 gen_st(ctx, OPC_SW, rt, 29, offset);
ea4ca3c2
YK
21968 break;
21969 case NM_SW16:
8bdb7029
YK
21970 rt = decode_gpr_gpr3_src_store(
21971 NANOMIPS_EXTRACT_RD(ctx->opcode));
21972 rs = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS(ctx->opcode));
21973 offset = extract32(ctx->opcode, 0, 4) << 2;
21974 gen_st(ctx, OPC_SW, rt, rs, offset);
ea4ca3c2
YK
21975 break;
21976 case NM_SWGP16:
8bdb7029
YK
21977 rt = decode_gpr_gpr3_src_store(
21978 NANOMIPS_EXTRACT_RD(ctx->opcode));
21979 offset = extract32(ctx->opcode, 0, 7) << 2;
21980 gen_st(ctx, OPC_SW, rt, 28, offset);
ea4ca3c2
YK
21981 break;
21982 case NM_BC16:
764371d2
SM
21983 gen_compute_branch_nm(ctx, OPC_BEQ, 2, 0, 0,
21984 (sextract32(ctx->opcode, 0, 1) << 10) |
21985 (extract32(ctx->opcode, 1, 9) << 1));
ea4ca3c2
YK
21986 break;
21987 case NM_BALC16:
764371d2
SM
21988 gen_compute_branch_nm(ctx, OPC_BGEZAL, 2, 0, 0,
21989 (sextract32(ctx->opcode, 0, 1) << 10) |
21990 (extract32(ctx->opcode, 1, 9) << 1));
ea4ca3c2
YK
21991 break;
21992 case NM_BEQZC16:
764371d2
SM
21993 gen_compute_branch_nm(ctx, OPC_BEQ, 2, rt, 0,
21994 (sextract32(ctx->opcode, 0, 1) << 7) |
21995 (extract32(ctx->opcode, 1, 6) << 1));
ea4ca3c2
YK
21996 break;
21997 case NM_BNEZC16:
764371d2
SM
21998 gen_compute_branch_nm(ctx, OPC_BNE, 2, rt, 0,
21999 (sextract32(ctx->opcode, 0, 1) << 7) |
22000 (extract32(ctx->opcode, 1, 6) << 1));
ea4ca3c2
YK
22001 break;
22002 case NM_P16_BR:
764371d2
SM
22003 switch (ctx->opcode & 0xf) {
22004 case 0:
22005 /* P16.JRC */
22006 switch (extract32(ctx->opcode, 4, 1)) {
22007 case NM_JRC:
22008 gen_compute_branch_nm(ctx, OPC_JR, 2,
22009 extract32(ctx->opcode, 5, 5), 0, 0);
22010 break;
22011 case NM_JALRC16:
22012 gen_compute_branch_nm(ctx, OPC_JALR, 2,
22013 extract32(ctx->opcode, 5, 5), 31, 0);
22014 break;
22015 }
22016 break;
22017 default:
22018 {
22019 /* P16.BRI */
22020 uint32_t opc = extract32(ctx->opcode, 4, 3) <
22021 extract32(ctx->opcode, 7, 3) ? OPC_BEQ : OPC_BNE;
22022 gen_compute_branch_nm(ctx, opc, 2, rs, rt,
22023 extract32(ctx->opcode, 0, 4) << 1);
22024 }
22025 break;
22026 }
ea4ca3c2
YK
22027 break;
22028 case NM_P16_SR:
bf0718c5
SM
22029 {
22030 int count = extract32(ctx->opcode, 0, 4);
22031 int u = extract32(ctx->opcode, 4, 4) << 4;
22032
22033 rt = 30 + extract32(ctx->opcode, 9, 1);
22034 switch (extract32(ctx->opcode, 8, 1)) {
22035 case NM_SAVE16:
22036 gen_save(ctx, rt, count, 0, u);
22037 break;
22038 case NM_RESTORE_JRC16:
22039 gen_restore(ctx, rt, count, 0, u);
22040 gen_compute_branch_nm(ctx, OPC_JR, 2, 31, 0, 0);
22041 break;
22042 }
22043 }
ea4ca3c2
YK
22044 break;
22045 case NM_MOVEP:
ea4ca3c2 22046 case NM_MOVEPREV:
fb32f8c8 22047 check_nms(ctx);
4d18232c
YK
22048 {
22049 static const int gpr2reg1[] = {4, 5, 6, 7};
22050 static const int gpr2reg2[] = {5, 6, 7, 8};
22051 int re;
22052 int rd2 = extract32(ctx->opcode, 3, 1) << 1 |
22053 extract32(ctx->opcode, 8, 1);
22054 int r1 = gpr2reg1[rd2];
22055 int r2 = gpr2reg2[rd2];
22056 int r3 = extract32(ctx->opcode, 4, 1) << 3 |
22057 extract32(ctx->opcode, 0, 3);
22058 int r4 = extract32(ctx->opcode, 9, 1) << 3 |
22059 extract32(ctx->opcode, 5, 3);
22060 TCGv t0 = tcg_temp_new();
22061 TCGv t1 = tcg_temp_new();
22062 if (op == NM_MOVEP) {
22063 rd = r1;
22064 re = r2;
22065 rs = decode_gpr_gpr4_zero(r3);
22066 rt = decode_gpr_gpr4_zero(r4);
22067 } else {
22068 rd = decode_gpr_gpr4(r3);
22069 re = decode_gpr_gpr4(r4);
22070 rs = r1;
22071 rt = r2;
22072 }
22073 gen_load_gpr(t0, rs);
22074 gen_load_gpr(t1, rt);
22075 tcg_gen_mov_tl(cpu_gpr[rd], t0);
22076 tcg_gen_mov_tl(cpu_gpr[re], t1);
22077 tcg_temp_free(t0);
22078 tcg_temp_free(t1);
22079 }
ea4ca3c2
YK
22080 break;
22081 default:
c0280983 22082 return decode_nanomips_32_48_opc(env, ctx);
ea4ca3c2
YK
22083 }
22084
c533c0f4
AM
22085 return 2;
22086}
22087
22088
3c824109
NF
22089/* SmartMIPS extension to MIPS32 */
22090
22091#if defined(TARGET_MIPS64)
22092
22093/* MDMX extension to MIPS64 */
22094
22095#endif
22096
9b1a1d68 22097/* MIPSDSP functions. */
d75c135e 22098static void gen_mipsdsp_ld(DisasContext *ctx, uint32_t opc,
9b1a1d68
JL
22099 int rd, int base, int offset)
22100{
9b1a1d68
JL
22101 TCGv t0;
22102
9b1a1d68
JL
22103 check_dsp(ctx);
22104 t0 = tcg_temp_new();
22105
22106 if (base == 0) {
22107 gen_load_gpr(t0, offset);
22108 } else if (offset == 0) {
22109 gen_load_gpr(t0, base);
22110 } else {
22111 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[offset]);
22112 }
22113
9b1a1d68
JL
22114 switch (opc) {
22115 case OPC_LBUX:
5f68f5ae 22116 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB);
9b1a1d68 22117 gen_store_gpr(t0, rd);
9b1a1d68
JL
22118 break;
22119 case OPC_LHX:
5f68f5ae 22120 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW);
9b1a1d68 22121 gen_store_gpr(t0, rd);
9b1a1d68
JL
22122 break;
22123 case OPC_LWX:
5f68f5ae 22124 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
9b1a1d68 22125 gen_store_gpr(t0, rd);
9b1a1d68
JL
22126 break;
22127#if defined(TARGET_MIPS64)
22128 case OPC_LDX:
5f68f5ae 22129 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
9b1a1d68 22130 gen_store_gpr(t0, rd);
9b1a1d68
JL
22131 break;
22132#endif
22133 }
9b1a1d68
JL
22134 tcg_temp_free(t0);
22135}
22136
461c08df
JL
22137static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
22138 int ret, int v1, int v2)
22139{
461c08df
JL
22140 TCGv v1_t;
22141 TCGv v2_t;
22142
22143 if (ret == 0) {
22144 /* Treat as NOP. */
461c08df
JL
22145 return;
22146 }
22147
22148 v1_t = tcg_temp_new();
22149 v2_t = tcg_temp_new();
22150
22151 gen_load_gpr(v1_t, v1);
22152 gen_load_gpr(v2_t, v2);
22153
22154 switch (op1) {
22155 /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
22156 case OPC_MULT_G_2E:
908f6be1 22157 check_dsp_r2(ctx);
461c08df
JL
22158 switch (op2) {
22159 case OPC_ADDUH_QB:
22160 gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t);
22161 break;
22162 case OPC_ADDUH_R_QB:
22163 gen_helper_adduh_r_qb(cpu_gpr[ret], v1_t, v2_t);
22164 break;
22165 case OPC_ADDQH_PH:
22166 gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t);
22167 break;
22168 case OPC_ADDQH_R_PH:
22169 gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
22170 break;
22171 case OPC_ADDQH_W:
22172 gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t);
22173 break;
22174 case OPC_ADDQH_R_W:
22175 gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t);
22176 break;
22177 case OPC_SUBUH_QB:
22178 gen_helper_subuh_qb(cpu_gpr[ret], v1_t, v2_t);
22179 break;
22180 case OPC_SUBUH_R_QB:
22181 gen_helper_subuh_r_qb(cpu_gpr[ret], v1_t, v2_t);
22182 break;
22183 case OPC_SUBQH_PH:
22184 gen_helper_subqh_ph(cpu_gpr[ret], v1_t, v2_t);
22185 break;
22186 case OPC_SUBQH_R_PH:
22187 gen_helper_subqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
22188 break;
22189 case OPC_SUBQH_W:
22190 gen_helper_subqh_w(cpu_gpr[ret], v1_t, v2_t);
22191 break;
22192 case OPC_SUBQH_R_W:
22193 gen_helper_subqh_r_w(cpu_gpr[ret], v1_t, v2_t);
22194 break;
22195 }
22196 break;
22197 case OPC_ABSQ_S_PH_DSP:
22198 switch (op2) {
22199 case OPC_ABSQ_S_QB:
908f6be1 22200 check_dsp_r2(ctx);
461c08df
JL
22201 gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, cpu_env);
22202 break;
22203 case OPC_ABSQ_S_PH:
22204 check_dsp(ctx);
22205 gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, cpu_env);
22206 break;
22207 case OPC_ABSQ_S_W:
22208 check_dsp(ctx);
22209 gen_helper_absq_s_w(cpu_gpr[ret], v2_t, cpu_env);
22210 break;
22211 case OPC_PRECEQ_W_PHL:
22212 check_dsp(ctx);
22213 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000);
22214 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
22215 break;
22216 case OPC_PRECEQ_W_PHR:
22217 check_dsp(ctx);
22218 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF);
22219 tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16);
22220 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
22221 break;
22222 case OPC_PRECEQU_PH_QBL:
22223 check_dsp(ctx);
22224 gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t);
22225 break;
22226 case OPC_PRECEQU_PH_QBR:
22227 check_dsp(ctx);
22228 gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t);
22229 break;
22230 case OPC_PRECEQU_PH_QBLA:
22231 check_dsp(ctx);
22232 gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t);
22233 break;
22234 case OPC_PRECEQU_PH_QBRA:
22235 check_dsp(ctx);
22236 gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t);
22237 break;
22238 case OPC_PRECEU_PH_QBL:
22239 check_dsp(ctx);
22240 gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t);
22241 break;
22242 case OPC_PRECEU_PH_QBR:
22243 check_dsp(ctx);
22244 gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t);
22245 break;
22246 case OPC_PRECEU_PH_QBLA:
22247 check_dsp(ctx);
22248 gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t);
22249 break;
22250 case OPC_PRECEU_PH_QBRA:
22251 check_dsp(ctx);
22252 gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t);
22253 break;
22254 }
22255 break;
22256 case OPC_ADDU_QB_DSP:
22257 switch (op2) {
22258 case OPC_ADDQ_PH:
22259 check_dsp(ctx);
22260 gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22261 break;
22262 case OPC_ADDQ_S_PH:
22263 check_dsp(ctx);
22264 gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22265 break;
22266 case OPC_ADDQ_S_W:
22267 check_dsp(ctx);
22268 gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22269 break;
22270 case OPC_ADDU_QB:
22271 check_dsp(ctx);
22272 gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22273 break;
22274 case OPC_ADDU_S_QB:
22275 check_dsp(ctx);
22276 gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22277 break;
22278 case OPC_ADDU_PH:
908f6be1 22279 check_dsp_r2(ctx);
461c08df
JL
22280 gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22281 break;
22282 case OPC_ADDU_S_PH:
908f6be1 22283 check_dsp_r2(ctx);
461c08df
JL
22284 gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22285 break;
22286 case OPC_SUBQ_PH:
22287 check_dsp(ctx);
22288 gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22289 break;
22290 case OPC_SUBQ_S_PH:
22291 check_dsp(ctx);
22292 gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22293 break;
22294 case OPC_SUBQ_S_W:
22295 check_dsp(ctx);
22296 gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22297 break;
22298 case OPC_SUBU_QB:
22299 check_dsp(ctx);
22300 gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22301 break;
22302 case OPC_SUBU_S_QB:
22303 check_dsp(ctx);
22304 gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22305 break;
22306 case OPC_SUBU_PH:
908f6be1 22307 check_dsp_r2(ctx);
461c08df
JL
22308 gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22309 break;
22310 case OPC_SUBU_S_PH:
908f6be1 22311 check_dsp_r2(ctx);
461c08df
JL
22312 gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22313 break;
22314 case OPC_ADDSC:
22315 check_dsp(ctx);
22316 gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22317 break;
22318 case OPC_ADDWC:
22319 check_dsp(ctx);
22320 gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22321 break;
22322 case OPC_MODSUB:
22323 check_dsp(ctx);
22324 gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t);
22325 break;
22326 case OPC_RADDU_W_QB:
22327 check_dsp(ctx);
22328 gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t);
22329 break;
22330 }
22331 break;
22332 case OPC_CMPU_EQ_QB_DSP:
22333 switch (op2) {
22334 case OPC_PRECR_QB_PH:
908f6be1 22335 check_dsp_r2(ctx);
461c08df
JL
22336 gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t);
22337 break;
22338 case OPC_PRECRQ_QB_PH:
22339 check_dsp(ctx);
22340 gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t);
22341 break;
22342 case OPC_PRECR_SRA_PH_W:
908f6be1 22343 check_dsp_r2(ctx);
461c08df
JL
22344 {
22345 TCGv_i32 sa_t = tcg_const_i32(v2);
22346 gen_helper_precr_sra_ph_w(cpu_gpr[ret], sa_t, v1_t,
22347 cpu_gpr[ret]);
22348 tcg_temp_free_i32(sa_t);
22349 break;
22350 }
22351 case OPC_PRECR_SRA_R_PH_W:
908f6be1 22352 check_dsp_r2(ctx);
461c08df
JL
22353 {
22354 TCGv_i32 sa_t = tcg_const_i32(v2);
22355 gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t,
22356 cpu_gpr[ret]);
22357 tcg_temp_free_i32(sa_t);
22358 break;
22359 }
22360 case OPC_PRECRQ_PH_W:
22361 check_dsp(ctx);
22362 gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t);
22363 break;
22364 case OPC_PRECRQ_RS_PH_W:
22365 check_dsp(ctx);
22366 gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22367 break;
22368 case OPC_PRECRQU_S_QB_PH:
22369 check_dsp(ctx);
22370 gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22371 break;
22372 }
22373 break;
22374#ifdef TARGET_MIPS64
22375 case OPC_ABSQ_S_QH_DSP:
22376 switch (op2) {
22377 case OPC_PRECEQ_L_PWL:
22378 check_dsp(ctx);
22379 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull);
22380 break;
22381 case OPC_PRECEQ_L_PWR:
22382 check_dsp(ctx);
22383 tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32);
22384 break;
22385 case OPC_PRECEQ_PW_QHL:
22386 check_dsp(ctx);
22387 gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t);
22388 break;
22389 case OPC_PRECEQ_PW_QHR:
22390 check_dsp(ctx);
22391 gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t);
22392 break;
22393 case OPC_PRECEQ_PW_QHLA:
22394 check_dsp(ctx);
22395 gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t);
22396 break;
22397 case OPC_PRECEQ_PW_QHRA:
22398 check_dsp(ctx);
22399 gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t);
22400 break;
22401 case OPC_PRECEQU_QH_OBL:
22402 check_dsp(ctx);
22403 gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t);
22404 break;
22405 case OPC_PRECEQU_QH_OBR:
22406 check_dsp(ctx);
22407 gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t);
22408 break;
22409 case OPC_PRECEQU_QH_OBLA:
22410 check_dsp(ctx);
22411 gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t);
22412 break;
22413 case OPC_PRECEQU_QH_OBRA:
22414 check_dsp(ctx);
22415 gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t);
22416 break;
22417 case OPC_PRECEU_QH_OBL:
22418 check_dsp(ctx);
22419 gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t);
22420 break;
22421 case OPC_PRECEU_QH_OBR:
22422 check_dsp(ctx);
22423 gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t);
22424 break;
22425 case OPC_PRECEU_QH_OBLA:
22426 check_dsp(ctx);
22427 gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t);
22428 break;
22429 case OPC_PRECEU_QH_OBRA:
22430 check_dsp(ctx);
22431 gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t);
22432 break;
22433 case OPC_ABSQ_S_OB:
908f6be1 22434 check_dsp_r2(ctx);
461c08df
JL
22435 gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, cpu_env);
22436 break;
22437 case OPC_ABSQ_S_PW:
22438 check_dsp(ctx);
22439 gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, cpu_env);
22440 break;
22441 case OPC_ABSQ_S_QH:
22442 check_dsp(ctx);
22443 gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, cpu_env);
22444 break;
22445 }
22446 break;
22447 case OPC_ADDU_OB_DSP:
22448 switch (op2) {
22449 case OPC_RADDU_L_OB:
22450 check_dsp(ctx);
22451 gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t);
22452 break;
22453 case OPC_SUBQ_PW:
22454 check_dsp(ctx);
22455 gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22456 break;
22457 case OPC_SUBQ_S_PW:
22458 check_dsp(ctx);
22459 gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22460 break;
22461 case OPC_SUBQ_QH:
22462 check_dsp(ctx);
22463 gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22464 break;
22465 case OPC_SUBQ_S_QH:
22466 check_dsp(ctx);
22467 gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22468 break;
22469 case OPC_SUBU_OB:
22470 check_dsp(ctx);
22471 gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22472 break;
22473 case OPC_SUBU_S_OB:
22474 check_dsp(ctx);
22475 gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22476 break;
22477 case OPC_SUBU_QH:
908f6be1 22478 check_dsp_r2(ctx);
461c08df
JL
22479 gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22480 break;
22481 case OPC_SUBU_S_QH:
908f6be1 22482 check_dsp_r2(ctx);
461c08df
JL
22483 gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22484 break;
22485 case OPC_SUBUH_OB:
908f6be1 22486 check_dsp_r2(ctx);
461c08df
JL
22487 gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t);
22488 break;
22489 case OPC_SUBUH_R_OB:
908f6be1 22490 check_dsp_r2(ctx);
461c08df
JL
22491 gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t);
22492 break;
22493 case OPC_ADDQ_PW:
22494 check_dsp(ctx);
22495 gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22496 break;
22497 case OPC_ADDQ_S_PW:
22498 check_dsp(ctx);
22499 gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22500 break;
22501 case OPC_ADDQ_QH:
22502 check_dsp(ctx);
22503 gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22504 break;
22505 case OPC_ADDQ_S_QH:
22506 check_dsp(ctx);
22507 gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22508 break;
22509 case OPC_ADDU_OB:
22510 check_dsp(ctx);
22511 gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22512 break;
22513 case OPC_ADDU_S_OB:
22514 check_dsp(ctx);
22515 gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22516 break;
22517 case OPC_ADDU_QH:
908f6be1 22518 check_dsp_r2(ctx);
461c08df
JL
22519 gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22520 break;
22521 case OPC_ADDU_S_QH:
908f6be1 22522 check_dsp_r2(ctx);
461c08df
JL
22523 gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22524 break;
22525 case OPC_ADDUH_OB:
908f6be1 22526 check_dsp_r2(ctx);
461c08df
JL
22527 gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t);
22528 break;
22529 case OPC_ADDUH_R_OB:
908f6be1 22530 check_dsp_r2(ctx);
461c08df
JL
22531 gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t);
22532 break;
22533 }
22534 break;
22535 case OPC_CMPU_EQ_OB_DSP:
22536 switch (op2) {
22537 case OPC_PRECR_OB_QH:
908f6be1 22538 check_dsp_r2(ctx);
461c08df
JL
22539 gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t);
22540 break;
22541 case OPC_PRECR_SRA_QH_PW:
908f6be1 22542 check_dsp_r2(ctx);
461c08df
JL
22543 {
22544 TCGv_i32 ret_t = tcg_const_i32(ret);
22545 gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t);
22546 tcg_temp_free_i32(ret_t);
22547 break;
22548 }
22549 case OPC_PRECR_SRA_R_QH_PW:
908f6be1 22550 check_dsp_r2(ctx);
461c08df
JL
22551 {
22552 TCGv_i32 sa_v = tcg_const_i32(ret);
22553 gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v);
22554 tcg_temp_free_i32(sa_v);
22555 break;
22556 }
22557 case OPC_PRECRQ_OB_QH:
22558 check_dsp(ctx);
22559 gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t);
22560 break;
22561 case OPC_PRECRQ_PW_L:
22562 check_dsp(ctx);
22563 gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t);
22564 break;
22565 case OPC_PRECRQ_QH_PW:
22566 check_dsp(ctx);
22567 gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t);
22568 break;
22569 case OPC_PRECRQ_RS_QH_PW:
22570 check_dsp(ctx);
22571 gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22572 break;
22573 case OPC_PRECRQU_S_OB_QH:
22574 check_dsp(ctx);
22575 gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22576 break;
22577 }
22578 break;
22579#endif
22580 }
22581
22582 tcg_temp_free(v1_t);
22583 tcg_temp_free(v2_t);
461c08df 22584}
9b1a1d68 22585
77c5fa8b
JL
22586static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc,
22587 int ret, int v1, int v2)
22588{
22589 uint32_t op2;
77c5fa8b
JL
22590 TCGv t0;
22591 TCGv v1_t;
22592 TCGv v2_t;
22593
22594 if (ret == 0) {
22595 /* Treat as NOP. */
77c5fa8b
JL
22596 return;
22597 }
22598
22599 t0 = tcg_temp_new();
22600 v1_t = tcg_temp_new();
22601 v2_t = tcg_temp_new();
22602
22603 tcg_gen_movi_tl(t0, v1);
22604 gen_load_gpr(v1_t, v1);
22605 gen_load_gpr(v2_t, v2);
22606
22607 switch (opc) {
22608 case OPC_SHLL_QB_DSP:
22609 {
22610 op2 = MASK_SHLL_QB(ctx->opcode);
22611 switch (op2) {
22612 case OPC_SHLL_QB:
22613 check_dsp(ctx);
22614 gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, cpu_env);
22615 break;
22616 case OPC_SHLLV_QB:
22617 check_dsp(ctx);
22618 gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22619 break;
22620 case OPC_SHLL_PH:
22621 check_dsp(ctx);
22622 gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
22623 break;
22624 case OPC_SHLLV_PH:
22625 check_dsp(ctx);
22626 gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22627 break;
22628 case OPC_SHLL_S_PH:
22629 check_dsp(ctx);
22630 gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
22631 break;
22632 case OPC_SHLLV_S_PH:
22633 check_dsp(ctx);
22634 gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22635 break;
22636 case OPC_SHLL_S_W:
22637 check_dsp(ctx);
22638 gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, cpu_env);
22639 break;
22640 case OPC_SHLLV_S_W:
22641 check_dsp(ctx);
22642 gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22643 break;
22644 case OPC_SHRL_QB:
22645 check_dsp(ctx);
22646 gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t);
22647 break;
22648 case OPC_SHRLV_QB:
22649 check_dsp(ctx);
22650 gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t);
22651 break;
22652 case OPC_SHRL_PH:
908f6be1 22653 check_dsp_r2(ctx);
77c5fa8b
JL
22654 gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t);
22655 break;
22656 case OPC_SHRLV_PH:
908f6be1 22657 check_dsp_r2(ctx);
77c5fa8b
JL
22658 gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t);
22659 break;
22660 case OPC_SHRA_QB:
908f6be1 22661 check_dsp_r2(ctx);
77c5fa8b
JL
22662 gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t);
22663 break;
22664 case OPC_SHRA_R_QB:
908f6be1 22665 check_dsp_r2(ctx);
77c5fa8b
JL
22666 gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t);
22667 break;
22668 case OPC_SHRAV_QB:
908f6be1 22669 check_dsp_r2(ctx);
77c5fa8b
JL
22670 gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t);
22671 break;
22672 case OPC_SHRAV_R_QB:
908f6be1 22673 check_dsp_r2(ctx);
77c5fa8b
JL
22674 gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t);
22675 break;
22676 case OPC_SHRA_PH:
22677 check_dsp(ctx);
22678 gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t);
22679 break;
22680 case OPC_SHRA_R_PH:
22681 check_dsp(ctx);
22682 gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t);
22683 break;
22684 case OPC_SHRAV_PH:
22685 check_dsp(ctx);
22686 gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t);
22687 break;
22688 case OPC_SHRAV_R_PH:
22689 check_dsp(ctx);
22690 gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t);
22691 break;
22692 case OPC_SHRA_R_W:
22693 check_dsp(ctx);
22694 gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t);
22695 break;
22696 case OPC_SHRAV_R_W:
22697 check_dsp(ctx);
22698 gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t);
22699 break;
22700 default: /* Invalid */
22701 MIPS_INVAL("MASK SHLL.QB");
9c708c7f 22702 generate_exception_end(ctx, EXCP_RI);
77c5fa8b
JL
22703 break;
22704 }
22705 break;
22706 }
22707#ifdef TARGET_MIPS64
22708 case OPC_SHLL_OB_DSP:
22709 op2 = MASK_SHLL_OB(ctx->opcode);
22710 switch (op2) {
22711 case OPC_SHLL_PW:
22712 check_dsp(ctx);
22713 gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
22714 break;
22715 case OPC_SHLLV_PW:
22716 check_dsp(ctx);
22717 gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
22718 break;
22719 case OPC_SHLL_S_PW:
22720 check_dsp(ctx);
22721 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
22722 break;
22723 case OPC_SHLLV_S_PW:
22724 check_dsp(ctx);
22725 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
22726 break;
22727 case OPC_SHLL_OB:
22728 check_dsp(ctx);
22729 gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, cpu_env);
22730 break;
22731 case OPC_SHLLV_OB:
22732 check_dsp(ctx);
22733 gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, cpu_env);
22734 break;
22735 case OPC_SHLL_QH:
22736 check_dsp(ctx);
22737 gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
22738 break;
22739 case OPC_SHLLV_QH:
22740 check_dsp(ctx);
22741 gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
22742 break;
22743 case OPC_SHLL_S_QH:
22744 check_dsp(ctx);
22745 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
22746 break;
22747 case OPC_SHLLV_S_QH:
22748 check_dsp(ctx);
22749 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
22750 break;
22751 case OPC_SHRA_OB:
908f6be1 22752 check_dsp_r2(ctx);
77c5fa8b
JL
22753 gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0);
22754 break;
22755 case OPC_SHRAV_OB:
908f6be1 22756 check_dsp_r2(ctx);
77c5fa8b
JL
22757 gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t);
22758 break;
22759 case OPC_SHRA_R_OB:
908f6be1 22760 check_dsp_r2(ctx);
77c5fa8b
JL
22761 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0);
22762 break;
22763 case OPC_SHRAV_R_OB:
908f6be1 22764 check_dsp_r2(ctx);
77c5fa8b
JL
22765 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t);
22766 break;
22767 case OPC_SHRA_PW:
22768 check_dsp(ctx);
22769 gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0);
22770 break;
22771 case OPC_SHRAV_PW:
22772 check_dsp(ctx);
22773 gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t);
22774 break;
22775 case OPC_SHRA_R_PW:
22776 check_dsp(ctx);
22777 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0);
22778 break;
22779 case OPC_SHRAV_R_PW:
22780 check_dsp(ctx);
22781 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t);
22782 break;
22783 case OPC_SHRA_QH:
22784 check_dsp(ctx);
22785 gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0);
22786 break;
22787 case OPC_SHRAV_QH:
22788 check_dsp(ctx);
22789 gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t);
22790 break;
22791 case OPC_SHRA_R_QH:
22792 check_dsp(ctx);
22793 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0);
22794 break;
22795 case OPC_SHRAV_R_QH:
22796 check_dsp(ctx);
22797 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t);
22798 break;
22799 case OPC_SHRL_OB:
22800 check_dsp(ctx);
22801 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0);
22802 break;
22803 case OPC_SHRLV_OB:
22804 check_dsp(ctx);
22805 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t);
22806 break;
22807 case OPC_SHRL_QH:
908f6be1 22808 check_dsp_r2(ctx);
77c5fa8b
JL
22809 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0);
22810 break;
22811 case OPC_SHRLV_QH:
908f6be1 22812 check_dsp_r2(ctx);
77c5fa8b
JL
22813 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t);
22814 break;
22815 default: /* Invalid */
22816 MIPS_INVAL("MASK SHLL.OB");
9c708c7f 22817 generate_exception_end(ctx, EXCP_RI);
77c5fa8b
JL
22818 break;
22819 }
22820 break;
22821#endif
22822 }
22823
22824 tcg_temp_free(t0);
22825 tcg_temp_free(v1_t);
22826 tcg_temp_free(v2_t);
77c5fa8b
JL
22827}
22828
a22260ae
JL
22829static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2,
22830 int ret, int v1, int v2, int check_ret)
22831{
a22260ae
JL
22832 TCGv_i32 t0;
22833 TCGv v1_t;
22834 TCGv v2_t;
22835
22836 if ((ret == 0) && (check_ret == 1)) {
22837 /* Treat as NOP. */
a22260ae
JL
22838 return;
22839 }
22840
22841 t0 = tcg_temp_new_i32();
22842 v1_t = tcg_temp_new();
22843 v2_t = tcg_temp_new();
22844
22845 tcg_gen_movi_i32(t0, ret);
22846 gen_load_gpr(v1_t, v1);
22847 gen_load_gpr(v2_t, v2);
22848
22849 switch (op1) {
22850 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
22851 * the same mask and op1. */
22852 case OPC_MULT_G_2E:
908f6be1 22853 check_dsp_r2(ctx);
a22260ae
JL
22854 switch (op2) {
22855 case OPC_MUL_PH:
22856 gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22857 break;
22858 case OPC_MUL_S_PH:
22859 gen_helper_mul_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22860 break;
22861 case OPC_MULQ_S_W:
22862 gen_helper_mulq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22863 break;
22864 case OPC_MULQ_RS_W:
22865 gen_helper_mulq_rs_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22866 break;
22867 }
22868 break;
22869 case OPC_DPA_W_PH_DSP:
22870 switch (op2) {
22871 case OPC_DPAU_H_QBL:
22872 check_dsp(ctx);
22873 gen_helper_dpau_h_qbl(t0, v1_t, v2_t, cpu_env);
22874 break;
22875 case OPC_DPAU_H_QBR:
22876 check_dsp(ctx);
22877 gen_helper_dpau_h_qbr(t0, v1_t, v2_t, cpu_env);
22878 break;
22879 case OPC_DPSU_H_QBL:
22880 check_dsp(ctx);
22881 gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, cpu_env);
22882 break;
22883 case OPC_DPSU_H_QBR:
22884 check_dsp(ctx);
22885 gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, cpu_env);
22886 break;
22887 case OPC_DPA_W_PH:
908f6be1 22888 check_dsp_r2(ctx);
a22260ae
JL
22889 gen_helper_dpa_w_ph(t0, v1_t, v2_t, cpu_env);
22890 break;
22891 case OPC_DPAX_W_PH:
908f6be1 22892 check_dsp_r2(ctx);
a22260ae
JL
22893 gen_helper_dpax_w_ph(t0, v1_t, v2_t, cpu_env);
22894 break;
22895 case OPC_DPAQ_S_W_PH:
22896 check_dsp(ctx);
22897 gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
22898 break;
22899 case OPC_DPAQX_S_W_PH:
908f6be1 22900 check_dsp_r2(ctx);
a22260ae
JL
22901 gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
22902 break;
22903 case OPC_DPAQX_SA_W_PH:
908f6be1 22904 check_dsp_r2(ctx);
a22260ae
JL
22905 gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
22906 break;
22907 case OPC_DPS_W_PH:
908f6be1 22908 check_dsp_r2(ctx);
a22260ae
JL
22909 gen_helper_dps_w_ph(t0, v1_t, v2_t, cpu_env);
22910 break;
22911 case OPC_DPSX_W_PH:
908f6be1 22912 check_dsp_r2(ctx);
a22260ae
JL
22913 gen_helper_dpsx_w_ph(t0, v1_t, v2_t, cpu_env);
22914 break;
22915 case OPC_DPSQ_S_W_PH:
22916 check_dsp(ctx);
22917 gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, cpu_env);
22918 break;
22919 case OPC_DPSQX_S_W_PH:
908f6be1 22920 check_dsp_r2(ctx);
a22260ae
JL
22921 gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
22922 break;
22923 case OPC_DPSQX_SA_W_PH:
908f6be1 22924 check_dsp_r2(ctx);
a22260ae
JL
22925 gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
22926 break;
22927 case OPC_MULSAQ_S_W_PH:
22928 check_dsp(ctx);
22929 gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
22930 break;
22931 case OPC_DPAQ_SA_L_W:
22932 check_dsp(ctx);
22933 gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, cpu_env);
22934 break;
22935 case OPC_DPSQ_SA_L_W:
22936 check_dsp(ctx);
22937 gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, cpu_env);
22938 break;
22939 case OPC_MAQ_S_W_PHL:
22940 check_dsp(ctx);
22941 gen_helper_maq_s_w_phl(t0, v1_t, v2_t, cpu_env);
22942 break;
22943 case OPC_MAQ_S_W_PHR:
22944 check_dsp(ctx);
22945 gen_helper_maq_s_w_phr(t0, v1_t, v2_t, cpu_env);
22946 break;
22947 case OPC_MAQ_SA_W_PHL:
22948 check_dsp(ctx);
22949 gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, cpu_env);
22950 break;
22951 case OPC_MAQ_SA_W_PHR:
22952 check_dsp(ctx);
22953 gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, cpu_env);
22954 break;
22955 case OPC_MULSA_W_PH:
908f6be1 22956 check_dsp_r2(ctx);
a22260ae
JL
22957 gen_helper_mulsa_w_ph(t0, v1_t, v2_t, cpu_env);
22958 break;
22959 }
22960 break;
22961#ifdef TARGET_MIPS64
22962 case OPC_DPAQ_W_QH_DSP:
22963 {
22964 int ac = ret & 0x03;
22965 tcg_gen_movi_i32(t0, ac);
22966
22967 switch (op2) {
22968 case OPC_DMADD:
22969 check_dsp(ctx);
22970 gen_helper_dmadd(v1_t, v2_t, t0, cpu_env);
22971 break;
22972 case OPC_DMADDU:
22973 check_dsp(ctx);
22974 gen_helper_dmaddu(v1_t, v2_t, t0, cpu_env);
22975 break;
22976 case OPC_DMSUB:
22977 check_dsp(ctx);
22978 gen_helper_dmsub(v1_t, v2_t, t0, cpu_env);
22979 break;
22980 case OPC_DMSUBU:
22981 check_dsp(ctx);
22982 gen_helper_dmsubu(v1_t, v2_t, t0, cpu_env);
22983 break;
22984 case OPC_DPA_W_QH:
908f6be1 22985 check_dsp_r2(ctx);
a22260ae
JL
22986 gen_helper_dpa_w_qh(v1_t, v2_t, t0, cpu_env);
22987 break;
22988 case OPC_DPAQ_S_W_QH:
22989 check_dsp(ctx);
22990 gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
22991 break;
22992 case OPC_DPAQ_SA_L_PW:
22993 check_dsp(ctx);
22994 gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
22995 break;
22996 case OPC_DPAU_H_OBL:
22997 check_dsp(ctx);
22998 gen_helper_dpau_h_obl(v1_t, v2_t, t0, cpu_env);
22999 break;
23000 case OPC_DPAU_H_OBR:
23001 check_dsp(ctx);
23002 gen_helper_dpau_h_obr(v1_t, v2_t, t0, cpu_env);
23003 break;
23004 case OPC_DPS_W_QH:
908f6be1 23005 check_dsp_r2(ctx);
a22260ae
JL
23006 gen_helper_dps_w_qh(v1_t, v2_t, t0, cpu_env);
23007 break;
23008 case OPC_DPSQ_S_W_QH:
23009 check_dsp(ctx);
23010 gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, cpu_env);
23011 break;
23012 case OPC_DPSQ_SA_L_PW:
23013 check_dsp(ctx);
23014 gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
23015 break;
23016 case OPC_DPSU_H_OBL:
23017 check_dsp(ctx);
23018 gen_helper_dpsu_h_obl(v1_t, v2_t, t0, cpu_env);
23019 break;
23020 case OPC_DPSU_H_OBR:
23021 check_dsp(ctx);
23022 gen_helper_dpsu_h_obr(v1_t, v2_t, t0, cpu_env);
23023 break;
23024 case OPC_MAQ_S_L_PWL:
23025 check_dsp(ctx);
23026 gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, cpu_env);
23027 break;
23028 case OPC_MAQ_S_L_PWR:
23029 check_dsp(ctx);
23030 gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, cpu_env);
23031 break;
23032 case OPC_MAQ_S_W_QHLL:
23033 check_dsp(ctx);
23034 gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, cpu_env);
23035 break;
23036 case OPC_MAQ_SA_W_QHLL:
23037 check_dsp(ctx);
23038 gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, cpu_env);
23039 break;
23040 case OPC_MAQ_S_W_QHLR:
23041 check_dsp(ctx);
23042 gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, cpu_env);
23043 break;
23044 case OPC_MAQ_SA_W_QHLR:
23045 check_dsp(ctx);
23046 gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, cpu_env);
23047 break;
23048 case OPC_MAQ_S_W_QHRL:
23049 check_dsp(ctx);
23050 gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, cpu_env);
23051 break;
23052 case OPC_MAQ_SA_W_QHRL:
23053 check_dsp(ctx);
23054 gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, cpu_env);
23055 break;
23056 case OPC_MAQ_S_W_QHRR:
23057 check_dsp(ctx);
23058 gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, cpu_env);
23059 break;
23060 case OPC_MAQ_SA_W_QHRR:
23061 check_dsp(ctx);
23062 gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, cpu_env);
23063 break;
23064 case OPC_MULSAQ_S_L_PW:
23065 check_dsp(ctx);
23066 gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, cpu_env);
23067 break;
23068 case OPC_MULSAQ_S_W_QH:
23069 check_dsp(ctx);
23070 gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
23071 break;
23072 }
23073 }
23074 break;
23075#endif
23076 case OPC_ADDU_QB_DSP:
23077 switch (op2) {
23078 case OPC_MULEU_S_PH_QBL:
23079 check_dsp(ctx);
23080 gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23081 break;
23082 case OPC_MULEU_S_PH_QBR:
23083 check_dsp(ctx);
23084 gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23085 break;
23086 case OPC_MULQ_RS_PH:
23087 check_dsp(ctx);
23088 gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23089 break;
23090 case OPC_MULEQ_S_W_PHL:
23091 check_dsp(ctx);
23092 gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23093 break;
23094 case OPC_MULEQ_S_W_PHR:
23095 check_dsp(ctx);
23096 gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23097 break;
23098 case OPC_MULQ_S_PH:
908f6be1 23099 check_dsp_r2(ctx);
a22260ae
JL
23100 gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23101 break;
23102 }
23103 break;
23104#ifdef TARGET_MIPS64
23105 case OPC_ADDU_OB_DSP:
23106 switch (op2) {
23107 case OPC_MULEQ_S_PW_QHL:
23108 check_dsp(ctx);
23109 gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23110 break;
23111 case OPC_MULEQ_S_PW_QHR:
23112 check_dsp(ctx);
23113 gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23114 break;
23115 case OPC_MULEU_S_QH_OBL:
23116 check_dsp(ctx);
23117 gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23118 break;
23119 case OPC_MULEU_S_QH_OBR:
23120 check_dsp(ctx);
23121 gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23122 break;
23123 case OPC_MULQ_RS_QH:
23124 check_dsp(ctx);
23125 gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23126 break;
23127 }
23128 break;
23129#endif
23130 }
23131
23132 tcg_temp_free_i32(t0);
23133 tcg_temp_free(v1_t);
23134 tcg_temp_free(v2_t);
a22260ae
JL
23135}
23136
d75c135e 23137static void gen_mipsdsp_bitinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
1cb6686c
JL
23138 int ret, int val)
23139{
1cb6686c
JL
23140 int16_t imm;
23141 TCGv t0;
23142 TCGv val_t;
23143
23144 if (ret == 0) {
23145 /* Treat as NOP. */
1cb6686c
JL
23146 return;
23147 }
23148
23149 t0 = tcg_temp_new();
23150 val_t = tcg_temp_new();
23151 gen_load_gpr(val_t, val);
23152
23153 switch (op1) {
23154 case OPC_ABSQ_S_PH_DSP:
23155 switch (op2) {
23156 case OPC_BITREV:
23157 check_dsp(ctx);
23158 gen_helper_bitrev(cpu_gpr[ret], val_t);
23159 break;
23160 case OPC_REPL_QB:
23161 check_dsp(ctx);
23162 {
23163 target_long result;
23164 imm = (ctx->opcode >> 16) & 0xFF;
23165 result = (uint32_t)imm << 24 |
23166 (uint32_t)imm << 16 |
23167 (uint32_t)imm << 8 |
23168 (uint32_t)imm;
23169 result = (int32_t)result;
23170 tcg_gen_movi_tl(cpu_gpr[ret], result);
23171 }
23172 break;
23173 case OPC_REPLV_QB:
23174 check_dsp(ctx);
23175 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
23176 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
23177 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23178 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
23179 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23180 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
23181 break;
23182 case OPC_REPL_PH:
23183 check_dsp(ctx);
23184 {
23185 imm = (ctx->opcode >> 16) & 0x03FF;
c4aaba92 23186 imm = (int16_t)(imm << 6) >> 6;
1cb6686c
JL
23187 tcg_gen_movi_tl(cpu_gpr[ret], \
23188 (target_long)((int32_t)imm << 16 | \
c4aaba92 23189 (uint16_t)imm));
1cb6686c
JL
23190 }
23191 break;
23192 case OPC_REPLV_PH:
23193 check_dsp(ctx);
23194 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
23195 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
23196 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23197 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
23198 break;
23199 }
23200 break;
23201#ifdef TARGET_MIPS64
23202 case OPC_ABSQ_S_QH_DSP:
23203 switch (op2) {
23204 case OPC_REPL_OB:
23205 check_dsp(ctx);
23206 {
23207 target_long temp;
23208
23209 imm = (ctx->opcode >> 16) & 0xFF;
23210 temp = ((uint64_t)imm << 8) | (uint64_t)imm;
23211 temp = (temp << 16) | temp;
23212 temp = (temp << 32) | temp;
23213 tcg_gen_movi_tl(cpu_gpr[ret], temp);
23214 break;
23215 }
23216 case OPC_REPL_PW:
23217 check_dsp(ctx);
23218 {
23219 target_long temp;
23220
23221 imm = (ctx->opcode >> 16) & 0x03FF;
23222 imm = (int16_t)(imm << 6) >> 6;
23223 temp = ((target_long)imm << 32) \
23224 | ((target_long)imm & 0xFFFFFFFF);
23225 tcg_gen_movi_tl(cpu_gpr[ret], temp);
23226 break;
23227 }
23228 case OPC_REPL_QH:
23229 check_dsp(ctx);
23230 {
23231 target_long temp;
23232
23233 imm = (ctx->opcode >> 16) & 0x03FF;
23234 imm = (int16_t)(imm << 6) >> 6;
23235
23236 temp = ((uint64_t)(uint16_t)imm << 48) |
23237 ((uint64_t)(uint16_t)imm << 32) |
23238 ((uint64_t)(uint16_t)imm << 16) |
23239 (uint64_t)(uint16_t)imm;
23240 tcg_gen_movi_tl(cpu_gpr[ret], temp);
23241 break;
23242 }
23243 case OPC_REPLV_OB:
23244 check_dsp(ctx);
23245 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
23246 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
23247 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23248 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
23249 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23250 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
23251 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23252 break;
23253 case OPC_REPLV_PW:
23254 check_dsp(ctx);
23255 tcg_gen_ext32u_i64(cpu_gpr[ret], val_t);
23256 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
23257 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23258 break;
23259 case OPC_REPLV_QH:
23260 check_dsp(ctx);
23261 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
23262 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
23263 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23264 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
23265 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23266 break;
23267 }
23268 break;
23269#endif
23270 }
23271 tcg_temp_free(t0);
23272 tcg_temp_free(val_t);
1cb6686c
JL
23273}
23274
26690560
JL
23275static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx,
23276 uint32_t op1, uint32_t op2,
23277 int ret, int v1, int v2, int check_ret)
23278{
26690560
JL
23279 TCGv t1;
23280 TCGv v1_t;
23281 TCGv v2_t;
23282
23283 if ((ret == 0) && (check_ret == 1)) {
23284 /* Treat as NOP. */
26690560
JL
23285 return;
23286 }
23287
26690560
JL
23288 t1 = tcg_temp_new();
23289 v1_t = tcg_temp_new();
23290 v2_t = tcg_temp_new();
23291
23292 gen_load_gpr(v1_t, v1);
23293 gen_load_gpr(v2_t, v2);
23294
23295 switch (op1) {
26690560
JL
23296 case OPC_CMPU_EQ_QB_DSP:
23297 switch (op2) {
23298 case OPC_CMPU_EQ_QB:
23299 check_dsp(ctx);
23300 gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
23301 break;
23302 case OPC_CMPU_LT_QB:
23303 check_dsp(ctx);
23304 gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
23305 break;
23306 case OPC_CMPU_LE_QB:
23307 check_dsp(ctx);
23308 gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
23309 break;
23310 case OPC_CMPGU_EQ_QB:
23311 check_dsp(ctx);
23312 gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t);
23313 break;
23314 case OPC_CMPGU_LT_QB:
23315 check_dsp(ctx);
23316 gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t);
23317 break;
23318 case OPC_CMPGU_LE_QB:
23319 check_dsp(ctx);
23320 gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t);
23321 break;
23322 case OPC_CMPGDU_EQ_QB:
908f6be1 23323 check_dsp_r2(ctx);
26690560
JL
23324 gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t);
23325 tcg_gen_mov_tl(cpu_gpr[ret], t1);
23326 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
23327 tcg_gen_shli_tl(t1, t1, 24);
23328 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
23329 break;
23330 case OPC_CMPGDU_LT_QB:
908f6be1 23331 check_dsp_r2(ctx);
26690560
JL
23332 gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t);
23333 tcg_gen_mov_tl(cpu_gpr[ret], t1);
23334 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
23335 tcg_gen_shli_tl(t1, t1, 24);
23336 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
23337 break;
23338 case OPC_CMPGDU_LE_QB:
908f6be1 23339 check_dsp_r2(ctx);
26690560
JL
23340 gen_helper_cmpgu_le_qb(t1, v1_t, v2_t);
23341 tcg_gen_mov_tl(cpu_gpr[ret], t1);
23342 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
23343 tcg_gen_shli_tl(t1, t1, 24);
23344 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
23345 break;
23346 case OPC_CMP_EQ_PH:
23347 check_dsp(ctx);
23348 gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
23349 break;
23350 case OPC_CMP_LT_PH:
23351 check_dsp(ctx);
23352 gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
23353 break;
23354 case OPC_CMP_LE_PH:
23355 check_dsp(ctx);
23356 gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
23357 break;
23358 case OPC_PICK_QB:
23359 check_dsp(ctx);
23360 gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23361 break;
23362 case OPC_PICK_PH:
23363 check_dsp(ctx);
23364 gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23365 break;
23366 case OPC_PACKRL_PH:
23367 check_dsp(ctx);
23368 gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t);
23369 break;
23370 }
23371 break;
23372#ifdef TARGET_MIPS64
23373 case OPC_CMPU_EQ_OB_DSP:
23374 switch (op2) {
23375 case OPC_CMP_EQ_PW:
23376 check_dsp(ctx);
23377 gen_helper_cmp_eq_pw(v1_t, v2_t, cpu_env);
23378 break;
23379 case OPC_CMP_LT_PW:
23380 check_dsp(ctx);
23381 gen_helper_cmp_lt_pw(v1_t, v2_t, cpu_env);
23382 break;
23383 case OPC_CMP_LE_PW:
23384 check_dsp(ctx);
23385 gen_helper_cmp_le_pw(v1_t, v2_t, cpu_env);
23386 break;
23387 case OPC_CMP_EQ_QH:
23388 check_dsp(ctx);
23389 gen_helper_cmp_eq_qh(v1_t, v2_t, cpu_env);
23390 break;
23391 case OPC_CMP_LT_QH:
23392 check_dsp(ctx);
23393 gen_helper_cmp_lt_qh(v1_t, v2_t, cpu_env);
23394 break;
23395 case OPC_CMP_LE_QH:
23396 check_dsp(ctx);
23397 gen_helper_cmp_le_qh(v1_t, v2_t, cpu_env);
23398 break;
23399 case OPC_CMPGDU_EQ_OB:
908f6be1 23400 check_dsp_r2(ctx);
26690560
JL
23401 gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23402 break;
23403 case OPC_CMPGDU_LT_OB:
908f6be1 23404 check_dsp_r2(ctx);
26690560
JL
23405 gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23406 break;
23407 case OPC_CMPGDU_LE_OB:
908f6be1 23408 check_dsp_r2(ctx);
26690560
JL
23409 gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23410 break;
23411 case OPC_CMPGU_EQ_OB:
23412 check_dsp(ctx);
23413 gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t);
23414 break;
23415 case OPC_CMPGU_LT_OB:
23416 check_dsp(ctx);
23417 gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t);
23418 break;
23419 case OPC_CMPGU_LE_OB:
23420 check_dsp(ctx);
23421 gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t);
23422 break;
23423 case OPC_CMPU_EQ_OB:
23424 check_dsp(ctx);
23425 gen_helper_cmpu_eq_ob(v1_t, v2_t, cpu_env);
23426 break;
23427 case OPC_CMPU_LT_OB:
23428 check_dsp(ctx);
23429 gen_helper_cmpu_lt_ob(v1_t, v2_t, cpu_env);
23430 break;
23431 case OPC_CMPU_LE_OB:
23432 check_dsp(ctx);
23433 gen_helper_cmpu_le_ob(v1_t, v2_t, cpu_env);
23434 break;
23435 case OPC_PACKRL_PW:
23436 check_dsp(ctx);
23437 gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t);
23438 break;
23439 case OPC_PICK_OB:
23440 check_dsp(ctx);
23441 gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23442 break;
23443 case OPC_PICK_PW:
23444 check_dsp(ctx);
23445 gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23446 break;
23447 case OPC_PICK_QH:
23448 check_dsp(ctx);
23449 gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23450 break;
23451 }
23452 break;
df6126a7
AJ
23453#endif
23454 }
23455
23456 tcg_temp_free(t1);
23457 tcg_temp_free(v1_t);
23458 tcg_temp_free(v2_t);
df6126a7
AJ
23459}
23460
23461static void gen_mipsdsp_append(CPUMIPSState *env, DisasContext *ctx,
23462 uint32_t op1, int rt, int rs, int sa)
23463{
df6126a7
AJ
23464 TCGv t0;
23465
908f6be1 23466 check_dsp_r2(ctx);
df6126a7
AJ
23467
23468 if (rt == 0) {
23469 /* Treat as NOP. */
df6126a7
AJ
23470 return;
23471 }
23472
23473 t0 = tcg_temp_new();
23474 gen_load_gpr(t0, rs);
23475
23476 switch (op1) {
23477 case OPC_APPEND_DSP:
23478 switch (MASK_APPEND(ctx->opcode)) {
23479 case OPC_APPEND:
23480 if (sa != 0) {
23481 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 32 - sa);
23482 }
23483 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
23484 break;
23485 case OPC_PREPEND:
23486 if (sa != 0) {
23487 tcg_gen_ext32u_tl(cpu_gpr[rt], cpu_gpr[rt]);
23488 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
23489 tcg_gen_shli_tl(t0, t0, 32 - sa);
23490 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
23491 }
23492 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
23493 break;
23494 case OPC_BALIGN:
23495 sa &= 3;
23496 if (sa != 0 && sa != 2) {
23497 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
23498 tcg_gen_ext32u_tl(t0, t0);
23499 tcg_gen_shri_tl(t0, t0, 8 * (4 - sa));
23500 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
23501 }
23502 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
23503 break;
23504 default: /* Invalid */
23505 MIPS_INVAL("MASK APPEND");
9c708c7f 23506 generate_exception_end(ctx, EXCP_RI);
df6126a7
AJ
23507 break;
23508 }
23509 break;
23510#ifdef TARGET_MIPS64
26690560 23511 case OPC_DAPPEND_DSP:
df6126a7 23512 switch (MASK_DAPPEND(ctx->opcode)) {
26690560 23513 case OPC_DAPPEND:
df6126a7
AJ
23514 if (sa != 0) {
23515 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 64 - sa);
23516 }
26690560
JL
23517 break;
23518 case OPC_PREPENDD:
df6126a7
AJ
23519 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], 0x20 | sa);
23520 tcg_gen_shli_tl(t0, t0, 64 - (0x20 | sa));
23521 tcg_gen_or_tl(cpu_gpr[rt], t0, t0);
26690560
JL
23522 break;
23523 case OPC_PREPENDW:
df6126a7
AJ
23524 if (sa != 0) {
23525 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
23526 tcg_gen_shli_tl(t0, t0, 64 - sa);
23527 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
23528 }
26690560
JL
23529 break;
23530 case OPC_DBALIGN:
df6126a7
AJ
23531 sa &= 7;
23532 if (sa != 0 && sa != 2 && sa != 4) {
23533 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
23534 tcg_gen_shri_tl(t0, t0, 8 * (8 - sa));
23535 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
23536 }
26690560
JL
23537 break;
23538 default: /* Invalid */
23539 MIPS_INVAL("MASK DAPPEND");
9c708c7f 23540 generate_exception_end(ctx, EXCP_RI);
26690560
JL
23541 break;
23542 }
23543 break;
23544#endif
23545 }
df6126a7 23546 tcg_temp_free(t0);
26690560
JL
23547}
23548
b53371ed
JL
23549static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
23550 int ret, int v1, int v2, int check_ret)
23551
23552{
b53371ed
JL
23553 TCGv t0;
23554 TCGv t1;
23555 TCGv v1_t;
23556 TCGv v2_t;
23557 int16_t imm;
23558
23559 if ((ret == 0) && (check_ret == 1)) {
23560 /* Treat as NOP. */
b53371ed
JL
23561 return;
23562 }
23563
23564 t0 = tcg_temp_new();
23565 t1 = tcg_temp_new();
23566 v1_t = tcg_temp_new();
23567 v2_t = tcg_temp_new();
23568
23569 gen_load_gpr(v1_t, v1);
23570 gen_load_gpr(v2_t, v2);
23571
23572 switch (op1) {
23573 case OPC_EXTR_W_DSP:
23574 check_dsp(ctx);
23575 switch (op2) {
23576 case OPC_EXTR_W:
23577 tcg_gen_movi_tl(t0, v2);
23578 tcg_gen_movi_tl(t1, v1);
23579 gen_helper_extr_w(cpu_gpr[ret], t0, t1, cpu_env);
23580 break;
23581 case OPC_EXTR_R_W:
23582 tcg_gen_movi_tl(t0, v2);
23583 tcg_gen_movi_tl(t1, v1);
23584 gen_helper_extr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
23585 break;
23586 case OPC_EXTR_RS_W:
23587 tcg_gen_movi_tl(t0, v2);
23588 tcg_gen_movi_tl(t1, v1);
23589 gen_helper_extr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
23590 break;
23591 case OPC_EXTR_S_H:
23592 tcg_gen_movi_tl(t0, v2);
23593 tcg_gen_movi_tl(t1, v1);
23594 gen_helper_extr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
23595 break;
23596 case OPC_EXTRV_S_H:
23597 tcg_gen_movi_tl(t0, v2);
23598 gen_helper_extr_s_h(cpu_gpr[ret], t0, v1_t, cpu_env);
23599 break;
23600 case OPC_EXTRV_W:
23601 tcg_gen_movi_tl(t0, v2);
23602 gen_helper_extr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
23603 break;
23604 case OPC_EXTRV_R_W:
23605 tcg_gen_movi_tl(t0, v2);
23606 gen_helper_extr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
23607 break;
23608 case OPC_EXTRV_RS_W:
23609 tcg_gen_movi_tl(t0, v2);
23610 gen_helper_extr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
23611 break;
23612 case OPC_EXTP:
23613 tcg_gen_movi_tl(t0, v2);
23614 tcg_gen_movi_tl(t1, v1);
23615 gen_helper_extp(cpu_gpr[ret], t0, t1, cpu_env);
23616 break;
23617 case OPC_EXTPV:
23618 tcg_gen_movi_tl(t0, v2);
23619 gen_helper_extp(cpu_gpr[ret], t0, v1_t, cpu_env);
23620 break;
23621 case OPC_EXTPDP:
23622 tcg_gen_movi_tl(t0, v2);
23623 tcg_gen_movi_tl(t1, v1);
23624 gen_helper_extpdp(cpu_gpr[ret], t0, t1, cpu_env);
23625 break;
23626 case OPC_EXTPDPV:
23627 tcg_gen_movi_tl(t0, v2);
23628 gen_helper_extpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
23629 break;
23630 case OPC_SHILO:
23631 imm = (ctx->opcode >> 20) & 0x3F;
23632 tcg_gen_movi_tl(t0, ret);
23633 tcg_gen_movi_tl(t1, imm);
23634 gen_helper_shilo(t0, t1, cpu_env);
23635 break;
23636 case OPC_SHILOV:
23637 tcg_gen_movi_tl(t0, ret);
23638 gen_helper_shilo(t0, v1_t, cpu_env);
23639 break;
23640 case OPC_MTHLIP:
23641 tcg_gen_movi_tl(t0, ret);
23642 gen_helper_mthlip(t0, v1_t, cpu_env);
23643 break;
23644 case OPC_WRDSP:
23645 imm = (ctx->opcode >> 11) & 0x3FF;
23646 tcg_gen_movi_tl(t0, imm);
23647 gen_helper_wrdsp(v1_t, t0, cpu_env);
23648 break;
23649 case OPC_RDDSP:
23650 imm = (ctx->opcode >> 16) & 0x03FF;
23651 tcg_gen_movi_tl(t0, imm);
23652 gen_helper_rddsp(cpu_gpr[ret], t0, cpu_env);
23653 break;
23654 }
23655 break;
23656#ifdef TARGET_MIPS64
23657 case OPC_DEXTR_W_DSP:
23658 check_dsp(ctx);
23659 switch (op2) {
23660 case OPC_DMTHLIP:
23661 tcg_gen_movi_tl(t0, ret);
23662 gen_helper_dmthlip(v1_t, t0, cpu_env);
23663 break;
23664 case OPC_DSHILO:
23665 {
23666 int shift = (ctx->opcode >> 19) & 0x7F;
23667 int ac = (ctx->opcode >> 11) & 0x03;
23668 tcg_gen_movi_tl(t0, shift);
23669 tcg_gen_movi_tl(t1, ac);
23670 gen_helper_dshilo(t0, t1, cpu_env);
23671 break;
23672 }
23673 case OPC_DSHILOV:
23674 {
23675 int ac = (ctx->opcode >> 11) & 0x03;
23676 tcg_gen_movi_tl(t0, ac);
23677 gen_helper_dshilo(v1_t, t0, cpu_env);
23678 break;
23679 }
23680 case OPC_DEXTP:
23681 tcg_gen_movi_tl(t0, v2);
23682 tcg_gen_movi_tl(t1, v1);
23683
23684 gen_helper_dextp(cpu_gpr[ret], t0, t1, cpu_env);
23685 break;
23686 case OPC_DEXTPV:
23687 tcg_gen_movi_tl(t0, v2);
23688 gen_helper_dextp(cpu_gpr[ret], t0, v1_t, cpu_env);
23689 break;
23690 case OPC_DEXTPDP:
23691 tcg_gen_movi_tl(t0, v2);
23692 tcg_gen_movi_tl(t1, v1);
23693 gen_helper_dextpdp(cpu_gpr[ret], t0, t1, cpu_env);
23694 break;
23695 case OPC_DEXTPDPV:
23696 tcg_gen_movi_tl(t0, v2);
23697 gen_helper_dextpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
23698 break;
23699 case OPC_DEXTR_L:
23700 tcg_gen_movi_tl(t0, v2);
23701 tcg_gen_movi_tl(t1, v1);
23702 gen_helper_dextr_l(cpu_gpr[ret], t0, t1, cpu_env);
23703 break;
23704 case OPC_DEXTR_R_L:
23705 tcg_gen_movi_tl(t0, v2);
23706 tcg_gen_movi_tl(t1, v1);
23707 gen_helper_dextr_r_l(cpu_gpr[ret], t0, t1, cpu_env);
23708 break;
23709 case OPC_DEXTR_RS_L:
23710 tcg_gen_movi_tl(t0, v2);
23711 tcg_gen_movi_tl(t1, v1);
23712 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, t1, cpu_env);
23713 break;
23714 case OPC_DEXTR_W:
23715 tcg_gen_movi_tl(t0, v2);
23716 tcg_gen_movi_tl(t1, v1);
23717 gen_helper_dextr_w(cpu_gpr[ret], t0, t1, cpu_env);
23718 break;
23719 case OPC_DEXTR_R_W:
23720 tcg_gen_movi_tl(t0, v2);
23721 tcg_gen_movi_tl(t1, v1);
23722 gen_helper_dextr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
23723 break;
23724 case OPC_DEXTR_RS_W:
23725 tcg_gen_movi_tl(t0, v2);
23726 tcg_gen_movi_tl(t1, v1);
23727 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
23728 break;
23729 case OPC_DEXTR_S_H:
23730 tcg_gen_movi_tl(t0, v2);
23731 tcg_gen_movi_tl(t1, v1);
23732 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
23733 break;
23734 case OPC_DEXTRV_S_H:
23735 tcg_gen_movi_tl(t0, v2);
23736 tcg_gen_movi_tl(t1, v1);
23737 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
23738 break;
23739 case OPC_DEXTRV_L:
23740 tcg_gen_movi_tl(t0, v2);
23741 gen_helper_dextr_l(cpu_gpr[ret], t0, v1_t, cpu_env);
23742 break;
23743 case OPC_DEXTRV_R_L:
23744 tcg_gen_movi_tl(t0, v2);
23745 gen_helper_dextr_r_l(cpu_gpr[ret], t0, v1_t, cpu_env);
23746 break;
23747 case OPC_DEXTRV_RS_L:
23748 tcg_gen_movi_tl(t0, v2);
23749 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, v1_t, cpu_env);
23750 break;
23751 case OPC_DEXTRV_W:
23752 tcg_gen_movi_tl(t0, v2);
23753 gen_helper_dextr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
23754 break;
23755 case OPC_DEXTRV_R_W:
23756 tcg_gen_movi_tl(t0, v2);
23757 gen_helper_dextr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
23758 break;
23759 case OPC_DEXTRV_RS_W:
23760 tcg_gen_movi_tl(t0, v2);
23761 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
23762 break;
23763 }
23764 break;
23765#endif
23766 }
23767
23768 tcg_temp_free(t0);
23769 tcg_temp_free(t1);
23770 tcg_temp_free(v1_t);
23771 tcg_temp_free(v2_t);
b53371ed
JL
23772}
23773
9b1a1d68
JL
23774/* End MIPSDSP functions. */
23775
10dc65db
LA
23776static void decode_opc_special_r6(CPUMIPSState *env, DisasContext *ctx)
23777{
4267d3e6 23778 int rs, rt, rd, sa;
b42ee5e1 23779 uint32_t op1, op2;
10dc65db
LA
23780
23781 rs = (ctx->opcode >> 21) & 0x1f;
23782 rt = (ctx->opcode >> 16) & 0x1f;
23783 rd = (ctx->opcode >> 11) & 0x1f;
4267d3e6 23784 sa = (ctx->opcode >> 6) & 0x1f;
10dc65db
LA
23785
23786 op1 = MASK_SPECIAL(ctx->opcode);
23787 switch (op1) {
d4ea6acd 23788 case OPC_LSA:
1f1b4c00 23789 gen_lsa(ctx, op1, rd, rs, rt, extract32(ctx->opcode, 6, 2));
d4ea6acd 23790 break;
c2e19f3c
AM
23791 case OPC_MULT:
23792 case OPC_MULTU:
23793 case OPC_DIV:
23794 case OPC_DIVU:
b42ee5e1
LA
23795 op2 = MASK_R6_MULDIV(ctx->opcode);
23796 switch (op2) {
23797 case R6_OPC_MUL:
23798 case R6_OPC_MUH:
23799 case R6_OPC_MULU:
23800 case R6_OPC_MUHU:
23801 case R6_OPC_DIV:
23802 case R6_OPC_MOD:
23803 case R6_OPC_DIVU:
23804 case R6_OPC_MODU:
23805 gen_r6_muldiv(ctx, op2, rd, rs, rt);
23806 break;
23807 default:
23808 MIPS_INVAL("special_r6 muldiv");
9c708c7f 23809 generate_exception_end(ctx, EXCP_RI);
b42ee5e1
LA
23810 break;
23811 }
23812 break;
10dc65db
LA
23813 case OPC_SELEQZ:
23814 case OPC_SELNEZ:
23815 gen_cond_move(ctx, op1, rd, rs, rt);
23816 break;
4267d3e6
LA
23817 case R6_OPC_CLO:
23818 case R6_OPC_CLZ:
23819 if (rt == 0 && sa == 1) {
23820 /* Major opcode and function field is shared with preR6 MFHI/MTHI.
23821 We need additionally to check other fields */
23822 gen_cl(ctx, op1, rd, rs);
23823 } else {
9c708c7f 23824 generate_exception_end(ctx, EXCP_RI);
4267d3e6
LA
23825 }
23826 break;
23827 case R6_OPC_SDBBP:
3b3c1694
LA
23828 if (is_uhi(extract32(ctx->opcode, 6, 20))) {
23829 gen_helper_do_semihosting(cpu_env);
faf1f68b 23830 } else {
3b3c1694 23831 if (ctx->hflags & MIPS_HFLAG_SBRI) {
9c708c7f 23832 generate_exception_end(ctx, EXCP_RI);
3b3c1694 23833 } else {
9c708c7f 23834 generate_exception_end(ctx, EXCP_DBp);
3b3c1694 23835 }
faf1f68b 23836 }
4267d3e6 23837 break;
b42ee5e1 23838#if defined(TARGET_MIPS64)
d4ea6acd
LA
23839 case OPC_DLSA:
23840 check_mips_64(ctx);
1f1b4c00 23841 gen_lsa(ctx, op1, rd, rs, rt, extract32(ctx->opcode, 6, 2));
d4ea6acd 23842 break;
4267d3e6
LA
23843 case R6_OPC_DCLO:
23844 case R6_OPC_DCLZ:
23845 if (rt == 0 && sa == 1) {
23846 /* Major opcode and function field is shared with preR6 MFHI/MTHI.
23847 We need additionally to check other fields */
23848 check_mips_64(ctx);
23849 gen_cl(ctx, op1, rd, rs);
23850 } else {
9c708c7f 23851 generate_exception_end(ctx, EXCP_RI);
4267d3e6
LA
23852 }
23853 break;
c2e19f3c
AM
23854 case OPC_DMULT:
23855 case OPC_DMULTU:
23856 case OPC_DDIV:
23857 case OPC_DDIVU:
23858
b42ee5e1
LA
23859 op2 = MASK_R6_MULDIV(ctx->opcode);
23860 switch (op2) {
23861 case R6_OPC_DMUL:
23862 case R6_OPC_DMUH:
23863 case R6_OPC_DMULU:
23864 case R6_OPC_DMUHU:
23865 case R6_OPC_DDIV:
23866 case R6_OPC_DMOD:
23867 case R6_OPC_DDIVU:
23868 case R6_OPC_DMODU:
23869 check_mips_64(ctx);
23870 gen_r6_muldiv(ctx, op2, rd, rs, rt);
23871 break;
23872 default:
23873 MIPS_INVAL("special_r6 muldiv");
9c708c7f 23874 generate_exception_end(ctx, EXCP_RI);
b42ee5e1
LA
23875 break;
23876 }
23877 break;
23878#endif
10dc65db
LA
23879 default: /* Invalid */
23880 MIPS_INVAL("special_r6");
9c708c7f 23881 generate_exception_end(ctx, EXCP_RI);
10dc65db
LA
23882 break;
23883 }
23884}
23885
9dc324ce
FN
23886static void decode_opc_special_tx79(CPUMIPSState *env, DisasContext *ctx)
23887{
23888 int rs = extract32(ctx->opcode, 21, 5);
23889 int rt = extract32(ctx->opcode, 16, 5);
23890 int rd = extract32(ctx->opcode, 11, 5);
23891 uint32_t op1 = MASK_SPECIAL(ctx->opcode);
23892
23893 switch (op1) {
23894 case OPC_MOVN: /* Conditional move */
23895 case OPC_MOVZ:
23896 gen_cond_move(ctx, op1, rd, rs, rt);
23897 break;
23898 case OPC_MFHI: /* Move from HI/LO */
23899 case OPC_MFLO:
23900 gen_HILO(ctx, op1, 0, rd);
23901 break;
23902 case OPC_MTHI:
23903 case OPC_MTLO: /* Move to HI/LO */
23904 gen_HILO(ctx, op1, 0, rs);
23905 break;
23906 case OPC_MULT:
23907 case OPC_MULTU:
23908 gen_mul_txx9(ctx, op1, rd, rs, rt);
23909 break;
23910 case OPC_DIV:
23911 case OPC_DIVU:
23912 gen_muldiv(ctx, op1, 0, rs, rt);
23913 break;
23914#if defined(TARGET_MIPS64)
23915 case OPC_DMULT:
23916 case OPC_DMULTU:
23917 case OPC_DDIV:
23918 case OPC_DDIVU:
23919 check_insn_opc_user_only(ctx, INSN_R5900);
23920 gen_muldiv(ctx, op1, 0, rs, rt);
23921 break;
23922#endif
23923 case OPC_JR:
23924 gen_compute_branch(ctx, op1, 4, rs, 0, 0, 4);
23925 break;
23926 default: /* Invalid */
23927 MIPS_INVAL("special_tx79");
23928 generate_exception_end(ctx, EXCP_RI);
23929 break;
23930 }
23931}
23932
10dc65db
LA
23933static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx)
23934{
b42ee5e1 23935 int rs, rt, rd, sa;
10dc65db
LA
23936 uint32_t op1;
23937
23938 rs = (ctx->opcode >> 21) & 0x1f;
23939 rt = (ctx->opcode >> 16) & 0x1f;
23940 rd = (ctx->opcode >> 11) & 0x1f;
b42ee5e1 23941 sa = (ctx->opcode >> 6) & 0x1f;
10dc65db
LA
23942
23943 op1 = MASK_SPECIAL(ctx->opcode);
23944 switch (op1) {
23945 case OPC_MOVN: /* Conditional move */
23946 case OPC_MOVZ:
23947 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32 |
9dc324ce 23948 INSN_LOONGSON2E | INSN_LOONGSON2F);
10dc65db
LA
23949 gen_cond_move(ctx, op1, rd, rs, rt);
23950 break;
23951 case OPC_MFHI: /* Move from HI/LO */
23952 case OPC_MFLO:
23953 gen_HILO(ctx, op1, rs & 3, rd);
23954 break;
23955 case OPC_MTHI:
23956 case OPC_MTLO: /* Move to HI/LO */
23957 gen_HILO(ctx, op1, rd & 3, rs);
23958 break;
23959 case OPC_MOVCI:
23960 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
23961 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
23962 check_cp1_enabled(ctx);
23963 gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
23964 (ctx->opcode >> 16) & 1);
23965 } else {
23966 generate_exception_err(ctx, EXCP_CpU, 1);
23967 }
23968 break;
b42ee5e1
LA
23969 case OPC_MULT:
23970 case OPC_MULTU:
23971 if (sa) {
23972 check_insn(ctx, INSN_VR54XX);
23973 op1 = MASK_MUL_VR54XX(ctx->opcode);
23974 gen_mul_vr54xx(ctx, op1, rd, rs, rt);
23975 } else {
23976 gen_muldiv(ctx, op1, rd & 3, rs, rt);
23977 }
23978 break;
23979 case OPC_DIV:
23980 case OPC_DIVU:
23981 gen_muldiv(ctx, op1, 0, rs, rt);
23982 break;
23983#if defined(TARGET_MIPS64)
c2e19f3c
AM
23984 case OPC_DMULT:
23985 case OPC_DMULTU:
23986 case OPC_DDIV:
23987 case OPC_DDIVU:
b42ee5e1
LA
23988 check_insn(ctx, ISA_MIPS3);
23989 check_mips_64(ctx);
23990 gen_muldiv(ctx, op1, 0, rs, rt);
23991 break;
23992#endif
0aefa333 23993 case OPC_JR:
b231c103 23994 gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
0aefa333 23995 break;
4267d3e6
LA
23996 case OPC_SPIM:
23997#ifdef MIPS_STRICT_STANDARD
23998 MIPS_INVAL("SPIM");
9c708c7f 23999 generate_exception_end(ctx, EXCP_RI);
4267d3e6
LA
24000#else
24001 /* Implemented as RI exception for now. */
24002 MIPS_INVAL("spim (unofficial)");
9c708c7f 24003 generate_exception_end(ctx, EXCP_RI);
4267d3e6
LA
24004#endif
24005 break;
10dc65db
LA
24006 default: /* Invalid */
24007 MIPS_INVAL("special_legacy");
9c708c7f 24008 generate_exception_end(ctx, EXCP_RI);
10dc65db
LA
24009 break;
24010 }
24011}
24012
099e5b4d 24013static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx)
3c824109 24014{
3c824109 24015 int rs, rt, rd, sa;
099e5b4d 24016 uint32_t op1;
3c824109 24017
3c824109
NF
24018 rs = (ctx->opcode >> 21) & 0x1f;
24019 rt = (ctx->opcode >> 16) & 0x1f;
24020 rd = (ctx->opcode >> 11) & 0x1f;
24021 sa = (ctx->opcode >> 6) & 0x1f;
099e5b4d
LA
24022
24023 op1 = MASK_SPECIAL(ctx->opcode);
24024 switch (op1) {
24025 case OPC_SLL: /* Shift with immediate */
339cd2a8
LA
24026 if (sa == 5 && rd == 0 &&
24027 rs == 0 && rt == 0) { /* PAUSE */
24028 if ((ctx->insn_flags & ISA_MIPS32R6) &&
24029 (ctx->hflags & MIPS_HFLAG_BMASK)) {
9c708c7f 24030 generate_exception_end(ctx, EXCP_RI);
339cd2a8
LA
24031 break;
24032 }
24033 }
24034 /* Fallthrough */
099e5b4d
LA
24035 case OPC_SRA:
24036 gen_shift_imm(ctx, op1, rd, rt, sa);
24037 break;
24038 case OPC_SRL:
24039 switch ((ctx->opcode >> 21) & 0x1f) {
24040 case 1:
24041 /* rotr is decoded as srl on non-R2 CPUs */
24042 if (ctx->insn_flags & ISA_MIPS32R2) {
24043 op1 = OPC_ROTR;
ea63e2c3 24044 }
099e5b4d
LA
24045 /* Fallthrough */
24046 case 0:
24047 gen_shift_imm(ctx, op1, rd, rt, sa);
ea63e2c3 24048 break;
099e5b4d 24049 default:
9c708c7f 24050 generate_exception_end(ctx, EXCP_RI);
ea63e2c3 24051 break;
099e5b4d
LA
24052 }
24053 break;
c2e19f3c
AM
24054 case OPC_ADD:
24055 case OPC_ADDU:
24056 case OPC_SUB:
24057 case OPC_SUBU:
099e5b4d
LA
24058 gen_arith(ctx, op1, rd, rs, rt);
24059 break;
24060 case OPC_SLLV: /* Shifts */
24061 case OPC_SRAV:
24062 gen_shift(ctx, op1, rd, rs, rt);
24063 break;
24064 case OPC_SRLV:
24065 switch ((ctx->opcode >> 6) & 0x1f) {
24066 case 1:
24067 /* rotrv is decoded as srlv on non-R2 CPUs */
24068 if (ctx->insn_flags & ISA_MIPS32R2) {
24069 op1 = OPC_ROTRV;
26135ead 24070 }
099e5b4d
LA
24071 /* Fallthrough */
24072 case 0:
24073 gen_shift(ctx, op1, rd, rs, rt);
26135ead 24074 break;
099e5b4d 24075 default:
9c708c7f 24076 generate_exception_end(ctx, EXCP_RI);
6af0bf9c 24077 break;
099e5b4d
LA
24078 }
24079 break;
24080 case OPC_SLT: /* Set on less than */
24081 case OPC_SLTU:
24082 gen_slt(ctx, op1, rd, rs, rt);
24083 break;
24084 case OPC_AND: /* Logic*/
24085 case OPC_OR:
24086 case OPC_NOR:
24087 case OPC_XOR:
24088 gen_logic(ctx, op1, rd, rs, rt);
24089 break;
0aefa333 24090 case OPC_JALR:
b231c103 24091 gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
099e5b4d 24092 break;
c2e19f3c
AM
24093 case OPC_TGE: /* Traps */
24094 case OPC_TGEU:
24095 case OPC_TLT:
24096 case OPC_TLTU:
24097 case OPC_TEQ:
099e5b4d 24098 case OPC_TNE:
d9224450 24099 check_insn(ctx, ISA_MIPS2);
099e5b4d
LA
24100 gen_trap(ctx, op1, rs, rt, -1);
24101 break;
d4ea6acd 24102 case OPC_LSA: /* OPC_PMON */
f7685877
YK
24103 if ((ctx->insn_flags & ISA_MIPS32R6) ||
24104 (env->CP0_Config3 & (1 << CP0C3_MSAP))) {
d4ea6acd
LA
24105 decode_opc_special_r6(env, ctx);
24106 } else {
24107 /* Pmon entry point, also R4010 selsl */
b48cfdff 24108#ifdef MIPS_STRICT_STANDARD
d4ea6acd 24109 MIPS_INVAL("PMON / selsl");
9c708c7f 24110 generate_exception_end(ctx, EXCP_RI);
b48cfdff 24111#else
d4ea6acd 24112 gen_helper_0e0i(pmon, sa);
b48cfdff 24113#endif
d4ea6acd 24114 }
099e5b4d
LA
24115 break;
24116 case OPC_SYSCALL:
9c708c7f 24117 generate_exception_end(ctx, EXCP_SYSCALL);
099e5b4d
LA
24118 break;
24119 case OPC_BREAK:
9c708c7f 24120 generate_exception_end(ctx, EXCP_BREAK);
099e5b4d 24121 break;
099e5b4d 24122 case OPC_SYNC:
d9224450 24123 check_insn(ctx, ISA_MIPS2);
d208ac0c 24124 gen_sync(extract32(ctx->opcode, 6, 5));
099e5b4d 24125 break;
4ad40f36 24126
d26bc211 24127#if defined(TARGET_MIPS64)
099e5b4d
LA
24128 /* MIPS64 specific opcodes */
24129 case OPC_DSLL:
24130 case OPC_DSRA:
24131 case OPC_DSLL32:
24132 case OPC_DSRA32:
24133 check_insn(ctx, ISA_MIPS3);
24134 check_mips_64(ctx);
24135 gen_shift_imm(ctx, op1, rd, rt, sa);
24136 break;
24137 case OPC_DSRL:
24138 switch ((ctx->opcode >> 21) & 0x1f) {
24139 case 1:
24140 /* drotr is decoded as dsrl on non-R2 CPUs */
24141 if (ctx->insn_flags & ISA_MIPS32R2) {
24142 op1 = OPC_DROTR;
ea63e2c3 24143 }
099e5b4d
LA
24144 /* Fallthrough */
24145 case 0:
d75c135e 24146 check_insn(ctx, ISA_MIPS3);
e189e748 24147 check_mips_64(ctx);
099e5b4d 24148 gen_shift_imm(ctx, op1, rd, rt, sa);
7a387fff 24149 break;
099e5b4d 24150 default:
9c708c7f 24151 generate_exception_end(ctx, EXCP_RI);
460f00c4 24152 break;
099e5b4d
LA
24153 }
24154 break;
24155 case OPC_DSRL32:
24156 switch ((ctx->opcode >> 21) & 0x1f) {
24157 case 1:
24158 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
24159 if (ctx->insn_flags & ISA_MIPS32R2) {
24160 op1 = OPC_DROTR32;
ea63e2c3 24161 }
099e5b4d
LA
24162 /* Fallthrough */
24163 case 0:
d75c135e 24164 check_insn(ctx, ISA_MIPS3);
e189e748 24165 check_mips_64(ctx);
099e5b4d 24166 gen_shift_imm(ctx, op1, rd, rt, sa);
7a387fff 24167 break;
099e5b4d 24168 default:
9c708c7f 24169 generate_exception_end(ctx, EXCP_RI);
6af0bf9c
FB
24170 break;
24171 }
24172 break;
c2e19f3c
AM
24173 case OPC_DADD:
24174 case OPC_DADDU:
24175 case OPC_DSUB:
24176 case OPC_DSUBU:
099e5b4d
LA
24177 check_insn(ctx, ISA_MIPS3);
24178 check_mips_64(ctx);
24179 gen_arith(ctx, op1, rd, rs, rt);
24180 break;
24181 case OPC_DSLLV:
24182 case OPC_DSRAV:
24183 check_insn(ctx, ISA_MIPS3);
24184 check_mips_64(ctx);
24185 gen_shift(ctx, op1, rd, rs, rt);
24186 break;
24187 case OPC_DSRLV:
24188 switch ((ctx->opcode >> 6) & 0x1f) {
24189 case 1:
24190 /* drotrv is decoded as dsrlv on non-R2 CPUs */
24191 if (ctx->insn_flags & ISA_MIPS32R2) {
24192 op1 = OPC_DROTRV;
6af0bf9c 24193 }
099e5b4d
LA
24194 /* Fallthrough */
24195 case 0:
24196 check_insn(ctx, ISA_MIPS3);
e189e748 24197 check_mips_64(ctx);
099e5b4d 24198 gen_shift(ctx, op1, rd, rs, rt);
161f85e6 24199 break;
099e5b4d 24200 default:
9c708c7f 24201 generate_exception_end(ctx, EXCP_RI);
6af0bf9c
FB
24202 break;
24203 }
24204 break;
f7685877
YK
24205 case OPC_DLSA:
24206 if ((ctx->insn_flags & ISA_MIPS32R6) ||
24207 (env->CP0_Config3 & (1 << CP0C3_MSAP))) {
24208 decode_opc_special_r6(env, ctx);
24209 }
24210 break;
099e5b4d 24211#endif
10dc65db
LA
24212 default:
24213 if (ctx->insn_flags & ISA_MIPS32R6) {
24214 decode_opc_special_r6(env, ctx);
9dc324ce
FN
24215 } else if (ctx->insn_flags & INSN_R5900) {
24216 decode_opc_special_tx79(env, ctx);
10dc65db
LA
24217 } else {
24218 decode_opc_special_legacy(env, ctx);
24219 }
24220 }
24221}
24222
d67da337
AM
24223
24224/* MXU accumulate add/subtract 1-bit pattern 'aptn1' */
24225#define MXU_APTN1_A 0
24226#define MXU_APTN1_S 1
24227
b70bb918
CJ
24228/* MXU accumulate add/subtract 2-bit pattern 'aptn2' */
24229#define MXU_APTN2_AA 0
24230#define MXU_APTN2_AS 1
24231#define MXU_APTN2_SA 2
24232#define MXU_APTN2_SS 3
24233
5bb29992
AM
24234/* MXU execute add/subtract 2-bit pattern 'eptn2' */
24235#define MXU_EPTN2_AA 0
24236#define MXU_EPTN2_AS 1
24237#define MXU_EPTN2_SA 2
24238#define MXU_EPTN2_SS 3
24239
a35723f4
CJ
24240/* MXU operand getting pattern 'optn2' */
24241#define MXU_OPTN2_WW 0
24242#define MXU_OPTN2_LW 1
24243#define MXU_OPTN2_HW 2
24244#define MXU_OPTN2_XW 3
24245
53f1131f
CJ
24246/* MXU operand getting pattern 'optn3' */
24247#define MXU_OPTN3_PTN0 0
24248#define MXU_OPTN3_PTN1 1
24249#define MXU_OPTN3_PTN2 2
24250#define MXU_OPTN3_PTN3 3
24251#define MXU_OPTN3_PTN4 4
24252#define MXU_OPTN3_PTN5 5
24253#define MXU_OPTN3_PTN6 6
24254#define MXU_OPTN3_PTN7 7
24255
d67da337 24256
96992d1a
CJ
24257/*
24258 * S32I2M XRa, rb - Register move from GRF to XRF
24259 */
24260static void gen_mxu_s32i2m(DisasContext *ctx)
24261{
24262 TCGv t0;
24263 uint32_t XRa, Rb;
24264
24265 t0 = tcg_temp_new();
24266
24267 XRa = extract32(ctx->opcode, 6, 5);
24268 Rb = extract32(ctx->opcode, 16, 5);
24269
24270 gen_load_gpr(t0, Rb);
24271 if (XRa <= 15) {
24272 gen_store_mxu_gpr(t0, XRa);
24273 } else if (XRa == 16) {
24274 gen_store_mxu_cr(t0);
24275 }
24276
24277 tcg_temp_free(t0);
24278}
24279
24280/*
24281 * S32M2I XRa, rb - Register move from XRF to GRF
24282 */
24283static void gen_mxu_s32m2i(DisasContext *ctx)
24284{
24285 TCGv t0;
24286 uint32_t XRa, Rb;
24287
24288 t0 = tcg_temp_new();
24289
24290 XRa = extract32(ctx->opcode, 6, 5);
24291 Rb = extract32(ctx->opcode, 16, 5);
24292
24293 if (XRa <= 15) {
24294 gen_load_mxu_gpr(t0, XRa);
24295 } else if (XRa == 16) {
24296 gen_load_mxu_cr(t0);
24297 }
24298
24299 gen_store_gpr(t0, Rb);
24300
24301 tcg_temp_free(t0);
24302}
24303
be57bcdb
CJ
24304/*
24305 * S8LDD XRa, Rb, s8, optn3 - Load a byte from memory to XRF
24306 */
24307static void gen_mxu_s8ldd(DisasContext *ctx)
24308{
24309 TCGv t0, t1;
be57bcdb
CJ
24310 uint32_t XRa, Rb, s8, optn3;
24311
24312 t0 = tcg_temp_new();
24313 t1 = tcg_temp_new();
24314
be57bcdb
CJ
24315 XRa = extract32(ctx->opcode, 6, 4);
24316 s8 = extract32(ctx->opcode, 10, 8);
24317 optn3 = extract32(ctx->opcode, 18, 3);
24318 Rb = extract32(ctx->opcode, 21, 5);
24319
be57bcdb
CJ
24320 gen_load_gpr(t0, Rb);
24321 tcg_gen_addi_tl(t0, t0, (int8_t)s8);
24322
24323 switch (optn3) {
24324 /* XRa[7:0] = tmp8 */
24325 case MXU_OPTN3_PTN0:
24326 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
24327 gen_load_mxu_gpr(t0, XRa);
24328 tcg_gen_deposit_tl(t0, t0, t1, 0, 8);
24329 break;
24330 /* XRa[15:8] = tmp8 */
24331 case MXU_OPTN3_PTN1:
24332 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
24333 gen_load_mxu_gpr(t0, XRa);
24334 tcg_gen_deposit_tl(t0, t0, t1, 8, 8);
24335 break;
24336 /* XRa[23:16] = tmp8 */
24337 case MXU_OPTN3_PTN2:
24338 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
24339 gen_load_mxu_gpr(t0, XRa);
24340 tcg_gen_deposit_tl(t0, t0, t1, 16, 8);
24341 break;
24342 /* XRa[31:24] = tmp8 */
24343 case MXU_OPTN3_PTN3:
24344 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
24345 gen_load_mxu_gpr(t0, XRa);
24346 tcg_gen_deposit_tl(t0, t0, t1, 24, 8);
24347 break;
24348 /* XRa = {8'b0, tmp8, 8'b0, tmp8} */
24349 case MXU_OPTN3_PTN4:
24350 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
24351 tcg_gen_deposit_tl(t0, t1, t1, 16, 16);
24352 break;
24353 /* XRa = {tmp8, 8'b0, tmp8, 8'b0} */
24354 case MXU_OPTN3_PTN5:
24355 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
24356 tcg_gen_shli_tl(t1, t1, 8);
24357 tcg_gen_deposit_tl(t0, t1, t1, 16, 16);
24358 break;
24359 /* XRa = {{8{sign of tmp8}}, tmp8, {8{sign of tmp8}}, tmp8} */
24360 case MXU_OPTN3_PTN6:
24361 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_SB);
24362 tcg_gen_mov_tl(t0, t1);
24363 tcg_gen_andi_tl(t0, t0, 0xFF00FFFF);
24364 tcg_gen_shli_tl(t1, t1, 16);
24365 tcg_gen_or_tl(t0, t0, t1);
24366 break;
24367 /* XRa = {tmp8, tmp8, tmp8, tmp8} */
24368 case MXU_OPTN3_PTN7:
24369 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
24370 tcg_gen_deposit_tl(t1, t1, t1, 8, 8);
24371 tcg_gen_deposit_tl(t0, t1, t1, 16, 16);
24372 break;
24373 }
24374
24375 gen_store_mxu_gpr(t0, XRa);
24376
be57bcdb
CJ
24377 tcg_temp_free(t0);
24378 tcg_temp_free(t1);
24379}
24380
72c9bcf8
CJ
24381/*
24382 * D16MUL XRa, XRb, XRc, XRd, optn2 - Signed 16 bit pattern multiplication
24383 */
24384static void gen_mxu_d16mul(DisasContext *ctx)
24385{
24386 TCGv t0, t1, t2, t3;
72c9bcf8
CJ
24387 uint32_t XRa, XRb, XRc, XRd, optn2;
24388
24389 t0 = tcg_temp_new();
24390 t1 = tcg_temp_new();
24391 t2 = tcg_temp_new();
24392 t3 = tcg_temp_new();
24393
72c9bcf8
CJ
24394 XRa = extract32(ctx->opcode, 6, 4);
24395 XRb = extract32(ctx->opcode, 10, 4);
24396 XRc = extract32(ctx->opcode, 14, 4);
24397 XRd = extract32(ctx->opcode, 18, 4);
24398 optn2 = extract32(ctx->opcode, 22, 2);
24399
72c9bcf8
CJ
24400 gen_load_mxu_gpr(t1, XRb);
24401 tcg_gen_sextract_tl(t0, t1, 0, 16);
24402 tcg_gen_sextract_tl(t1, t1, 16, 16);
24403 gen_load_mxu_gpr(t3, XRc);
24404 tcg_gen_sextract_tl(t2, t3, 0, 16);
24405 tcg_gen_sextract_tl(t3, t3, 16, 16);
24406
24407 switch (optn2) {
24408 case MXU_OPTN2_WW: /* XRB.H*XRC.H == lop, XRB.L*XRC.L == rop */
24409 tcg_gen_mul_tl(t3, t1, t3);
24410 tcg_gen_mul_tl(t2, t0, t2);
24411 break;
24412 case MXU_OPTN2_LW: /* XRB.L*XRC.H == lop, XRB.L*XRC.L == rop */
24413 tcg_gen_mul_tl(t3, t0, t3);
24414 tcg_gen_mul_tl(t2, t0, t2);
24415 break;
24416 case MXU_OPTN2_HW: /* XRB.H*XRC.H == lop, XRB.H*XRC.L == rop */
24417 tcg_gen_mul_tl(t3, t1, t3);
24418 tcg_gen_mul_tl(t2, t1, t2);
24419 break;
24420 case MXU_OPTN2_XW: /* XRB.L*XRC.H == lop, XRB.H*XRC.L == rop */
24421 tcg_gen_mul_tl(t3, t0, t3);
24422 tcg_gen_mul_tl(t2, t1, t2);
24423 break;
24424 }
24425 gen_store_mxu_gpr(t3, XRa);
24426 gen_store_mxu_gpr(t2, XRd);
24427
72c9bcf8
CJ
24428 tcg_temp_free(t0);
24429 tcg_temp_free(t1);
24430 tcg_temp_free(t2);
24431 tcg_temp_free(t3);
24432}
24433
e67915b4
CJ
24434/*
24435 * D16MAC XRa, XRb, XRc, XRd, aptn2, optn2 - Signed 16 bit pattern multiply
24436 * and accumulate
24437 */
24438static void gen_mxu_d16mac(DisasContext *ctx)
24439{
24440 TCGv t0, t1, t2, t3;
e67915b4
CJ
24441 uint32_t XRa, XRb, XRc, XRd, optn2, aptn2;
24442
24443 t0 = tcg_temp_new();
24444 t1 = tcg_temp_new();
24445 t2 = tcg_temp_new();
24446 t3 = tcg_temp_new();
24447
e67915b4
CJ
24448 XRa = extract32(ctx->opcode, 6, 4);
24449 XRb = extract32(ctx->opcode, 10, 4);
24450 XRc = extract32(ctx->opcode, 14, 4);
24451 XRd = extract32(ctx->opcode, 18, 4);
24452 optn2 = extract32(ctx->opcode, 22, 2);
24453 aptn2 = extract32(ctx->opcode, 24, 2);
24454
e67915b4
CJ
24455 gen_load_mxu_gpr(t1, XRb);
24456 tcg_gen_sextract_tl(t0, t1, 0, 16);
24457 tcg_gen_sextract_tl(t1, t1, 16, 16);
24458
24459 gen_load_mxu_gpr(t3, XRc);
24460 tcg_gen_sextract_tl(t2, t3, 0, 16);
24461 tcg_gen_sextract_tl(t3, t3, 16, 16);
24462
24463 switch (optn2) {
24464 case MXU_OPTN2_WW: /* XRB.H*XRC.H == lop, XRB.L*XRC.L == rop */
24465 tcg_gen_mul_tl(t3, t1, t3);
24466 tcg_gen_mul_tl(t2, t0, t2);
24467 break;
24468 case MXU_OPTN2_LW: /* XRB.L*XRC.H == lop, XRB.L*XRC.L == rop */
24469 tcg_gen_mul_tl(t3, t0, t3);
24470 tcg_gen_mul_tl(t2, t0, t2);
24471 break;
24472 case MXU_OPTN2_HW: /* XRB.H*XRC.H == lop, XRB.H*XRC.L == rop */
24473 tcg_gen_mul_tl(t3, t1, t3);
24474 tcg_gen_mul_tl(t2, t1, t2);
24475 break;
24476 case MXU_OPTN2_XW: /* XRB.L*XRC.H == lop, XRB.H*XRC.L == rop */
24477 tcg_gen_mul_tl(t3, t0, t3);
24478 tcg_gen_mul_tl(t2, t1, t2);
24479 break;
24480 }
24481 gen_load_mxu_gpr(t0, XRa);
24482 gen_load_mxu_gpr(t1, XRd);
24483
24484 switch (aptn2) {
24485 case MXU_APTN2_AA:
24486 tcg_gen_add_tl(t3, t0, t3);
24487 tcg_gen_add_tl(t2, t1, t2);
24488 break;
24489 case MXU_APTN2_AS:
24490 tcg_gen_add_tl(t3, t0, t3);
24491 tcg_gen_sub_tl(t2, t1, t2);
24492 break;
24493 case MXU_APTN2_SA:
24494 tcg_gen_sub_tl(t3, t0, t3);
24495 tcg_gen_add_tl(t2, t1, t2);
24496 break;
24497 case MXU_APTN2_SS:
24498 tcg_gen_sub_tl(t3, t0, t3);
24499 tcg_gen_sub_tl(t2, t1, t2);
24500 break;
24501 }
24502 gen_store_mxu_gpr(t3, XRa);
24503 gen_store_mxu_gpr(t2, XRd);
24504
e67915b4
CJ
24505 tcg_temp_free(t0);
24506 tcg_temp_free(t1);
24507 tcg_temp_free(t2);
24508 tcg_temp_free(t3);
24509}
24510
a9a4181b
CJ
24511/*
24512 * Q8MUL XRa, XRb, XRc, XRd - Parallel unsigned 8 bit pattern multiply
24513 * Q8MULSU XRa, XRb, XRc, XRd - Parallel signed 8 bit pattern multiply
24514 */
24515static void gen_mxu_q8mul_q8mulsu(DisasContext *ctx)
24516{
24517 TCGv t0, t1, t2, t3, t4, t5, t6, t7;
a9a4181b
CJ
24518 uint32_t XRa, XRb, XRc, XRd, sel;
24519
24520 t0 = tcg_temp_new();
24521 t1 = tcg_temp_new();
24522 t2 = tcg_temp_new();
24523 t3 = tcg_temp_new();
24524 t4 = tcg_temp_new();
24525 t5 = tcg_temp_new();
24526 t6 = tcg_temp_new();
24527 t7 = tcg_temp_new();
24528
a9a4181b
CJ
24529 XRa = extract32(ctx->opcode, 6, 4);
24530 XRb = extract32(ctx->opcode, 10, 4);
24531 XRc = extract32(ctx->opcode, 14, 4);
24532 XRd = extract32(ctx->opcode, 18, 4);
24533 sel = extract32(ctx->opcode, 22, 2);
24534
a9a4181b
CJ
24535 gen_load_mxu_gpr(t3, XRb);
24536 gen_load_mxu_gpr(t7, XRc);
24537
24538 if (sel == 0x2) {
24539 /* Q8MULSU */
24540 tcg_gen_ext8s_tl(t0, t3);
24541 tcg_gen_shri_tl(t3, t3, 8);
24542 tcg_gen_ext8s_tl(t1, t3);
24543 tcg_gen_shri_tl(t3, t3, 8);
24544 tcg_gen_ext8s_tl(t2, t3);
24545 tcg_gen_shri_tl(t3, t3, 8);
24546 tcg_gen_ext8s_tl(t3, t3);
24547 } else {
24548 /* Q8MUL */
24549 tcg_gen_ext8u_tl(t0, t3);
24550 tcg_gen_shri_tl(t3, t3, 8);
24551 tcg_gen_ext8u_tl(t1, t3);
24552 tcg_gen_shri_tl(t3, t3, 8);
24553 tcg_gen_ext8u_tl(t2, t3);
24554 tcg_gen_shri_tl(t3, t3, 8);
24555 tcg_gen_ext8u_tl(t3, t3);
24556 }
24557
24558 tcg_gen_ext8u_tl(t4, t7);
24559 tcg_gen_shri_tl(t7, t7, 8);
24560 tcg_gen_ext8u_tl(t5, t7);
24561 tcg_gen_shri_tl(t7, t7, 8);
24562 tcg_gen_ext8u_tl(t6, t7);
24563 tcg_gen_shri_tl(t7, t7, 8);
24564 tcg_gen_ext8u_tl(t7, t7);
24565
24566 tcg_gen_mul_tl(t0, t0, t4);
24567 tcg_gen_mul_tl(t1, t1, t5);
24568 tcg_gen_mul_tl(t2, t2, t6);
24569 tcg_gen_mul_tl(t3, t3, t7);
24570
24571 tcg_gen_andi_tl(t0, t0, 0xFFFF);
24572 tcg_gen_andi_tl(t1, t1, 0xFFFF);
24573 tcg_gen_andi_tl(t2, t2, 0xFFFF);
24574 tcg_gen_andi_tl(t3, t3, 0xFFFF);
24575
24576 tcg_gen_shli_tl(t1, t1, 16);
24577 tcg_gen_shli_tl(t3, t3, 16);
24578
24579 tcg_gen_or_tl(t0, t0, t1);
24580 tcg_gen_or_tl(t1, t2, t3);
24581
24582 gen_store_mxu_gpr(t0, XRd);
24583 gen_store_mxu_gpr(t1, XRa);
24584
a9a4181b
CJ
24585 tcg_temp_free(t0);
24586 tcg_temp_free(t1);
24587 tcg_temp_free(t2);
24588 tcg_temp_free(t3);
24589 tcg_temp_free(t4);
24590 tcg_temp_free(t5);
24591 tcg_temp_free(t6);
24592 tcg_temp_free(t7);
24593}
24594
4ca83721
CJ
24595/*
24596 * S32LDD XRa, Rb, S12 - Load a word from memory to XRF
24597 * S32LDDR XRa, Rb, S12 - Load a word from memory to XRF, reversed byte seq.
24598 */
24599static void gen_mxu_s32ldd_s32lddr(DisasContext *ctx)
24600{
24601 TCGv t0, t1;
4ca83721
CJ
24602 uint32_t XRa, Rb, s12, sel;
24603
24604 t0 = tcg_temp_new();
24605 t1 = tcg_temp_new();
24606
4ca83721
CJ
24607 XRa = extract32(ctx->opcode, 6, 4);
24608 s12 = extract32(ctx->opcode, 10, 10);
24609 sel = extract32(ctx->opcode, 20, 1);
24610 Rb = extract32(ctx->opcode, 21, 5);
24611
4ca83721
CJ
24612 gen_load_gpr(t0, Rb);
24613
24614 tcg_gen_movi_tl(t1, s12);
24615 tcg_gen_shli_tl(t1, t1, 2);
24616 if (s12 & 0x200) {
24617 tcg_gen_ori_tl(t1, t1, 0xFFFFF000);
24618 }
24619 tcg_gen_add_tl(t1, t0, t1);
24620 tcg_gen_qemu_ld_tl(t1, t1, ctx->mem_idx, MO_SL);
24621
24622 if (sel == 1) {
24623 /* S32LDDR */
24624 tcg_gen_bswap32_tl(t1, t1);
24625 }
24626 gen_store_mxu_gpr(t1, XRa);
24627
4ca83721
CJ
24628 tcg_temp_free(t0);
24629 tcg_temp_free(t1);
24630}
24631
96992d1a
CJ
24632
24633/*
24634 * Decoding engine for MXU
24635 * =======================
24636 */
24637
03f40088
AM
24638/*
24639 *
24640 * Decode MXU pool00
24641 *
24642 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
24643 * +-----------+---------+-----+-------+-------+-------+-----------+
24644 * | SPECIAL2 |0 0 0 0 0|x x x| XRc | XRb | XRa |MXU__POOL00|
24645 * +-----------+---------+-----+-------+-------+-------+-----------+
24646 *
24647 */
24648static void decode_opc_mxu__pool00(CPUMIPSState *env, DisasContext *ctx)
24649{
24650 uint32_t opcode = extract32(ctx->opcode, 18, 3);
24651
24652 switch (opcode) {
24653 case OPC_MXU_S32MAX:
24654 /* TODO: Implement emulation of S32MAX instruction. */
24655 MIPS_INVAL("OPC_MXU_S32MAX");
24656 generate_exception_end(ctx, EXCP_RI);
24657 break;
24658 case OPC_MXU_S32MIN:
24659 /* TODO: Implement emulation of S32MIN instruction. */
24660 MIPS_INVAL("OPC_MXU_S32MIN");
24661 generate_exception_end(ctx, EXCP_RI);
24662 break;
24663 case OPC_MXU_D16MAX:
24664 /* TODO: Implement emulation of D16MAX instruction. */
24665 MIPS_INVAL("OPC_MXU_D16MAX");
24666 generate_exception_end(ctx, EXCP_RI);
24667 break;
24668 case OPC_MXU_D16MIN:
24669 /* TODO: Implement emulation of D16MIN instruction. */
24670 MIPS_INVAL("OPC_MXU_D16MIN");
24671 generate_exception_end(ctx, EXCP_RI);
24672 break;
24673 case OPC_MXU_Q8MAX:
24674 /* TODO: Implement emulation of Q8MAX instruction. */
24675 MIPS_INVAL("OPC_MXU_Q8MAX");
24676 generate_exception_end(ctx, EXCP_RI);
24677 break;
24678 case OPC_MXU_Q8MIN:
24679 /* TODO: Implement emulation of Q8MIN instruction. */
24680 MIPS_INVAL("OPC_MXU_Q8MIN");
24681 generate_exception_end(ctx, EXCP_RI);
24682 break;
24683 case OPC_MXU_Q8SLT:
24684 /* TODO: Implement emulation of Q8SLT instruction. */
24685 MIPS_INVAL("OPC_MXU_Q8SLT");
24686 generate_exception_end(ctx, EXCP_RI);
24687 break;
24688 case OPC_MXU_Q8SLTU:
24689 /* TODO: Implement emulation of Q8SLTU instruction. */
24690 MIPS_INVAL("OPC_MXU_Q8SLTU");
24691 generate_exception_end(ctx, EXCP_RI);
24692 break;
24693 default:
24694 MIPS_INVAL("decode_opc_mxu");
24695 generate_exception_end(ctx, EXCP_RI);
24696 break;
24697 }
24698}
24699
24700/*
24701 *
24702 * Decode MXU pool01
24703 *
24704 * S32SLT, D16SLT, D16AVG, D16AVGR, Q8AVG, Q8AVGR:
24705 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
24706 * +-----------+---------+-----+-------+-------+-------+-----------+
24707 * | SPECIAL2 |0 0 0 0 0|x x x| XRc | XRb | XRa |MXU__POOL01|
24708 * +-----------+---------+-----+-------+-------+-------+-----------+
24709 *
24710 * Q8ADD:
24711 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
24712 * +-----------+---+-----+-----+-------+-------+-------+-----------+
24713 * | SPECIAL2 |en2|0 0 0|x x x| XRc | XRb | XRa |MXU__POOL01|
24714 * +-----------+---+-----+-----+-------+-------+-------+-----------+
24715 *
24716 */
24717static void decode_opc_mxu__pool01(CPUMIPSState *env, DisasContext *ctx)
24718{
24719 uint32_t opcode = extract32(ctx->opcode, 18, 3);
24720
24721 switch (opcode) {
24722 case OPC_MXU_S32SLT:
24723 /* TODO: Implement emulation of S32SLT instruction. */
24724 MIPS_INVAL("OPC_MXU_S32SLT");
24725 generate_exception_end(ctx, EXCP_RI);
24726 break;
24727 case OPC_MXU_D16SLT:
24728 /* TODO: Implement emulation of D16SLT instruction. */
24729 MIPS_INVAL("OPC_MXU_D16SLT");
24730 generate_exception_end(ctx, EXCP_RI);
24731 break;
24732 case OPC_MXU_D16AVG:
24733 /* TODO: Implement emulation of D16AVG instruction. */
24734 MIPS_INVAL("OPC_MXU_D16AVG");
24735 generate_exception_end(ctx, EXCP_RI);
24736 break;
24737 case OPC_MXU_D16AVGR:
24738 /* TODO: Implement emulation of D16AVGR instruction. */
24739 MIPS_INVAL("OPC_MXU_D16AVGR");
24740 generate_exception_end(ctx, EXCP_RI);
24741 break;
24742 case OPC_MXU_Q8AVG:
24743 /* TODO: Implement emulation of Q8AVG instruction. */
24744 MIPS_INVAL("OPC_MXU_Q8AVG");
24745 generate_exception_end(ctx, EXCP_RI);
24746 break;
24747 case OPC_MXU_Q8AVGR:
24748 /* TODO: Implement emulation of Q8AVGR instruction. */
24749 MIPS_INVAL("OPC_MXU_Q8AVGR");
24750 generate_exception_end(ctx, EXCP_RI);
24751 break;
24752 case OPC_MXU_Q8ADD:
24753 /* TODO: Implement emulation of Q8ADD instruction. */
24754 MIPS_INVAL("OPC_MXU_Q8ADD");
24755 generate_exception_end(ctx, EXCP_RI);
24756 break;
24757 default:
24758 MIPS_INVAL("decode_opc_mxu");
24759 generate_exception_end(ctx, EXCP_RI);
24760 break;
24761 }
24762}
24763
24764/*
24765 *
24766 * Decode MXU pool02
24767 *
24768 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
24769 * +-----------+---------+-----+-------+-------+-------+-----------+
24770 * | SPECIAL2 |0 0 0 0 0|x x x| XRc | XRb | XRa |MXU__POOL02|
24771 * +-----------+---------+-----+-------+-------+-------+-----------+
24772 *
24773 */
24774static void decode_opc_mxu__pool02(CPUMIPSState *env, DisasContext *ctx)
24775{
24776 uint32_t opcode = extract32(ctx->opcode, 18, 3);
24777
24778 switch (opcode) {
24779 case OPC_MXU_S32CPS:
24780 /* TODO: Implement emulation of S32CPS instruction. */
24781 MIPS_INVAL("OPC_MXU_S32CPS");
24782 generate_exception_end(ctx, EXCP_RI);
24783 break;
24784 case OPC_MXU_D16CPS:
24785 /* TODO: Implement emulation of D16CPS instruction. */
24786 MIPS_INVAL("OPC_MXU_D16CPS");
24787 generate_exception_end(ctx, EXCP_RI);
24788 break;
24789 case OPC_MXU_Q8ABD:
24790 /* TODO: Implement emulation of Q8ABD instruction. */
24791 MIPS_INVAL("OPC_MXU_Q8ABD");
24792 generate_exception_end(ctx, EXCP_RI);
24793 break;
24794 case OPC_MXU_Q16SAT:
24795 /* TODO: Implement emulation of Q16SAT instruction. */
24796 MIPS_INVAL("OPC_MXU_Q16SAT");
24797 generate_exception_end(ctx, EXCP_RI);
24798 break;
24799 default:
24800 MIPS_INVAL("decode_opc_mxu");
24801 generate_exception_end(ctx, EXCP_RI);
24802 break;
24803 }
24804}
24805
24806/*
24807 *
24808 * Decode MXU pool03
24809 *
24810 * D16MULF:
24811 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
24812 * +-----------+---+---+-------+-------+-------+-------+-----------+
24813 * | SPECIAL2 |x x|on2|0 0 0 0| XRc | XRb | XRa |MXU__POOL03|
24814 * +-----------+---+---+-------+-------+-------+-------+-----------+
24815 *
24816 * D16MULE:
24817 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
24818 * +-----------+---+---+-------+-------+-------+-------+-----------+
24819 * | SPECIAL2 |x x|on2| Xd | XRc | XRb | XRa |MXU__POOL03|
24820 * +-----------+---+---+-------+-------+-------+-------+-----------+
24821 *
24822 */
24823static void decode_opc_mxu__pool03(CPUMIPSState *env, DisasContext *ctx)
24824{
24825 uint32_t opcode = extract32(ctx->opcode, 24, 2);
24826
24827 switch (opcode) {
24828 case OPC_MXU_D16MULF:
24829 /* TODO: Implement emulation of D16MULF instruction. */
24830 MIPS_INVAL("OPC_MXU_D16MULF");
24831 generate_exception_end(ctx, EXCP_RI);
24832 break;
24833 case OPC_MXU_D16MULE:
24834 /* TODO: Implement emulation of D16MULE instruction. */
24835 MIPS_INVAL("OPC_MXU_D16MULE");
24836 generate_exception_end(ctx, EXCP_RI);
24837 break;
24838 default:
24839 MIPS_INVAL("decode_opc_mxu");
24840 generate_exception_end(ctx, EXCP_RI);
24841 break;
24842 }
24843}
24844
24845/*
24846 *
24847 * Decode MXU pool04
24848 *
24849 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
24850 * +-----------+---------+-+-------------------+-------+-----------+
24851 * | SPECIAL2 | rb |x| s12 | XRa |MXU__POOL04|
24852 * +-----------+---------+-+-------------------+-------+-----------+
24853 *
24854 */
24855static void decode_opc_mxu__pool04(CPUMIPSState *env, DisasContext *ctx)
24856{
24857 uint32_t opcode = extract32(ctx->opcode, 20, 1);
24858
24859 switch (opcode) {
24860 case OPC_MXU_S32LDD:
03f40088 24861 case OPC_MXU_S32LDDR:
4ca83721 24862 gen_mxu_s32ldd_s32lddr(ctx);
03f40088
AM
24863 break;
24864 default:
24865 MIPS_INVAL("decode_opc_mxu");
24866 generate_exception_end(ctx, EXCP_RI);
24867 break;
24868 }
24869}
24870
24871/*
24872 *
24873 * Decode MXU pool05
24874 *
24875 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
24876 * +-----------+---------+-+-------------------+-------+-----------+
24877 * | SPECIAL2 | rb |x| s12 | XRa |MXU__POOL05|
24878 * +-----------+---------+-+-------------------+-------+-----------+
24879 *
24880 */
24881static void decode_opc_mxu__pool05(CPUMIPSState *env, DisasContext *ctx)
24882{
24883 uint32_t opcode = extract32(ctx->opcode, 20, 1);
24884
24885 switch (opcode) {
24886 case OPC_MXU_S32STD:
24887 /* TODO: Implement emulation of S32STD instruction. */
24888 MIPS_INVAL("OPC_MXU_S32STD");
24889 generate_exception_end(ctx, EXCP_RI);
24890 break;
24891 case OPC_MXU_S32STDR:
24892 /* TODO: Implement emulation of S32STDR instruction. */
24893 MIPS_INVAL("OPC_MXU_S32STDR");
24894 generate_exception_end(ctx, EXCP_RI);
24895 break;
24896 default:
24897 MIPS_INVAL("decode_opc_mxu");
24898 generate_exception_end(ctx, EXCP_RI);
24899 break;
24900 }
24901}
24902
24903/*
24904 *
24905 * Decode MXU pool06
24906 *
24907 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
24908 * +-----------+---------+---------+---+-------+-------+-----------+
24909 * | SPECIAL2 | rb | rc |st2|x x x x| XRa |MXU__POOL06|
24910 * +-----------+---------+---------+---+-------+-------+-----------+
24911 *
24912 */
24913static void decode_opc_mxu__pool06(CPUMIPSState *env, DisasContext *ctx)
24914{
24915 uint32_t opcode = extract32(ctx->opcode, 10, 4);
24916
24917 switch (opcode) {
24918 case OPC_MXU_S32LDDV:
24919 /* TODO: Implement emulation of S32LDDV instruction. */
24920 MIPS_INVAL("OPC_MXU_S32LDDV");
24921 generate_exception_end(ctx, EXCP_RI);
24922 break;
24923 case OPC_MXU_S32LDDVR:
24924 /* TODO: Implement emulation of S32LDDVR instruction. */
24925 MIPS_INVAL("OPC_MXU_S32LDDVR");
24926 generate_exception_end(ctx, EXCP_RI);
24927 break;
24928 default:
24929 MIPS_INVAL("decode_opc_mxu");
24930 generate_exception_end(ctx, EXCP_RI);
24931 break;
24932 }
24933}
24934
24935/*
24936 *
24937 * Decode MXU pool07
24938 *
24939 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
24940 * +-----------+---------+---------+---+-------+-------+-----------+
24941 * | SPECIAL2 | rb | rc |st2|x x x x| XRa |MXU__POOL07|
24942 * +-----------+---------+---------+---+-------+-------+-----------+
24943 *
24944 */
24945static void decode_opc_mxu__pool07(CPUMIPSState *env, DisasContext *ctx)
24946{
24947 uint32_t opcode = extract32(ctx->opcode, 10, 4);
24948
24949 switch (opcode) {
24950 case OPC_MXU_S32STDV:
24951 /* TODO: Implement emulation of S32TDV instruction. */
24952 MIPS_INVAL("OPC_MXU_S32TDV");
24953 generate_exception_end(ctx, EXCP_RI);
24954 break;
24955 case OPC_MXU_S32STDVR:
24956 /* TODO: Implement emulation of S32TDVR instruction. */
24957 MIPS_INVAL("OPC_MXU_S32TDVR");
24958 generate_exception_end(ctx, EXCP_RI);
24959 break;
24960 default:
24961 MIPS_INVAL("decode_opc_mxu");
24962 generate_exception_end(ctx, EXCP_RI);
24963 break;
24964 }
24965}
24966
24967/*
24968 *
24969 * Decode MXU pool08
24970 *
24971 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
24972 * +-----------+---------+-+-------------------+-------+-----------+
24973 * | SPECIAL2 | rb |x| s12 | XRa |MXU__POOL08|
24974 * +-----------+---------+-+-------------------+-------+-----------+
24975 *
24976*/
24977static void decode_opc_mxu__pool08(CPUMIPSState *env, DisasContext *ctx)
24978{
24979 uint32_t opcode = extract32(ctx->opcode, 20, 1);
24980
24981 switch (opcode) {
24982 case OPC_MXU_S32LDI:
24983 /* TODO: Implement emulation of S32LDI instruction. */
24984 MIPS_INVAL("OPC_MXU_S32LDI");
24985 generate_exception_end(ctx, EXCP_RI);
24986 break;
24987 case OPC_MXU_S32LDIR:
24988 /* TODO: Implement emulation of S32LDIR instruction. */
24989 MIPS_INVAL("OPC_MXU_S32LDIR");
24990 generate_exception_end(ctx, EXCP_RI);
24991 break;
24992 default:
24993 MIPS_INVAL("decode_opc_mxu");
24994 generate_exception_end(ctx, EXCP_RI);
24995 break;
24996 }
24997}
24998
24999/*
25000 *
25001 * Decode MXU pool09
25002 *
25003 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
25004 * +-----------+---------+-+-------------------+-------+-----------+
25005 * | SPECIAL2 | rb |x| s12 | XRa |MXU__POOL09|
25006 * +-----------+---------+-+-------------------+-------+-----------+
25007 *
25008 */
25009static void decode_opc_mxu__pool09(CPUMIPSState *env, DisasContext *ctx)
25010{
25011 uint32_t opcode = extract32(ctx->opcode, 5, 0);
25012
25013 switch (opcode) {
25014 case OPC_MXU_S32SDI:
25015 /* TODO: Implement emulation of S32SDI instruction. */
25016 MIPS_INVAL("OPC_MXU_S32SDI");
25017 generate_exception_end(ctx, EXCP_RI);
25018 break;
25019 case OPC_MXU_S32SDIR:
25020 /* TODO: Implement emulation of S32SDIR instruction. */
25021 MIPS_INVAL("OPC_MXU_S32SDIR");
25022 generate_exception_end(ctx, EXCP_RI);
25023 break;
25024 default:
25025 MIPS_INVAL("decode_opc_mxu");
25026 generate_exception_end(ctx, EXCP_RI);
25027 break;
25028 }
25029}
25030
25031/*
25032 *
25033 * Decode MXU pool10
25034 *
25035 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
25036 * +-----------+---------+---------+---+-------+-------+-----------+
25037 * | SPECIAL2 | rb | rc |st2|x x x x| XRa |MXU__POOL10|
25038 * +-----------+---------+---------+---+-------+-------+-----------+
25039 *
25040 */
25041static void decode_opc_mxu__pool10(CPUMIPSState *env, DisasContext *ctx)
25042{
25043 uint32_t opcode = extract32(ctx->opcode, 5, 0);
25044
25045 switch (opcode) {
25046 case OPC_MXU_S32LDIV:
25047 /* TODO: Implement emulation of S32LDIV instruction. */
25048 MIPS_INVAL("OPC_MXU_S32LDIV");
25049 generate_exception_end(ctx, EXCP_RI);
25050 break;
25051 case OPC_MXU_S32LDIVR:
25052 /* TODO: Implement emulation of S32LDIVR instruction. */
25053 MIPS_INVAL("OPC_MXU_S32LDIVR");
25054 generate_exception_end(ctx, EXCP_RI);
25055 break;
25056 default:
25057 MIPS_INVAL("decode_opc_mxu");
25058 generate_exception_end(ctx, EXCP_RI);
25059 break;
25060 }
25061}
25062
25063/*
25064 *
25065 * Decode MXU pool11
25066 *
25067 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
25068 * +-----------+---------+---------+---+-------+-------+-----------+
25069 * | SPECIAL2 | rb | rc |st2|x x x x| XRa |MXU__POOL11|
25070 * +-----------+---------+---------+---+-------+-------+-----------+
25071 *
25072 */
25073static void decode_opc_mxu__pool11(CPUMIPSState *env, DisasContext *ctx)
25074{
25075 uint32_t opcode = extract32(ctx->opcode, 10, 4);
25076
25077 switch (opcode) {
25078 case OPC_MXU_S32SDIV:
25079 /* TODO: Implement emulation of S32SDIV instruction. */
25080 MIPS_INVAL("OPC_MXU_S32SDIV");
25081 generate_exception_end(ctx, EXCP_RI);
25082 break;
25083 case OPC_MXU_S32SDIVR:
25084 /* TODO: Implement emulation of S32SDIVR instruction. */
25085 MIPS_INVAL("OPC_MXU_S32SDIVR");
25086 generate_exception_end(ctx, EXCP_RI);
25087 break;
25088 default:
25089 MIPS_INVAL("decode_opc_mxu");
25090 generate_exception_end(ctx, EXCP_RI);
25091 break;
25092 }
25093}
25094
25095/*
25096 *
25097 * Decode MXU pool12
25098 *
25099 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
25100 * +-----------+---+---+-------+-------+-------+-------+-----------+
25101 * | SPECIAL2 |an2|x x| Xd | XRc | XRb | XRa |MXU__POOL12|
25102 * +-----------+---+---+-------+-------+-------+-------+-----------+
25103 *
25104 */
25105static void decode_opc_mxu__pool12(CPUMIPSState *env, DisasContext *ctx)
25106{
25107 uint32_t opcode = extract32(ctx->opcode, 22, 2);
25108
25109 switch (opcode) {
25110 case OPC_MXU_D32ACC:
25111 /* TODO: Implement emulation of D32ACC instruction. */
25112 MIPS_INVAL("OPC_MXU_D32ACC");
25113 generate_exception_end(ctx, EXCP_RI);
25114 break;
25115 case OPC_MXU_D32ACCM:
25116 /* TODO: Implement emulation of D32ACCM instruction. */
25117 MIPS_INVAL("OPC_MXU_D32ACCM");
25118 generate_exception_end(ctx, EXCP_RI);
25119 break;
25120 case OPC_MXU_D32ASUM:
25121 /* TODO: Implement emulation of D32ASUM instruction. */
25122 MIPS_INVAL("OPC_MXU_D32ASUM");
25123 generate_exception_end(ctx, EXCP_RI);
25124 break;
25125 default:
25126 MIPS_INVAL("decode_opc_mxu");
25127 generate_exception_end(ctx, EXCP_RI);
25128 break;
25129 }
25130}
25131
25132/*
25133 *
25134 * Decode MXU pool13
25135 *
25136 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
25137 * +-----------+---+---+-------+-------+-------+-------+-----------+
25138 * | SPECIAL2 |en2|x x|0 0 0 0| XRc | XRb | XRa |MXU__POOL13|
25139 * +-----------+---+---+-------+-------+-------+-------+-----------+
25140 *
25141 */
25142static void decode_opc_mxu__pool13(CPUMIPSState *env, DisasContext *ctx)
25143{
25144 uint32_t opcode = extract32(ctx->opcode, 22, 2);
25145
25146 switch (opcode) {
25147 case OPC_MXU_Q16ACC:
25148 /* TODO: Implement emulation of Q16ACC instruction. */
25149 MIPS_INVAL("OPC_MXU_Q16ACC");
25150 generate_exception_end(ctx, EXCP_RI);
25151 break;
25152 case OPC_MXU_Q16ACCM:
25153 /* TODO: Implement emulation of Q16ACCM instruction. */
25154 MIPS_INVAL("OPC_MXU_Q16ACCM");
25155 generate_exception_end(ctx, EXCP_RI);
25156 break;
25157 case OPC_MXU_Q16ASUM:
25158 /* TODO: Implement emulation of Q16ASUM instruction. */
25159 MIPS_INVAL("OPC_MXU_Q16ASUM");
25160 generate_exception_end(ctx, EXCP_RI);
25161 break;
25162 default:
25163 MIPS_INVAL("decode_opc_mxu");
25164 generate_exception_end(ctx, EXCP_RI);
25165 break;
25166 }
25167}
25168
25169/*
25170 *
25171 * Decode MXU pool14
25172 *
25173 * Q8ADDE, Q8ACCE:
25174 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
25175 * +-----------+---+---+-------+-------+-------+-------+-----------+
25176 * | SPECIAL2 |0 0|x x| XRd | XRc | XRb | XRa |MXU__POOL14|
25177 * +-----------+---+---+-------+-------+-------+-------+-----------+
25178 *
25179 * D8SUM, D8SUMC:
25180 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
25181 * +-----------+---+---+-------+-------+-------+-------+-----------+
25182 * | SPECIAL2 |en2|x x|0 0 0 0| XRc | XRb | XRa |MXU__POOL14|
25183 * +-----------+---+---+-------+-------+-------+-------+-----------+
25184 *
25185 */
25186static void decode_opc_mxu__pool14(CPUMIPSState *env, DisasContext *ctx)
25187{
25188 uint32_t opcode = extract32(ctx->opcode, 22, 2);
25189
25190 switch (opcode) {
25191 case OPC_MXU_Q8ADDE:
25192 /* TODO: Implement emulation of Q8ADDE instruction. */
25193 MIPS_INVAL("OPC_MXU_Q8ADDE");
25194 generate_exception_end(ctx, EXCP_RI);
25195 break;
25196 case OPC_MXU_D8SUM:
25197 /* TODO: Implement emulation of D8SUM instruction. */
25198 MIPS_INVAL("OPC_MXU_D8SUM");
25199 generate_exception_end(ctx, EXCP_RI);
25200 break;
25201 case OPC_MXU_D8SUMC:
25202 /* TODO: Implement emulation of D8SUMC instruction. */
25203 MIPS_INVAL("OPC_MXU_D8SUMC");
25204 generate_exception_end(ctx, EXCP_RI);
25205 break;
25206 default:
25207 MIPS_INVAL("decode_opc_mxu");
25208 generate_exception_end(ctx, EXCP_RI);
25209 break;
25210 }
25211}
25212
25213/*
25214 *
25215 * Decode MXU pool15
25216 *
25217 * S32MUL, S32MULU, S32EXTRV:
25218 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
25219 * +-----------+---------+---------+---+-------+-------+-----------+
25220 * | SPECIAL2 | rs | rt |x x| XRd | XRa |MXU__POOL15|
25221 * +-----------+---------+---------+---+-------+-------+-----------+
25222 *
25223 * S32EXTR:
25224 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
25225 * +-----------+---------+---------+---+-------+-------+-----------+
25226 * | SPECIAL2 | rb | sft5 |x x| XRd | XRa |MXU__POOL15|
25227 * +-----------+---------+---------+---+-------+-------+-----------+
25228 *
25229 */
25230static void decode_opc_mxu__pool15(CPUMIPSState *env, DisasContext *ctx)
25231{
25232 uint32_t opcode = extract32(ctx->opcode, 14, 2);
25233
25234 switch (opcode) {
25235 case OPC_MXU_S32MUL:
25236 /* TODO: Implement emulation of S32MUL instruction. */
25237 MIPS_INVAL("OPC_MXU_S32MUL");
25238 generate_exception_end(ctx, EXCP_RI);
25239 break;
25240 case OPC_MXU_S32MULU:
25241 /* TODO: Implement emulation of S32MULU instruction. */
25242 MIPS_INVAL("OPC_MXU_S32MULU");
25243 generate_exception_end(ctx, EXCP_RI);
25244 break;
25245 case OPC_MXU_S32EXTR:
25246 /* TODO: Implement emulation of S32EXTR instruction. */
25247 MIPS_INVAL("OPC_MXU_S32EXTR");
25248 generate_exception_end(ctx, EXCP_RI);
25249 break;
25250 case OPC_MXU_S32EXTRV:
25251 /* TODO: Implement emulation of S32EXTRV instruction. */
25252 MIPS_INVAL("OPC_MXU_S32EXTRV");
25253 generate_exception_end(ctx, EXCP_RI);
25254 break;
25255 default:
25256 MIPS_INVAL("decode_opc_mxu");
25257 generate_exception_end(ctx, EXCP_RI);
25258 break;
25259 }
25260}
25261
25262/*
25263 *
25264 * Decode MXU pool16
25265 *
25266 * D32SARW:
25267 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
25268 * +-----------+---------+-----+-------+-------+-------+-----------+
25269 * | SPECIAL2 | rb |x x x| XRc | XRb | XRa |MXU__POOL16|
25270 * +-----------+---------+-----+-------+-------+-------+-----------+
25271 *
25272 * S32ALN:
25273 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
25274 * +-----------+---------+-----+-------+-------+-------+-----------+
25275 * | SPECIAL2 | rs |x x x| XRc | XRb | XRa |MXU__POOL16|
25276 * +-----------+---------+-----+-------+-------+-------+-----------+
25277 *
25278 * S32ALNI:
25279 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
25280 * +-----------+-----+---+-----+-------+-------+-------+-----------+
25281 * | SPECIAL2 | s3 |0 0|x x x| XRc | XRb | XRa |MXU__POOL16|
25282 * +-----------+-----+---+-----+-------+-------+-------+-----------+
25283 *
25284 * S32NOR, S32AND, S32OR, S32XOR:
25285 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
25286 * +-----------+---------+-----+-------+-------+-------+-----------+
25287 * | SPECIAL2 |0 0 0 0 0|x x x| XRc | XRb | XRa |MXU__POOL16|
25288 * +-----------+---------+-----+-------+-------+-------+-----------+
25289 *
25290 * S32LUI:
25291 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
25292 * +-----------+-----+---+-----+-------+---------------+-----------+
25293 * | SPECIAL2 |optn3|0 0|x x x| XRc | s8 |MXU__POOL16|
25294 * +-----------+-----+---+-----+-------+---------------+-----------+
25295 *
25296 */
25297static void decode_opc_mxu__pool16(CPUMIPSState *env, DisasContext *ctx)
25298{
25299 uint32_t opcode = extract32(ctx->opcode, 18, 3);
25300
25301 switch (opcode) {
25302 case OPC_MXU_D32SARW:
25303 /* TODO: Implement emulation of D32SARW instruction. */
25304 MIPS_INVAL("OPC_MXU_D32SARW");
25305 generate_exception_end(ctx, EXCP_RI);
25306 break;
25307 case OPC_MXU_S32ALN:
25308 /* TODO: Implement emulation of S32ALN instruction. */
25309 MIPS_INVAL("OPC_MXU_S32ALN");
25310 generate_exception_end(ctx, EXCP_RI);
25311 break;
25312 case OPC_MXU_S32ALNI:
25313 /* TODO: Implement emulation of S32ALNI instruction. */
25314 MIPS_INVAL("OPC_MXU_S32ALNI");
25315 generate_exception_end(ctx, EXCP_RI);
25316 break;
25317 case OPC_MXU_S32NOR:
25318 /* TODO: Implement emulation of S32NOR instruction. */
25319 MIPS_INVAL("OPC_MXU_S32NOR");
25320 generate_exception_end(ctx, EXCP_RI);
25321 break;
25322 case OPC_MXU_S32AND:
25323 /* TODO: Implement emulation of S32AND instruction. */
25324 MIPS_INVAL("OPC_MXU_S32AND");
25325 generate_exception_end(ctx, EXCP_RI);
25326 break;
25327 case OPC_MXU_S32OR:
25328 /* TODO: Implement emulation of S32OR instruction. */
25329 MIPS_INVAL("OPC_MXU_S32OR");
25330 generate_exception_end(ctx, EXCP_RI);
25331 break;
25332 case OPC_MXU_S32XOR:
25333 /* TODO: Implement emulation of S32XOR instruction. */
25334 MIPS_INVAL("OPC_MXU_S32XOR");
25335 generate_exception_end(ctx, EXCP_RI);
25336 break;
25337 case OPC_MXU_S32LUI:
25338 /* TODO: Implement emulation of S32LUI instruction. */
25339 MIPS_INVAL("OPC_MXU_S32LUI");
25340 generate_exception_end(ctx, EXCP_RI);
25341 break;
25342 default:
25343 MIPS_INVAL("decode_opc_mxu");
25344 generate_exception_end(ctx, EXCP_RI);
25345 break;
25346 }
25347}
25348
25349/*
25350 *
25351 * Decode MXU pool17
25352 *
25353 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
c233bf07
AM
25354 * +-----------+---------+---------+---+---------+-----+-----------+
25355 * | SPECIAL2 | rs | rt |0 0| rd |x x x|MXU__POOL15|
25356 * +-----------+---------+---------+---+---------+-----+-----------+
25357 *
25358 */
25359static void decode_opc_mxu__pool17(CPUMIPSState *env, DisasContext *ctx)
25360{
25361 uint32_t opcode = extract32(ctx->opcode, 6, 2);
25362
25363 switch (opcode) {
25364 case OPC_MXU_LXW:
25365 /* TODO: Implement emulation of LXW instruction. */
25366 MIPS_INVAL("OPC_MXU_LXW");
25367 generate_exception_end(ctx, EXCP_RI);
25368 break;
25369 case OPC_MXU_LXH:
25370 /* TODO: Implement emulation of LXH instruction. */
25371 MIPS_INVAL("OPC_MXU_LXH");
25372 generate_exception_end(ctx, EXCP_RI);
25373 break;
25374 case OPC_MXU_LXHU:
25375 /* TODO: Implement emulation of LXHU instruction. */
25376 MIPS_INVAL("OPC_MXU_LXHU");
25377 generate_exception_end(ctx, EXCP_RI);
25378 break;
25379 case OPC_MXU_LXB:
25380 /* TODO: Implement emulation of LXB instruction. */
25381 MIPS_INVAL("OPC_MXU_LXB");
25382 generate_exception_end(ctx, EXCP_RI);
25383 break;
25384 case OPC_MXU_LXBU:
25385 /* TODO: Implement emulation of LXBU instruction. */
25386 MIPS_INVAL("OPC_MXU_LXBU");
25387 generate_exception_end(ctx, EXCP_RI);
25388 break;
25389 default:
25390 MIPS_INVAL("decode_opc_mxu");
25391 generate_exception_end(ctx, EXCP_RI);
25392 break;
25393 }
25394}
25395/*
25396 *
25397 * Decode MXU pool18
25398 *
25399 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
03f40088 25400 * +-----------+---------+-----+-------+-------+-------+-----------+
c233bf07 25401 * | SPECIAL2 | rb |x x x| XRd | XRa |0 0 0 0|MXU__POOL18|
03f40088
AM
25402 * +-----------+---------+-----+-------+-------+-------+-----------+
25403 *
25404 */
c233bf07 25405static void decode_opc_mxu__pool18(CPUMIPSState *env, DisasContext *ctx)
03f40088
AM
25406{
25407 uint32_t opcode = extract32(ctx->opcode, 18, 3);
25408
25409 switch (opcode) {
25410 case OPC_MXU_D32SLLV:
25411 /* TODO: Implement emulation of D32SLLV instruction. */
25412 MIPS_INVAL("OPC_MXU_D32SLLV");
25413 generate_exception_end(ctx, EXCP_RI);
25414 break;
25415 case OPC_MXU_D32SLRV:
25416 /* TODO: Implement emulation of D32SLRV instruction. */
25417 MIPS_INVAL("OPC_MXU_D32SLRV");
25418 generate_exception_end(ctx, EXCP_RI);
25419 break;
25420 case OPC_MXU_D32SARV:
25421 /* TODO: Implement emulation of D32SARV instruction. */
25422 MIPS_INVAL("OPC_MXU_D32SARV");
25423 generate_exception_end(ctx, EXCP_RI);
25424 break;
25425 case OPC_MXU_Q16SLLV:
25426 /* TODO: Implement emulation of Q16SLLV instruction. */
25427 MIPS_INVAL("OPC_MXU_Q16SLLV");
25428 generate_exception_end(ctx, EXCP_RI);
25429 break;
25430 case OPC_MXU_Q16SLRV:
25431 /* TODO: Implement emulation of Q16SLRV instruction. */
25432 MIPS_INVAL("OPC_MXU_Q16SLRV");
25433 generate_exception_end(ctx, EXCP_RI);
25434 break;
25435 case OPC_MXU_Q16SARV:
25436 /* TODO: Implement emulation of Q16SARV instruction. */
25437 MIPS_INVAL("OPC_MXU_Q16SARV");
25438 generate_exception_end(ctx, EXCP_RI);
25439 break;
25440 default:
25441 MIPS_INVAL("decode_opc_mxu");
25442 generate_exception_end(ctx, EXCP_RI);
25443 break;
25444 }
25445}
25446
25447/*
25448 *
c233bf07 25449 * Decode MXU pool19
03f40088
AM
25450 *
25451 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
25452 * +-----------+---+---+-------+-------+-------+-------+-----------+
c233bf07 25453 * | SPECIAL2 |0 0|x x| XRd | XRc | XRb | XRa |MXU__POOL19|
03f40088
AM
25454 * +-----------+---+---+-------+-------+-------+-------+-----------+
25455 *
25456 */
c233bf07 25457static void decode_opc_mxu__pool19(CPUMIPSState *env, DisasContext *ctx)
03f40088
AM
25458{
25459 uint32_t opcode = extract32(ctx->opcode, 22, 2);
25460
25461 switch (opcode) {
25462 case OPC_MXU_Q8MUL:
03f40088 25463 case OPC_MXU_Q8MULSU:
a9a4181b 25464 gen_mxu_q8mul_q8mulsu(ctx);
03f40088
AM
25465 break;
25466 default:
25467 MIPS_INVAL("decode_opc_mxu");
25468 generate_exception_end(ctx, EXCP_RI);
25469 break;
25470 }
25471}
25472
25473/*
25474 *
c233bf07 25475 * Decode MXU pool20
03f40088
AM
25476 *
25477 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
25478 * +-----------+---------+-----+-------+-------+-------+-----------+
c233bf07 25479 * | SPECIAL2 |0 0 0 0 0|x x x| XRc | XRb | XRa |MXU__POOL20|
03f40088
AM
25480 * +-----------+---------+-----+-------+-------+-------+-----------+
25481 *
25482 */
c233bf07 25483static void decode_opc_mxu__pool20(CPUMIPSState *env, DisasContext *ctx)
03f40088
AM
25484{
25485 uint32_t opcode = extract32(ctx->opcode, 18, 3);
25486
25487 switch (opcode) {
25488 case OPC_MXU_Q8MOVZ:
25489 /* TODO: Implement emulation of Q8MOVZ instruction. */
25490 MIPS_INVAL("OPC_MXU_Q8MOVZ");
25491 generate_exception_end(ctx, EXCP_RI);
25492 break;
25493 case OPC_MXU_Q8MOVN:
25494 /* TODO: Implement emulation of Q8MOVN instruction. */
25495 MIPS_INVAL("OPC_MXU_Q8MOVN");
25496 generate_exception_end(ctx, EXCP_RI);
25497 break;
25498 case OPC_MXU_D16MOVZ:
25499 /* TODO: Implement emulation of D16MOVZ instruction. */
25500 MIPS_INVAL("OPC_MXU_D16MOVZ");
25501 generate_exception_end(ctx, EXCP_RI);
25502 break;
25503 case OPC_MXU_D16MOVN:
25504 /* TODO: Implement emulation of D16MOVN instruction. */
25505 MIPS_INVAL("OPC_MXU_D16MOVN");
25506 generate_exception_end(ctx, EXCP_RI);
25507 break;
25508 case OPC_MXU_S32MOVZ:
25509 /* TODO: Implement emulation of S32MOVZ instruction. */
25510 MIPS_INVAL("OPC_MXU_S32MOVZ");
25511 generate_exception_end(ctx, EXCP_RI);
25512 break;
25513 case OPC_MXU_S32MOVN:
25514 /* TODO: Implement emulation of S32MOVN instruction. */
25515 MIPS_INVAL("OPC_MXU_S32MOVN");
25516 generate_exception_end(ctx, EXCP_RI);
25517 break;
25518 default:
25519 MIPS_INVAL("decode_opc_mxu");
25520 generate_exception_end(ctx, EXCP_RI);
25521 break;
25522 }
25523}
25524
25525/*
25526 *
c233bf07 25527 * Decode MXU pool21
03f40088
AM
25528 *
25529 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
25530 * +-----------+---+---+-------+-------+-------+-------+-----------+
c233bf07 25531 * | SPECIAL2 |an2|x x| XRd | XRc | XRb | XRa |MXU__POOL21|
03f40088
AM
25532 * +-----------+---+---+-------+-------+-------+-------+-----------+
25533 *
25534 */
c233bf07 25535static void decode_opc_mxu__pool21(CPUMIPSState *env, DisasContext *ctx)
03f40088
AM
25536{
25537 uint32_t opcode = extract32(ctx->opcode, 22, 2);
25538
25539 switch (opcode) {
25540 case OPC_MXU_Q8MAC:
25541 /* TODO: Implement emulation of Q8MAC instruction. */
25542 MIPS_INVAL("OPC_MXU_Q8MAC");
25543 generate_exception_end(ctx, EXCP_RI);
25544 break;
25545 case OPC_MXU_Q8MACSU:
25546 /* TODO: Implement emulation of Q8MACSU instruction. */
25547 MIPS_INVAL("OPC_MXU_Q8MACSU");
25548 generate_exception_end(ctx, EXCP_RI);
25549 break;
25550 default:
25551 MIPS_INVAL("decode_opc_mxu");
25552 generate_exception_end(ctx, EXCP_RI);
25553 break;
25554 }
25555}
25556
25557
25558/*
25559 * Main MXU decoding function
25560 *
25561 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
25562 * +-----------+---------------------------------------+-----------+
25563 * | SPECIAL2 | |x x x x x x|
25564 * +-----------+---------------------------------------+-----------+
25565 *
25566 */
0a348b9a
AM
25567static void decode_opc_mxu(CPUMIPSState *env, DisasContext *ctx)
25568{
11d56f61
CJ
25569 /*
25570 * TODO: Investigate necessity of including handling of
25571 * CLZ, CLO, SDBB in this function, as they belong to
25572 * SPECIAL2 opcode space for regular pre-R6 MIPS ISAs.
25573 */
03f40088
AM
25574 uint32_t opcode = extract32(ctx->opcode, 0, 6);
25575
87860df5
AM
25576 if (opcode == OPC__MXU_MUL) {
25577 uint32_t rs, rt, rd, op1;
25578
25579 rs = extract32(ctx->opcode, 21, 5);
25580 rt = extract32(ctx->opcode, 16, 5);
25581 rd = extract32(ctx->opcode, 11, 5);
25582 op1 = MASK_SPECIAL2(ctx->opcode);
25583
25584 gen_arith(ctx, op1, rd, rs, rt);
25585
25586 return;
25587 }
25588
25589 if (opcode == OPC_MXU_S32M2I) {
25590 gen_mxu_s32m2i(ctx);
25591 return;
25592 }
25593
25594 if (opcode == OPC_MXU_S32I2M) {
25595 gen_mxu_s32i2m(ctx);
25596 return;
25597 }
25598
e5bf8a08
AM
25599 {
25600 TCGv t_mxu_cr = tcg_temp_new();
25601 TCGLabel *l_exit = gen_new_label();
25602
25603 gen_load_mxu_cr(t_mxu_cr);
25604 tcg_gen_andi_tl(t_mxu_cr, t_mxu_cr, MXU_CR_MXU_EN);
25605 tcg_gen_brcondi_tl(TCG_COND_NE, t_mxu_cr, MXU_CR_MXU_EN, l_exit);
25606
25607 switch (opcode) {
25608 case OPC_MXU_S32MADD:
25609 /* TODO: Implement emulation of S32MADD instruction. */
25610 MIPS_INVAL("OPC_MXU_S32MADD");
25611 generate_exception_end(ctx, EXCP_RI);
25612 break;
25613 case OPC_MXU_S32MADDU:
25614 /* TODO: Implement emulation of S32MADDU instruction. */
25615 MIPS_INVAL("OPC_MXU_S32MADDU");
25616 generate_exception_end(ctx, EXCP_RI);
25617 break;
25618 case OPC_MXU__POOL00:
25619 decode_opc_mxu__pool00(env, ctx);
25620 break;
25621 case OPC_MXU_S32MSUB:
25622 /* TODO: Implement emulation of S32MSUB instruction. */
25623 MIPS_INVAL("OPC_MXU_S32MSUB");
25624 generate_exception_end(ctx, EXCP_RI);
25625 break;
25626 case OPC_MXU_S32MSUBU:
25627 /* TODO: Implement emulation of S32MSUBU instruction. */
25628 MIPS_INVAL("OPC_MXU_S32MSUBU");
25629 generate_exception_end(ctx, EXCP_RI);
25630 break;
25631 case OPC_MXU__POOL01:
25632 decode_opc_mxu__pool01(env, ctx);
25633 break;
25634 case OPC_MXU__POOL02:
25635 decode_opc_mxu__pool02(env, ctx);
25636 break;
25637 case OPC_MXU_D16MUL:
25638 gen_mxu_d16mul(ctx);
25639 break;
25640 case OPC_MXU__POOL03:
25641 decode_opc_mxu__pool03(env, ctx);
25642 break;
25643 case OPC_MXU_D16MAC:
25644 gen_mxu_d16mac(ctx);
25645 break;
25646 case OPC_MXU_D16MACF:
25647 /* TODO: Implement emulation of D16MACF instruction. */
25648 MIPS_INVAL("OPC_MXU_D16MACF");
25649 generate_exception_end(ctx, EXCP_RI);
25650 break;
25651 case OPC_MXU_D16MADL:
25652 /* TODO: Implement emulation of D16MADL instruction. */
25653 MIPS_INVAL("OPC_MXU_D16MADL");
25654 generate_exception_end(ctx, EXCP_RI);
25655 break;
25656 case OPC_MXU_S16MAD:
25657 /* TODO: Implement emulation of S16MAD instruction. */
25658 MIPS_INVAL("OPC_MXU_S16MAD");
25659 generate_exception_end(ctx, EXCP_RI);
25660 break;
25661 case OPC_MXU_Q16ADD:
25662 /* TODO: Implement emulation of Q16ADD instruction. */
25663 MIPS_INVAL("OPC_MXU_Q16ADD");
25664 generate_exception_end(ctx, EXCP_RI);
25665 break;
25666 case OPC_MXU_D16MACE:
25667 /* TODO: Implement emulation of D16MACE instruction. */
25668 MIPS_INVAL("OPC_MXU_D16MACE");
25669 generate_exception_end(ctx, EXCP_RI);
25670 break;
25671 case OPC_MXU__POOL04:
25672 decode_opc_mxu__pool04(env, ctx);
25673 break;
25674 case OPC_MXU__POOL05:
25675 decode_opc_mxu__pool05(env, ctx);
25676 break;
25677 case OPC_MXU__POOL06:
25678 decode_opc_mxu__pool06(env, ctx);
25679 break;
25680 case OPC_MXU__POOL07:
25681 decode_opc_mxu__pool07(env, ctx);
25682 break;
25683 case OPC_MXU__POOL08:
25684 decode_opc_mxu__pool08(env, ctx);
25685 break;
25686 case OPC_MXU__POOL09:
25687 decode_opc_mxu__pool09(env, ctx);
25688 break;
25689 case OPC_MXU__POOL10:
25690 decode_opc_mxu__pool10(env, ctx);
25691 break;
25692 case OPC_MXU__POOL11:
25693 decode_opc_mxu__pool11(env, ctx);
25694 break;
25695 case OPC_MXU_D32ADD:
25696 /* TODO: Implement emulation of D32ADD instruction. */
25697 MIPS_INVAL("OPC_MXU_D32ADD");
25698 generate_exception_end(ctx, EXCP_RI);
25699 break;
25700 case OPC_MXU__POOL12:
25701 decode_opc_mxu__pool12(env, ctx);
25702 break;
25703 case OPC_MXU__POOL13:
25704 decode_opc_mxu__pool13(env, ctx);
25705 break;
25706 case OPC_MXU__POOL14:
25707 decode_opc_mxu__pool14(env, ctx);
25708 break;
25709 case OPC_MXU_Q8ACCE:
25710 /* TODO: Implement emulation of Q8ACCE instruction. */
25711 MIPS_INVAL("OPC_MXU_Q8ACCE");
25712 generate_exception_end(ctx, EXCP_RI);
25713 break;
25714 case OPC_MXU_S8LDD:
25715 gen_mxu_s8ldd(ctx);
25716 break;
25717 case OPC_MXU_S8STD:
25718 /* TODO: Implement emulation of S8STD instruction. */
25719 MIPS_INVAL("OPC_MXU_S8STD");
25720 generate_exception_end(ctx, EXCP_RI);
25721 break;
25722 case OPC_MXU_S8LDI:
25723 /* TODO: Implement emulation of S8LDI instruction. */
25724 MIPS_INVAL("OPC_MXU_S8LDI");
25725 generate_exception_end(ctx, EXCP_RI);
25726 break;
25727 case OPC_MXU_S8SDI:
25728 /* TODO: Implement emulation of S8SDI instruction. */
25729 MIPS_INVAL("OPC_MXU_S8SDI");
25730 generate_exception_end(ctx, EXCP_RI);
25731 break;
25732 case OPC_MXU__POOL15:
25733 decode_opc_mxu__pool15(env, ctx);
25734 break;
25735 case OPC_MXU__POOL16:
25736 decode_opc_mxu__pool16(env, ctx);
25737 break;
c233bf07
AM
25738 case OPC_MXU__POOL17:
25739 decode_opc_mxu__pool17(env, ctx);
e5bf8a08
AM
25740 break;
25741 case OPC_MXU_S16LDD:
25742 /* TODO: Implement emulation of S16LDD instruction. */
25743 MIPS_INVAL("OPC_MXU_S16LDD");
25744 generate_exception_end(ctx, EXCP_RI);
25745 break;
25746 case OPC_MXU_S16STD:
25747 /* TODO: Implement emulation of S16STD instruction. */
25748 MIPS_INVAL("OPC_MXU_S16STD");
25749 generate_exception_end(ctx, EXCP_RI);
25750 break;
25751 case OPC_MXU_S16LDI:
25752 /* TODO: Implement emulation of S16LDI instruction. */
25753 MIPS_INVAL("OPC_MXU_S16LDI");
25754 generate_exception_end(ctx, EXCP_RI);
25755 break;
25756 case OPC_MXU_S16SDI:
25757 /* TODO: Implement emulation of S16SDI instruction. */
25758 MIPS_INVAL("OPC_MXU_S16SDI");
25759 generate_exception_end(ctx, EXCP_RI);
25760 break;
25761 case OPC_MXU_D32SLL:
25762 /* TODO: Implement emulation of D32SLL instruction. */
25763 MIPS_INVAL("OPC_MXU_D32SLL");
25764 generate_exception_end(ctx, EXCP_RI);
25765 break;
25766 case OPC_MXU_D32SLR:
25767 /* TODO: Implement emulation of D32SLR instruction. */
25768 MIPS_INVAL("OPC_MXU_D32SLR");
25769 generate_exception_end(ctx, EXCP_RI);
25770 break;
25771 case OPC_MXU_D32SARL:
25772 /* TODO: Implement emulation of D32SARL instruction. */
25773 MIPS_INVAL("OPC_MXU_D32SARL");
25774 generate_exception_end(ctx, EXCP_RI);
25775 break;
25776 case OPC_MXU_D32SAR:
25777 /* TODO: Implement emulation of D32SAR instruction. */
25778 MIPS_INVAL("OPC_MXU_D32SAR");
25779 generate_exception_end(ctx, EXCP_RI);
25780 break;
25781 case OPC_MXU_Q16SLL:
25782 /* TODO: Implement emulation of Q16SLL instruction. */
25783 MIPS_INVAL("OPC_MXU_Q16SLL");
25784 generate_exception_end(ctx, EXCP_RI);
25785 break;
25786 case OPC_MXU_Q16SLR:
25787 /* TODO: Implement emulation of Q16SLR instruction. */
25788 MIPS_INVAL("OPC_MXU_Q16SLR");
25789 generate_exception_end(ctx, EXCP_RI);
25790 break;
c233bf07
AM
25791 case OPC_MXU__POOL18:
25792 decode_opc_mxu__pool18(env, ctx);
e5bf8a08
AM
25793 break;
25794 case OPC_MXU_Q16SAR:
25795 /* TODO: Implement emulation of Q16SAR instruction. */
25796 MIPS_INVAL("OPC_MXU_Q16SAR");
25797 generate_exception_end(ctx, EXCP_RI);
25798 break;
e5bf8a08
AM
25799 case OPC_MXU__POOL19:
25800 decode_opc_mxu__pool19(env, ctx);
25801 break;
25802 case OPC_MXU__POOL20:
25803 decode_opc_mxu__pool20(env, ctx);
25804 break;
c233bf07
AM
25805 case OPC_MXU__POOL21:
25806 decode_opc_mxu__pool21(env, ctx);
25807 break;
e5bf8a08
AM
25808 case OPC_MXU_Q16SCOP:
25809 /* TODO: Implement emulation of Q16SCOP instruction. */
25810 MIPS_INVAL("OPC_MXU_Q16SCOP");
25811 generate_exception_end(ctx, EXCP_RI);
25812 break;
25813 case OPC_MXU_Q8MADL:
25814 /* TODO: Implement emulation of Q8MADL instruction. */
25815 MIPS_INVAL("OPC_MXU_Q8MADL");
25816 generate_exception_end(ctx, EXCP_RI);
25817 break;
25818 case OPC_MXU_S32SFL:
25819 /* TODO: Implement emulation of S32SFL instruction. */
25820 MIPS_INVAL("OPC_MXU_S32SFL");
25821 generate_exception_end(ctx, EXCP_RI);
25822 break;
25823 case OPC_MXU_Q8SAD:
25824 /* TODO: Implement emulation of Q8SAD instruction. */
25825 MIPS_INVAL("OPC_MXU_Q8SAD");
25826 generate_exception_end(ctx, EXCP_RI);
25827 break;
25828 default:
25829 MIPS_INVAL("decode_opc_mxu");
25830 generate_exception_end(ctx, EXCP_RI);
25831 }
25832
25833 gen_set_label(l_exit);
25834 tcg_temp_free(t_mxu_cr);
03f40088 25835 }
0a348b9a
AM
25836}
25837
03f40088 25838
10dc65db 25839static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx)
099e5b4d
LA
25840{
25841 int rs, rt, rd;
25842 uint32_t op1;
6c5c1e20 25843
4267d3e6
LA
25844 check_insn_opc_removed(ctx, ISA_MIPS32R6);
25845
099e5b4d
LA
25846 rs = (ctx->opcode >> 21) & 0x1f;
25847 rt = (ctx->opcode >> 16) & 0x1f;
25848 rd = (ctx->opcode >> 11) & 0x1f;
25849
25850 op1 = MASK_SPECIAL2(ctx->opcode);
25851 switch (op1) {
c2e19f3c
AM
25852 case OPC_MADD: /* Multiply and add/sub */
25853 case OPC_MADDU:
25854 case OPC_MSUB:
25855 case OPC_MSUBU:
099e5b4d
LA
25856 check_insn(ctx, ISA_MIPS32);
25857 gen_muldiv(ctx, op1, rd & 3, rs, rt);
25858 break;
25859 case OPC_MUL:
099e5b4d
LA
25860 gen_arith(ctx, op1, rd, rs, rt);
25861 break;
fac5a073
LA
25862 case OPC_DIV_G_2F:
25863 case OPC_DIVU_G_2F:
25864 case OPC_MULT_G_2F:
25865 case OPC_MULTU_G_2F:
25866 case OPC_MOD_G_2F:
25867 case OPC_MODU_G_2F:
25868 check_insn(ctx, INSN_LOONGSON2F);
25869 gen_loongson_integer(ctx, op1, rd, rs, rt);
25870 break;
099e5b4d
LA
25871 case OPC_CLO:
25872 case OPC_CLZ:
25873 check_insn(ctx, ISA_MIPS32);
25874 gen_cl(ctx, op1, rd, rs);
25875 break;
25876 case OPC_SDBBP:
3b3c1694
LA
25877 if (is_uhi(extract32(ctx->opcode, 6, 20))) {
25878 gen_helper_do_semihosting(cpu_env);
25879 } else {
25880 /* XXX: not clear which exception should be raised
25881 * when in debug mode...
25882 */
25883 check_insn(ctx, ISA_MIPS32);
9c708c7f 25884 generate_exception_end(ctx, EXCP_DBp);
3b3c1694 25885 }
099e5b4d 25886 break;
9b1a1d68 25887#if defined(TARGET_MIPS64)
099e5b4d
LA
25888 case OPC_DCLO:
25889 case OPC_DCLZ:
25890 check_insn(ctx, ISA_MIPS64);
25891 check_mips_64(ctx);
25892 gen_cl(ctx, op1, rd, rs);
25893 break;
4267d3e6
LA
25894 case OPC_DMULT_G_2F:
25895 case OPC_DMULTU_G_2F:
25896 case OPC_DDIV_G_2F:
25897 case OPC_DDIVU_G_2F:
25898 case OPC_DMOD_G_2F:
25899 case OPC_DMODU_G_2F:
25900 check_insn(ctx, INSN_LOONGSON2F);
25901 gen_loongson_integer(ctx, op1, rd, rs, rt);
25902 break;
10dc65db 25903#endif
4267d3e6
LA
25904 default: /* Invalid */
25905 MIPS_INVAL("special2_legacy");
9c708c7f 25906 generate_exception_end(ctx, EXCP_RI);
4267d3e6 25907 break;
10dc65db
LA
25908 }
25909}
25910
25911static void decode_opc_special3_r6(CPUMIPSState *env, DisasContext *ctx)
25912{
15eacb9b
YK
25913 int rs, rt, rd, sa;
25914 uint32_t op1, op2;
10dc65db
LA
25915 int16_t imm;
25916
25917 rs = (ctx->opcode >> 21) & 0x1f;
25918 rt = (ctx->opcode >> 16) & 0x1f;
15eacb9b
YK
25919 rd = (ctx->opcode >> 11) & 0x1f;
25920 sa = (ctx->opcode >> 6) & 0x1f;
10dc65db
LA
25921 imm = (int16_t)ctx->opcode >> 7;
25922
25923 op1 = MASK_SPECIAL3(ctx->opcode);
25924 switch (op1) {
bf7910c6
LA
25925 case R6_OPC_PREF:
25926 if (rt >= 24) {
25927 /* hint codes 24-31 are reserved and signal RI */
9c708c7f 25928 generate_exception_end(ctx, EXCP_RI);
bf7910c6
LA
25929 }
25930 /* Treat as NOP. */
25931 break;
25932 case R6_OPC_CACHE:
40d48212 25933 check_cp0_enabled(ctx);
0d74a222
LA
25934 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
25935 gen_cache_operation(ctx, rt, rs, imm);
25936 }
bf7910c6 25937 break;
10dc65db
LA
25938 case R6_OPC_SC:
25939 gen_st_cond(ctx, op1, rt, rs, imm);
25940 break;
25941 case R6_OPC_LL:
25942 gen_ld(ctx, op1, rt, rs, imm);
25943 break;
15eacb9b
YK
25944 case OPC_BSHFL:
25945 {
25946 if (rd == 0) {
25947 /* Treat as NOP. */
25948 break;
25949 }
15eacb9b
YK
25950 op2 = MASK_BSHFL(ctx->opcode);
25951 switch (op2) {
c2e19f3c 25952 case OPC_ALIGN:
373ecd38
AM
25953 case OPC_ALIGN_1:
25954 case OPC_ALIGN_2:
25955 case OPC_ALIGN_3:
821f2008 25956 gen_align(ctx, 32, rd, rs, rt, sa & 3);
15eacb9b
YK
25957 break;
25958 case OPC_BITSWAP:
1f1b4c00 25959 gen_bitswap(ctx, op2, rd, rt);
15eacb9b
YK
25960 break;
25961 }
15eacb9b
YK
25962 }
25963 break;
bf7910c6
LA
25964#if defined(TARGET_MIPS64)
25965 case R6_OPC_SCD:
25966 gen_st_cond(ctx, op1, rt, rs, imm);
25967 break;
25968 case R6_OPC_LLD:
25969 gen_ld(ctx, op1, rt, rs, imm);
25970 break;
15eacb9b
YK
25971 case OPC_DBSHFL:
25972 check_mips_64(ctx);
25973 {
25974 if (rd == 0) {
25975 /* Treat as NOP. */
25976 break;
25977 }
15eacb9b
YK
25978 op2 = MASK_DBSHFL(ctx->opcode);
25979 switch (op2) {
c2e19f3c 25980 case OPC_DALIGN:
373ecd38
AM
25981 case OPC_DALIGN_1:
25982 case OPC_DALIGN_2:
25983 case OPC_DALIGN_3:
25984 case OPC_DALIGN_4:
25985 case OPC_DALIGN_5:
25986 case OPC_DALIGN_6:
25987 case OPC_DALIGN_7:
821f2008 25988 gen_align(ctx, 64, rd, rs, rt, sa & 7);
15eacb9b
YK
25989 break;
25990 case OPC_DBITSWAP:
1f1b4c00 25991 gen_bitswap(ctx, op2, rd, rt);
15eacb9b
YK
25992 break;
25993 }
1f1b4c00 25994
15eacb9b
YK
25995 }
25996 break;
bf7910c6 25997#endif
10dc65db
LA
25998 default: /* Invalid */
25999 MIPS_INVAL("special3_r6");
9c708c7f 26000 generate_exception_end(ctx, EXCP_RI);
10dc65db
LA
26001 break;
26002 }
26003}
26004
26005static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx)
26006{
fac5a073 26007 int rs, rt, rd;
099e5b4d 26008 uint32_t op1, op2;
099e5b4d
LA
26009
26010 rs = (ctx->opcode >> 21) & 0x1f;
26011 rt = (ctx->opcode >> 16) & 0x1f;
26012 rd = (ctx->opcode >> 11) & 0x1f;
099e5b4d
LA
26013
26014 op1 = MASK_SPECIAL3(ctx->opcode);
26015 switch (op1) {
c2e19f3c
AM
26016 case OPC_DIV_G_2E:
26017 case OPC_DIVU_G_2E:
26018 case OPC_MOD_G_2E:
26019 case OPC_MODU_G_2E:
26020 case OPC_MULT_G_2E:
26021 case OPC_MULTU_G_2E:
099e5b4d
LA
26022 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
26023 * the same mask and op1. */
908f6be1 26024 if ((ctx->insn_flags & ASE_DSP_R2) && (op1 == OPC_MULT_G_2E)) {
099e5b4d 26025 op2 = MASK_ADDUH_QB(ctx->opcode);
461c08df 26026 switch (op2) {
099e5b4d
LA
26027 case OPC_ADDUH_QB:
26028 case OPC_ADDUH_R_QB:
26029 case OPC_ADDQH_PH:
26030 case OPC_ADDQH_R_PH:
26031 case OPC_ADDQH_W:
26032 case OPC_ADDQH_R_W:
26033 case OPC_SUBUH_QB:
26034 case OPC_SUBUH_R_QB:
26035 case OPC_SUBQH_PH:
26036 case OPC_SUBQH_R_PH:
26037 case OPC_SUBQH_W:
26038 case OPC_SUBQH_R_W:
461c08df
JL
26039 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
26040 break;
099e5b4d
LA
26041 case OPC_MUL_PH:
26042 case OPC_MUL_S_PH:
26043 case OPC_MULQ_S_W:
26044 case OPC_MULQ_RS_W:
26045 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
1cb6686c 26046 break;
461c08df 26047 default:
099e5b4d 26048 MIPS_INVAL("MASK ADDUH.QB");
9c708c7f 26049 generate_exception_end(ctx, EXCP_RI);
461c08df
JL
26050 break;
26051 }
099e5b4d
LA
26052 } else if (ctx->insn_flags & INSN_LOONGSON2E) {
26053 gen_loongson_integer(ctx, op1, rd, rs, rt);
26054 } else {
9c708c7f 26055 generate_exception_end(ctx, EXCP_RI);
099e5b4d
LA
26056 }
26057 break;
26058 case OPC_LX_DSP:
26059 op2 = MASK_LX(ctx->opcode);
26060 switch (op2) {
26061#if defined(TARGET_MIPS64)
26062 case OPC_LDX:
26063#endif
26064 case OPC_LBUX:
26065 case OPC_LHX:
26066 case OPC_LWX:
26067 gen_mipsdsp_ld(ctx, op2, rd, rs, rt);
26068 break;
26069 default: /* Invalid */
26070 MIPS_INVAL("MASK LX");
9c708c7f 26071 generate_exception_end(ctx, EXCP_RI);
099e5b4d
LA
26072 break;
26073 }
26074 break;
26075 case OPC_ABSQ_S_PH_DSP:
26076 op2 = MASK_ABSQ_S_PH(ctx->opcode);
26077 switch (op2) {
26078 case OPC_ABSQ_S_QB:
26079 case OPC_ABSQ_S_PH:
26080 case OPC_ABSQ_S_W:
26081 case OPC_PRECEQ_W_PHL:
26082 case OPC_PRECEQ_W_PHR:
26083 case OPC_PRECEQU_PH_QBL:
26084 case OPC_PRECEQU_PH_QBR:
26085 case OPC_PRECEQU_PH_QBLA:
26086 case OPC_PRECEQU_PH_QBRA:
26087 case OPC_PRECEU_PH_QBL:
26088 case OPC_PRECEU_PH_QBR:
26089 case OPC_PRECEU_PH_QBLA:
26090 case OPC_PRECEU_PH_QBRA:
26091 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
26092 break;
26093 case OPC_BITREV:
26094 case OPC_REPL_QB:
26095 case OPC_REPLV_QB:
26096 case OPC_REPL_PH:
26097 case OPC_REPLV_PH:
26098 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
26099 break;
26100 default:
26101 MIPS_INVAL("MASK ABSQ_S.PH");
9c708c7f 26102 generate_exception_end(ctx, EXCP_RI);
099e5b4d
LA
26103 break;
26104 }
26105 break;
26106 case OPC_ADDU_QB_DSP:
26107 op2 = MASK_ADDU_QB(ctx->opcode);
26108 switch (op2) {
26109 case OPC_ADDQ_PH:
26110 case OPC_ADDQ_S_PH:
26111 case OPC_ADDQ_S_W:
26112 case OPC_ADDU_QB:
26113 case OPC_ADDU_S_QB:
26114 case OPC_ADDU_PH:
26115 case OPC_ADDU_S_PH:
26116 case OPC_SUBQ_PH:
26117 case OPC_SUBQ_S_PH:
26118 case OPC_SUBQ_S_W:
26119 case OPC_SUBU_QB:
26120 case OPC_SUBU_S_QB:
26121 case OPC_SUBU_PH:
26122 case OPC_SUBU_S_PH:
26123 case OPC_ADDSC:
26124 case OPC_ADDWC:
26125 case OPC_MODSUB:
26126 case OPC_RADDU_W_QB:
26127 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
26128 break;
26129 case OPC_MULEU_S_PH_QBL:
26130 case OPC_MULEU_S_PH_QBR:
26131 case OPC_MULQ_RS_PH:
26132 case OPC_MULEQ_S_W_PHL:
26133 case OPC_MULEQ_S_W_PHR:
26134 case OPC_MULQ_S_PH:
26135 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
26136 break;
26137 default: /* Invalid */
26138 MIPS_INVAL("MASK ADDU.QB");
9c708c7f 26139 generate_exception_end(ctx, EXCP_RI);
461c08df 26140 break;
461c08df 26141
099e5b4d
LA
26142 }
26143 break;
26144 case OPC_CMPU_EQ_QB_DSP:
26145 op2 = MASK_CMPU_EQ_QB(ctx->opcode);
26146 switch (op2) {
26147 case OPC_PRECR_SRA_PH_W:
26148 case OPC_PRECR_SRA_R_PH_W:
26149 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
461c08df 26150 break;
099e5b4d
LA
26151 case OPC_PRECR_QB_PH:
26152 case OPC_PRECRQ_QB_PH:
26153 case OPC_PRECRQ_PH_W:
26154 case OPC_PRECRQ_RS_PH_W:
26155 case OPC_PRECRQU_S_QB_PH:
26156 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
461c08df 26157 break;
099e5b4d
LA
26158 case OPC_CMPU_EQ_QB:
26159 case OPC_CMPU_LT_QB:
26160 case OPC_CMPU_LE_QB:
26161 case OPC_CMP_EQ_PH:
26162 case OPC_CMP_LT_PH:
26163 case OPC_CMP_LE_PH:
26164 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
77c5fa8b 26165 break;
099e5b4d
LA
26166 case OPC_CMPGU_EQ_QB:
26167 case OPC_CMPGU_LT_QB:
26168 case OPC_CMPGU_LE_QB:
26169 case OPC_CMPGDU_EQ_QB:
26170 case OPC_CMPGDU_LT_QB:
26171 case OPC_CMPGDU_LE_QB:
26172 case OPC_PICK_QB:
26173 case OPC_PICK_PH:
26174 case OPC_PACKRL_PH:
26175 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
26176 break;
26177 default: /* Invalid */
26178 MIPS_INVAL("MASK CMPU.EQ.QB");
9c708c7f 26179 generate_exception_end(ctx, EXCP_RI);
099e5b4d
LA
26180 break;
26181 }
26182 break;
26183 case OPC_SHLL_QB_DSP:
26184 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
26185 break;
26186 case OPC_DPA_W_PH_DSP:
26187 op2 = MASK_DPA_W_PH(ctx->opcode);
26188 switch (op2) {
26189 case OPC_DPAU_H_QBL:
26190 case OPC_DPAU_H_QBR:
26191 case OPC_DPSU_H_QBL:
26192 case OPC_DPSU_H_QBR:
26193 case OPC_DPA_W_PH:
26194 case OPC_DPAX_W_PH:
26195 case OPC_DPAQ_S_W_PH:
26196 case OPC_DPAQX_S_W_PH:
26197 case OPC_DPAQX_SA_W_PH:
26198 case OPC_DPS_W_PH:
26199 case OPC_DPSX_W_PH:
26200 case OPC_DPSQ_S_W_PH:
26201 case OPC_DPSQX_S_W_PH:
26202 case OPC_DPSQX_SA_W_PH:
26203 case OPC_MULSAQ_S_W_PH:
26204 case OPC_DPAQ_SA_L_W:
26205 case OPC_DPSQ_SA_L_W:
26206 case OPC_MAQ_S_W_PHL:
26207 case OPC_MAQ_S_W_PHR:
26208 case OPC_MAQ_SA_W_PHL:
26209 case OPC_MAQ_SA_W_PHR:
26210 case OPC_MULSA_W_PH:
26211 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
26212 break;
26213 default: /* Invalid */
26214 MIPS_INVAL("MASK DPAW.PH");
9c708c7f 26215 generate_exception_end(ctx, EXCP_RI);
099e5b4d
LA
26216 break;
26217 }
26218 break;
26219 case OPC_INSV_DSP:
26220 op2 = MASK_INSV(ctx->opcode);
26221 switch (op2) {
26222 case OPC_INSV:
26223 check_dsp(ctx);
26224 {
26225 TCGv t0, t1;
26226
26227 if (rt == 0) {
099e5b4d
LA
26228 break;
26229 }
26230
26231 t0 = tcg_temp_new();
26232 t1 = tcg_temp_new();
26233
26234 gen_load_gpr(t0, rt);
26235 gen_load_gpr(t1, rs);
26236
26237 gen_helper_insv(cpu_gpr[rt], cpu_env, t1, t0);
26238
26239 tcg_temp_free(t0);
26240 tcg_temp_free(t1);
a22260ae
JL
26241 break;
26242 }
099e5b4d
LA
26243 default: /* Invalid */
26244 MIPS_INVAL("MASK INSV");
9c708c7f 26245 generate_exception_end(ctx, EXCP_RI);
099e5b4d
LA
26246 break;
26247 }
26248 break;
26249 case OPC_APPEND_DSP:
26250 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
26251 break;
26252 case OPC_EXTR_W_DSP:
26253 op2 = MASK_EXTR_W(ctx->opcode);
26254 switch (op2) {
26255 case OPC_EXTR_W:
26256 case OPC_EXTR_R_W:
26257 case OPC_EXTR_RS_W:
26258 case OPC_EXTR_S_H:
26259 case OPC_EXTRV_S_H:
26260 case OPC_EXTRV_W:
26261 case OPC_EXTRV_R_W:
26262 case OPC_EXTRV_RS_W:
26263 case OPC_EXTP:
26264 case OPC_EXTPV:
26265 case OPC_EXTPDP:
26266 case OPC_EXTPDPV:
26267 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
26268 break;
26269 case OPC_RDDSP:
26270 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 1);
26271 break;
26272 case OPC_SHILO:
26273 case OPC_SHILOV:
26274 case OPC_MTHLIP:
26275 case OPC_WRDSP:
26276 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
26277 break;
26278 default: /* Invalid */
26279 MIPS_INVAL("MASK EXTR.W");
9c708c7f 26280 generate_exception_end(ctx, EXCP_RI);
099e5b4d
LA
26281 break;
26282 }
26283 break;
099e5b4d 26284#if defined(TARGET_MIPS64)
c2e19f3c
AM
26285 case OPC_DDIV_G_2E:
26286 case OPC_DDIVU_G_2E:
26287 case OPC_DMULT_G_2E:
26288 case OPC_DMULTU_G_2E:
26289 case OPC_DMOD_G_2E:
26290 case OPC_DMODU_G_2E:
fac5a073
LA
26291 check_insn(ctx, INSN_LOONGSON2E);
26292 gen_loongson_integer(ctx, op1, rd, rs, rt);
099e5b4d 26293 break;
099e5b4d
LA
26294 case OPC_ABSQ_S_QH_DSP:
26295 op2 = MASK_ABSQ_S_QH(ctx->opcode);
26296 switch (op2) {
26297 case OPC_PRECEQ_L_PWL:
26298 case OPC_PRECEQ_L_PWR:
26299 case OPC_PRECEQ_PW_QHL:
26300 case OPC_PRECEQ_PW_QHR:
26301 case OPC_PRECEQ_PW_QHLA:
26302 case OPC_PRECEQ_PW_QHRA:
26303 case OPC_PRECEQU_QH_OBL:
26304 case OPC_PRECEQU_QH_OBR:
26305 case OPC_PRECEQU_QH_OBLA:
26306 case OPC_PRECEQU_QH_OBRA:
26307 case OPC_PRECEU_QH_OBL:
26308 case OPC_PRECEU_QH_OBR:
26309 case OPC_PRECEU_QH_OBLA:
26310 case OPC_PRECEU_QH_OBRA:
26311 case OPC_ABSQ_S_OB:
26312 case OPC_ABSQ_S_PW:
26313 case OPC_ABSQ_S_QH:
26314 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
26315 break;
26316 case OPC_REPL_OB:
26317 case OPC_REPL_PW:
26318 case OPC_REPL_QH:
26319 case OPC_REPLV_OB:
26320 case OPC_REPLV_PW:
26321 case OPC_REPLV_QH:
26322 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
26323 break;
26324 default: /* Invalid */
26325 MIPS_INVAL("MASK ABSQ_S.QH");
9c708c7f 26326 generate_exception_end(ctx, EXCP_RI);
099e5b4d
LA
26327 break;
26328 }
26329 break;
26330 case OPC_ADDU_OB_DSP:
26331 op2 = MASK_ADDU_OB(ctx->opcode);
26332 switch (op2) {
26333 case OPC_RADDU_L_OB:
26334 case OPC_SUBQ_PW:
26335 case OPC_SUBQ_S_PW:
26336 case OPC_SUBQ_QH:
26337 case OPC_SUBQ_S_QH:
26338 case OPC_SUBU_OB:
26339 case OPC_SUBU_S_OB:
26340 case OPC_SUBU_QH:
26341 case OPC_SUBU_S_QH:
26342 case OPC_SUBUH_OB:
26343 case OPC_SUBUH_R_OB:
26344 case OPC_ADDQ_PW:
26345 case OPC_ADDQ_S_PW:
26346 case OPC_ADDQ_QH:
26347 case OPC_ADDQ_S_QH:
26348 case OPC_ADDU_OB:
26349 case OPC_ADDU_S_OB:
26350 case OPC_ADDU_QH:
26351 case OPC_ADDU_S_QH:
26352 case OPC_ADDUH_OB:
26353 case OPC_ADDUH_R_OB:
26354 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
a22260ae 26355 break;
099e5b4d
LA
26356 case OPC_MULEQ_S_PW_QHL:
26357 case OPC_MULEQ_S_PW_QHR:
26358 case OPC_MULEU_S_QH_OBL:
26359 case OPC_MULEU_S_QH_OBR:
26360 case OPC_MULQ_RS_QH:
26361 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
1cb6686c 26362 break;
099e5b4d
LA
26363 default: /* Invalid */
26364 MIPS_INVAL("MASK ADDU.OB");
9c708c7f 26365 generate_exception_end(ctx, EXCP_RI);
26690560 26366 break;
099e5b4d
LA
26367 }
26368 break;
26369 case OPC_CMPU_EQ_OB_DSP:
26370 op2 = MASK_CMPU_EQ_OB(ctx->opcode);
26371 switch (op2) {
26372 case OPC_PRECR_SRA_QH_PW:
26373 case OPC_PRECR_SRA_R_QH_PW:
26374 /* Return value is rt. */
26375 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
b53371ed 26376 break;
099e5b4d
LA
26377 case OPC_PRECR_OB_QH:
26378 case OPC_PRECRQ_OB_QH:
26379 case OPC_PRECRQ_PW_L:
26380 case OPC_PRECRQ_QH_PW:
26381 case OPC_PRECRQ_RS_QH_PW:
26382 case OPC_PRECRQU_S_OB_QH:
26383 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
4368b29a 26384 break;
099e5b4d
LA
26385 case OPC_CMPU_EQ_OB:
26386 case OPC_CMPU_LT_OB:
26387 case OPC_CMPU_LE_OB:
26388 case OPC_CMP_EQ_QH:
26389 case OPC_CMP_LT_QH:
26390 case OPC_CMP_LE_QH:
26391 case OPC_CMP_EQ_PW:
26392 case OPC_CMP_LT_PW:
26393 case OPC_CMP_LE_PW:
26394 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
7a387fff 26395 break;
099e5b4d
LA
26396 case OPC_CMPGDU_EQ_OB:
26397 case OPC_CMPGDU_LT_OB:
26398 case OPC_CMPGDU_LE_OB:
26399 case OPC_CMPGU_EQ_OB:
26400 case OPC_CMPGU_LT_OB:
26401 case OPC_CMPGU_LE_OB:
26402 case OPC_PACKRL_PW:
26403 case OPC_PICK_OB:
26404 case OPC_PICK_PW:
26405 case OPC_PICK_QH:
26406 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
c6d6dd7c 26407 break;
099e5b4d
LA
26408 default: /* Invalid */
26409 MIPS_INVAL("MASK CMPU_EQ.OB");
9c708c7f 26410 generate_exception_end(ctx, EXCP_RI);
161f85e6 26411 break;
099e5b4d
LA
26412 }
26413 break;
26414 case OPC_DAPPEND_DSP:
26415 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
26416 break;
26417 case OPC_DEXTR_W_DSP:
26418 op2 = MASK_DEXTR_W(ctx->opcode);
26419 switch (op2) {
26420 case OPC_DEXTP:
26421 case OPC_DEXTPDP:
26422 case OPC_DEXTPDPV:
26423 case OPC_DEXTPV:
26424 case OPC_DEXTR_L:
26425 case OPC_DEXTR_R_L:
26426 case OPC_DEXTR_RS_L:
26427 case OPC_DEXTR_W:
26428 case OPC_DEXTR_R_W:
26429 case OPC_DEXTR_RS_W:
26430 case OPC_DEXTR_S_H:
26431 case OPC_DEXTRV_L:
26432 case OPC_DEXTRV_R_L:
26433 case OPC_DEXTRV_RS_L:
26434 case OPC_DEXTRV_S_H:
26435 case OPC_DEXTRV_W:
26436 case OPC_DEXTRV_R_W:
26437 case OPC_DEXTRV_RS_W:
26438 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
461c08df 26439 break;
099e5b4d
LA
26440 case OPC_DMTHLIP:
26441 case OPC_DSHILO:
26442 case OPC_DSHILOV:
26443 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
461c08df 26444 break;
099e5b4d
LA
26445 default: /* Invalid */
26446 MIPS_INVAL("MASK EXTR.W");
9c708c7f 26447 generate_exception_end(ctx, EXCP_RI);
461c08df 26448 break;
099e5b4d
LA
26449 }
26450 break;
26451 case OPC_DPAQ_W_QH_DSP:
26452 op2 = MASK_DPAQ_W_QH(ctx->opcode);
26453 switch (op2) {
26454 case OPC_DPAU_H_OBL:
26455 case OPC_DPAU_H_OBR:
26456 case OPC_DPSU_H_OBL:
26457 case OPC_DPSU_H_OBR:
26458 case OPC_DPA_W_QH:
26459 case OPC_DPAQ_S_W_QH:
26460 case OPC_DPS_W_QH:
26461 case OPC_DPSQ_S_W_QH:
26462 case OPC_MULSAQ_S_W_QH:
26463 case OPC_DPAQ_SA_L_PW:
26464 case OPC_DPSQ_SA_L_PW:
26465 case OPC_MULSAQ_S_L_PW:
26466 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
26467 break;
26468 case OPC_MAQ_S_W_QHLL:
26469 case OPC_MAQ_S_W_QHLR:
26470 case OPC_MAQ_S_W_QHRL:
26471 case OPC_MAQ_S_W_QHRR:
26472 case OPC_MAQ_SA_W_QHLL:
26473 case OPC_MAQ_SA_W_QHLR:
26474 case OPC_MAQ_SA_W_QHRL:
26475 case OPC_MAQ_SA_W_QHRR:
26476 case OPC_MAQ_S_L_PWL:
26477 case OPC_MAQ_S_L_PWR:
26478 case OPC_DMADD:
26479 case OPC_DMADDU:
26480 case OPC_DMSUB:
26481 case OPC_DMSUBU:
26482 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
26690560 26483 break;
099e5b4d
LA
26484 default: /* Invalid */
26485 MIPS_INVAL("MASK DPAQ.W.QH");
9c708c7f 26486 generate_exception_end(ctx, EXCP_RI);
b53371ed 26487 break;
099e5b4d
LA
26488 }
26489 break;
26490 case OPC_DINSV_DSP:
26491 op2 = MASK_INSV(ctx->opcode);
26492 switch (op2) {
26493 case OPC_DINSV:
26494 {
26495 TCGv t0, t1;
26496
26497 if (rt == 0) {
a22260ae
JL
26498 break;
26499 }
099e5b4d 26500 check_dsp(ctx);
1cb6686c 26501
099e5b4d
LA
26502 t0 = tcg_temp_new();
26503 t1 = tcg_temp_new();
1cb6686c 26504
099e5b4d
LA
26505 gen_load_gpr(t0, rt);
26506 gen_load_gpr(t1, rs);
1cb6686c 26507
099e5b4d 26508 gen_helper_dinsv(cpu_gpr[rt], cpu_env, t1, t0);
62eb3b9a 26509
099e5b4d
LA
26510 tcg_temp_free(t0);
26511 tcg_temp_free(t1);
77c5fa8b 26512 break;
099e5b4d 26513 }
7a387fff 26514 default: /* Invalid */
099e5b4d 26515 MIPS_INVAL("MASK DINSV");
9c708c7f 26516 generate_exception_end(ctx, EXCP_RI);
7a387fff
TS
26517 break;
26518 }
26519 break;
099e5b4d
LA
26520 case OPC_SHLL_OB_DSP:
26521 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
26522 break;
26523#endif
fac5a073
LA
26524 default: /* Invalid */
26525 MIPS_INVAL("special3_legacy");
9c708c7f 26526 generate_exception_end(ctx, EXCP_RI);
fac5a073
LA
26527 break;
26528 }
26529}
26530
874b2879 26531static void decode_mmi0(CPUMIPSState *env, DisasContext *ctx)
88eafe0b 26532{
c8341e00 26533 uint32_t opc = MASK_MMI0(ctx->opcode);
88eafe0b
FN
26534
26535 switch (opc) {
baa609db
AM
26536 case MMI_OPC_0_PADDW: /* TODO: MMI_OPC_0_PADDW */
26537 case MMI_OPC_0_PSUBW: /* TODO: MMI_OPC_0_PSUBW */
26538 case MMI_OPC_0_PCGTW: /* TODO: MMI_OPC_0_PCGTW */
26539 case MMI_OPC_0_PMAXW: /* TODO: MMI_OPC_0_PMAXW */
26540 case MMI_OPC_0_PADDH: /* TODO: MMI_OPC_0_PADDH */
26541 case MMI_OPC_0_PSUBH: /* TODO: MMI_OPC_0_PSUBH */
26542 case MMI_OPC_0_PCGTH: /* TODO: MMI_OPC_0_PCGTH */
26543 case MMI_OPC_0_PMAXH: /* TODO: MMI_OPC_0_PMAXH */
26544 case MMI_OPC_0_PADDB: /* TODO: MMI_OPC_0_PADDB */
26545 case MMI_OPC_0_PSUBB: /* TODO: MMI_OPC_0_PSUBB */
26546 case MMI_OPC_0_PCGTB: /* TODO: MMI_OPC_0_PCGTB */
26547 case MMI_OPC_0_PADDSW: /* TODO: MMI_OPC_0_PADDSW */
26548 case MMI_OPC_0_PSUBSW: /* TODO: MMI_OPC_0_PSUBSW */
26549 case MMI_OPC_0_PEXTLW: /* TODO: MMI_OPC_0_PEXTLW */
26550 case MMI_OPC_0_PPACW: /* TODO: MMI_OPC_0_PPACW */
26551 case MMI_OPC_0_PADDSH: /* TODO: MMI_OPC_0_PADDSH */
26552 case MMI_OPC_0_PSUBSH: /* TODO: MMI_OPC_0_PSUBSH */
26553 case MMI_OPC_0_PEXTLH: /* TODO: MMI_OPC_0_PEXTLH */
26554 case MMI_OPC_0_PPACH: /* TODO: MMI_OPC_0_PPACH */
26555 case MMI_OPC_0_PADDSB: /* TODO: MMI_OPC_0_PADDSB */
26556 case MMI_OPC_0_PSUBSB: /* TODO: MMI_OPC_0_PSUBSB */
26557 case MMI_OPC_0_PEXTLB: /* TODO: MMI_OPC_0_PEXTLB */
26558 case MMI_OPC_0_PPACB: /* TODO: MMI_OPC_0_PPACB */
26559 case MMI_OPC_0_PEXT5: /* TODO: MMI_OPC_0_PEXT5 */
26560 case MMI_OPC_0_PPAC5: /* TODO: MMI_OPC_0_PPAC5 */
26561 generate_exception_end(ctx, EXCP_RI); /* TODO: MMI_OPC_CLASS_MMI0 */
88eafe0b
FN
26562 break;
26563 default:
26564 MIPS_INVAL("TX79 MMI class MMI0");
26565 generate_exception_end(ctx, EXCP_RI);
26566 break;
26567 }
26568}
26569
874b2879 26570static void decode_mmi1(CPUMIPSState *env, DisasContext *ctx)
7a803ca2 26571{
c8341e00 26572 uint32_t opc = MASK_MMI1(ctx->opcode);
7a803ca2
FN
26573
26574 switch (opc) {
baa609db
AM
26575 case MMI_OPC_1_PABSW: /* TODO: MMI_OPC_1_PABSW */
26576 case MMI_OPC_1_PCEQW: /* TODO: MMI_OPC_1_PCEQW */
26577 case MMI_OPC_1_PMINW: /* TODO: MMI_OPC_1_PMINW */
26578 case MMI_OPC_1_PADSBH: /* TODO: MMI_OPC_1_PADSBH */
26579 case MMI_OPC_1_PABSH: /* TODO: MMI_OPC_1_PABSH */
26580 case MMI_OPC_1_PCEQH: /* TODO: MMI_OPC_1_PCEQH */
26581 case MMI_OPC_1_PMINH: /* TODO: MMI_OPC_1_PMINH */
26582 case MMI_OPC_1_PCEQB: /* TODO: MMI_OPC_1_PCEQB */
26583 case MMI_OPC_1_PADDUW: /* TODO: MMI_OPC_1_PADDUW */
26584 case MMI_OPC_1_PSUBUW: /* TODO: MMI_OPC_1_PSUBUW */
26585 case MMI_OPC_1_PEXTUW: /* TODO: MMI_OPC_1_PEXTUW */
26586 case MMI_OPC_1_PADDUH: /* TODO: MMI_OPC_1_PADDUH */
26587 case MMI_OPC_1_PSUBUH: /* TODO: MMI_OPC_1_PSUBUH */
26588 case MMI_OPC_1_PEXTUH: /* TODO: MMI_OPC_1_PEXTUH */
26589 case MMI_OPC_1_PADDUB: /* TODO: MMI_OPC_1_PADDUB */
26590 case MMI_OPC_1_PSUBUB: /* TODO: MMI_OPC_1_PSUBUB */
26591 case MMI_OPC_1_PEXTUB: /* TODO: MMI_OPC_1_PEXTUB */
26592 case MMI_OPC_1_QFSRV: /* TODO: MMI_OPC_1_QFSRV */
26593 generate_exception_end(ctx, EXCP_RI); /* TODO: MMI_OPC_CLASS_MMI1 */
7a803ca2
FN
26594 break;
26595 default:
26596 MIPS_INVAL("TX79 MMI class MMI1");
26597 generate_exception_end(ctx, EXCP_RI);
26598 break;
26599 }
26600}
26601
874b2879 26602static void decode_mmi2(CPUMIPSState *env, DisasContext *ctx)
6c1e48d3 26603{
c8341e00 26604 uint32_t opc = MASK_MMI2(ctx->opcode);
6c1e48d3
FN
26605
26606 switch (opc) {
baa609db
AM
26607 case MMI_OPC_2_PMADDW: /* TODO: MMI_OPC_2_PMADDW */
26608 case MMI_OPC_2_PSLLVW: /* TODO: MMI_OPC_2_PSLLVW */
26609 case MMI_OPC_2_PSRLVW: /* TODO: MMI_OPC_2_PSRLVW */
26610 case MMI_OPC_2_PMSUBW: /* TODO: MMI_OPC_2_PMSUBW */
26611 case MMI_OPC_2_PMFHI: /* TODO: MMI_OPC_2_PMFHI */
26612 case MMI_OPC_2_PMFLO: /* TODO: MMI_OPC_2_PMFLO */
26613 case MMI_OPC_2_PINTH: /* TODO: MMI_OPC_2_PINTH */
26614 case MMI_OPC_2_PMULTW: /* TODO: MMI_OPC_2_PMULTW */
26615 case MMI_OPC_2_PDIVW: /* TODO: MMI_OPC_2_PDIVW */
26616 case MMI_OPC_2_PCPYLD: /* TODO: MMI_OPC_2_PCPYLD */
26617 case MMI_OPC_2_PMADDH: /* TODO: MMI_OPC_2_PMADDH */
26618 case MMI_OPC_2_PHMADH: /* TODO: MMI_OPC_2_PHMADH */
26619 case MMI_OPC_2_PAND: /* TODO: MMI_OPC_2_PAND */
26620 case MMI_OPC_2_PXOR: /* TODO: MMI_OPC_2_PXOR */
26621 case MMI_OPC_2_PMSUBH: /* TODO: MMI_OPC_2_PMSUBH */
26622 case MMI_OPC_2_PHMSBH: /* TODO: MMI_OPC_2_PHMSBH */
26623 case MMI_OPC_2_PEXEH: /* TODO: MMI_OPC_2_PEXEH */
26624 case MMI_OPC_2_PREVH: /* TODO: MMI_OPC_2_PREVH */
26625 case MMI_OPC_2_PMULTH: /* TODO: MMI_OPC_2_PMULTH */
26626 case MMI_OPC_2_PDIVBW: /* TODO: MMI_OPC_2_PDIVBW */
26627 case MMI_OPC_2_PEXEW: /* TODO: MMI_OPC_2_PEXEW */
26628 case MMI_OPC_2_PROT3W: /* TODO: MMI_OPC_2_PROT3W */
26629 generate_exception_end(ctx, EXCP_RI); /* TODO: MMI_OPC_CLASS_MMI2 */
6c1e48d3
FN
26630 break;
26631 default:
26632 MIPS_INVAL("TX79 MMI class MMI2");
26633 generate_exception_end(ctx, EXCP_RI);
26634 break;
26635 }
26636}
26637
874b2879 26638static void decode_mmi3(CPUMIPSState *env, DisasContext *ctx)
ec1944fc 26639{
c8341e00 26640 uint32_t opc = MASK_MMI3(ctx->opcode);
ec1944fc
FN
26641
26642 switch (opc) {
baa609db
AM
26643 case MMI_OPC_3_PMADDUW: /* TODO: MMI_OPC_3_PMADDUW */
26644 case MMI_OPC_3_PSRAVW: /* TODO: MMI_OPC_3_PSRAVW */
26645 case MMI_OPC_3_PMTHI: /* TODO: MMI_OPC_3_PMTHI */
26646 case MMI_OPC_3_PMTLO: /* TODO: MMI_OPC_3_PMTLO */
26647 case MMI_OPC_3_PINTEH: /* TODO: MMI_OPC_3_PINTEH */
26648 case MMI_OPC_3_PMULTUW: /* TODO: MMI_OPC_3_PMULTUW */
26649 case MMI_OPC_3_PDIVUW: /* TODO: MMI_OPC_3_PDIVUW */
26650 case MMI_OPC_3_PCPYUD: /* TODO: MMI_OPC_3_PCPYUD */
26651 case MMI_OPC_3_POR: /* TODO: MMI_OPC_3_POR */
26652 case MMI_OPC_3_PNOR: /* TODO: MMI_OPC_3_PNOR */
26653 case MMI_OPC_3_PEXCH: /* TODO: MMI_OPC_3_PEXCH */
26654 case MMI_OPC_3_PCPYH: /* TODO: MMI_OPC_3_PCPYH */
26655 case MMI_OPC_3_PEXCW: /* TODO: MMI_OPC_3_PEXCW */
26656 generate_exception_end(ctx, EXCP_RI); /* TODO: MMI_OPC_CLASS_MMI3 */
ec1944fc
FN
26657 break;
26658 default:
26659 MIPS_INVAL("TX79 MMI class MMI3");
26660 generate_exception_end(ctx, EXCP_RI);
26661 break;
26662 }
26663}
26664
874b2879 26665static void decode_mmi(CPUMIPSState *env, DisasContext *ctx)
71b8a6b3 26666{
c8341e00 26667 uint32_t opc = MASK_MMI(ctx->opcode);
06de726b
FN
26668 int rs = extract32(ctx->opcode, 21, 5);
26669 int rt = extract32(ctx->opcode, 16, 5);
26670 int rd = extract32(ctx->opcode, 11, 5);
71b8a6b3
FN
26671
26672 switch (opc) {
baa609db 26673 case MMI_OPC_CLASS_MMI0:
874b2879 26674 decode_mmi0(env, ctx);
88eafe0b 26675 break;
baa609db 26676 case MMI_OPC_CLASS_MMI1:
874b2879 26677 decode_mmi1(env, ctx);
7a803ca2 26678 break;
baa609db 26679 case MMI_OPC_CLASS_MMI2:
874b2879 26680 decode_mmi2(env, ctx);
6c1e48d3 26681 break;
baa609db 26682 case MMI_OPC_CLASS_MMI3:
874b2879 26683 decode_mmi3(env, ctx);
ec1944fc 26684 break;
baa609db
AM
26685 case MMI_OPC_MULT1:
26686 case MMI_OPC_MULTU1:
06de726b
FN
26687 gen_mul_txx9(ctx, opc, rd, rs, rt);
26688 break;
baa609db
AM
26689 case MMI_OPC_DIV1:
26690 case MMI_OPC_DIVU1:
c42171c3 26691 gen_div1_tx79(ctx, opc, rs, rt);
be9c42c9 26692 break;
baa609db
AM
26693 case MMI_OPC_MTLO1:
26694 case MMI_OPC_MTHI1:
86efbfb6 26695 gen_HILO1_tx79(ctx, opc, rs);
8d927f7c 26696 break;
baa609db
AM
26697 case MMI_OPC_MFLO1:
26698 case MMI_OPC_MFHI1:
86efbfb6 26699 gen_HILO1_tx79(ctx, opc, rd);
8d927f7c 26700 break;
baa609db
AM
26701 case MMI_OPC_MADD: /* TODO: MMI_OPC_MADD */
26702 case MMI_OPC_MADDU: /* TODO: MMI_OPC_MADDU */
26703 case MMI_OPC_PLZCW: /* TODO: MMI_OPC_PLZCW */
26704 case MMI_OPC_MADD1: /* TODO: MMI_OPC_MADD1 */
26705 case MMI_OPC_MADDU1: /* TODO: MMI_OPC_MADDU1 */
26706 case MMI_OPC_PMFHL: /* TODO: MMI_OPC_PMFHL */
26707 case MMI_OPC_PMTHL: /* TODO: MMI_OPC_PMTHL */
26708 case MMI_OPC_PSLLH: /* TODO: MMI_OPC_PSLLH */
26709 case MMI_OPC_PSRLH: /* TODO: MMI_OPC_PSRLH */
26710 case MMI_OPC_PSRAH: /* TODO: MMI_OPC_PSRAH */
26711 case MMI_OPC_PSLLW: /* TODO: MMI_OPC_PSLLW */
26712 case MMI_OPC_PSRLW: /* TODO: MMI_OPC_PSRLW */
26713 case MMI_OPC_PSRAW: /* TODO: MMI_OPC_PSRAW */
26714 generate_exception_end(ctx, EXCP_RI); /* TODO: MMI_OPC_CLASS_MMI */
71b8a6b3
FN
26715 break;
26716 default:
26717 MIPS_INVAL("TX79 MMI class");
26718 generate_exception_end(ctx, EXCP_RI);
26719 break;
26720 }
26721}
26722
874b2879 26723static void gen_mmi_lq(CPUMIPSState *env, DisasContext *ctx)
f08099ad 26724{
baa609db 26725 generate_exception_end(ctx, EXCP_RI); /* TODO: MMI_OPC_LQ */
f08099ad
FN
26726}
26727
874b2879 26728static void gen_mmi_sq(DisasContext *ctx, int base, int rt, int offset)
bb41e74b 26729{
baa609db 26730 generate_exception_end(ctx, EXCP_RI); /* TODO: MMI_OPC_SQ */
bb41e74b
FN
26731}
26732
26733/*
26734 * The TX79-specific instruction Store Quadword
26735 *
26736 * +--------+-------+-------+------------------------+
26737 * | 011111 | base | rt | offset | SQ
26738 * +--------+-------+-------+------------------------+
26739 * 6 5 5 16
26740 *
26741 * has the same opcode as the Read Hardware Register instruction
26742 *
26743 * +--------+-------+-------+-------+-------+--------+
26744 * | 011111 | 00000 | rt | rd | 00000 | 111011 | RDHWR
26745 * +--------+-------+-------+-------+-------+--------+
26746 * 6 5 5 5 5 6
26747 *
26748 * that is required, trapped and emulated by the Linux kernel. However, all
26749 * RDHWR encodings yield address error exceptions on the TX79 since the SQ
26750 * offset is odd. Therefore all valid SQ instructions can execute normally.
26751 * In user mode, QEMU must verify the upper and lower 11 bits to distinguish
26752 * between SQ and RDHWR, as the Linux kernel does.
26753 */
874b2879 26754static void decode_mmi_sq(CPUMIPSState *env, DisasContext *ctx)
bb41e74b
FN
26755{
26756 int base = extract32(ctx->opcode, 21, 5);
26757 int rt = extract32(ctx->opcode, 16, 5);
26758 int offset = extract32(ctx->opcode, 0, 16);
26759
26760#ifdef CONFIG_USER_ONLY
26761 uint32_t op1 = MASK_SPECIAL3(ctx->opcode);
26762 uint32_t op2 = extract32(ctx->opcode, 6, 5);
26763
26764 if (base == 0 && op2 == 0 && op1 == OPC_RDHWR) {
26765 int rd = extract32(ctx->opcode, 11, 5);
26766
26767 gen_rdhwr(ctx, rt, rd, 0);
26768 return;
26769 }
26770#endif
26771
874b2879 26772 gen_mmi_sq(ctx, base, rt, offset);
bb41e74b
FN
26773}
26774
fac5a073
LA
26775static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx)
26776{
26777 int rs, rt, rd, sa;
26778 uint32_t op1, op2;
76964147 26779 int16_t imm;
fac5a073
LA
26780
26781 rs = (ctx->opcode >> 21) & 0x1f;
26782 rt = (ctx->opcode >> 16) & 0x1f;
26783 rd = (ctx->opcode >> 11) & 0x1f;
26784 sa = (ctx->opcode >> 6) & 0x1f;
76964147 26785 imm = sextract32(ctx->opcode, 7, 9);
fac5a073
LA
26786
26787 op1 = MASK_SPECIAL3(ctx->opcode);
76964147
JH
26788
26789 /*
26790 * EVA loads and stores overlap Loongson 2E instructions decoded by
26791 * decode_opc_special3_legacy(), so be careful to allow their decoding when
26792 * EVA is absent.
26793 */
26794 if (ctx->eva) {
26795 switch (op1) {
c2e19f3c
AM
26796 case OPC_LWLE:
26797 case OPC_LWRE:
76964147
JH
26798 check_insn_opc_removed(ctx, ISA_MIPS32R6);
26799 /* fall through */
c2e19f3c
AM
26800 case OPC_LBUE:
26801 case OPC_LHUE:
26802 case OPC_LBE:
26803 case OPC_LHE:
26804 case OPC_LLE:
26805 case OPC_LWE:
76964147
JH
26806 check_cp0_enabled(ctx);
26807 gen_ld(ctx, op1, rt, rs, imm);
26808 return;
c2e19f3c
AM
26809 case OPC_SWLE:
26810 case OPC_SWRE:
76964147
JH
26811 check_insn_opc_removed(ctx, ISA_MIPS32R6);
26812 /* fall through */
c2e19f3c
AM
26813 case OPC_SBE:
26814 case OPC_SHE:
76964147
JH
26815 case OPC_SWE:
26816 check_cp0_enabled(ctx);
26817 gen_st(ctx, op1, rt, rs, imm);
26818 return;
26819 case OPC_SCE:
26820 check_cp0_enabled(ctx);
26821 gen_st_cond(ctx, op1, rt, rs, imm);
26822 return;
26823 case OPC_CACHEE:
26824 check_cp0_enabled(ctx);
26825 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
26826 gen_cache_operation(ctx, rt, rs, imm);
26827 }
26828 /* Treat as NOP. */
26829 return;
26830 case OPC_PREFE:
26831 check_cp0_enabled(ctx);
26832 /* Treat as NOP. */
26833 return;
26834 }
26835 }
26836
fac5a073
LA
26837 switch (op1) {
26838 case OPC_EXT:
26839 case OPC_INS:
26840 check_insn(ctx, ISA_MIPS32R2);
26841 gen_bitops(ctx, op1, rt, rs, sa, rd);
26842 break;
26843 case OPC_BSHFL:
fac5a073 26844 op2 = MASK_BSHFL(ctx->opcode);
15eacb9b 26845 switch (op2) {
c2e19f3c 26846 case OPC_ALIGN:
373ecd38
AM
26847 case OPC_ALIGN_1:
26848 case OPC_ALIGN_2:
26849 case OPC_ALIGN_3:
15eacb9b
YK
26850 case OPC_BITSWAP:
26851 check_insn(ctx, ISA_MIPS32R6);
26852 decode_opc_special3_r6(env, ctx);
26853 break;
26854 default:
26855 check_insn(ctx, ISA_MIPS32R2);
26856 gen_bshfl(ctx, op2, rt, rd);
26857 break;
26858 }
fac5a073
LA
26859 break;
26860#if defined(TARGET_MIPS64)
c2e19f3c
AM
26861 case OPC_DEXTM:
26862 case OPC_DEXTU:
26863 case OPC_DEXT:
26864 case OPC_DINSM:
26865 case OPC_DINSU:
26866 case OPC_DINS:
fac5a073
LA
26867 check_insn(ctx, ISA_MIPS64R2);
26868 check_mips_64(ctx);
26869 gen_bitops(ctx, op1, rt, rs, sa, rd);
26870 break;
26871 case OPC_DBSHFL:
fac5a073 26872 op2 = MASK_DBSHFL(ctx->opcode);
15eacb9b 26873 switch (op2) {
c2e19f3c 26874 case OPC_DALIGN:
373ecd38
AM
26875 case OPC_DALIGN_1:
26876 case OPC_DALIGN_2:
26877 case OPC_DALIGN_3:
26878 case OPC_DALIGN_4:
26879 case OPC_DALIGN_5:
26880 case OPC_DALIGN_6:
26881 case OPC_DALIGN_7:
15eacb9b
YK
26882 case OPC_DBITSWAP:
26883 check_insn(ctx, ISA_MIPS32R6);
26884 decode_opc_special3_r6(env, ctx);
26885 break;
26886 default:
26887 check_insn(ctx, ISA_MIPS64R2);
26888 check_mips_64(ctx);
26889 op2 = MASK_DBSHFL(ctx->opcode);
26890 gen_bshfl(ctx, op2, rt, rd);
26891 break;
26892 }
fac5a073
LA
26893 break;
26894#endif
26895 case OPC_RDHWR:
b00c7218 26896 gen_rdhwr(ctx, rt, rd, extract32(ctx->opcode, 6, 3));
fac5a073
LA
26897 break;
26898 case OPC_FORK:
9affc1c5 26899 check_mt(ctx);
fac5a073
LA
26900 {
26901 TCGv t0 = tcg_temp_new();
26902 TCGv t1 = tcg_temp_new();
26903
26904 gen_load_gpr(t0, rt);
26905 gen_load_gpr(t1, rs);
26906 gen_helper_fork(t0, t1);
26907 tcg_temp_free(t0);
26908 tcg_temp_free(t1);
26909 }
26910 break;
26911 case OPC_YIELD:
9affc1c5 26912 check_mt(ctx);
fac5a073
LA
26913 {
26914 TCGv t0 = tcg_temp_new();
26915
fac5a073
LA
26916 gen_load_gpr(t0, rs);
26917 gen_helper_yield(t0, cpu_env, t0);
26918 gen_store_gpr(t0, rd);
26919 tcg_temp_free(t0);
26920 }
26921 break;
10dc65db
LA
26922 default:
26923 if (ctx->insn_flags & ISA_MIPS32R6) {
26924 decode_opc_special3_r6(env, ctx);
26925 } else {
26926 decode_opc_special3_legacy(env, ctx);
26927 }
099e5b4d
LA
26928 }
26929}
26930
863f264d
YK
26931/* MIPS SIMD Architecture (MSA) */
26932static inline int check_msa_access(DisasContext *ctx)
26933{
26934 if (unlikely((ctx->hflags & MIPS_HFLAG_FPU) &&
26935 !(ctx->hflags & MIPS_HFLAG_F64))) {
9c708c7f 26936 generate_exception_end(ctx, EXCP_RI);
863f264d
YK
26937 return 0;
26938 }
26939
26940 if (unlikely(!(ctx->hflags & MIPS_HFLAG_MSA))) {
26941 if (ctx->insn_flags & ASE_MSA) {
9c708c7f 26942 generate_exception_end(ctx, EXCP_MSADIS);
863f264d
YK
26943 return 0;
26944 } else {
9c708c7f 26945 generate_exception_end(ctx, EXCP_RI);
863f264d
YK
26946 return 0;
26947 }
26948 }
26949 return 1;
26950}
26951
5692c6e1
YK
26952static void gen_check_zero_element(TCGv tresult, uint8_t df, uint8_t wt)
26953{
26954 /* generates tcg ops to check if any element is 0 */
26955 /* Note this function only works with MSA_WRLEN = 128 */
26956 uint64_t eval_zero_or_big = 0;
26957 uint64_t eval_big = 0;
26958 TCGv_i64 t0 = tcg_temp_new_i64();
26959 TCGv_i64 t1 = tcg_temp_new_i64();
26960 switch (df) {
26961 case DF_BYTE:
26962 eval_zero_or_big = 0x0101010101010101ULL;
26963 eval_big = 0x8080808080808080ULL;
26964 break;
26965 case DF_HALF:
26966 eval_zero_or_big = 0x0001000100010001ULL;
26967 eval_big = 0x8000800080008000ULL;
26968 break;
26969 case DF_WORD:
26970 eval_zero_or_big = 0x0000000100000001ULL;
26971 eval_big = 0x8000000080000000ULL;
26972 break;
26973 case DF_DOUBLE:
26974 eval_zero_or_big = 0x0000000000000001ULL;
26975 eval_big = 0x8000000000000000ULL;
26976 break;
26977 }
26978 tcg_gen_subi_i64(t0, msa_wr_d[wt<<1], eval_zero_or_big);
26979 tcg_gen_andc_i64(t0, t0, msa_wr_d[wt<<1]);
26980 tcg_gen_andi_i64(t0, t0, eval_big);
26981 tcg_gen_subi_i64(t1, msa_wr_d[(wt<<1)+1], eval_zero_or_big);
26982 tcg_gen_andc_i64(t1, t1, msa_wr_d[(wt<<1)+1]);
26983 tcg_gen_andi_i64(t1, t1, eval_big);
26984 tcg_gen_or_i64(t0, t0, t1);
26985 /* if all bits are zero then all elements are not zero */
26986 /* if some bit is non-zero then some element is zero */
26987 tcg_gen_setcondi_i64(TCG_COND_NE, t0, t0, 0);
26988 tcg_gen_trunc_i64_tl(tresult, t0);
26989 tcg_temp_free_i64(t0);
26990 tcg_temp_free_i64(t1);
26991}
26992
26993static void gen_msa_branch(CPUMIPSState *env, DisasContext *ctx, uint32_t op1)
26994{
26995 uint8_t df = (ctx->opcode >> 21) & 0x3;
26996 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
26997 int64_t s16 = (int16_t)ctx->opcode;
26998
26999 check_msa_access(ctx);
27000
075a1fe7 27001 if (ctx->hflags & MIPS_HFLAG_BMASK) {
9c708c7f 27002 generate_exception_end(ctx, EXCP_RI);
5692c6e1
YK
27003 return;
27004 }
27005 switch (op1) {
27006 case OPC_BZ_V:
27007 case OPC_BNZ_V:
27008 {
27009 TCGv_i64 t0 = tcg_temp_new_i64();
27010 tcg_gen_or_i64(t0, msa_wr_d[wt<<1], msa_wr_d[(wt<<1)+1]);
27011 tcg_gen_setcondi_i64((op1 == OPC_BZ_V) ?
27012 TCG_COND_EQ : TCG_COND_NE, t0, t0, 0);
27013 tcg_gen_trunc_i64_tl(bcond, t0);
27014 tcg_temp_free_i64(t0);
27015 }
27016 break;
27017 case OPC_BZ_B:
27018 case OPC_BZ_H:
27019 case OPC_BZ_W:
27020 case OPC_BZ_D:
27021 gen_check_zero_element(bcond, df, wt);
27022 break;
27023 case OPC_BNZ_B:
27024 case OPC_BNZ_H:
27025 case OPC_BNZ_W:
27026 case OPC_BNZ_D:
27027 gen_check_zero_element(bcond, df, wt);
27028 tcg_gen_setcondi_tl(TCG_COND_EQ, bcond, bcond, 0);
27029 break;
27030 }
27031
eeb3bba8 27032 ctx->btarget = ctx->base.pc_next + (s16 << 2) + 4;
5692c6e1
YK
27033
27034 ctx->hflags |= MIPS_HFLAG_BC;
27035 ctx->hflags |= MIPS_HFLAG_BDS32;
27036}
27037
4c789546
YK
27038static void gen_msa_i8(CPUMIPSState *env, DisasContext *ctx)
27039{
27040#define MASK_MSA_I8(op) (MASK_MSA_MINOR(op) | (op & (0x03 << 24)))
27041 uint8_t i8 = (ctx->opcode >> 16) & 0xff;
27042 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
27043 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
27044
27045 TCGv_i32 twd = tcg_const_i32(wd);
27046 TCGv_i32 tws = tcg_const_i32(ws);
27047 TCGv_i32 ti8 = tcg_const_i32(i8);
27048
27049 switch (MASK_MSA_I8(ctx->opcode)) {
27050 case OPC_ANDI_B:
27051 gen_helper_msa_andi_b(cpu_env, twd, tws, ti8);
27052 break;
27053 case OPC_ORI_B:
27054 gen_helper_msa_ori_b(cpu_env, twd, tws, ti8);
27055 break;
27056 case OPC_NORI_B:
27057 gen_helper_msa_nori_b(cpu_env, twd, tws, ti8);
27058 break;
27059 case OPC_XORI_B:
27060 gen_helper_msa_xori_b(cpu_env, twd, tws, ti8);
27061 break;
27062 case OPC_BMNZI_B:
27063 gen_helper_msa_bmnzi_b(cpu_env, twd, tws, ti8);
27064 break;
27065 case OPC_BMZI_B:
27066 gen_helper_msa_bmzi_b(cpu_env, twd, tws, ti8);
27067 break;
27068 case OPC_BSELI_B:
27069 gen_helper_msa_bseli_b(cpu_env, twd, tws, ti8);
27070 break;
27071 case OPC_SHF_B:
27072 case OPC_SHF_H:
27073 case OPC_SHF_W:
27074 {
27075 uint8_t df = (ctx->opcode >> 24) & 0x3;
27076 if (df == DF_DOUBLE) {
9c708c7f 27077 generate_exception_end(ctx, EXCP_RI);
4c789546
YK
27078 } else {
27079 TCGv_i32 tdf = tcg_const_i32(df);
27080 gen_helper_msa_shf_df(cpu_env, tdf, twd, tws, ti8);
27081 tcg_temp_free_i32(tdf);
27082 }
27083 }
27084 break;
27085 default:
27086 MIPS_INVAL("MSA instruction");
9c708c7f 27087 generate_exception_end(ctx, EXCP_RI);
4c789546
YK
27088 break;
27089 }
27090
27091 tcg_temp_free_i32(twd);
27092 tcg_temp_free_i32(tws);
27093 tcg_temp_free_i32(ti8);
27094}
27095
80e71591
YK
27096static void gen_msa_i5(CPUMIPSState *env, DisasContext *ctx)
27097{
27098#define MASK_MSA_I5(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
27099 uint8_t df = (ctx->opcode >> 21) & 0x3;
27100 int8_t s5 = (int8_t) sextract32(ctx->opcode, 16, 5);
27101 uint8_t u5 = (ctx->opcode >> 16) & 0x1f;
27102 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
27103 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
27104
27105 TCGv_i32 tdf = tcg_const_i32(df);
27106 TCGv_i32 twd = tcg_const_i32(wd);
27107 TCGv_i32 tws = tcg_const_i32(ws);
27108 TCGv_i32 timm = tcg_temp_new_i32();
27109 tcg_gen_movi_i32(timm, u5);
27110
27111 switch (MASK_MSA_I5(ctx->opcode)) {
27112 case OPC_ADDVI_df:
27113 gen_helper_msa_addvi_df(cpu_env, tdf, twd, tws, timm);
27114 break;
27115 case OPC_SUBVI_df:
27116 gen_helper_msa_subvi_df(cpu_env, tdf, twd, tws, timm);
27117 break;
27118 case OPC_MAXI_S_df:
27119 tcg_gen_movi_i32(timm, s5);
27120 gen_helper_msa_maxi_s_df(cpu_env, tdf, twd, tws, timm);
27121 break;
27122 case OPC_MAXI_U_df:
27123 gen_helper_msa_maxi_u_df(cpu_env, tdf, twd, tws, timm);
27124 break;
27125 case OPC_MINI_S_df:
27126 tcg_gen_movi_i32(timm, s5);
27127 gen_helper_msa_mini_s_df(cpu_env, tdf, twd, tws, timm);
27128 break;
27129 case OPC_MINI_U_df:
27130 gen_helper_msa_mini_u_df(cpu_env, tdf, twd, tws, timm);
27131 break;
27132 case OPC_CEQI_df:
27133 tcg_gen_movi_i32(timm, s5);
27134 gen_helper_msa_ceqi_df(cpu_env, tdf, twd, tws, timm);
27135 break;
27136 case OPC_CLTI_S_df:
27137 tcg_gen_movi_i32(timm, s5);
27138 gen_helper_msa_clti_s_df(cpu_env, tdf, twd, tws, timm);
27139 break;
27140 case OPC_CLTI_U_df:
27141 gen_helper_msa_clti_u_df(cpu_env, tdf, twd, tws, timm);
27142 break;
27143 case OPC_CLEI_S_df:
27144 tcg_gen_movi_i32(timm, s5);
27145 gen_helper_msa_clei_s_df(cpu_env, tdf, twd, tws, timm);
27146 break;
27147 case OPC_CLEI_U_df:
27148 gen_helper_msa_clei_u_df(cpu_env, tdf, twd, tws, timm);
27149 break;
27150 case OPC_LDI_df:
27151 {
27152 int32_t s10 = sextract32(ctx->opcode, 11, 10);
27153 tcg_gen_movi_i32(timm, s10);
27154 gen_helper_msa_ldi_df(cpu_env, tdf, twd, timm);
27155 }
27156 break;
27157 default:
27158 MIPS_INVAL("MSA instruction");
9c708c7f 27159 generate_exception_end(ctx, EXCP_RI);
80e71591
YK
27160 break;
27161 }
27162
27163 tcg_temp_free_i32(tdf);
27164 tcg_temp_free_i32(twd);
27165 tcg_temp_free_i32(tws);
27166 tcg_temp_free_i32(timm);
27167}
27168
d4cf28de
YK
27169static void gen_msa_bit(CPUMIPSState *env, DisasContext *ctx)
27170{
27171#define MASK_MSA_BIT(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
27172 uint8_t dfm = (ctx->opcode >> 16) & 0x7f;
27173 uint32_t df = 0, m = 0;
27174 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
27175 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
27176
27177 TCGv_i32 tdf;
27178 TCGv_i32 tm;
27179 TCGv_i32 twd;
27180 TCGv_i32 tws;
27181
27182 if ((dfm & 0x40) == 0x00) {
27183 m = dfm & 0x3f;
27184 df = DF_DOUBLE;
27185 } else if ((dfm & 0x60) == 0x40) {
27186 m = dfm & 0x1f;
27187 df = DF_WORD;
27188 } else if ((dfm & 0x70) == 0x60) {
27189 m = dfm & 0x0f;
27190 df = DF_HALF;
27191 } else if ((dfm & 0x78) == 0x70) {
27192 m = dfm & 0x7;
27193 df = DF_BYTE;
27194 } else {
9c708c7f 27195 generate_exception_end(ctx, EXCP_RI);
d4cf28de
YK
27196 return;
27197 }
27198
27199 tdf = tcg_const_i32(df);
27200 tm = tcg_const_i32(m);
27201 twd = tcg_const_i32(wd);
27202 tws = tcg_const_i32(ws);
27203
27204 switch (MASK_MSA_BIT(ctx->opcode)) {
27205 case OPC_SLLI_df:
27206 gen_helper_msa_slli_df(cpu_env, tdf, twd, tws, tm);
27207 break;
27208 case OPC_SRAI_df:
27209 gen_helper_msa_srai_df(cpu_env, tdf, twd, tws, tm);
27210 break;
27211 case OPC_SRLI_df:
27212 gen_helper_msa_srli_df(cpu_env, tdf, twd, tws, tm);
27213 break;
27214 case OPC_BCLRI_df:
27215 gen_helper_msa_bclri_df(cpu_env, tdf, twd, tws, tm);
27216 break;
27217 case OPC_BSETI_df:
27218 gen_helper_msa_bseti_df(cpu_env, tdf, twd, tws, tm);
27219 break;
27220 case OPC_BNEGI_df:
27221 gen_helper_msa_bnegi_df(cpu_env, tdf, twd, tws, tm);
27222 break;
27223 case OPC_BINSLI_df:
27224 gen_helper_msa_binsli_df(cpu_env, tdf, twd, tws, tm);
27225 break;
27226 case OPC_BINSRI_df:
27227 gen_helper_msa_binsri_df(cpu_env, tdf, twd, tws, tm);
27228 break;
27229 case OPC_SAT_S_df:
27230 gen_helper_msa_sat_s_df(cpu_env, tdf, twd, tws, tm);
27231 break;
27232 case OPC_SAT_U_df:
27233 gen_helper_msa_sat_u_df(cpu_env, tdf, twd, tws, tm);
27234 break;
27235 case OPC_SRARI_df:
27236 gen_helper_msa_srari_df(cpu_env, tdf, twd, tws, tm);
27237 break;
27238 case OPC_SRLRI_df:
27239 gen_helper_msa_srlri_df(cpu_env, tdf, twd, tws, tm);
27240 break;
27241 default:
27242 MIPS_INVAL("MSA instruction");
9c708c7f 27243 generate_exception_end(ctx, EXCP_RI);
d4cf28de
YK
27244 break;
27245 }
27246
27247 tcg_temp_free_i32(tdf);
27248 tcg_temp_free_i32(tm);
27249 tcg_temp_free_i32(twd);
27250 tcg_temp_free_i32(tws);
27251}
27252
28f99f08
YK
27253static void gen_msa_3r(CPUMIPSState *env, DisasContext *ctx)
27254{
27255#define MASK_MSA_3R(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
27256 uint8_t df = (ctx->opcode >> 21) & 0x3;
27257 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
27258 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
27259 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
27260
27261 TCGv_i32 tdf = tcg_const_i32(df);
27262 TCGv_i32 twd = tcg_const_i32(wd);
27263 TCGv_i32 tws = tcg_const_i32(ws);
27264 TCGv_i32 twt = tcg_const_i32(wt);
27265
27266 switch (MASK_MSA_3R(ctx->opcode)) {
27267 case OPC_SLL_df:
27268 gen_helper_msa_sll_df(cpu_env, tdf, twd, tws, twt);
27269 break;
27270 case OPC_ADDV_df:
27271 gen_helper_msa_addv_df(cpu_env, tdf, twd, tws, twt);
27272 break;
27273 case OPC_CEQ_df:
27274 gen_helper_msa_ceq_df(cpu_env, tdf, twd, tws, twt);
27275 break;
27276 case OPC_ADD_A_df:
27277 gen_helper_msa_add_a_df(cpu_env, tdf, twd, tws, twt);
27278 break;
27279 case OPC_SUBS_S_df:
27280 gen_helper_msa_subs_s_df(cpu_env, tdf, twd, tws, twt);
27281 break;
27282 case OPC_MULV_df:
27283 gen_helper_msa_mulv_df(cpu_env, tdf, twd, tws, twt);
27284 break;
27285 case OPC_SLD_df:
27286 gen_helper_msa_sld_df(cpu_env, tdf, twd, tws, twt);
27287 break;
27288 case OPC_VSHF_df:
27289 gen_helper_msa_vshf_df(cpu_env, tdf, twd, tws, twt);
27290 break;
27291 case OPC_SRA_df:
27292 gen_helper_msa_sra_df(cpu_env, tdf, twd, tws, twt);
27293 break;
27294 case OPC_SUBV_df:
27295 gen_helper_msa_subv_df(cpu_env, tdf, twd, tws, twt);
27296 break;
27297 case OPC_ADDS_A_df:
27298 gen_helper_msa_adds_a_df(cpu_env, tdf, twd, tws, twt);
27299 break;
27300 case OPC_SUBS_U_df:
27301 gen_helper_msa_subs_u_df(cpu_env, tdf, twd, tws, twt);
27302 break;
27303 case OPC_MADDV_df:
27304 gen_helper_msa_maddv_df(cpu_env, tdf, twd, tws, twt);
27305 break;
27306 case OPC_SPLAT_df:
27307 gen_helper_msa_splat_df(cpu_env, tdf, twd, tws, twt);
27308 break;
27309 case OPC_SRAR_df:
27310 gen_helper_msa_srar_df(cpu_env, tdf, twd, tws, twt);
27311 break;
27312 case OPC_SRL_df:
27313 gen_helper_msa_srl_df(cpu_env, tdf, twd, tws, twt);
27314 break;
27315 case OPC_MAX_S_df:
27316 gen_helper_msa_max_s_df(cpu_env, tdf, twd, tws, twt);
27317 break;
27318 case OPC_CLT_S_df:
27319 gen_helper_msa_clt_s_df(cpu_env, tdf, twd, tws, twt);
27320 break;
27321 case OPC_ADDS_S_df:
27322 gen_helper_msa_adds_s_df(cpu_env, tdf, twd, tws, twt);
27323 break;
27324 case OPC_SUBSUS_U_df:
27325 gen_helper_msa_subsus_u_df(cpu_env, tdf, twd, tws, twt);
27326 break;
27327 case OPC_MSUBV_df:
27328 gen_helper_msa_msubv_df(cpu_env, tdf, twd, tws, twt);
27329 break;
27330 case OPC_PCKEV_df:
27331 gen_helper_msa_pckev_df(cpu_env, tdf, twd, tws, twt);
27332 break;
27333 case OPC_SRLR_df:
27334 gen_helper_msa_srlr_df(cpu_env, tdf, twd, tws, twt);
27335 break;
27336 case OPC_BCLR_df:
27337 gen_helper_msa_bclr_df(cpu_env, tdf, twd, tws, twt);
27338 break;
27339 case OPC_MAX_U_df:
27340 gen_helper_msa_max_u_df(cpu_env, tdf, twd, tws, twt);
27341 break;
27342 case OPC_CLT_U_df:
27343 gen_helper_msa_clt_u_df(cpu_env, tdf, twd, tws, twt);
27344 break;
27345 case OPC_ADDS_U_df:
27346 gen_helper_msa_adds_u_df(cpu_env, tdf, twd, tws, twt);
27347 break;
27348 case OPC_SUBSUU_S_df:
27349 gen_helper_msa_subsuu_s_df(cpu_env, tdf, twd, tws, twt);
27350 break;
27351 case OPC_PCKOD_df:
27352 gen_helper_msa_pckod_df(cpu_env, tdf, twd, tws, twt);
27353 break;
27354 case OPC_BSET_df:
27355 gen_helper_msa_bset_df(cpu_env, tdf, twd, tws, twt);
27356 break;
27357 case OPC_MIN_S_df:
27358 gen_helper_msa_min_s_df(cpu_env, tdf, twd, tws, twt);
27359 break;
27360 case OPC_CLE_S_df:
27361 gen_helper_msa_cle_s_df(cpu_env, tdf, twd, tws, twt);
27362 break;
27363 case OPC_AVE_S_df:
27364 gen_helper_msa_ave_s_df(cpu_env, tdf, twd, tws, twt);
27365 break;
27366 case OPC_ASUB_S_df:
27367 gen_helper_msa_asub_s_df(cpu_env, tdf, twd, tws, twt);
27368 break;
27369 case OPC_DIV_S_df:
27370 gen_helper_msa_div_s_df(cpu_env, tdf, twd, tws, twt);
27371 break;
27372 case OPC_ILVL_df:
27373 gen_helper_msa_ilvl_df(cpu_env, tdf, twd, tws, twt);
27374 break;
27375 case OPC_BNEG_df:
27376 gen_helper_msa_bneg_df(cpu_env, tdf, twd, tws, twt);
27377 break;
27378 case OPC_MIN_U_df:
27379 gen_helper_msa_min_u_df(cpu_env, tdf, twd, tws, twt);
27380 break;
27381 case OPC_CLE_U_df:
27382 gen_helper_msa_cle_u_df(cpu_env, tdf, twd, tws, twt);
27383 break;
27384 case OPC_AVE_U_df:
27385 gen_helper_msa_ave_u_df(cpu_env, tdf, twd, tws, twt);
27386 break;
27387 case OPC_ASUB_U_df:
27388 gen_helper_msa_asub_u_df(cpu_env, tdf, twd, tws, twt);
27389 break;
27390 case OPC_DIV_U_df:
27391 gen_helper_msa_div_u_df(cpu_env, tdf, twd, tws, twt);
27392 break;
27393 case OPC_ILVR_df:
27394 gen_helper_msa_ilvr_df(cpu_env, tdf, twd, tws, twt);
27395 break;
27396 case OPC_BINSL_df:
27397 gen_helper_msa_binsl_df(cpu_env, tdf, twd, tws, twt);
27398 break;
27399 case OPC_MAX_A_df:
27400 gen_helper_msa_max_a_df(cpu_env, tdf, twd, tws, twt);
27401 break;
27402 case OPC_AVER_S_df:
27403 gen_helper_msa_aver_s_df(cpu_env, tdf, twd, tws, twt);
27404 break;
27405 case OPC_MOD_S_df:
27406 gen_helper_msa_mod_s_df(cpu_env, tdf, twd, tws, twt);
27407 break;
27408 case OPC_ILVEV_df:
27409 gen_helper_msa_ilvev_df(cpu_env, tdf, twd, tws, twt);
27410 break;
27411 case OPC_BINSR_df:
27412 gen_helper_msa_binsr_df(cpu_env, tdf, twd, tws, twt);
27413 break;
27414 case OPC_MIN_A_df:
27415 gen_helper_msa_min_a_df(cpu_env, tdf, twd, tws, twt);
27416 break;
27417 case OPC_AVER_U_df:
27418 gen_helper_msa_aver_u_df(cpu_env, tdf, twd, tws, twt);
27419 break;
27420 case OPC_MOD_U_df:
27421 gen_helper_msa_mod_u_df(cpu_env, tdf, twd, tws, twt);
27422 break;
27423 case OPC_ILVOD_df:
27424 gen_helper_msa_ilvod_df(cpu_env, tdf, twd, tws, twt);
27425 break;
27426
27427 case OPC_DOTP_S_df:
27428 case OPC_DOTP_U_df:
27429 case OPC_DPADD_S_df:
27430 case OPC_DPADD_U_df:
27431 case OPC_DPSUB_S_df:
27432 case OPC_HADD_S_df:
27433 case OPC_DPSUB_U_df:
27434 case OPC_HADD_U_df:
27435 case OPC_HSUB_S_df:
27436 case OPC_HSUB_U_df:
27437 if (df == DF_BYTE) {
9c708c7f
PD
27438 generate_exception_end(ctx, EXCP_RI);
27439 break;
28f99f08
YK
27440 }
27441 switch (MASK_MSA_3R(ctx->opcode)) {
27442 case OPC_DOTP_S_df:
27443 gen_helper_msa_dotp_s_df(cpu_env, tdf, twd, tws, twt);
27444 break;
27445 case OPC_DOTP_U_df:
27446 gen_helper_msa_dotp_u_df(cpu_env, tdf, twd, tws, twt);
27447 break;
27448 case OPC_DPADD_S_df:
27449 gen_helper_msa_dpadd_s_df(cpu_env, tdf, twd, tws, twt);
27450 break;
27451 case OPC_DPADD_U_df:
27452 gen_helper_msa_dpadd_u_df(cpu_env, tdf, twd, tws, twt);
27453 break;
27454 case OPC_DPSUB_S_df:
27455 gen_helper_msa_dpsub_s_df(cpu_env, tdf, twd, tws, twt);
27456 break;
27457 case OPC_HADD_S_df:
27458 gen_helper_msa_hadd_s_df(cpu_env, tdf, twd, tws, twt);
27459 break;
27460 case OPC_DPSUB_U_df:
27461 gen_helper_msa_dpsub_u_df(cpu_env, tdf, twd, tws, twt);
27462 break;
27463 case OPC_HADD_U_df:
27464 gen_helper_msa_hadd_u_df(cpu_env, tdf, twd, tws, twt);
27465 break;
27466 case OPC_HSUB_S_df:
27467 gen_helper_msa_hsub_s_df(cpu_env, tdf, twd, tws, twt);
27468 break;
27469 case OPC_HSUB_U_df:
27470 gen_helper_msa_hsub_u_df(cpu_env, tdf, twd, tws, twt);
27471 break;
27472 }
27473 break;
27474 default:
27475 MIPS_INVAL("MSA instruction");
9c708c7f 27476 generate_exception_end(ctx, EXCP_RI);
28f99f08
YK
27477 break;
27478 }
27479 tcg_temp_free_i32(twd);
27480 tcg_temp_free_i32(tws);
27481 tcg_temp_free_i32(twt);
27482 tcg_temp_free_i32(tdf);
27483}
27484
1e608ec1
YK
27485static void gen_msa_elm_3e(CPUMIPSState *env, DisasContext *ctx)
27486{
27487#define MASK_MSA_ELM_DF3E(op) (MASK_MSA_MINOR(op) | (op & (0x3FF << 16)))
27488 uint8_t source = (ctx->opcode >> 11) & 0x1f;
27489 uint8_t dest = (ctx->opcode >> 6) & 0x1f;
27490 TCGv telm = tcg_temp_new();
27491 TCGv_i32 tsr = tcg_const_i32(source);
27492 TCGv_i32 tdt = tcg_const_i32(dest);
27493
27494 switch (MASK_MSA_ELM_DF3E(ctx->opcode)) {
27495 case OPC_CTCMSA:
27496 gen_load_gpr(telm, source);
27497 gen_helper_msa_ctcmsa(cpu_env, telm, tdt);
27498 break;
27499 case OPC_CFCMSA:
27500 gen_helper_msa_cfcmsa(telm, cpu_env, tsr);
27501 gen_store_gpr(telm, dest);
27502 break;
27503 case OPC_MOVE_V:
27504 gen_helper_msa_move_v(cpu_env, tdt, tsr);
27505 break;
27506 default:
27507 MIPS_INVAL("MSA instruction");
9c708c7f 27508 generate_exception_end(ctx, EXCP_RI);
1e608ec1
YK
27509 break;
27510 }
27511
27512 tcg_temp_free(telm);
27513 tcg_temp_free_i32(tdt);
27514 tcg_temp_free_i32(tsr);
27515}
27516
27517static void gen_msa_elm_df(CPUMIPSState *env, DisasContext *ctx, uint32_t df,
27518 uint32_t n)
27519{
27520#define MASK_MSA_ELM(op) (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
27521 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
27522 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
27523
27524 TCGv_i32 tws = tcg_const_i32(ws);
27525 TCGv_i32 twd = tcg_const_i32(wd);
27526 TCGv_i32 tn = tcg_const_i32(n);
27527 TCGv_i32 tdf = tcg_const_i32(df);
27528
27529 switch (MASK_MSA_ELM(ctx->opcode)) {
27530 case OPC_SLDI_df:
27531 gen_helper_msa_sldi_df(cpu_env, tdf, twd, tws, tn);
27532 break;
27533 case OPC_SPLATI_df:
27534 gen_helper_msa_splati_df(cpu_env, tdf, twd, tws, tn);
27535 break;
27536 case OPC_INSVE_df:
27537 gen_helper_msa_insve_df(cpu_env, tdf, twd, tws, tn);
27538 break;
27539 case OPC_COPY_S_df:
27540 case OPC_COPY_U_df:
27541 case OPC_INSERT_df:
27542#if !defined(TARGET_MIPS64)
27543 /* Double format valid only for MIPS64 */
27544 if (df == DF_DOUBLE) {
9c708c7f 27545 generate_exception_end(ctx, EXCP_RI);
1e608ec1
YK
27546 break;
27547 }
27548#endif
27549 switch (MASK_MSA_ELM(ctx->opcode)) {
27550 case OPC_COPY_S_df:
cab48881
MD
27551 if (likely(wd != 0)) {
27552 gen_helper_msa_copy_s_df(cpu_env, tdf, twd, tws, tn);
27553 }
1e608ec1
YK
27554 break;
27555 case OPC_COPY_U_df:
cab48881
MD
27556 if (likely(wd != 0)) {
27557 gen_helper_msa_copy_u_df(cpu_env, tdf, twd, tws, tn);
27558 }
1e608ec1
YK
27559 break;
27560 case OPC_INSERT_df:
27561 gen_helper_msa_insert_df(cpu_env, tdf, twd, tws, tn);
27562 break;
27563 }
27564 break;
27565 default:
27566 MIPS_INVAL("MSA instruction");
9c708c7f 27567 generate_exception_end(ctx, EXCP_RI);
1e608ec1
YK
27568 }
27569 tcg_temp_free_i32(twd);
27570 tcg_temp_free_i32(tws);
27571 tcg_temp_free_i32(tn);
27572 tcg_temp_free_i32(tdf);
27573}
27574
27575static void gen_msa_elm(CPUMIPSState *env, DisasContext *ctx)
27576{
27577 uint8_t dfn = (ctx->opcode >> 16) & 0x3f;
27578 uint32_t df = 0, n = 0;
27579
27580 if ((dfn & 0x30) == 0x00) {
27581 n = dfn & 0x0f;
27582 df = DF_BYTE;
27583 } else if ((dfn & 0x38) == 0x20) {
27584 n = dfn & 0x07;
27585 df = DF_HALF;
27586 } else if ((dfn & 0x3c) == 0x30) {
27587 n = dfn & 0x03;
27588 df = DF_WORD;
27589 } else if ((dfn & 0x3e) == 0x38) {
27590 n = dfn & 0x01;
27591 df = DF_DOUBLE;
27592 } else if (dfn == 0x3E) {
27593 /* CTCMSA, CFCMSA, MOVE.V */
27594 gen_msa_elm_3e(env, ctx);
27595 return;
27596 } else {
9c708c7f 27597 generate_exception_end(ctx, EXCP_RI);
1e608ec1
YK
27598 return;
27599 }
27600
27601 gen_msa_elm_df(env, ctx, df, n);
27602}
27603
7d05b9c8
YK
27604static void gen_msa_3rf(CPUMIPSState *env, DisasContext *ctx)
27605{
27606#define MASK_MSA_3RF(op) (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
27607 uint8_t df = (ctx->opcode >> 21) & 0x1;
27608 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
27609 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
27610 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
27611
27612 TCGv_i32 twd = tcg_const_i32(wd);
27613 TCGv_i32 tws = tcg_const_i32(ws);
27614 TCGv_i32 twt = tcg_const_i32(wt);
27615 TCGv_i32 tdf = tcg_temp_new_i32();
27616
27617 /* adjust df value for floating-point instruction */
27618 tcg_gen_movi_i32(tdf, df + 2);
27619
27620 switch (MASK_MSA_3RF(ctx->opcode)) {
27621 case OPC_FCAF_df:
27622 gen_helper_msa_fcaf_df(cpu_env, tdf, twd, tws, twt);
27623 break;
27624 case OPC_FADD_df:
27625 gen_helper_msa_fadd_df(cpu_env, tdf, twd, tws, twt);
27626 break;
27627 case OPC_FCUN_df:
27628 gen_helper_msa_fcun_df(cpu_env, tdf, twd, tws, twt);
27629 break;
27630 case OPC_FSUB_df:
27631 gen_helper_msa_fsub_df(cpu_env, tdf, twd, tws, twt);
27632 break;
27633 case OPC_FCOR_df:
27634 gen_helper_msa_fcor_df(cpu_env, tdf, twd, tws, twt);
27635 break;
27636 case OPC_FCEQ_df:
27637 gen_helper_msa_fceq_df(cpu_env, tdf, twd, tws, twt);
27638 break;
27639 case OPC_FMUL_df:
27640 gen_helper_msa_fmul_df(cpu_env, tdf, twd, tws, twt);
27641 break;
27642 case OPC_FCUNE_df:
27643 gen_helper_msa_fcune_df(cpu_env, tdf, twd, tws, twt);
27644 break;
27645 case OPC_FCUEQ_df:
27646 gen_helper_msa_fcueq_df(cpu_env, tdf, twd, tws, twt);
27647 break;
27648 case OPC_FDIV_df:
27649 gen_helper_msa_fdiv_df(cpu_env, tdf, twd, tws, twt);
27650 break;
27651 case OPC_FCNE_df:
27652 gen_helper_msa_fcne_df(cpu_env, tdf, twd, tws, twt);
27653 break;
27654 case OPC_FCLT_df:
27655 gen_helper_msa_fclt_df(cpu_env, tdf, twd, tws, twt);
27656 break;
27657 case OPC_FMADD_df:
27658 gen_helper_msa_fmadd_df(cpu_env, tdf, twd, tws, twt);
27659 break;
27660 case OPC_MUL_Q_df:
27661 tcg_gen_movi_i32(tdf, df + 1);
27662 gen_helper_msa_mul_q_df(cpu_env, tdf, twd, tws, twt);
27663 break;
27664 case OPC_FCULT_df:
27665 gen_helper_msa_fcult_df(cpu_env, tdf, twd, tws, twt);
27666 break;
27667 case OPC_FMSUB_df:
27668 gen_helper_msa_fmsub_df(cpu_env, tdf, twd, tws, twt);
27669 break;
27670 case OPC_MADD_Q_df:
27671 tcg_gen_movi_i32(tdf, df + 1);
27672 gen_helper_msa_madd_q_df(cpu_env, tdf, twd, tws, twt);
27673 break;
27674 case OPC_FCLE_df:
27675 gen_helper_msa_fcle_df(cpu_env, tdf, twd, tws, twt);
27676 break;
27677 case OPC_MSUB_Q_df:
27678 tcg_gen_movi_i32(tdf, df + 1);
27679 gen_helper_msa_msub_q_df(cpu_env, tdf, twd, tws, twt);
27680 break;
27681 case OPC_FCULE_df:
27682 gen_helper_msa_fcule_df(cpu_env, tdf, twd, tws, twt);
27683 break;
27684 case OPC_FEXP2_df:
27685 gen_helper_msa_fexp2_df(cpu_env, tdf, twd, tws, twt);
27686 break;
27687 case OPC_FSAF_df:
27688 gen_helper_msa_fsaf_df(cpu_env, tdf, twd, tws, twt);
27689 break;
27690 case OPC_FEXDO_df:
27691 gen_helper_msa_fexdo_df(cpu_env, tdf, twd, tws, twt);
27692 break;
27693 case OPC_FSUN_df:
27694 gen_helper_msa_fsun_df(cpu_env, tdf, twd, tws, twt);
27695 break;
27696 case OPC_FSOR_df:
27697 gen_helper_msa_fsor_df(cpu_env, tdf, twd, tws, twt);
27698 break;
27699 case OPC_FSEQ_df:
27700 gen_helper_msa_fseq_df(cpu_env, tdf, twd, tws, twt);
27701 break;
27702 case OPC_FTQ_df:
27703 gen_helper_msa_ftq_df(cpu_env, tdf, twd, tws, twt);
27704 break;
27705 case OPC_FSUNE_df:
27706 gen_helper_msa_fsune_df(cpu_env, tdf, twd, tws, twt);
27707 break;
27708 case OPC_FSUEQ_df:
27709 gen_helper_msa_fsueq_df(cpu_env, tdf, twd, tws, twt);
27710 break;
27711 case OPC_FSNE_df:
27712 gen_helper_msa_fsne_df(cpu_env, tdf, twd, tws, twt);
27713 break;
27714 case OPC_FSLT_df:
27715 gen_helper_msa_fslt_df(cpu_env, tdf, twd, tws, twt);
27716 break;
27717 case OPC_FMIN_df:
27718 gen_helper_msa_fmin_df(cpu_env, tdf, twd, tws, twt);
27719 break;
27720 case OPC_MULR_Q_df:
27721 tcg_gen_movi_i32(tdf, df + 1);
27722 gen_helper_msa_mulr_q_df(cpu_env, tdf, twd, tws, twt);
27723 break;
27724 case OPC_FSULT_df:
27725 gen_helper_msa_fsult_df(cpu_env, tdf, twd, tws, twt);
27726 break;
27727 case OPC_FMIN_A_df:
27728 gen_helper_msa_fmin_a_df(cpu_env, tdf, twd, tws, twt);
27729 break;
27730 case OPC_MADDR_Q_df:
27731 tcg_gen_movi_i32(tdf, df + 1);
27732 gen_helper_msa_maddr_q_df(cpu_env, tdf, twd, tws, twt);
27733 break;
27734 case OPC_FSLE_df:
27735 gen_helper_msa_fsle_df(cpu_env, tdf, twd, tws, twt);
27736 break;
27737 case OPC_FMAX_df:
27738 gen_helper_msa_fmax_df(cpu_env, tdf, twd, tws, twt);
27739 break;
27740 case OPC_MSUBR_Q_df:
27741 tcg_gen_movi_i32(tdf, df + 1);
27742 gen_helper_msa_msubr_q_df(cpu_env, tdf, twd, tws, twt);
27743 break;
27744 case OPC_FSULE_df:
27745 gen_helper_msa_fsule_df(cpu_env, tdf, twd, tws, twt);
27746 break;
27747 case OPC_FMAX_A_df:
27748 gen_helper_msa_fmax_a_df(cpu_env, tdf, twd, tws, twt);
27749 break;
27750 default:
27751 MIPS_INVAL("MSA instruction");
9c708c7f 27752 generate_exception_end(ctx, EXCP_RI);
7d05b9c8
YK
27753 break;
27754 }
27755
27756 tcg_temp_free_i32(twd);
27757 tcg_temp_free_i32(tws);
27758 tcg_temp_free_i32(twt);
27759 tcg_temp_free_i32(tdf);
27760}
27761
cbe50b9a
YK
27762static void gen_msa_2r(CPUMIPSState *env, DisasContext *ctx)
27763{
27764#define MASK_MSA_2R(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
27765 (op & (0x7 << 18)))
27766 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
27767 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
27768 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
27769 uint8_t df = (ctx->opcode >> 16) & 0x3;
27770 TCGv_i32 twd = tcg_const_i32(wd);
27771 TCGv_i32 tws = tcg_const_i32(ws);
27772 TCGv_i32 twt = tcg_const_i32(wt);
27773 TCGv_i32 tdf = tcg_const_i32(df);
27774
27775 switch (MASK_MSA_2R(ctx->opcode)) {
27776 case OPC_FILL_df:
27777#if !defined(TARGET_MIPS64)
27778 /* Double format valid only for MIPS64 */
27779 if (df == DF_DOUBLE) {
9c708c7f 27780 generate_exception_end(ctx, EXCP_RI);
cbe50b9a
YK
27781 break;
27782 }
27783#endif
27784 gen_helper_msa_fill_df(cpu_env, tdf, twd, tws); /* trs */
27785 break;
27786 case OPC_PCNT_df:
27787 gen_helper_msa_pcnt_df(cpu_env, tdf, twd, tws);
27788 break;
27789 case OPC_NLOC_df:
27790 gen_helper_msa_nloc_df(cpu_env, tdf, twd, tws);
27791 break;
27792 case OPC_NLZC_df:
27793 gen_helper_msa_nlzc_df(cpu_env, tdf, twd, tws);
27794 break;
27795 default:
27796 MIPS_INVAL("MSA instruction");
9c708c7f 27797 generate_exception_end(ctx, EXCP_RI);
cbe50b9a
YK
27798 break;
27799 }
27800
27801 tcg_temp_free_i32(twd);
27802 tcg_temp_free_i32(tws);
27803 tcg_temp_free_i32(twt);
27804 tcg_temp_free_i32(tdf);
27805}
27806
3bdeb688
YK
27807static void gen_msa_2rf(CPUMIPSState *env, DisasContext *ctx)
27808{
27809#define MASK_MSA_2RF(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
27810 (op & (0xf << 17)))
27811 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
27812 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
27813 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
27814 uint8_t df = (ctx->opcode >> 16) & 0x1;
27815 TCGv_i32 twd = tcg_const_i32(wd);
27816 TCGv_i32 tws = tcg_const_i32(ws);
27817 TCGv_i32 twt = tcg_const_i32(wt);
27818 /* adjust df value for floating-point instruction */
27819 TCGv_i32 tdf = tcg_const_i32(df + 2);
27820
27821 switch (MASK_MSA_2RF(ctx->opcode)) {
27822 case OPC_FCLASS_df:
27823 gen_helper_msa_fclass_df(cpu_env, tdf, twd, tws);
27824 break;
27825 case OPC_FTRUNC_S_df:
27826 gen_helper_msa_ftrunc_s_df(cpu_env, tdf, twd, tws);
27827 break;
27828 case OPC_FTRUNC_U_df:
27829 gen_helper_msa_ftrunc_u_df(cpu_env, tdf, twd, tws);
27830 break;
27831 case OPC_FSQRT_df:
27832 gen_helper_msa_fsqrt_df(cpu_env, tdf, twd, tws);
27833 break;
27834 case OPC_FRSQRT_df:
27835 gen_helper_msa_frsqrt_df(cpu_env, tdf, twd, tws);
27836 break;
27837 case OPC_FRCP_df:
27838 gen_helper_msa_frcp_df(cpu_env, tdf, twd, tws);
27839 break;
27840 case OPC_FRINT_df:
27841 gen_helper_msa_frint_df(cpu_env, tdf, twd, tws);
27842 break;
27843 case OPC_FLOG2_df:
27844 gen_helper_msa_flog2_df(cpu_env, tdf, twd, tws);
27845 break;
27846 case OPC_FEXUPL_df:
27847 gen_helper_msa_fexupl_df(cpu_env, tdf, twd, tws);
27848 break;
27849 case OPC_FEXUPR_df:
27850 gen_helper_msa_fexupr_df(cpu_env, tdf, twd, tws);
27851 break;
27852 case OPC_FFQL_df:
27853 gen_helper_msa_ffql_df(cpu_env, tdf, twd, tws);
27854 break;
27855 case OPC_FFQR_df:
27856 gen_helper_msa_ffqr_df(cpu_env, tdf, twd, tws);
27857 break;
27858 case OPC_FTINT_S_df:
27859 gen_helper_msa_ftint_s_df(cpu_env, tdf, twd, tws);
27860 break;
27861 case OPC_FTINT_U_df:
27862 gen_helper_msa_ftint_u_df(cpu_env, tdf, twd, tws);
27863 break;
27864 case OPC_FFINT_S_df:
27865 gen_helper_msa_ffint_s_df(cpu_env, tdf, twd, tws);
27866 break;
27867 case OPC_FFINT_U_df:
27868 gen_helper_msa_ffint_u_df(cpu_env, tdf, twd, tws);
27869 break;
27870 }
27871
27872 tcg_temp_free_i32(twd);
27873 tcg_temp_free_i32(tws);
27874 tcg_temp_free_i32(twt);
27875 tcg_temp_free_i32(tdf);
27876}
27877
cbe50b9a
YK
27878static void gen_msa_vec_v(CPUMIPSState *env, DisasContext *ctx)
27879{
27880#define MASK_MSA_VEC(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)))
27881 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
27882 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
27883 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
27884 TCGv_i32 twd = tcg_const_i32(wd);
27885 TCGv_i32 tws = tcg_const_i32(ws);
27886 TCGv_i32 twt = tcg_const_i32(wt);
27887
27888 switch (MASK_MSA_VEC(ctx->opcode)) {
27889 case OPC_AND_V:
27890 gen_helper_msa_and_v(cpu_env, twd, tws, twt);
27891 break;
27892 case OPC_OR_V:
27893 gen_helper_msa_or_v(cpu_env, twd, tws, twt);
27894 break;
27895 case OPC_NOR_V:
27896 gen_helper_msa_nor_v(cpu_env, twd, tws, twt);
27897 break;
27898 case OPC_XOR_V:
27899 gen_helper_msa_xor_v(cpu_env, twd, tws, twt);
27900 break;
27901 case OPC_BMNZ_V:
27902 gen_helper_msa_bmnz_v(cpu_env, twd, tws, twt);
27903 break;
27904 case OPC_BMZ_V:
27905 gen_helper_msa_bmz_v(cpu_env, twd, tws, twt);
27906 break;
27907 case OPC_BSEL_V:
27908 gen_helper_msa_bsel_v(cpu_env, twd, tws, twt);
27909 break;
27910 default:
27911 MIPS_INVAL("MSA instruction");
9c708c7f 27912 generate_exception_end(ctx, EXCP_RI);
cbe50b9a
YK
27913 break;
27914 }
27915
27916 tcg_temp_free_i32(twd);
27917 tcg_temp_free_i32(tws);
27918 tcg_temp_free_i32(twt);
27919}
27920
27921static void gen_msa_vec(CPUMIPSState *env, DisasContext *ctx)
27922{
27923 switch (MASK_MSA_VEC(ctx->opcode)) {
27924 case OPC_AND_V:
27925 case OPC_OR_V:
27926 case OPC_NOR_V:
27927 case OPC_XOR_V:
27928 case OPC_BMNZ_V:
27929 case OPC_BMZ_V:
27930 case OPC_BSEL_V:
27931 gen_msa_vec_v(env, ctx);
27932 break;
27933 case OPC_MSA_2R:
27934 gen_msa_2r(env, ctx);
27935 break;
3bdeb688
YK
27936 case OPC_MSA_2RF:
27937 gen_msa_2rf(env, ctx);
27938 break;
cbe50b9a
YK
27939 default:
27940 MIPS_INVAL("MSA instruction");
9c708c7f 27941 generate_exception_end(ctx, EXCP_RI);
cbe50b9a
YK
27942 break;
27943 }
27944}
27945
4c789546
YK
27946static void gen_msa(CPUMIPSState *env, DisasContext *ctx)
27947{
27948 uint32_t opcode = ctx->opcode;
27949 check_insn(ctx, ASE_MSA);
27950 check_msa_access(ctx);
27951
27952 switch (MASK_MSA_MINOR(opcode)) {
27953 case OPC_MSA_I8_00:
27954 case OPC_MSA_I8_01:
27955 case OPC_MSA_I8_02:
27956 gen_msa_i8(env, ctx);
27957 break;
80e71591
YK
27958 case OPC_MSA_I5_06:
27959 case OPC_MSA_I5_07:
27960 gen_msa_i5(env, ctx);
27961 break;
d4cf28de
YK
27962 case OPC_MSA_BIT_09:
27963 case OPC_MSA_BIT_0A:
27964 gen_msa_bit(env, ctx);
27965 break;
28f99f08
YK
27966 case OPC_MSA_3R_0D:
27967 case OPC_MSA_3R_0E:
27968 case OPC_MSA_3R_0F:
27969 case OPC_MSA_3R_10:
27970 case OPC_MSA_3R_11:
27971 case OPC_MSA_3R_12:
27972 case OPC_MSA_3R_13:
27973 case OPC_MSA_3R_14:
27974 case OPC_MSA_3R_15:
27975 gen_msa_3r(env, ctx);
27976 break;
1e608ec1
YK
27977 case OPC_MSA_ELM:
27978 gen_msa_elm(env, ctx);
27979 break;
7d05b9c8
YK
27980 case OPC_MSA_3RF_1A:
27981 case OPC_MSA_3RF_1B:
27982 case OPC_MSA_3RF_1C:
27983 gen_msa_3rf(env, ctx);
27984 break;
cbe50b9a
YK
27985 case OPC_MSA_VEC:
27986 gen_msa_vec(env, ctx);
27987 break;
f7685877
YK
27988 case OPC_LD_B:
27989 case OPC_LD_H:
27990 case OPC_LD_W:
27991 case OPC_LD_D:
27992 case OPC_ST_B:
27993 case OPC_ST_H:
27994 case OPC_ST_W:
27995 case OPC_ST_D:
27996 {
27997 int32_t s10 = sextract32(ctx->opcode, 16, 10);
27998 uint8_t rs = (ctx->opcode >> 11) & 0x1f;
27999 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
28000 uint8_t df = (ctx->opcode >> 0) & 0x3;
28001
f7685877 28002 TCGv_i32 twd = tcg_const_i32(wd);
adc370a4
YK
28003 TCGv taddr = tcg_temp_new();
28004 gen_base_offset_addr(ctx, taddr, rs, s10 << df);
f7685877
YK
28005
28006 switch (MASK_MSA_MINOR(opcode)) {
28007 case OPC_LD_B:
adc370a4
YK
28008 gen_helper_msa_ld_b(cpu_env, twd, taddr);
28009 break;
f7685877 28010 case OPC_LD_H:
adc370a4
YK
28011 gen_helper_msa_ld_h(cpu_env, twd, taddr);
28012 break;
f7685877 28013 case OPC_LD_W:
adc370a4
YK
28014 gen_helper_msa_ld_w(cpu_env, twd, taddr);
28015 break;
f7685877 28016 case OPC_LD_D:
adc370a4 28017 gen_helper_msa_ld_d(cpu_env, twd, taddr);
f7685877
YK
28018 break;
28019 case OPC_ST_B:
adc370a4
YK
28020 gen_helper_msa_st_b(cpu_env, twd, taddr);
28021 break;
f7685877 28022 case OPC_ST_H:
adc370a4
YK
28023 gen_helper_msa_st_h(cpu_env, twd, taddr);
28024 break;
f7685877 28025 case OPC_ST_W:
adc370a4
YK
28026 gen_helper_msa_st_w(cpu_env, twd, taddr);
28027 break;
f7685877 28028 case OPC_ST_D:
adc370a4 28029 gen_helper_msa_st_d(cpu_env, twd, taddr);
f7685877
YK
28030 break;
28031 }
28032
28033 tcg_temp_free_i32(twd);
adc370a4 28034 tcg_temp_free(taddr);
f7685877
YK
28035 }
28036 break;
4c789546
YK
28037 default:
28038 MIPS_INVAL("MSA instruction");
9c708c7f 28039 generate_exception_end(ctx, EXCP_RI);
4c789546
YK
28040 break;
28041 }
28042
28043}
28044
d2bfa6e6 28045static void decode_opc(CPUMIPSState *env, DisasContext *ctx)
099e5b4d
LA
28046{
28047 int32_t offset;
28048 int rs, rt, rd, sa;
28049 uint32_t op, op1;
28050 int16_t imm;
28051
28052 /* make sure instructions are on a word boundary */
eeb3bba8
EC
28053 if (ctx->base.pc_next & 0x3) {
28054 env->CP0_BadVAddr = ctx->base.pc_next;
aea14095 28055 generate_exception_err(ctx, EXCP_AdEL, EXCP_INST_NOTAVAIL);
099e5b4d
LA
28056 return;
28057 }
28058
28059 /* Handle blikely not taken case */
28060 if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
42a268c2 28061 TCGLabel *l1 = gen_new_label();
099e5b4d 28062
099e5b4d
LA
28063 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
28064 tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
eeb3bba8 28065 gen_goto_tb(ctx, 1, ctx->base.pc_next + 4);
099e5b4d
LA
28066 gen_set_label(l1);
28067 }
28068
099e5b4d
LA
28069 op = MASK_OP_MAJOR(ctx->opcode);
28070 rs = (ctx->opcode >> 21) & 0x1f;
28071 rt = (ctx->opcode >> 16) & 0x1f;
28072 rd = (ctx->opcode >> 11) & 0x1f;
28073 sa = (ctx->opcode >> 6) & 0x1f;
28074 imm = (int16_t)ctx->opcode;
28075 switch (op) {
28076 case OPC_SPECIAL:
28077 decode_opc_special(env, ctx);
28078 break;
28079 case OPC_SPECIAL2:
71b8a6b3 28080 if ((ctx->insn_flags & INSN_R5900) && (ctx->insn_flags & ASE_MMI)) {
874b2879 28081 decode_mmi(env, ctx);
0a348b9a
AM
28082 } else if (ctx->insn_flags & ASE_MXU) {
28083 decode_opc_mxu(env, ctx);
71b8a6b3
FN
28084 } else {
28085 decode_opc_special2_legacy(env, ctx);
28086 }
099e5b4d
LA
28087 break;
28088 case OPC_SPECIAL3:
bb41e74b 28089 if (ctx->insn_flags & INSN_R5900) {
874b2879 28090 decode_mmi_sq(env, ctx); /* MMI_OPC_SQ */
bb41e74b
FN
28091 } else {
28092 decode_opc_special3(env, ctx);
28093 }
099e5b4d 28094 break;
7a387fff
TS
28095 case OPC_REGIMM:
28096 op1 = MASK_REGIMM(ctx->opcode);
28097 switch (op1) {
fecd2646
LA
28098 case OPC_BLTZL: /* REGIMM branches */
28099 case OPC_BGEZL:
28100 case OPC_BLTZALL:
28101 case OPC_BGEZALL:
d9224450 28102 check_insn(ctx, ISA_MIPS2);
fecd2646 28103 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d9224450 28104 /* Fallthrough */
fecd2646
LA
28105 case OPC_BLTZ:
28106 case OPC_BGEZ:
b231c103 28107 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
0aefa333 28108 break;
fecd2646
LA
28109 case OPC_BLTZAL:
28110 case OPC_BGEZAL:
0aefa333
YK
28111 if (ctx->insn_flags & ISA_MIPS32R6) {
28112 if (rs == 0) {
28113 /* OPC_NAL, OPC_BAL */
b231c103 28114 gen_compute_branch(ctx, op1, 4, 0, -1, imm << 2, 4);
0aefa333 28115 } else {
9c708c7f 28116 generate_exception_end(ctx, EXCP_RI);
0aefa333
YK
28117 }
28118 } else {
b231c103 28119 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
0aefa333 28120 }
c9602061 28121 break;
c2e19f3c
AM
28122 case OPC_TGEI: /* REGIMM traps */
28123 case OPC_TGEIU:
28124 case OPC_TLTI:
28125 case OPC_TLTIU:
28126 case OPC_TEQI:
28127
7a387fff 28128 case OPC_TNEI:
d9224450 28129 check_insn(ctx, ISA_MIPS2);
fecd2646 28130 check_insn_opc_removed(ctx, ISA_MIPS32R6);
7a387fff
TS
28131 gen_trap(ctx, op1, rs, -1, imm);
28132 break;
bb238210
YK
28133 case OPC_SIGRIE:
28134 check_insn(ctx, ISA_MIPS32R6);
28135 generate_exception_end(ctx, EXCP_RI);
28136 break;
7a387fff 28137 case OPC_SYNCI:
d75c135e 28138 check_insn(ctx, ISA_MIPS32R2);
a83bddd6
DZ
28139 /* Break the TB to be able to sync copied instructions
28140 immediately */
eeb3bba8 28141 ctx->base.is_jmp = DISAS_STOP;
6af0bf9c 28142 break;
e45a93e2
JL
28143 case OPC_BPOSGE32: /* MIPS DSP branch */
28144#if defined(TARGET_MIPS64)
28145 case OPC_BPOSGE64:
28146#endif
28147 check_dsp(ctx);
b231c103 28148 gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2, 4);
e45a93e2 28149 break;
d4ea6acd
LA
28150#if defined(TARGET_MIPS64)
28151 case OPC_DAHI:
28152 check_insn(ctx, ISA_MIPS32R6);
28153 check_mips_64(ctx);
28154 if (rs != 0) {
28155 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 32);
28156 }
d4ea6acd
LA
28157 break;
28158 case OPC_DATI:
28159 check_insn(ctx, ISA_MIPS32R6);
28160 check_mips_64(ctx);
28161 if (rs != 0) {
28162 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 48);
28163 }
d4ea6acd
LA
28164 break;
28165#endif
6af0bf9c 28166 default: /* Invalid */
923617a3 28167 MIPS_INVAL("regimm");
9c708c7f 28168 generate_exception_end(ctx, EXCP_RI);
6af0bf9c
FB
28169 break;
28170 }
28171 break;
7a387fff 28172 case OPC_CP0:
387a8fe5 28173 check_cp0_enabled(ctx);
7a387fff 28174 op1 = MASK_CP0(ctx->opcode);
6af0bf9c 28175 switch (op1) {
7a387fff
TS
28176 case OPC_MFC0:
28177 case OPC_MTC0:
ead9360e
TS
28178 case OPC_MFTR:
28179 case OPC_MTTR:
5204ea79
LA
28180 case OPC_MFHC0:
28181 case OPC_MTHC0:
d26bc211 28182#if defined(TARGET_MIPS64)
7a387fff
TS
28183 case OPC_DMFC0:
28184 case OPC_DMTC0:
28185#endif
f1aa6320 28186#ifndef CONFIG_USER_ONLY
932e71cd 28187 gen_cp0(env, ctx, op1, rt, rd);
0eaef5aa 28188#endif /* !CONFIG_USER_ONLY */
7a387fff 28189 break;
c38a1d52
AR
28190 case OPC_C0:
28191 case OPC_C0_1:
28192 case OPC_C0_2:
28193 case OPC_C0_3:
28194 case OPC_C0_4:
28195 case OPC_C0_5:
28196 case OPC_C0_6:
28197 case OPC_C0_7:
28198 case OPC_C0_8:
28199 case OPC_C0_9:
28200 case OPC_C0_A:
28201 case OPC_C0_B:
28202 case OPC_C0_C:
28203 case OPC_C0_D:
28204 case OPC_C0_E:
28205 case OPC_C0_F:
f1aa6320 28206#ifndef CONFIG_USER_ONLY
932e71cd 28207 gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
0eaef5aa 28208#endif /* !CONFIG_USER_ONLY */
7a387fff
TS
28209 break;
28210 case OPC_MFMC0:
8706c382 28211#ifndef CONFIG_USER_ONLY
932e71cd 28212 {
099e5b4d 28213 uint32_t op2;
35fbce2c 28214 TCGv t0 = tcg_temp_new();
6c5c1e20 28215
0eaef5aa 28216 op2 = MASK_MFMC0(ctx->opcode);
6c5c1e20
TS
28217 switch (op2) {
28218 case OPC_DMT:
9affc1c5 28219 check_cp0_mt(ctx);
9ed5726c 28220 gen_helper_dmt(t0);
35fbce2c 28221 gen_store_gpr(t0, rt);
6c5c1e20
TS
28222 break;
28223 case OPC_EMT:
9affc1c5 28224 check_cp0_mt(ctx);
9ed5726c 28225 gen_helper_emt(t0);
35fbce2c 28226 gen_store_gpr(t0, rt);
da80682b 28227 break;
6c5c1e20 28228 case OPC_DVPE:
9affc1c5 28229 check_cp0_mt(ctx);
895c2d04 28230 gen_helper_dvpe(t0, cpu_env);
35fbce2c 28231 gen_store_gpr(t0, rt);
6c5c1e20
TS
28232 break;
28233 case OPC_EVPE:
9affc1c5 28234 check_cp0_mt(ctx);
895c2d04 28235 gen_helper_evpe(t0, cpu_env);
35fbce2c 28236 gen_store_gpr(t0, rt);
6c5c1e20 28237 break;
01bc435b
YK
28238 case OPC_DVP:
28239 check_insn(ctx, ISA_MIPS32R6);
28240 if (ctx->vp) {
28241 gen_helper_dvp(t0, cpu_env);
28242 gen_store_gpr(t0, rt);
28243 }
28244 break;
28245 case OPC_EVP:
28246 check_insn(ctx, ISA_MIPS32R6);
28247 if (ctx->vp) {
28248 gen_helper_evp(t0, cpu_env);
28249 gen_store_gpr(t0, rt);
28250 }
28251 break;
6c5c1e20 28252 case OPC_DI:
d75c135e 28253 check_insn(ctx, ISA_MIPS32R2);
867abc7e 28254 save_cpu_state(ctx, 1);
895c2d04 28255 gen_helper_di(t0, cpu_env);
35fbce2c 28256 gen_store_gpr(t0, rt);
d2bfa6e6
MR
28257 /* Stop translation as we may have switched
28258 the execution mode. */
eeb3bba8 28259 ctx->base.is_jmp = DISAS_STOP;
6c5c1e20
TS
28260 break;
28261 case OPC_EI:
d75c135e 28262 check_insn(ctx, ISA_MIPS32R2);
867abc7e 28263 save_cpu_state(ctx, 1);
895c2d04 28264 gen_helper_ei(t0, cpu_env);
35fbce2c 28265 gen_store_gpr(t0, rt);
b28425ba
EC
28266 /* DISAS_STOP isn't sufficient, we need to ensure we break
28267 out of translated code to check for pending interrupts */
eeb3bba8
EC
28268 gen_save_pc(ctx->base.pc_next + 4);
28269 ctx->base.is_jmp = DISAS_EXIT;
6c5c1e20
TS
28270 break;
28271 default: /* Invalid */
28272 MIPS_INVAL("mfmc0");
9c708c7f 28273 generate_exception_end(ctx, EXCP_RI);
6c5c1e20
TS
28274 break;
28275 }
6c5c1e20 28276 tcg_temp_free(t0);
7a387fff 28277 }
0eaef5aa 28278#endif /* !CONFIG_USER_ONLY */
6af0bf9c 28279 break;
7a387fff 28280 case OPC_RDPGPR:
d75c135e 28281 check_insn(ctx, ISA_MIPS32R2);
be24bb4f 28282 gen_load_srsgpr(rt, rd);
ead9360e 28283 break;
7a387fff 28284 case OPC_WRPGPR:
d75c135e 28285 check_insn(ctx, ISA_MIPS32R2);
be24bb4f 28286 gen_store_srsgpr(rt, rd);
38121543 28287 break;
6af0bf9c 28288 default:
923617a3 28289 MIPS_INVAL("cp0");
9c708c7f 28290 generate_exception_end(ctx, EXCP_RI);
6af0bf9c
FB
28291 break;
28292 }
28293 break;
31837be3
YK
28294 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC, OPC_ADDI */
28295 if (ctx->insn_flags & ISA_MIPS32R6) {
28296 /* OPC_BOVC, OPC_BEQZALC, OPC_BEQC */
28297 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
28298 } else {
28299 /* OPC_ADDI */
28300 /* Arithmetic with immediate opcode */
28301 gen_arith_imm(ctx, op, rt, rs, imm);
28302 }
28303 break;
324d9e32 28304 case OPC_ADDIU:
d75c135e 28305 gen_arith_imm(ctx, op, rt, rs, imm);
7a387fff 28306 break;
324d9e32
AJ
28307 case OPC_SLTI: /* Set on less than with immediate opcode */
28308 case OPC_SLTIU:
d75c135e 28309 gen_slt_imm(ctx, op, rt, rs, imm);
324d9e32
AJ
28310 break;
28311 case OPC_ANDI: /* Arithmetic with immediate opcode */
d4ea6acd 28312 case OPC_LUI: /* OPC_AUI */
324d9e32
AJ
28313 case OPC_ORI:
28314 case OPC_XORI:
d75c135e 28315 gen_logic_imm(ctx, op, rt, rs, imm);
324d9e32 28316 break;
c2e19f3c
AM
28317 case OPC_J: /* Jump */
28318 case OPC_JAL:
7a387fff 28319 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
b231c103 28320 gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
c9602061 28321 break;
31837be3
YK
28322 /* Branch */
28323 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC, OPC_BLEZL */
28324 if (ctx->insn_flags & ISA_MIPS32R6) {
28325 if (rt == 0) {
9c708c7f 28326 generate_exception_end(ctx, EXCP_RI);
31837be3
YK
28327 break;
28328 }
28329 /* OPC_BLEZC, OPC_BGEZC, OPC_BGEC */
28330 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
28331 } else {
28332 /* OPC_BLEZL */
b231c103 28333 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
31837be3
YK
28334 }
28335 break;
28336 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC, OPC_BGTZL */
28337 if (ctx->insn_flags & ISA_MIPS32R6) {
28338 if (rt == 0) {
9c708c7f 28339 generate_exception_end(ctx, EXCP_RI);
31837be3
YK
28340 break;
28341 }
28342 /* OPC_BGTZC, OPC_BLTZC, OPC_BLTC */
28343 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
28344 } else {
28345 /* OPC_BGTZL */
b231c103 28346 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
31837be3
YK
28347 }
28348 break;
28349 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC, OPC_BLEZ */
28350 if (rt == 0) {
28351 /* OPC_BLEZ */
b231c103 28352 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
31837be3
YK
28353 } else {
28354 check_insn(ctx, ISA_MIPS32R6);
28355 /* OPC_BLEZALC, OPC_BGEZALC, OPC_BGEUC */
28356 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
28357 }
28358 break;
28359 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC, OPC_BGTZ */
28360 if (rt == 0) {
28361 /* OPC_BGTZ */
b231c103 28362 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
31837be3
YK
28363 } else {
28364 check_insn(ctx, ISA_MIPS32R6);
28365 /* OPC_BGTZALC, OPC_BLTZALC, OPC_BLTUC */
28366 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
28367 }
28368 break;
28369 case OPC_BEQL:
28370 case OPC_BNEL:
d9224450 28371 check_insn(ctx, ISA_MIPS2);
fecd2646 28372 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d9224450 28373 /* Fallthrough */
31837be3
YK
28374 case OPC_BEQ:
28375 case OPC_BNE:
b231c103 28376 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
c9602061 28377 break;
d9224450
MR
28378 case OPC_LL: /* Load and stores */
28379 check_insn(ctx, ISA_MIPS2);
55fc7a69
FN
28380 if (ctx->insn_flags & INSN_R5900) {
28381 check_insn_opc_user_only(ctx, INSN_R5900);
28382 }
d9224450
MR
28383 /* Fallthrough */
28384 case OPC_LWL:
fecd2646
LA
28385 case OPC_LWR:
28386 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d9224450 28387 /* Fallthrough */
c2e19f3c
AM
28388 case OPC_LB:
28389 case OPC_LH:
28390 case OPC_LW:
28391 case OPC_LWPC:
28392 case OPC_LBU:
28393 case OPC_LHU:
d75c135e 28394 gen_ld(ctx, op, rt, rs, imm);
5c13fdfd 28395 break;
fecd2646 28396 case OPC_SWL:
7a387fff 28397 case OPC_SWR:
fecd2646 28398 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b6f3b233 28399 /* fall through */
c2e19f3c
AM
28400 case OPC_SB:
28401 case OPC_SH:
fecd2646 28402 case OPC_SW:
5c13fdfd 28403 gen_st(ctx, op, rt, rs, imm);
7a387fff 28404 break;
d66c7132 28405 case OPC_SC:
d9224450 28406 check_insn(ctx, ISA_MIPS2);
4368b29a 28407 check_insn_opc_removed(ctx, ISA_MIPS32R6);
55fc7a69
FN
28408 if (ctx->insn_flags & INSN_R5900) {
28409 check_insn_opc_user_only(ctx, INSN_R5900);
28410 }
d66c7132
AJ
28411 gen_st_cond(ctx, op, rt, rs, imm);
28412 break;
7a387fff 28413 case OPC_CACHE:
bf7910c6 28414 check_insn_opc_removed(ctx, ISA_MIPS32R6);
2e15497c 28415 check_cp0_enabled(ctx);
d75c135e 28416 check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
0d74a222
LA
28417 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
28418 gen_cache_operation(ctx, rt, rs, imm);
28419 }
ead9360e 28420 /* Treat as NOP. */
34ae7b51 28421 break;
7a387fff 28422 case OPC_PREF:
bf7910c6 28423 check_insn_opc_removed(ctx, ISA_MIPS32R6);
992e8176
FN
28424 if (ctx->insn_flags & INSN_R5900) {
28425 /* Treat as NOP. */
28426 } else {
28427 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
28428 /* Treat as NOP. */
28429 }
6af0bf9c 28430 break;
4ad40f36 28431
923617a3 28432 /* Floating point (COP1). */
7a387fff
TS
28433 case OPC_LWC1:
28434 case OPC_LDC1:
28435 case OPC_SWC1:
28436 case OPC_SDC1:
5ab5c041 28437 gen_cop1_ldst(ctx, op, rt, rs, imm);
6ea83fed
FB
28438 break;
28439
7a387fff 28440 case OPC_CP1:
5692c6e1
YK
28441 op1 = MASK_CP1(ctx->opcode);
28442
28443 switch (op1) {
28444 case OPC_MFHC1:
28445 case OPC_MTHC1:
5e755519 28446 check_cp1_enabled(ctx);
5692c6e1 28447 check_insn(ctx, ISA_MIPS32R2);
146dd620 28448 /* fall through */
5692c6e1
YK
28449 case OPC_MFC1:
28450 case OPC_CFC1:
28451 case OPC_MTC1:
28452 case OPC_CTC1:
28453 check_cp1_enabled(ctx);
28454 gen_cp1(ctx, op1, rt, rd);
28455 break;
d26bc211 28456#if defined(TARGET_MIPS64)
5692c6e1
YK
28457 case OPC_DMFC1:
28458 case OPC_DMTC1:
28459 check_cp1_enabled(ctx);
28460 check_insn(ctx, ISA_MIPS3);
d9224450 28461 check_mips_64(ctx);
5692c6e1
YK
28462 gen_cp1(ctx, op1, rt, rd);
28463 break;
e189e748 28464#endif
5692c6e1
YK
28465 case OPC_BC1EQZ: /* OPC_BC1ANY2 */
28466 check_cp1_enabled(ctx);
28467 if (ctx->insn_flags & ISA_MIPS32R6) {
28468 /* OPC_BC1EQZ */
31837be3 28469 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
65935f07 28470 rt, imm << 2, 4);
5692c6e1
YK
28471 } else {
28472 /* OPC_BC1ANY2 */
b8aa4598 28473 check_cop1x(ctx);
d75c135e 28474 check_insn(ctx, ASE_MIPS3D);
d75c135e 28475 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
5a5012ec 28476 (rt >> 2) & 0x7, imm << 2);
5692c6e1
YK
28477 }
28478 break;
28479 case OPC_BC1NEZ:
28480 check_cp1_enabled(ctx);
28481 check_insn(ctx, ISA_MIPS32R6);
28482 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
65935f07 28483 rt, imm << 2, 4);
5692c6e1
YK
28484 break;
28485 case OPC_BC1ANY4:
28486 check_cp1_enabled(ctx);
28487 check_insn_opc_removed(ctx, ISA_MIPS32R6);
28488 check_cop1x(ctx);
28489 check_insn(ctx, ASE_MIPS3D);
28490 /* fall through */
28491 case OPC_BC1:
28492 check_cp1_enabled(ctx);
28493 check_insn_opc_removed(ctx, ISA_MIPS32R6);
28494 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
28495 (rt >> 2) & 0x7, imm << 2);
28496 break;
28497 case OPC_PS_FMT:
e29c9628 28498 check_ps(ctx);
b6f3b233 28499 /* fall through */
5692c6e1
YK
28500 case OPC_S_FMT:
28501 case OPC_D_FMT:
28502 check_cp1_enabled(ctx);
28503 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
28504 (imm >> 8) & 0x7);
28505 break;
28506 case OPC_W_FMT:
28507 case OPC_L_FMT:
28508 {
28509 int r6_op = ctx->opcode & FOP(0x3f, 0x1f);
28510 check_cp1_enabled(ctx);
28511 if (ctx->insn_flags & ISA_MIPS32R6) {
28512 switch (r6_op) {
28513 case R6_OPC_CMP_AF_S:
28514 case R6_OPC_CMP_UN_S:
28515 case R6_OPC_CMP_EQ_S:
28516 case R6_OPC_CMP_UEQ_S:
28517 case R6_OPC_CMP_LT_S:
28518 case R6_OPC_CMP_ULT_S:
28519 case R6_OPC_CMP_LE_S:
28520 case R6_OPC_CMP_ULE_S:
28521 case R6_OPC_CMP_SAF_S:
28522 case R6_OPC_CMP_SUN_S:
28523 case R6_OPC_CMP_SEQ_S:
28524 case R6_OPC_CMP_SEUQ_S:
28525 case R6_OPC_CMP_SLT_S:
28526 case R6_OPC_CMP_SULT_S:
28527 case R6_OPC_CMP_SLE_S:
28528 case R6_OPC_CMP_SULE_S:
28529 case R6_OPC_CMP_OR_S:
28530 case R6_OPC_CMP_UNE_S:
28531 case R6_OPC_CMP_NE_S:
28532 case R6_OPC_CMP_SOR_S:
28533 case R6_OPC_CMP_SUNE_S:
28534 case R6_OPC_CMP_SNE_S:
28535 gen_r6_cmp_s(ctx, ctx->opcode & 0x1f, rt, rd, sa);
28536 break;
28537 case R6_OPC_CMP_AF_D:
28538 case R6_OPC_CMP_UN_D:
28539 case R6_OPC_CMP_EQ_D:
28540 case R6_OPC_CMP_UEQ_D:
28541 case R6_OPC_CMP_LT_D:
28542 case R6_OPC_CMP_ULT_D:
28543 case R6_OPC_CMP_LE_D:
28544 case R6_OPC_CMP_ULE_D:
28545 case R6_OPC_CMP_SAF_D:
28546 case R6_OPC_CMP_SUN_D:
28547 case R6_OPC_CMP_SEQ_D:
28548 case R6_OPC_CMP_SEUQ_D:
28549 case R6_OPC_CMP_SLT_D:
28550 case R6_OPC_CMP_SULT_D:
28551 case R6_OPC_CMP_SLE_D:
28552 case R6_OPC_CMP_SULE_D:
28553 case R6_OPC_CMP_OR_D:
28554 case R6_OPC_CMP_UNE_D:
28555 case R6_OPC_CMP_NE_D:
28556 case R6_OPC_CMP_SOR_D:
28557 case R6_OPC_CMP_SUNE_D:
28558 case R6_OPC_CMP_SNE_D:
28559 gen_r6_cmp_d(ctx, ctx->opcode & 0x1f, rt, rd, sa);
28560 break;
28561 default:
d2bfa6e6
MR
28562 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f),
28563 rt, rd, sa, (imm >> 8) & 0x7);
28564
5692c6e1 28565 break;
3f493883 28566 }
5692c6e1
YK
28567 } else {
28568 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
28569 (imm >> 8) & 0x7);
36d23958 28570 }
5692c6e1
YK
28571 break;
28572 }
28573 case OPC_BZ_V:
28574 case OPC_BNZ_V:
28575 case OPC_BZ_B:
28576 case OPC_BZ_H:
28577 case OPC_BZ_W:
28578 case OPC_BZ_D:
28579 case OPC_BNZ_B:
28580 case OPC_BNZ_H:
28581 case OPC_BNZ_W:
28582 case OPC_BNZ_D:
28583 check_insn(ctx, ASE_MSA);
28584 gen_msa_branch(env, ctx, op1);
28585 break;
28586 default:
28587 MIPS_INVAL("cp1");
9c708c7f 28588 generate_exception_end(ctx, EXCP_RI);
5692c6e1 28589 break;
6ea83fed 28590 }
4ad40f36
FB
28591 break;
28592
31837be3
YK
28593 /* Compact branches [R6] and COP2 [non-R6] */
28594 case OPC_BC: /* OPC_LWC2 */
28595 case OPC_BALC: /* OPC_SWC2 */
28596 if (ctx->insn_flags & ISA_MIPS32R6) {
28597 /* OPC_BC, OPC_BALC */
28598 gen_compute_compact_branch(ctx, op, 0, 0,
28599 sextract32(ctx->opcode << 2, 0, 28));
28600 } else {
28601 /* OPC_LWC2, OPC_SWC2 */
28602 /* COP2: Not implemented. */
28603 generate_exception_err(ctx, EXCP_CpU, 2);
28604 }
28605 break;
28606 case OPC_BEQZC: /* OPC_JIC, OPC_LDC2 */
28607 case OPC_BNEZC: /* OPC_JIALC, OPC_SDC2 */
28608 if (ctx->insn_flags & ISA_MIPS32R6) {
28609 if (rs != 0) {
28610 /* OPC_BEQZC, OPC_BNEZC */
28611 gen_compute_compact_branch(ctx, op, rs, 0,
28612 sextract32(ctx->opcode << 2, 0, 23));
28613 } else {
28614 /* OPC_JIC, OPC_JIALC */
28615 gen_compute_compact_branch(ctx, op, 0, rt, imm);
28616 }
28617 } else {
28618 /* OPC_LWC2, OPC_SWC2 */
28619 /* COP2: Not implemented. */
28620 generate_exception_err(ctx, EXCP_CpU, 2);
28621 }
4ad40f36 28622 break;
bd277fa1 28623 case OPC_CP2:
d75c135e 28624 check_insn(ctx, INSN_LOONGSON2F);
bd277fa1
RH
28625 /* Note that these instructions use different fields. */
28626 gen_loongson_multimedia(ctx, sa, rd, rt);
28627 break;
4ad40f36 28628
7a387fff 28629 case OPC_CP3:
fecd2646 28630 check_insn_opc_removed(ctx, ISA_MIPS32R6);
5ab5c041 28631 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
5e755519 28632 check_cp1_enabled(ctx);
36d23958
TS
28633 op1 = MASK_CP3(ctx->opcode);
28634 switch (op1) {
d9224450
MR
28635 case OPC_LUXC1:
28636 case OPC_SUXC1:
28637 check_insn(ctx, ISA_MIPS5 | ISA_MIPS32R2);
28638 /* Fallthrough */
5a5012ec
TS
28639 case OPC_LWXC1:
28640 case OPC_LDXC1:
5a5012ec
TS
28641 case OPC_SWXC1:
28642 case OPC_SDXC1:
d9224450 28643 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
93b12ccc 28644 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
5a5012ec 28645 break;
e0c84da7 28646 case OPC_PREFX:
d9224450 28647 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
ead9360e 28648 /* Treat as NOP. */
e0c84da7 28649 break;
5a5012ec 28650 case OPC_ALNV_PS:
d9224450
MR
28651 check_insn(ctx, ISA_MIPS5 | ISA_MIPS32R2);
28652 /* Fallthrough */
5a5012ec
TS
28653 case OPC_MADD_S:
28654 case OPC_MADD_D:
28655 case OPC_MADD_PS:
28656 case OPC_MSUB_S:
28657 case OPC_MSUB_D:
28658 case OPC_MSUB_PS:
28659 case OPC_NMADD_S:
28660 case OPC_NMADD_D:
28661 case OPC_NMADD_PS:
28662 case OPC_NMSUB_S:
28663 case OPC_NMSUB_D:
28664 case OPC_NMSUB_PS:
d9224450 28665 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
5a5012ec
TS
28666 gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
28667 break;
36d23958 28668 default:
923617a3 28669 MIPS_INVAL("cp3");
9c708c7f 28670 generate_exception_end(ctx, EXCP_RI);
36d23958
TS
28671 break;
28672 }
28673 } else {
e397ee33 28674 generate_exception_err(ctx, EXCP_CpU, 1);
7a387fff 28675 }
4ad40f36
FB
28676 break;
28677
d26bc211 28678#if defined(TARGET_MIPS64)
7a387fff 28679 /* MIPS64 opcodes */
96631327 28680 case OPC_LLD:
55fc7a69
FN
28681 if (ctx->insn_flags & INSN_R5900) {
28682 check_insn_opc_user_only(ctx, INSN_R5900);
28683 }
96631327 28684 /* fall through */
c2e19f3c
AM
28685 case OPC_LDL:
28686 case OPC_LDR:
fecd2646 28687 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b6f3b233 28688 /* fall through */
fecd2646 28689 case OPC_LWU:
7a387fff 28690 case OPC_LD:
d75c135e 28691 check_insn(ctx, ISA_MIPS3);
5c13fdfd 28692 check_mips_64(ctx);
d75c135e 28693 gen_ld(ctx, op, rt, rs, imm);
5c13fdfd 28694 break;
c2e19f3c
AM
28695 case OPC_SDL:
28696 case OPC_SDR:
fecd2646 28697 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b6f3b233 28698 /* fall through */
7a387fff 28699 case OPC_SD:
d75c135e 28700 check_insn(ctx, ISA_MIPS3);
e189e748 28701 check_mips_64(ctx);
5c13fdfd 28702 gen_st(ctx, op, rt, rs, imm);
7a387fff 28703 break;
d66c7132 28704 case OPC_SCD:
bf7910c6 28705 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d75c135e 28706 check_insn(ctx, ISA_MIPS3);
55fc7a69
FN
28707 if (ctx->insn_flags & INSN_R5900) {
28708 check_insn_opc_user_only(ctx, INSN_R5900);
28709 }
d66c7132
AJ
28710 check_mips_64(ctx);
28711 gen_st_cond(ctx, op, rt, rs, imm);
28712 break;
31837be3
YK
28713 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC, OPC_DADDI */
28714 if (ctx->insn_flags & ISA_MIPS32R6) {
28715 /* OPC_BNVC, OPC_BNEZALC, OPC_BNEC */
28716 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
28717 } else {
28718 /* OPC_DADDI */
28719 check_insn(ctx, ISA_MIPS3);
28720 check_mips_64(ctx);
28721 gen_arith_imm(ctx, op, rt, rs, imm);
28722 }
28723 break;
324d9e32 28724 case OPC_DADDIU:
d75c135e 28725 check_insn(ctx, ISA_MIPS3);
e189e748 28726 check_mips_64(ctx);
d75c135e 28727 gen_arith_imm(ctx, op, rt, rs, imm);
7a387fff 28728 break;
31837be3
YK
28729#else
28730 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
28731 if (ctx->insn_flags & ISA_MIPS32R6) {
28732 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
28733 } else {
28734 MIPS_INVAL("major opcode");
9c708c7f 28735 generate_exception_end(ctx, EXCP_RI);
31837be3
YK
28736 }
28737 break;
6af0bf9c 28738#endif
d4ea6acd
LA
28739 case OPC_DAUI: /* OPC_JALX */
28740 if (ctx->insn_flags & ISA_MIPS32R6) {
28741#if defined(TARGET_MIPS64)
28742 /* OPC_DAUI */
28743 check_mips_64(ctx);
db77d852
LA
28744 if (rs == 0) {
28745 generate_exception(ctx, EXCP_RI);
28746 } else if (rt != 0) {
d4ea6acd
LA
28747 TCGv t0 = tcg_temp_new();
28748 gen_load_gpr(t0, rs);
28749 tcg_gen_addi_tl(cpu_gpr[rt], t0, imm << 16);
28750 tcg_temp_free(t0);
28751 }
d4ea6acd 28752#else
9c708c7f 28753 generate_exception_end(ctx, EXCP_RI);
d4ea6acd
LA
28754 MIPS_INVAL("major opcode");
28755#endif
28756 } else {
28757 /* OPC_JALX */
28758 check_insn(ctx, ASE_MIPS16 | ASE_MICROMIPS);
28759 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
b231c103 28760 gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
d4ea6acd 28761 }
364d4831 28762 break;
4c789546 28763 case OPC_MSA: /* OPC_MDMX */
f08099ad 28764 if (ctx->insn_flags & INSN_R5900) {
874b2879 28765 gen_mmi_lq(env, ctx); /* MMI_OPC_LQ */
f08099ad
FN
28766 } else {
28767 /* MDMX: Not implemented. */
28768 gen_msa(env, ctx);
28769 }
d4ea6acd
LA
28770 break;
28771 case OPC_PCREL:
28772 check_insn(ctx, ISA_MIPS32R6);
eeb3bba8 28773 gen_pcrel(ctx, ctx->opcode, ctx->base.pc_next, rs);
d4ea6acd 28774 break;
6af0bf9c 28775 default: /* Invalid */
923617a3 28776 MIPS_INVAL("major opcode");
9c708c7f 28777 generate_exception_end(ctx, EXCP_RI);
6af0bf9c
FB
28778 break;
28779 }
6af0bf9c
FB
28780}
28781
18f440ed 28782static void mips_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
6af0bf9c 28783{
18f440ed 28784 DisasContext *ctx = container_of(dcbase, DisasContext, base);
9c489ea6 28785 CPUMIPSState *env = cs->env_ptr;
12be9258 28786
18f440ed 28787 ctx->page_start = ctx->base.pc_first & TARGET_PAGE_MASK;
12be9258
EC
28788 ctx->saved_pc = -1;
28789 ctx->insn_flags = env->insn_flags;
28790 ctx->CP0_Config1 = env->CP0_Config1;
49735f76 28791 ctx->CP0_Config2 = env->CP0_Config2;
ab77fc61
DN
28792 ctx->CP0_Config3 = env->CP0_Config3;
28793 ctx->CP0_Config5 = env->CP0_Config5;
12be9258
EC
28794 ctx->btarget = 0;
28795 ctx->kscrexist = (env->CP0_Config4 >> CP0C4_KScrExist) & 0xff;
28796 ctx->rxi = (env->CP0_Config3 >> CP0C3_RXI) & 1;
28797 ctx->ie = (env->CP0_Config4 >> CP0C4_IE) & 3;
28798 ctx->bi = (env->CP0_Config3 >> CP0C3_BI) & 1;
28799 ctx->bp = (env->CP0_Config3 >> CP0C3_BP) & 1;
28800 ctx->PAMask = env->PAMask;
28801 ctx->mvh = (env->CP0_Config5 >> CP0C5_MVH) & 1;
28802 ctx->eva = (env->CP0_Config5 >> CP0C5_EVA) & 1;
28803 ctx->sc = (env->CP0_Config3 >> CP0C3_SC) & 1;
28804 ctx->CP0_LLAddr_shift = env->CP0_LLAddr_shift;
28805 ctx->cmgcr = (env->CP0_Config3 >> CP0C3_CMGCR) & 1;
4ad40f36 28806 /* Restore delay slot state from the tb context. */
12be9258
EC
28807 ctx->hflags = (uint32_t)ctx->base.tb->flags; /* FIXME: maybe use 64 bits? */
28808 ctx->ulri = (env->CP0_Config3 >> CP0C3_ULRI) & 1;
28809 ctx->ps = ((env->active_fpu.fcr0 >> FCR0_PS) & 1) ||
e29c9628 28810 (env->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F));
12be9258
EC
28811 ctx->vp = (env->CP0_Config5 >> CP0C5_VP) & 1;
28812 ctx->mrp = (env->CP0_Config5 >> CP0C5_MRP) & 1;
28813 ctx->nan2008 = (env->active_fpu.fcr31 >> FCR31_NAN2008) & 1;
28814 ctx->abs2008 = (env->active_fpu.fcr31 >> FCR31_ABS2008) & 1;
28815 restore_cpu_state(env, ctx);
932e71cd 28816#ifdef CONFIG_USER_ONLY
12be9258 28817 ctx->mem_idx = MIPS_HFLAG_UM;
932e71cd 28818#else
12be9258 28819 ctx->mem_idx = hflags_mmu_index(ctx->hflags);
932e71cd 28820#endif
12be9258
EC
28821 ctx->default_tcg_memop_mask = (ctx->insn_flags & ISA_MIPS32R6) ?
28822 MO_UNALN : MO_ALIGN;
190ce7fb 28823
18f440ed
EC
28824 LOG_DISAS("\ntb %p idx %d hflags %04x\n", ctx->base.tb, ctx->mem_idx,
28825 ctx->hflags);
28826}
12be9258 28827
18f440ed
EC
28828static void mips_tr_tb_start(DisasContextBase *dcbase, CPUState *cs)
28829{
28830}
b933066a 28831
18f440ed
EC
28832static void mips_tr_insn_start(DisasContextBase *dcbase, CPUState *cs)
28833{
28834 DisasContext *ctx = container_of(dcbase, DisasContext, base);
c9602061 28835
18f440ed
EC
28836 tcg_gen_insn_start(ctx->base.pc_next, ctx->hflags & MIPS_HFLAG_BMASK,
28837 ctx->btarget);
28838}
31837be3 28839
18f440ed
EC
28840static bool mips_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cs,
28841 const CPUBreakpoint *bp)
28842{
28843 DisasContext *ctx = container_of(dcbase, DisasContext, base);
c9602061 28844
18f440ed
EC
28845 save_cpu_state(ctx, 1);
28846 ctx->base.is_jmp = DISAS_NORETURN;
28847 gen_helper_raise_exception_debug(cpu_env);
28848 /* The address covered by the breakpoint must be included in
28849 [tb->pc, tb->pc + tb->size) in order to for it to be
28850 properly cleared -- thus we increment the PC here so that
28851 the logic setting tb->size below does the right thing. */
28852 ctx->base.pc_next += 4;
28853 return true;
28854}
4ad40f36 28855
18f440ed
EC
28856static void mips_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
28857{
28858 CPUMIPSState *env = cs->env_ptr;
28859 DisasContext *ctx = container_of(dcbase, DisasContext, base);
28860 int insn_bytes;
28861 int is_slot;
4ad40f36 28862
18f440ed 28863 is_slot = ctx->hflags & MIPS_HFLAG_BMASK;
c533c0f4
AM
28864 if (ctx->insn_flags & ISA_NANOMIPS32) {
28865 ctx->opcode = cpu_lduw_code(env, ctx->base.pc_next);
28866 insn_bytes = decode_nanomips_opc(env, ctx);
28867 } else if (!(ctx->hflags & MIPS_HFLAG_M16)) {
18f440ed
EC
28868 ctx->opcode = cpu_ldl_code(env, ctx->base.pc_next);
28869 insn_bytes = 4;
28870 decode_opc(env, ctx);
28871 } else if (ctx->insn_flags & ASE_MICROMIPS) {
28872 ctx->opcode = cpu_lduw_code(env, ctx->base.pc_next);
28873 insn_bytes = decode_micromips_opc(env, ctx);
28874 } else if (ctx->insn_flags & ASE_MIPS16) {
28875 ctx->opcode = cpu_lduw_code(env, ctx->base.pc_next);
28876 insn_bytes = decode_mips16_opc(env, ctx);
28877 } else {
28878 generate_exception_end(ctx, EXCP_RI);
28879 g_assert(ctx->base.is_jmp == DISAS_NORETURN);
28880 return;
28881 }
faf7aaa9 28882
18f440ed
EC
28883 if (ctx->hflags & MIPS_HFLAG_BMASK) {
28884 if (!(ctx->hflags & (MIPS_HFLAG_BDS16 | MIPS_HFLAG_BDS32 |
28885 MIPS_HFLAG_FBNSLOT))) {
28886 /* force to generate branch as there is neither delay nor
28887 forbidden slot */
28888 is_slot = 1;
28889 }
28890 if ((ctx->hflags & MIPS_HFLAG_M16) &&
28891 (ctx->hflags & MIPS_HFLAG_FBNSLOT)) {
28892 /* Force to generate branch as microMIPS R6 doesn't restrict
28893 branches in the forbidden slot. */
28894 is_slot = 1;
eeb3bba8 28895 }
18f440ed
EC
28896 }
28897 if (is_slot) {
28898 gen_branch(ctx, insn_bytes);
28899 }
28900 ctx->base.pc_next += insn_bytes;
1b530a6d 28901
18f440ed
EC
28902 if (ctx->base.is_jmp != DISAS_NEXT) {
28903 return;
6af0bf9c 28904 }
18f440ed
EC
28905 /* Execute a branch and its delay slot as a single instruction.
28906 This is what GDB expects and is consistent with what the
28907 hardware does (e.g. if a delay slot instruction faults, the
28908 reported PC is the PC of the branch). */
28909 if (ctx->base.singlestep_enabled &&
28910 (ctx->hflags & MIPS_HFLAG_BMASK) == 0) {
28911 ctx->base.is_jmp = DISAS_TOO_MANY;
28912 }
28913 if (ctx->base.pc_next - ctx->page_start >= TARGET_PAGE_SIZE) {
28914 ctx->base.is_jmp = DISAS_TOO_MANY;
ed2803da 28915 }
18f440ed
EC
28916}
28917
28918static void mips_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
28919{
28920 DisasContext *ctx = container_of(dcbase, DisasContext, base);
28921
12be9258
EC
28922 if (ctx->base.singlestep_enabled && ctx->base.is_jmp != DISAS_NORETURN) {
28923 save_cpu_state(ctx, ctx->base.is_jmp != DISAS_EXIT);
9c708c7f 28924 gen_helper_raise_exception_debug(cpu_env);
16c00cb2 28925 } else {
12be9258 28926 switch (ctx->base.is_jmp) {
b28425ba 28927 case DISAS_STOP:
12be9258 28928 gen_save_pc(ctx->base.pc_next);
cd314a7d 28929 tcg_gen_lookup_and_goto_ptr();
df1561e2 28930 break;
b28425ba 28931 case DISAS_NEXT:
18f440ed 28932 case DISAS_TOO_MANY:
12be9258
EC
28933 save_cpu_state(ctx, 0);
28934 gen_goto_tb(ctx, 0, ctx->base.pc_next);
16c00cb2 28935 break;
b28425ba 28936 case DISAS_EXIT:
07ea28b4 28937 tcg_gen_exit_tb(NULL, 0);
16c00cb2 28938 break;
b28425ba 28939 case DISAS_NORETURN:
5a5012ec 28940 break;
18f440ed
EC
28941 default:
28942 g_assert_not_reached();
6958549d 28943 }
6af0bf9c 28944 }
18f440ed
EC
28945}
28946
28947static void mips_tr_disas_log(const DisasContextBase *dcbase, CPUState *cs)
28948{
28949 qemu_log("IN: %s\n", lookup_symbol(dcbase->pc_first));
28950 log_target_disas(cs, dcbase->pc_first, dcbase->tb->size);
28951}
28952
28953static const TranslatorOps mips_tr_ops = {
28954 .init_disas_context = mips_tr_init_disas_context,
28955 .tb_start = mips_tr_tb_start,
28956 .insn_start = mips_tr_insn_start,
28957 .breakpoint_check = mips_tr_breakpoint_check,
28958 .translate_insn = mips_tr_translate_insn,
28959 .tb_stop = mips_tr_tb_stop,
28960 .disas_log = mips_tr_disas_log,
28961};
28962
28963void gen_intermediate_code(CPUState *cs, struct TranslationBlock *tb)
28964{
28965 DisasContext ctx;
28966
28967 translator_loop(&mips_tr_ops, &ctx.base, cs, tb);
6af0bf9c
FB
28968}
28969
7db13fae 28970static void fpu_dump_state(CPUMIPSState *env, FILE *f, fprintf_function fpu_fprintf,
8706c382 28971 int flags)
6ea83fed
FB
28972{
28973 int i;
5e755519 28974 int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
5a5012ec 28975
2a5612e6
SW
28976#define printfpr(fp) \
28977 do { \
28978 if (is_fpu64) \
28979 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
28980 " fd:%13g fs:%13g psu: %13g\n", \
28981 (fp)->w[FP_ENDIAN_IDX], (fp)->d, \
28982 (double)(fp)->fd, \
28983 (double)(fp)->fs[FP_ENDIAN_IDX], \
28984 (double)(fp)->fs[!FP_ENDIAN_IDX]); \
28985 else { \
28986 fpr_t tmp; \
28987 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
28988 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
28989 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
28990 " fd:%13g fs:%13g psu:%13g\n", \
28991 tmp.w[FP_ENDIAN_IDX], tmp.d, \
28992 (double)tmp.fd, \
28993 (double)tmp.fs[FP_ENDIAN_IDX], \
28994 (double)tmp.fs[!FP_ENDIAN_IDX]); \
28995 } \
6ea83fed
FB
28996 } while(0)
28997
5a5012ec 28998
9a78eead
SW
28999 fpu_fprintf(f, "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%02x\n",
29000 env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64,
f01be154 29001 get_float_exception_flags(&env->active_fpu.fp_status));
5a5012ec
TS
29002 for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
29003 fpu_fprintf(f, "%3s: ", fregnames[i]);
f01be154 29004 printfpr(&env->active_fpu.fpr[i]);
6ea83fed
FB
29005 }
29006
29007#undef printfpr
29008}
29009
878096ee
AF
29010void mips_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
29011 int flags)
6af0bf9c 29012{
878096ee
AF
29013 MIPSCPU *cpu = MIPS_CPU(cs);
29014 CPUMIPSState *env = &cpu->env;
6af0bf9c 29015 int i;
3b46e624 29016
a7200c9f
SW
29017 cpu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
29018 " LO=0x" TARGET_FMT_lx " ds %04x "
29019 TARGET_FMT_lx " " TARGET_FMT_ld "\n",
3d5be870
TS
29020 env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
29021 env->hflags, env->btarget, env->bcond);
6af0bf9c
FB
29022 for (i = 0; i < 32; i++) {
29023 if ((i & 3) == 0)
29024 cpu_fprintf(f, "GPR%02d:", i);
b5dc7732 29025 cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
6af0bf9c
FB
29026 if ((i & 3) == 3)
29027 cpu_fprintf(f, "\n");
29028 }
568b600d 29029
3594c774 29030 cpu_fprintf(f, "CP0 Status 0x%08x Cause 0x%08x EPC 0x" TARGET_FMT_lx "\n",
5e755519 29031 env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
284b731a
LA
29032 cpu_fprintf(f, " Config0 0x%08x Config1 0x%08x LLAddr 0x%016"
29033 PRIx64 "\n",
5499b6ff 29034 env->CP0_Config0, env->CP0_Config1, env->lladdr);
27e1fb13
MR
29035 cpu_fprintf(f, " Config2 0x%08x Config3 0x%08x\n",
29036 env->CP0_Config2, env->CP0_Config3);
29037 cpu_fprintf(f, " Config4 0x%08x Config5 0x%08x\n",
29038 env->CP0_Config4, env->CP0_Config5);
1cc5af69 29039 if ((flags & CPU_DUMP_FPU) && (env->hflags & MIPS_HFLAG_FPU)) {
7a387fff 29040 fpu_dump_state(env, f, cpu_fprintf, flags);
1cc5af69 29041 }
6af0bf9c
FB
29042}
29043
78ce64f4 29044void mips_tcg_init(void)
39454628 29045{
f01be154 29046 int i;
39454628 29047
f764718d 29048 cpu_gpr[0] = NULL;
bb928dbe 29049 for (i = 1; i < 32; i++)
e1ccc054 29050 cpu_gpr[i] = tcg_global_mem_new(cpu_env,
7db13fae 29051 offsetof(CPUMIPSState, active_tc.gpr[i]),
4b2eb8d2 29052 regnames[i]);
d73ee8a2 29053
863f264d
YK
29054 for (i = 0; i < 32; i++) {
29055 int off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[0]);
29056 msa_wr_d[i * 2] =
e1ccc054 29057 tcg_global_mem_new_i64(cpu_env, off, msaregnames[i * 2]);
cb269f27
YK
29058 /* The scalar floating-point unit (FPU) registers are mapped on
29059 * the MSA vector registers. */
29060 fpu_f64[i] = msa_wr_d[i * 2];
863f264d
YK
29061 off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[1]);
29062 msa_wr_d[i * 2 + 1] =
e1ccc054 29063 tcg_global_mem_new_i64(cpu_env, off, msaregnames[i * 2 + 1]);
863f264d
YK
29064 }
29065
e1ccc054 29066 cpu_PC = tcg_global_mem_new(cpu_env,
7db13fae 29067 offsetof(CPUMIPSState, active_tc.PC), "PC");
4b2eb8d2 29068 for (i = 0; i < MIPS_DSP_ACC; i++) {
e1ccc054 29069 cpu_HI[i] = tcg_global_mem_new(cpu_env,
7db13fae 29070 offsetof(CPUMIPSState, active_tc.HI[i]),
4b2eb8d2 29071 regnames_HI[i]);
e1ccc054 29072 cpu_LO[i] = tcg_global_mem_new(cpu_env,
7db13fae 29073 offsetof(CPUMIPSState, active_tc.LO[i]),
4b2eb8d2 29074 regnames_LO[i]);
4b2eb8d2 29075 }
e1ccc054 29076 cpu_dspctrl = tcg_global_mem_new(cpu_env,
7db13fae 29077 offsetof(CPUMIPSState, active_tc.DSPControl),
4b2eb8d2 29078 "DSPControl");
e1ccc054 29079 bcond = tcg_global_mem_new(cpu_env,
7db13fae 29080 offsetof(CPUMIPSState, bcond), "bcond");
e1ccc054 29081 btarget = tcg_global_mem_new(cpu_env,
7db13fae 29082 offsetof(CPUMIPSState, btarget), "btarget");
e1ccc054 29083 hflags = tcg_global_mem_new_i32(cpu_env,
7db13fae 29084 offsetof(CPUMIPSState, hflags), "hflags");
41db4607 29085
e1ccc054 29086 fpu_fcr0 = tcg_global_mem_new_i32(cpu_env,
7db13fae 29087 offsetof(CPUMIPSState, active_fpu.fcr0),
a7812ae4 29088 "fcr0");
e1ccc054 29089 fpu_fcr31 = tcg_global_mem_new_i32(cpu_env,
7db13fae 29090 offsetof(CPUMIPSState, active_fpu.fcr31),
a7812ae4 29091 "fcr31");
eb5559f6
CJ
29092
29093 for (i = 0; i < NUMBER_OF_MXU_REGISTERS - 1; i++) {
29094 mxu_gpr[i] = tcg_global_mem_new(cpu_env,
29095 offsetof(CPUMIPSState,
29096 active_tc.mxu_gpr[i]),
29097 mxuregnames[i]);
29098 }
29099
29100 mxu_CR = tcg_global_mem_new(cpu_env,
29101 offsetof(CPUMIPSState, active_tc.mxu_cr),
29102 mxuregnames[NUMBER_OF_MXU_REGISTERS - 1]);
39454628
TS
29103}
29104
5b27a92d 29105#include "translate_init.inc.c"
aaed909a 29106
27e38392
PMD
29107void cpu_mips_realize_env(CPUMIPSState *env)
29108{
29109 env->exception_base = (int32_t)0xBFC00000;
29110
29111#ifndef CONFIG_USER_ONLY
29112 mmu_init(env, env->cpu_model);
29113#endif
29114 fpu_init(env, env->cpu_model);
29115 mvp_init(env, env->cpu_model);
29116}
29117
a7519f2b 29118bool cpu_supports_cps_smp(const char *cpu_type)
bff384a4 29119{
a7519f2b
IM
29120 const MIPSCPUClass *mcc = MIPS_CPU_CLASS(object_class_by_name(cpu_type));
29121 return (mcc->cpu_def->CP0_Config3 & (1 << CP0C3_CMGCR)) != 0;
bff384a4
LA
29122}
29123
a7519f2b 29124bool cpu_supports_isa(const char *cpu_type, unsigned int isa)
bed9e5ce 29125{
a7519f2b
IM
29126 const MIPSCPUClass *mcc = MIPS_CPU_CLASS(object_class_by_name(cpu_type));
29127 return (mcc->cpu_def->insn_flags & isa) != 0;
bed9e5ce
PB
29128}
29129
89777fd1
LA
29130void cpu_set_exception_base(int vp_index, target_ulong address)
29131{
29132 MIPSCPU *vp = MIPS_CPU(qemu_get_cpu(vp_index));
29133 vp->env.exception_base = address;
29134}
29135
1bba0dc9 29136void cpu_state_reset(CPUMIPSState *env)
6ae81775 29137{
55e5c285
AF
29138 MIPSCPU *cpu = mips_env_get_cpu(env);
29139 CPUState *cs = CPU(cpu);
6ae81775 29140
51cc2e78
BS
29141 /* Reset registers to their default values */
29142 env->CP0_PRid = env->cpu_model->CP0_PRid;
29143 env->CP0_Config0 = env->cpu_model->CP0_Config0;
29144#ifdef TARGET_WORDS_BIGENDIAN
29145 env->CP0_Config0 |= (1 << CP0C0_BE);
29146#endif
29147 env->CP0_Config1 = env->cpu_model->CP0_Config1;
29148 env->CP0_Config2 = env->cpu_model->CP0_Config2;
29149 env->CP0_Config3 = env->cpu_model->CP0_Config3;
b4160af1
PJ
29150 env->CP0_Config4 = env->cpu_model->CP0_Config4;
29151 env->CP0_Config4_rw_bitmask = env->cpu_model->CP0_Config4_rw_bitmask;
b4dd99a3
PJ
29152 env->CP0_Config5 = env->cpu_model->CP0_Config5;
29153 env->CP0_Config5_rw_bitmask = env->cpu_model->CP0_Config5_rw_bitmask;
51cc2e78
BS
29154 env->CP0_Config6 = env->cpu_model->CP0_Config6;
29155 env->CP0_Config7 = env->cpu_model->CP0_Config7;
2a6e32dd
AJ
29156 env->CP0_LLAddr_rw_bitmask = env->cpu_model->CP0_LLAddr_rw_bitmask
29157 << env->cpu_model->CP0_LLAddr_shift;
29158 env->CP0_LLAddr_shift = env->cpu_model->CP0_LLAddr_shift;
51cc2e78
BS
29159 env->SYNCI_Step = env->cpu_model->SYNCI_Step;
29160 env->CCRes = env->cpu_model->CCRes;
29161 env->CP0_Status_rw_bitmask = env->cpu_model->CP0_Status_rw_bitmask;
29162 env->CP0_TCStatus_rw_bitmask = env->cpu_model->CP0_TCStatus_rw_bitmask;
29163 env->CP0_SRSCtl = env->cpu_model->CP0_SRSCtl;
29164 env->current_tc = 0;
29165 env->SEGBITS = env->cpu_model->SEGBITS;
29166 env->SEGMask = (target_ulong)((1ULL << env->cpu_model->SEGBITS) - 1);
29167#if defined(TARGET_MIPS64)
29168 if (env->cpu_model->insn_flags & ISA_MIPS3) {
29169 env->SEGMask |= 3ULL << 62;
29170 }
29171#endif
29172 env->PABITS = env->cpu_model->PABITS;
51cc2e78
BS
29173 env->CP0_SRSConf0_rw_bitmask = env->cpu_model->CP0_SRSConf0_rw_bitmask;
29174 env->CP0_SRSConf0 = env->cpu_model->CP0_SRSConf0;
29175 env->CP0_SRSConf1_rw_bitmask = env->cpu_model->CP0_SRSConf1_rw_bitmask;
29176 env->CP0_SRSConf1 = env->cpu_model->CP0_SRSConf1;
29177 env->CP0_SRSConf2_rw_bitmask = env->cpu_model->CP0_SRSConf2_rw_bitmask;
29178 env->CP0_SRSConf2 = env->cpu_model->CP0_SRSConf2;
29179 env->CP0_SRSConf3_rw_bitmask = env->cpu_model->CP0_SRSConf3_rw_bitmask;
29180 env->CP0_SRSConf3 = env->cpu_model->CP0_SRSConf3;
29181 env->CP0_SRSConf4_rw_bitmask = env->cpu_model->CP0_SRSConf4_rw_bitmask;
29182 env->CP0_SRSConf4 = env->cpu_model->CP0_SRSConf4;
7207c7f9
LA
29183 env->CP0_PageGrain_rw_bitmask = env->cpu_model->CP0_PageGrain_rw_bitmask;
29184 env->CP0_PageGrain = env->cpu_model->CP0_PageGrain;
74dbf824 29185 env->CP0_EBaseWG_rw_bitmask = env->cpu_model->CP0_EBaseWG_rw_bitmask;
f1cb0951 29186 env->active_fpu.fcr0 = env->cpu_model->CP1_fcr0;
599bc5e8 29187 env->active_fpu.fcr31_rw_bitmask = env->cpu_model->CP1_fcr31_rw_bitmask;
ba5c79f2 29188 env->active_fpu.fcr31 = env->cpu_model->CP1_fcr31;
863f264d 29189 env->msair = env->cpu_model->MSAIR;
51cc2e78
BS
29190 env->insn_flags = env->cpu_model->insn_flags;
29191
0eaef5aa 29192#if defined(CONFIG_USER_ONLY)
03e6e501 29193 env->CP0_Status = (MIPS_HFLAG_UM << CP0St_KSU);
68473f15
RH
29194# ifdef TARGET_MIPS64
29195 /* Enable 64-bit register mode. */
29196 env->CP0_Status |= (1 << CP0St_PX);
29197# endif
29198# ifdef TARGET_ABI_MIPSN64
29199 /* Enable 64-bit address mode. */
29200 env->CP0_Status |= (1 << CP0St_UX);
29201# endif
94159135
MI
29202 /* Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
29203 hardware registers. */
29204 env->CP0_HWREna |= 0x0000000F;
91a75935 29205 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
03e6e501 29206 env->CP0_Status |= (1 << CP0St_CU1);
91a75935 29207 }
6f0af304
PJ
29208 if (env->CP0_Config3 & (1 << CP0C3_DSPP)) {
29209 env->CP0_Status |= (1 << CP0St_MX);
853c3240 29210 }
4d66261f
PJ
29211# if defined(TARGET_MIPS64)
29212 /* For MIPS64, init FR bit to 1 if FPU unit is there and bit is writable. */
29213 if ((env->CP0_Config1 & (1 << CP0C1_FP)) &&
29214 (env->CP0_Status_rw_bitmask & (1 << CP0St_FR))) {
68473f15
RH
29215 env->CP0_Status |= (1 << CP0St_FR);
29216 }
4d66261f 29217# endif
932e71cd
AJ
29218#else
29219 if (env->hflags & MIPS_HFLAG_BMASK) {
29220 /* If the exception was raised from a delay slot,
29221 come back to the jump. */
c3577479
MR
29222 env->CP0_ErrorEPC = (env->active_tc.PC
29223 - (env->hflags & MIPS_HFLAG_B16 ? 2 : 4));
aa328add 29224 } else {
932e71cd
AJ
29225 env->CP0_ErrorEPC = env->active_tc.PC;
29226 }
89777fd1 29227 env->active_tc.PC = env->exception_base;
51cc2e78
BS
29228 env->CP0_Random = env->tlb->nb_tlb - 1;
29229 env->tlb->tlb_in_use = env->tlb->nb_tlb;
932e71cd 29230 env->CP0_Wired = 0;
01bc435b 29231 env->CP0_GlobalNumber = (cs->cpu_index & 0xFF) << CP0GN_VPId;
0a2672b7 29232 env->CP0_EBase = (cs->cpu_index & 0x3FF);
d3d93c6c 29233 if (mips_um_ksegs_enabled()) {
0a2672b7
JH
29234 env->CP0_EBase |= 0x40000000;
29235 } else {
74dbf824 29236 env->CP0_EBase |= (int32_t)0x80000000;
0a2672b7 29237 }
c870e3f5
YK
29238 if (env->CP0_Config3 & (1 << CP0C3_CMGCR)) {
29239 env->CP0_CMGCRBase = 0x1fbf8000 >> 4;
29240 }
a0c80608
PB
29241 env->CP0_EntryHi_ASID_mask = (env->CP0_Config4 & (1 << CP0C4_AE)) ?
29242 0x3ff : 0xff;
932e71cd
AJ
29243 env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
29244 /* vectored interrupts not implemented, timer on int 7,
29245 no performance counters. */
29246 env->CP0_IntCtl = 0xe0000000;
29247 {
29248 int i;
29249
29250 for (i = 0; i < 7; i++) {
29251 env->CP0_WatchLo[i] = 0;
29252 env->CP0_WatchHi[i] = 0x80000000;
fd88b6ab 29253 }
932e71cd
AJ
29254 env->CP0_WatchLo[7] = 0;
29255 env->CP0_WatchHi[7] = 0;
fd88b6ab 29256 }
932e71cd
AJ
29257 /* Count register increments in debug mode, EJTAG version 1 */
29258 env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
9e56e756 29259
4b69c7e2
JH
29260 cpu_mips_store_count(env, 1);
29261
9e56e756
EI
29262 if (env->CP0_Config3 & (1 << CP0C3_MT)) {
29263 int i;
29264
29265 /* Only TC0 on VPE 0 starts as active. */
29266 for (i = 0; i < ARRAY_SIZE(env->tcs); i++) {
55e5c285 29267 env->tcs[i].CP0_TCBind = cs->cpu_index << CP0TCBd_CurVPE;
9e56e756
EI
29268 env->tcs[i].CP0_TCHalt = 1;
29269 }
29270 env->active_tc.CP0_TCHalt = 1;
259186a7 29271 cs->halted = 1;
9e56e756 29272
55e5c285 29273 if (cs->cpu_index == 0) {
9e56e756
EI
29274 /* VPE0 starts up enabled. */
29275 env->mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
29276 env->CP0_VPEConf0 |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
29277
29278 /* TC0 starts up unhalted. */
259186a7 29279 cs->halted = 0;
9e56e756
EI
29280 env->active_tc.CP0_TCHalt = 0;
29281 env->tcs[0].CP0_TCHalt = 0;
29282 /* With thread 0 active. */
29283 env->active_tc.CP0_TCStatus = (1 << CP0TCSt_A);
29284 env->tcs[0].CP0_TCStatus = (1 << CP0TCSt_A);
29285 }
29286 }
cec56a73
JH
29287
29288 /*
29289 * Configure default legacy segmentation control. We use this regardless of
29290 * whether segmentation control is presented to the guest.
29291 */
29292 /* KSeg3 (seg0 0xE0000000..0xFFFFFFFF) */
29293 env->CP0_SegCtl0 = (CP0SC_AM_MK << CP0SC_AM);
29294 /* KSeg2 (seg1 0xC0000000..0xDFFFFFFF) */
29295 env->CP0_SegCtl0 |= ((CP0SC_AM_MSK << CP0SC_AM)) << 16;
29296 /* KSeg1 (seg2 0xA0000000..0x9FFFFFFF) */
29297 env->CP0_SegCtl1 = (0 << CP0SC_PA) | (CP0SC_AM_UK << CP0SC_AM) |
29298 (2 << CP0SC_C);
29299 /* KSeg0 (seg3 0x80000000..0x9FFFFFFF) */
29300 env->CP0_SegCtl1 |= ((0 << CP0SC_PA) | (CP0SC_AM_UK << CP0SC_AM) |
29301 (3 << CP0SC_C)) << 16;
29302 /* USeg (seg4 0x40000000..0x7FFFFFFF) */
29303 env->CP0_SegCtl2 = (2 << CP0SC_PA) | (CP0SC_AM_MUSK << CP0SC_AM) |
29304 (1 << CP0SC_EU) | (2 << CP0SC_C);
29305 /* USeg (seg5 0x00000000..0x3FFFFFFF) */
29306 env->CP0_SegCtl2 |= ((0 << CP0SC_PA) | (CP0SC_AM_MUSK << CP0SC_AM) |
29307 (1 << CP0SC_EU) | (2 << CP0SC_C)) << 16;
29308 /* XKPhys (note, SegCtl2.XR = 0, so XAM won't be used) */
29309 env->CP0_SegCtl1 |= (CP0SC_AM_UK << CP0SC1_XAM);
51cc2e78 29310#endif
ddc584bd
LA
29311 if ((env->insn_flags & ISA_MIPS32R6) &&
29312 (env->active_fpu.fcr0 & (1 << FCR0_F64))) {
29313 /* Status.FR = 0 mode in 64-bit FPU not allowed in R6 */
29314 env->CP0_Status |= (1 << CP0St_FR);
29315 }
29316
63010795
YK
29317 if (env->insn_flags & ISA_MIPS32R6) {
29318 /* PTW = 1 */
29319 env->CP0_PWSize = 0x40;
29320 /* GDI = 12 */
29321 /* UDI = 12 */
29322 /* MDI = 12 */
29323 /* PRI = 12 */
29324 /* PTEI = 2 */
29325 env->CP0_PWField = 0x0C30C302;
29326 } else {
29327 /* GDI = 0 */
29328 /* UDI = 0 */
29329 /* MDI = 0 */
29330 /* PRI = 0 */
29331 /* PTEI = 2 */
29332 env->CP0_PWField = 0x02;
29333 }
29334
0bbc0396
SM
29335 if (env->CP0_Config3 & (1 << CP0C3_ISA) & (1 << (CP0C3_ISA + 1))) {
29336 /* microMIPS on reset when Config3.ISA is 3 */
0305d194
YK
29337 env->hflags |= MIPS_HFLAG_M16;
29338 }
29339
863f264d
YK
29340 /* MSA */
29341 if (env->CP0_Config3 & (1 << CP0C3_MSAP)) {
29342 msa_reset(env);
29343 }
29344
03e6e501 29345 compute_hflags(env);
599bc5e8 29346 restore_fp_status(env);
e117f526 29347 restore_pamask(env);
27103424 29348 cs->exception_index = EXCP_NONE;
3b3c1694
LA
29349
29350 if (semihosting_get_argc()) {
29351 /* UHI interface can be used to obtain argc and argv */
29352 env->active_tc.gpr[4] = -1;
29353 }
6af0bf9c 29354}
d2856f1a 29355
bad729e2
RH
29356void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb,
29357 target_ulong *data)
d2856f1a 29358{
bad729e2 29359 env->active_tc.PC = data[0];
d2856f1a 29360 env->hflags &= ~MIPS_HFLAG_BMASK;
bad729e2 29361 env->hflags |= data[1];
4636401d
AJ
29362 switch (env->hflags & MIPS_HFLAG_BMASK_BASE) {
29363 case MIPS_HFLAG_BR:
29364 break;
29365 case MIPS_HFLAG_BC:
29366 case MIPS_HFLAG_BL:
29367 case MIPS_HFLAG_B:
bad729e2 29368 env->btarget = data[2];
4636401d
AJ
29369 break;
29370 }
d2856f1a 29371}
This page took 6.402124 seconds and 4 git commands to generate.