]> Git Repo - qemu.git/blame - target/mips/translate.c
target/mips: Add bit encoding for MXU accumulate add/sub 1-bit pattern 'aptn1'
[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 *
1d0e663c
AM
1413 * The notation used in MXU assembler mnemonics:
1414 *
1415 * XRa, XRb, XRc, XRd - MXU registers
1416 * Rb, Rc, Rd, Rs, Rt - general purpose MIPS registers
1417 * s12 - a subfield of an instruction code
1418 * strd2 - a subfield of an instruction code
1419 * eptn2 - a subfield of an instruction code
1420 * eptn3 - a subfield of an instruction code
1421 * optn2 - a subfield of an instruction code
1422 * optn3 - a subfield of an instruction code
1423 * sft4 - a subfield of an instruction code
1424 *
1425 * Load/Store instructions Multiplication instructions
1426 * ----------------------- ---------------------------
1427 *
1428 * S32LDD XRa, Rb, s12 S32MADD XRa, XRd, Rs, Rt
1429 * S32STD XRa, Rb, s12 S32MADDU XRa, XRd, Rs, Rt
1430 * S32LDDV XRa, Rb, rc, strd2 S32SUB XRa, XRd, Rs, Rt
1431 * S32STDV XRa, Rb, rc, strd2 S32SUBU XRa, XRd, Rs, Rt
1432 * S32LDI XRa, Rb, s12 S32MUL XRa, XRd, Rs, Rt
1433 * S32SDI XRa, Rb, s12 S32MULU XRa, XRd, Rs, Rt
1434 * S32LDIV XRa, Rb, rc, strd2 D16MUL XRa, XRb, XRc, XRd, optn2
1435 * S32SDIV XRa, Rb, rc, strd2 D16MULE XRa, XRb, XRc, optn2
1436 * S32LDDR XRa, Rb, s12 D16MULF XRa, XRb, XRc, optn2
1437 * S32STDR XRa, Rb, s12 D16MAC XRa, XRb, XRc, XRd, aptn2, optn2
1438 * S32LDDVR XRa, Rb, rc, strd2 D16MACE XRa, XRb, XRc, XRd, aptn2, optn2
1439 * S32STDVR XRa, Rb, rc, strd2 D16MACF XRa, XRb, XRc, XRd, aptn2, optn2
1440 * S32LDIR XRa, Rb, s12 D16MADL XRa, XRb, XRc, XRd, aptn2, optn2
1441 * S32SDIR XRa, Rb, s12 S16MAD XRa, XRb, XRc, XRd, aptn1, optn2
1442 * S32LDIVR XRa, Rb, rc, strd2 Q8MUL XRa, XRb, XRc, XRd
1443 * S32SDIVR XRa, Rb, rc, strd2 Q8MULSU XRa, XRb, XRc, XRd
1444 * S16LDD XRa, Rb, s10, eptn2 Q8MAC XRa, XRb, XRc, XRd, aptn2
1445 * S16STD XRa, Rb, s10, eptn2 Q8MACSU XRa, XRb, XRc, XRd, aptn2
1446 * S16LDI XRa, Rb, s10, eptn2 Q8MADL XRa, XRb, XRc, XRd, aptn2
1447 * S16SDI XRa, Rb, s10, eptn2
1448 * S8LDD XRa, Rb, s8, eptn3
1449 * S8STD XRa, Rb, s8, eptn3 Addition and subtraction instructions
1450 * S8LDI XRa, Rb, s8, eptn3 -------------------------------------
1451 * S8SDI XRa, Rb, s8, eptn3
1452 * LXW Rd, Rs, Rt, strd2 D32ADD XRa, XRb, XRc, XRd, eptn2
1453 * LXH Rd, Rs, Rt, strd2 D32ADDC XRa, XRb, XRc, XRd
1454 * LXHU Rd, Rs, Rt, strd2 D32ACC XRa, XRb, XRc, XRd, eptn2
1455 * LXB Rd, Rs, Rt, strd2 D32ACCM XRa, XRb, XRc, XRd, eptn2
1456 * LXBU Rd, Rs, Rt, strd2 D32ASUM XRa, XRb, XRc, XRd, eptn2
1457 * S32CPS XRa, XRb, XRc
1458 * Q16ADD XRa, XRb, XRc, XRd, eptn2, optn2
1459 * Comparison instructions Q16ACC XRa, XRb, XRc, XRd, eptn2
1460 * ----------------------- Q16ACCM XRa, XRb, XRc, XRd, eptn2
1461 * D16ASUM XRa, XRb, XRc, XRd, eptn2
1462 * S32MAX XRa, XRb, XRc D16CPS XRa, XRb,
1463 * S32MIN XRa, XRb, XRc D16AVG XRa, XRb, XRc
1464 * S32SLT XRa, XRb, XRc D16AVGR XRa, XRb, XRc
1465 * S32MOVZ XRa, XRb, XRc Q8ADD XRa, XRb, XRc, eptn2
1466 * S32MOVN XRa, XRb, XRc Q8ADDE XRa, XRb, XRc, XRd, eptn2
1467 * D16MAX XRa, XRb, XRc Q8ACCE XRa, XRb, XRc, XRd, eptn2
1468 * D16MIN XRa, XRb, XRc Q8ABD XRa, XRb, XRc
1469 * D16SLT XRa, XRb, XRc Q8SAD XRa, XRb, XRc, XRd
1470 * D16MOVZ XRa, XRb, XRc Q8AVG XRa, XRb, XRc
1471 * D16MOVN XRa, XRb, XRc Q8AVGR XRa, XRb, XRc
1472 * Q8MAX XRa, XRb, XRc D8SUM XRa, XRb, XRc, XRd
1473 * Q8MIN XRa, XRb, XRc D8SUMC XRa, XRb, XRc, XRd
1474 * Q8SLT XRa, XRb, XRc
1475 * Q8SLTU XRa, XRb, XRc
1476 * Q8MOVZ XRa, XRb, XRc Shift instructions
1477 * Q8MOVN XRa, XRb, XRc ------------------
1478 *
1479 * D32SLL XRa, XRb, XRc, XRd, sft4
1480 * Bitwise instructions D32SLR XRa, XRb, XRc, XRd, sft4
1481 * -------------------- D32SAR XRa, XRb, XRc, XRd, sft4
1482 * D32SARL XRa, XRb, XRc, sft4
1483 * S32NOR XRa, XRb, XRc D32SLLV XRa, XRb, Rb
1484 * S32AND XRa, XRb, XRc D32SLRV XRa, XRb, Rb
1485 * S32XOR XRa, XRb, XRc D32SARV XRa, XRb, Rb
1486 * S32OR XRa, XRb, XRc D32SARW XRa, XRb, XRc, Rb
1487 * Q16SLL XRa, XRb, XRc, XRd, sft4
1488 * Q16SLR XRa, XRb, XRc, XRd, sft4
eab0bdb0 1489 * Miscellaneous instructions Q16SAR XRa, XRb, XRc, XRd, sft4
1d0e663c
AM
1490 * ------------------------- Q16SLLV XRa, XRb, Rb
1491 * Q16SLRV XRa, XRb, Rb
1492 * S32SFL XRa, XRb, XRc, XRd, optn2 Q16SARV XRa, XRb, Rb
1493 * S32ALN XRa, XRb, XRc, Rb
1494 * S32ALNI XRa, XRb, XRc, s3
1495 * S32LUI XRa, s8, optn3 Move instructions
1496 * S32EXTR XRa, XRb, Rb, bits5 -----------------
1497 * S32EXTRV XRa, XRb, Rs, Rt
1498 * Q16SCOP XRa, XRb, XRc, XRd S32M2I XRa, Rb
1499 * Q16SAT XRa, XRb, XRc S32I2M XRa, Rb
1500 *
9ef5bff9
AM
1501 *
1502 * bits
1503 * 05..00
1504 *
1505 * ┌─ 000000 ─ OPC_MXU_S32MADD
1506 * ├─ 000001 ─ OPC_MXU_S32MADDU
eab0bdb0
AM
1507 * ├─ 000010 ─ <not assigned> (non-MXU OPC_MUL)
1508 * │
9ef5bff9
AM
1509 * │ 20..18
1510 * ├─ 000011 ─ OPC_MXU__POOL00 ─┬─ 000 ─ OPC_MXU_S32MAX
1511 * │ ├─ 001 ─ OPC_MXU_S32MIN
1512 * │ ├─ 010 ─ OPC_MXU_D16MAX
1513 * │ ├─ 011 ─ OPC_MXU_D16MIN
1514 * │ ├─ 100 ─ OPC_MXU_Q8MAX
1515 * │ ├─ 101 ─ OPC_MXU_Q8MIN
1516 * │ ├─ 110 ─ OPC_MXU_Q8SLT
1517 * │ └─ 111 ─ OPC_MXU_Q8SLTU
1518 * ├─ 000100 ─ OPC_MXU_S32MSUB
1519 * ├─ 000101 ─ OPC_MXU_S32MSUBU 20..18
1520 * ├─ 000110 ─ OPC_MXU__POOL01 ─┬─ 000 ─ OPC_MXU_S32SLT
1521 * │ ├─ 001 ─ OPC_MXU_D16SLT
1522 * │ ├─ 010 ─ OPC_MXU_D16AVG
1523 * │ ├─ 011 ─ OPC_MXU_D16AVGR
1524 * │ ├─ 100 ─ OPC_MXU_Q8AVG
1525 * │ ├─ 101 ─ OPC_MXU_Q8AVGR
1526 * │ └─ 111 ─ OPC_MXU_Q8ADD
1527 * │
1528 * │ 20..18
1529 * ├─ 000111 ─ OPC_MXU__POOL02 ─┬─ 000 ─ OPC_MXU_S32CPS
1530 * │ ├─ 010 ─ OPC_MXU_D16CPS
1531 * │ ├─ 100 ─ OPC_MXU_Q8ABD
1532 * │ └─ 110 ─ OPC_MXU_Q16SAT
1533 * ├─ 001000 ─ OPC_MXU_D16MUL
1534 * │ 25..24
1535 * ├─ 001001 ─ OPC_MXU__POOL03 ─┬─ 00 ─ OPC_MXU_D16MULF
1536 * │ └─ 01 ─ OPC_MXU_D16MULE
1537 * ├─ 001010 ─ OPC_MXU_D16MAC
1538 * ├─ 001011 ─ OPC_MXU_D16MACF
1539 * ├─ 001100 ─ OPC_MXU_D16MADL
eab0bdb0 1540 * ├─ 001101 ─ OPC_MXU_S16MAD
9ef5bff9 1541 * ├─ 001110 ─ OPC_MXU_Q16ADD
eab0bdb0
AM
1542 * ├─ 001111 ─ OPC_MXU_D16MACE 23
1543 * │ ┌─ 0 ─ OPC_MXU_S32LDD
1544 * ├─ 010000 ─ OPC_MXU__POOL04 ─┴─ 1 ─ OPC_MXU_S32LDDR
9ef5bff9
AM
1545 * │
1546 * │ 23
eab0bdb0 1547 * ├─ 010001 ─ OPC_MXU__POOL05 ─┬─ 0 ─ OPC_MXU_S32STD
9ef5bff9
AM
1548 * │ └─ 1 ─ OPC_MXU_S32STDR
1549 * │
1550 * │ 13..10
eab0bdb0 1551 * ├─ 010010 ─ OPC_MXU__POOL06 ─┬─ 0000 ─ OPC_MXU_S32LDDV
9ef5bff9
AM
1552 * │ └─ 0001 ─ OPC_MXU_S32LDDVR
1553 * │
1554 * │ 13..10
eab0bdb0 1555 * ├─ 010011 ─ OPC_MXU__POOL07 ─┬─ 0000 ─ OPC_MXU_S32STDV
9ef5bff9
AM
1556 * │ └─ 0001 ─ OPC_MXU_S32STDVR
1557 * │
1558 * │ 23
eab0bdb0 1559 * ├─ 010100 ─ OPC_MXU__POOL08 ─┬─ 0 ─ OPC_MXU_S32LDI
9ef5bff9
AM
1560 * │ └─ 1 ─ OPC_MXU_S32LDIR
1561 * │
1562 * │ 23
eab0bdb0 1563 * ├─ 010101 ─ OPC_MXU__POOL09 ─┬─ 0 ─ OPC_MXU_S32SDI
9ef5bff9
AM
1564 * │ └─ 1 ─ OPC_MXU_S32SDIR
1565 * │
1566 * │ 13..10
eab0bdb0 1567 * ├─ 010110 ─ OPC_MXU__POOL10 ─┬─ 0000 ─ OPC_MXU_S32LDIV
9ef5bff9
AM
1568 * │ └─ 0001 ─ OPC_MXU_S32LDIVR
1569 * │
1570 * │ 13..10
eab0bdb0 1571 * ├─ 010111 ─ OPC_MXU__POOL11 ─┬─ 0000 ─ OPC_MXU_S32SDIV
9ef5bff9
AM
1572 * │ └─ 0001 ─ OPC_MXU_S32SDIVR
1573 * ├─ 011000 ─ OPC_MXU_D32ADD
1574 * │ 23..22
eab0bdb0 1575 * MXU ├─ 011001 ─ OPC_MXU__POOL12 ─┬─ 00 ─ OPC_MXU_D32ACC
9ef5bff9
AM
1576 * opcodes ─┤ ├─ 01 ─ OPC_MXU_D32ACCM
1577 * │ └─ 10 ─ OPC_MXU_D32ASUM
1578 * ├─ 011010 ─ <not assigned>
1579 * │ 23..22
eab0bdb0 1580 * ├─ 011011 ─ OPC_MXU__POOL13 ─┬─ 00 ─ OPC_MXU_Q16ACC
9ef5bff9
AM
1581 * │ ├─ 01 ─ OPC_MXU_Q16ACCM
1582 * │ └─ 10 ─ OPC_MXU_Q16ASUM
1583 * │
1584 * │ 23..22
eab0bdb0 1585 * ├─ 011100 ─ OPC_MXU__POOL14 ─┬─ 00 ─ OPC_MXU_Q8ADDE
9ef5bff9
AM
1586 * │ ├─ 01 ─ OPC_MXU_D8SUM
1587 * ├─ 011101 ─ OPC_MXU_Q8ACCE └─ 10 ─ OPC_MXU_D8SUMC
1588 * ├─ 011110 ─ <not assigned>
1589 * ├─ 011111 ─ <not assigned>
eab0bdb0
AM
1590 * ├─ 100000 ─ <not assigned> (overlaps with CLZ)
1591 * ├─ 100001 ─ <not assigned> (overlaps with CLO)
9ef5bff9 1592 * ├─ 100010 ─ OPC_MXU_S8LDD
eab0bdb0
AM
1593 * ├─ 100011 ─ OPC_MXU_S8STD 15..14
1594 * ├─ 100100 ─ OPC_MXU_S8LDI ┌─ 00 ─ OPC_MXU_S32MUL
1595 * ├─ 100101 ─ OPC_MXU_S8SDI ├─ 00 ─ OPC_MXU_S32MULU
9ef5bff9 1596 * │ ├─ 00 ─ OPC_MXU_S32EXTR
eab0bdb0 1597 * ├─ 100110 ─ OPC_MXU__POOL15 ─┴─ 00 ─ OPC_MXU_S32EXTRV
9ef5bff9
AM
1598 * │
1599 * │ 20..18
eab0bdb0 1600 * ├─ 100111 ─ OPC_MXU__POOL16 ─┬─ 000 ─ OPC_MXU_D32SARW
9ef5bff9
AM
1601 * │ ├─ 001 ─ OPC_MXU_S32ALN
1602 * ├─ 101000 ─ OPC_MXU_LXB ├─ 010 ─ OPC_MXU_S32ALNI
1603 * ├─ 101001 ─ <not assigned> ├─ 011 ─ OPC_MXU_S32NOR
1604 * ├─ 101010 ─ OPC_MXU_S16LDD ├─ 100 ─ OPC_MXU_S32AND
1605 * ├─ 101011 ─ OPC_MXU_S16STD ├─ 101 ─ OPC_MXU_S32OR
1606 * ├─ 101100 ─ OPC_MXU_S16LDI ├─ 110 ─ OPC_MXU_S32XOR
1607 * ├─ 101101 ─ OPC_MXU_S16SDI └─ 111 ─ OPC_MXU_S32LUI
9ef5bff9
AM
1608 * ├─ 101110 ─ OPC_MXU_S32M2I
1609 * ├─ 101111 ─ OPC_MXU_S32I2M
1610 * ├─ 110000 ─ OPC_MXU_D32SLL
eab0bdb0
AM
1611 * ├─ 110001 ─ OPC_MXU_D32SLR 20..18
1612 * ├─ 110010 ─ OPC_MXU_D32SARL ┌─ 000 ─ OPC_MXU_D32SLLV
1613 * ├─ 110011 ─ OPC_MXU_D32SAR ├─ 001 ─ OPC_MXU_D32SLRV
1614 * ├─ 110100 ─ OPC_MXU_Q16SLL ├─ 010 ─ OPC_MXU_D32SARV
1615 * ├─ 110101 ─ OPC_MXU_Q16SLR ├─ 011 ─ OPC_MXU_Q16SLLV
9ef5bff9 1616 * │ ├─ 100 ─ OPC_MXU_Q16SLRV
eab0bdb0
AM
1617 * ├─ 110110 ─ OPC_MXU__POOL17 ─┴─ 101 ─ OPC_MXU_Q16SARV
1618 * │
9ef5bff9
AM
1619 * ├─ 110111 ─ OPC_MXU_Q16SAR
1620 * │ 23..22
eab0bdb0 1621 * ├─ 111000 ─ OPC_MXU__POOL18 ─┬─ 00 ─ OPC_MXU_Q8MUL
9ef5bff9
AM
1622 * │ └─ 01 ─ OPC_MXU_Q8MULSU
1623 * │
1624 * │ 20..18
eab0bdb0 1625 * ├─ 111001 ─ OPC_MXU__POOL19 ─┬─ 000 ─ OPC_MXU_Q8MOVZ
9ef5bff9
AM
1626 * │ ├─ 001 ─ OPC_MXU_Q8MOVN
1627 * │ ├─ 010 ─ OPC_MXU_D16MOVZ
1628 * │ ├─ 011 ─ OPC_MXU_D16MOVN
1629 * │ ├─ 100 ─ OPC_MXU_S32MOVZ
1630 * │ └─ 101 ─ OPC_MXU_S32MOV
1631 * │
1632 * │ 23..22
eab0bdb0 1633 * ├─ 111010 ─ OPC_MXU__POOL20 ─┬─ 00 ─ OPC_MXU_Q8MAC
9ef5bff9
AM
1634 * │ └─ 10 ─ OPC_MXU_Q8MACSU
1635 * ├─ 111011 ─ OPC_MXU_Q16SCOP
1636 * ├─ 111100 ─ OPC_MXU_Q8MADL
1637 * ├─ 111101 ─ OPC_MXU_S32SFL
1638 * ├─ 111110 ─ OPC_MXU_Q8SAD
eab0bdb0 1639 * └─ 111111 ─ <not assigned> (overlaps with SDBBP)
9ef5bff9
AM
1640 *
1641 *
b158d449
AM
1642 * Compiled after:
1643 *
1644 * "XBurst® Instruction Set Architecture MIPS eXtension/enhanced Unit
1645 * Programming Manual", Ingenic Semiconductor Co, Ltd., 2017
1646 */
1647
8bacd1ff
AM
1648enum {
1649 OPC_MXU_S32MADD = 0x00,
1650 OPC_MXU_S32MADDU = 0x01,
1651 /* not assigned 0x02 */
1652 OPC_MXU__POOL00 = 0x03,
1653 OPC_MXU_S32MSUB = 0x04,
1654 OPC_MXU_S32MSUBU = 0x05,
1655 OPC_MXU__POOL01 = 0x06,
1656 OPC_MXU__POOL02 = 0x07,
1657 OPC_MXU_D16MUL = 0x08,
1658 OPC_MXU__POOL03 = 0x09,
1659 OPC_MXU_D16MAC = 0x0A,
1660 OPC_MXU_D16MACF = 0x0B,
1661 OPC_MXU_D16MADL = 0x0C,
eab0bdb0 1662 OPC_MXU_S16MAD = 0x0D,
8bacd1ff
AM
1663 OPC_MXU_Q16ADD = 0x0E,
1664 OPC_MXU_D16MACE = 0x0F,
eab0bdb0
AM
1665 OPC_MXU__POOL04 = 0x10,
1666 OPC_MXU__POOL05 = 0x11,
1667 OPC_MXU__POOL06 = 0x12,
1668 OPC_MXU__POOL07 = 0x13,
1669 OPC_MXU__POOL08 = 0x14,
1670 OPC_MXU__POOL09 = 0x15,
1671 OPC_MXU__POOL10 = 0x16,
1672 OPC_MXU__POOL11 = 0x17,
8bacd1ff 1673 OPC_MXU_D32ADD = 0x18,
eab0bdb0 1674 OPC_MXU__POOL12 = 0x19,
8bacd1ff 1675 /* not assigned 0x1A */
eab0bdb0
AM
1676 OPC_MXU__POOL13 = 0x1B,
1677 OPC_MXU__POOL14 = 0x1C,
8bacd1ff
AM
1678 OPC_MXU_Q8ACCE = 0x1D,
1679 /* not assigned 0x1E */
1680 /* not assigned 0x1F */
1681 /* not assigned 0x20 */
1682 /* not assigned 0x21 */
1683 OPC_MXU_S8LDD = 0x22,
1684 OPC_MXU_S8STD = 0x23,
1685 OPC_MXU_S8LDI = 0x24,
1686 OPC_MXU_S8SDI = 0x25,
eab0bdb0
AM
1687 OPC_MXU__POOL15 = 0x26,
1688 OPC_MXU__POOL16 = 0x27,
8bacd1ff
AM
1689 OPC_MXU_LXB = 0x28,
1690 /* not assigned 0x29 */
1691 OPC_MXU_S16LDD = 0x2A,
1692 OPC_MXU_S16STD = 0x2B,
1693 OPC_MXU_S16LDI = 0x2C,
1694 OPC_MXU_S16SDI = 0x2D,
1695 OPC_MXU_S32M2I = 0x2E,
1696 OPC_MXU_S32I2M = 0x2F,
1697 OPC_MXU_D32SLL = 0x30,
1698 OPC_MXU_D32SLR = 0x31,
1699 OPC_MXU_D32SARL = 0x32,
1700 OPC_MXU_D32SAR = 0x33,
1701 OPC_MXU_Q16SLL = 0x34,
1702 OPC_MXU_Q16SLR = 0x35,
eab0bdb0 1703 OPC_MXU__POOL17 = 0x36,
8bacd1ff 1704 OPC_MXU_Q16SAR = 0x37,
eab0bdb0
AM
1705 OPC_MXU__POOL18 = 0x38,
1706 OPC_MXU__POOL19 = 0x39,
1707 OPC_MXU__POOL20 = 0x3A,
8bacd1ff
AM
1708 OPC_MXU_Q16SCOP = 0x3B,
1709 OPC_MXU_Q8MADL = 0x3C,
1710 OPC_MXU_S32SFL = 0x3D,
1711 OPC_MXU_Q8SAD = 0x3E,
1712 /* not assigned 0x3F */
1713};
1714
1715
1716/*
1717 * MXU pool 00
1718 */
1719enum {
1720 OPC_MXU_S32MAX = 0x00,
1721 OPC_MXU_S32MIN = 0x01,
1722 OPC_MXU_D16MAX = 0x02,
1723 OPC_MXU_D16MIN = 0x03,
1724 OPC_MXU_Q8MAX = 0x04,
1725 OPC_MXU_Q8MIN = 0x05,
1726 OPC_MXU_Q8SLT = 0x06,
1727 OPC_MXU_Q8SLTU = 0x07,
1728};
1729
1730/*
1731 * MXU pool 01
1732 */
1733enum {
1734 OPC_MXU_S32SLT = 0x00,
1735 OPC_MXU_D16SLT = 0x01,
1736 OPC_MXU_D16AVG = 0x02,
1737 OPC_MXU_D16AVGR = 0x03,
1738 OPC_MXU_Q8AVG = 0x04,
1739 OPC_MXU_Q8AVGR = 0x05,
1740 OPC_MXU_Q8ADD = 0x07,
1741};
1742
1743/*
1744 * MXU pool 02
1745 */
1746enum {
1747 OPC_MXU_S32CPS = 0x00,
1748 OPC_MXU_D16CPS = 0x02,
1749 OPC_MXU_Q8ABD = 0x04,
1750 OPC_MXU_Q16SAT = 0x06,
1751};
1752
1753/*
1754 * MXU pool 03
1755 */
1756enum {
1757 OPC_MXU_D16MULF = 0x00,
1758 OPC_MXU_D16MULE = 0x01,
1759};
1760
1761/*
1762 * MXU pool 04
1763 */
8bacd1ff
AM
1764enum {
1765 OPC_MXU_S32LDD = 0x00,
1766 OPC_MXU_S32LDDR = 0x01,
1767};
1768
1769/*
eab0bdb0 1770 * MXU pool 05
8bacd1ff
AM
1771 */
1772enum {
1773 OPC_MXU_S32STD = 0x00,
1774 OPC_MXU_S32STDR = 0x01,
1775};
1776
1777/*
eab0bdb0 1778 * MXU pool 06
8bacd1ff
AM
1779 */
1780enum {
1781 OPC_MXU_S32LDDV = 0x00,
1782 OPC_MXU_S32LDDVR = 0x01,
1783};
1784
1785/*
eab0bdb0 1786 * MXU pool 07
8bacd1ff
AM
1787 */
1788enum {
1789 OPC_MXU_S32STDV = 0x00,
1790 OPC_MXU_S32STDVR = 0x01,
1791};
1792
1793/*
eab0bdb0 1794 * MXU pool 08
8bacd1ff
AM
1795 */
1796enum {
1797 OPC_MXU_S32LDI = 0x00,
1798 OPC_MXU_S32LDIR = 0x01,
1799};
1800
1801/*
eab0bdb0 1802 * MXU pool 09
8bacd1ff
AM
1803 */
1804enum {
1805 OPC_MXU_S32SDI = 0x00,
1806 OPC_MXU_S32SDIR = 0x01,
1807};
1808
1809/*
eab0bdb0 1810 * MXU pool 10
8bacd1ff
AM
1811 */
1812enum {
1813 OPC_MXU_S32LDIV = 0x00,
1814 OPC_MXU_S32LDIVR = 0x01,
1815};
1816
1817/*
eab0bdb0 1818 * MXU pool 11
8bacd1ff
AM
1819 */
1820enum {
1821 OPC_MXU_S32SDIV = 0x00,
1822 OPC_MXU_S32SDIVR = 0x01,
1823};
1824
1825/*
eab0bdb0 1826 * MXU pool 12
8bacd1ff
AM
1827 */
1828enum {
1829 OPC_MXU_D32ACC = 0x00,
1830 OPC_MXU_D32ACCM = 0x01,
1831 OPC_MXU_D32ASUM = 0x02,
1832};
1833
1834/*
eab0bdb0 1835 * MXU pool 13
8bacd1ff
AM
1836 */
1837enum {
1838 OPC_MXU_Q16ACC = 0x00,
1839 OPC_MXU_Q16ACCM = 0x01,
1840 OPC_MXU_Q16ASUM = 0x02,
1841};
1842
1843/*
eab0bdb0 1844 * MXU pool 14
8bacd1ff
AM
1845 */
1846enum {
1847 OPC_MXU_Q8ADDE = 0x00,
1848 OPC_MXU_D8SUM = 0x01,
1849 OPC_MXU_D8SUMC = 0x02,
1850};
1851
1852/*
eab0bdb0 1853 * MXU pool 15
8bacd1ff
AM
1854 */
1855enum {
1856 OPC_MXU_S32MUL = 0x00,
1857 OPC_MXU_S32MULU = 0x01,
1858 OPC_MXU_S32EXTR = 0x02,
1859 OPC_MXU_S32EXTRV = 0x03,
1860};
1861
1862/*
eab0bdb0 1863 * MXU pool 16
8bacd1ff
AM
1864 */
1865enum {
1866 OPC_MXU_D32SARW = 0x00,
1867 OPC_MXU_S32ALN = 0x01,
1868 OPC_MXU_S32ALNI = 0x02,
1869 OPC_MXU_S32NOR = 0x03,
1870 OPC_MXU_S32AND = 0x04,
1871 OPC_MXU_S32OR = 0x05,
1872 OPC_MXU_S32XOR = 0x06,
1873 OPC_MXU_S32LUI = 0x07,
1874};
1875
1876/*
eab0bdb0 1877 * MXU pool 17
8bacd1ff
AM
1878 */
1879enum {
1880 OPC_MXU_D32SLLV = 0x00,
1881 OPC_MXU_D32SLRV = 0x01,
1882 OPC_MXU_D32SARV = 0x03,
1883 OPC_MXU_Q16SLLV = 0x04,
1884 OPC_MXU_Q16SLRV = 0x05,
1885 OPC_MXU_Q16SARV = 0x07,
1886};
1887
1888/*
eab0bdb0 1889 * MXU pool 18
8bacd1ff
AM
1890 */
1891enum {
1892 OPC_MXU_Q8MUL = 0x00,
1893 OPC_MXU_Q8MULSU = 0x01,
1894};
1895
1896/*
eab0bdb0 1897 * MXU pool 19
8bacd1ff
AM
1898 */
1899enum {
1900 OPC_MXU_Q8MOVZ = 0x00,
1901 OPC_MXU_Q8MOVN = 0x01,
1902 OPC_MXU_D16MOVZ = 0x02,
1903 OPC_MXU_D16MOVN = 0x03,
1904 OPC_MXU_S32MOVZ = 0x04,
1905 OPC_MXU_S32MOVN = 0x05,
1906};
1907
1908/*
eab0bdb0 1909 * MXU pool 20
8bacd1ff
AM
1910 */
1911enum {
1912 OPC_MXU_Q8MAC = 0x00,
1913 OPC_MXU_Q8MACSU = 0x01,
1914};
1915
497f072b
FN
1916/*
1917 * Overview of the TX79-specific instruction set
1918 * =============================================
1919 *
1920 * The R5900 and the C790 have 128-bit wide GPRs, where the upper 64 bits
1921 * are only used by the specific quadword (128-bit) LQ/SQ load/store
1922 * instructions and certain multimedia instructions (MMIs). These MMIs
1923 * configure the 128-bit data path as two 64-bit, four 32-bit, eight 16-bit
1924 * or sixteen 8-bit paths.
1925 *
1926 * Reference:
1927 *
1928 * The Toshiba TX System RISC TX79 Core Architecture manual,
1929 * https://wiki.qemu.org/File:C790.pdf
1930 *
1931 * Three-Operand Multiply and Multiply-Add (4 instructions)
1932 * --------------------------------------------------------
1933 * MADD [rd,] rs, rt Multiply/Add
1934 * MADDU [rd,] rs, rt Multiply/Add Unsigned
1935 * MULT [rd,] rs, rt Multiply (3-operand)
1936 * MULTU [rd,] rs, rt Multiply Unsigned (3-operand)
1937 *
1938 * Multiply Instructions for Pipeline 1 (10 instructions)
1939 * ------------------------------------------------------
1940 * MULT1 [rd,] rs, rt Multiply Pipeline 1
1941 * MULTU1 [rd,] rs, rt Multiply Unsigned Pipeline 1
1942 * DIV1 rs, rt Divide Pipeline 1
1943 * DIVU1 rs, rt Divide Unsigned Pipeline 1
1944 * MADD1 [rd,] rs, rt Multiply-Add Pipeline 1
1945 * MADDU1 [rd,] rs, rt Multiply-Add Unsigned Pipeline 1
1946 * MFHI1 rd Move From HI1 Register
1947 * MFLO1 rd Move From LO1 Register
1948 * MTHI1 rs Move To HI1 Register
1949 * MTLO1 rs Move To LO1 Register
1950 *
1951 * Arithmetic (19 instructions)
1952 * ----------------------------
1953 * PADDB rd, rs, rt Parallel Add Byte
1954 * PSUBB rd, rs, rt Parallel Subtract Byte
1955 * PADDH rd, rs, rt Parallel Add Halfword
1956 * PSUBH rd, rs, rt Parallel Subtract Halfword
1957 * PADDW rd, rs, rt Parallel Add Word
1958 * PSUBW rd, rs, rt Parallel Subtract Word
1959 * PADSBH rd, rs, rt Parallel Add/Subtract Halfword
1960 * PADDSB rd, rs, rt Parallel Add with Signed Saturation Byte
1961 * PSUBSB rd, rs, rt Parallel Subtract with Signed Saturation Byte
1962 * PADDSH rd, rs, rt Parallel Add with Signed Saturation Halfword
1963 * PSUBSH rd, rs, rt Parallel Subtract with Signed Saturation Halfword
1964 * PADDSW rd, rs, rt Parallel Add with Signed Saturation Word
1965 * PSUBSW rd, rs, rt Parallel Subtract with Signed Saturation Word
1966 * PADDUB rd, rs, rt Parallel Add with Unsigned saturation Byte
1967 * PSUBUB rd, rs, rt Parallel Subtract with Unsigned saturation Byte
1968 * PADDUH rd, rs, rt Parallel Add with Unsigned saturation Halfword
1969 * PSUBUH rd, rs, rt Parallel Subtract with Unsigned saturation Halfword
1970 * PADDUW rd, rs, rt Parallel Add with Unsigned saturation Word
1971 * PSUBUW rd, rs, rt Parallel Subtract with Unsigned saturation Word
1972 *
1973 * Min/Max (4 instructions)
1974 * ------------------------
1975 * PMAXH rd, rs, rt Parallel Maximum Halfword
1976 * PMINH rd, rs, rt Parallel Minimum Halfword
1977 * PMAXW rd, rs, rt Parallel Maximum Word
1978 * PMINW rd, rs, rt Parallel Minimum Word
1979 *
1980 * Absolute (2 instructions)
1981 * -------------------------
1982 * PABSH rd, rt Parallel Absolute Halfword
1983 * PABSW rd, rt Parallel Absolute Word
1984 *
1985 * Logical (4 instructions)
1986 * ------------------------
1987 * PAND rd, rs, rt Parallel AND
1988 * POR rd, rs, rt Parallel OR
1989 * PXOR rd, rs, rt Parallel XOR
1990 * PNOR rd, rs, rt Parallel NOR
1991 *
1992 * Shift (9 instructions)
1993 * ----------------------
1994 * PSLLH rd, rt, sa Parallel Shift Left Logical Halfword
1995 * PSRLH rd, rt, sa Parallel Shift Right Logical Halfword
1996 * PSRAH rd, rt, sa Parallel Shift Right Arithmetic Halfword
1997 * PSLLW rd, rt, sa Parallel Shift Left Logical Word
1998 * PSRLW rd, rt, sa Parallel Shift Right Logical Word
1999 * PSRAW rd, rt, sa Parallel Shift Right Arithmetic Word
2000 * PSLLVW rd, rt, rs Parallel Shift Left Logical Variable Word
2001 * PSRLVW rd, rt, rs Parallel Shift Right Logical Variable Word
2002 * PSRAVW rd, rt, rs Parallel Shift Right Arithmetic Variable Word
2003 *
2004 * Compare (6 instructions)
2005 * ------------------------
2006 * PCGTB rd, rs, rt Parallel Compare for Greater Than Byte
2007 * PCEQB rd, rs, rt Parallel Compare for Equal Byte
2008 * PCGTH rd, rs, rt Parallel Compare for Greater Than Halfword
2009 * PCEQH rd, rs, rt Parallel Compare for Equal Halfword
2010 * PCGTW rd, rs, rt Parallel Compare for Greater Than Word
2011 * PCEQW rd, rs, rt Parallel Compare for Equal Word
2012 *
2013 * LZC (1 instruction)
2014 * -------------------
2015 * PLZCW rd, rs Parallel Leading Zero or One Count Word
2016 *
2017 * Quadword Load and Store (2 instructions)
2018 * ----------------------------------------
2019 * LQ rt, offset(base) Load Quadword
2020 * SQ rt, offset(base) Store Quadword
2021 *
2022 * Multiply and Divide (19 instructions)
2023 * -------------------------------------
2024 * PMULTW rd, rs, rt Parallel Multiply Word
2025 * PMULTUW rd, rs, rt Parallel Multiply Unsigned Word
2026 * PDIVW rs, rt Parallel Divide Word
2027 * PDIVUW rs, rt Parallel Divide Unsigned Word
2028 * PMADDW rd, rs, rt Parallel Multiply-Add Word
2029 * PMADDUW rd, rs, rt Parallel Multiply-Add Unsigned Word
2030 * PMSUBW rd, rs, rt Parallel Multiply-Subtract Word
2031 * PMULTH rd, rs, rt Parallel Multiply Halfword
2032 * PMADDH rd, rs, rt Parallel Multiply-Add Halfword
2033 * PMSUBH rd, rs, rt Parallel Multiply-Subtract Halfword
2034 * PHMADH rd, rs, rt Parallel Horizontal Multiply-Add Halfword
2035 * PHMSBH rd, rs, rt Parallel Horizontal Multiply-Subtract Halfword
2036 * PDIVBW rs, rt Parallel Divide Broadcast Word
2037 * PMFHI rd Parallel Move From HI Register
2038 * PMFLO rd Parallel Move From LO Register
2039 * PMTHI rs Parallel Move To HI Register
2040 * PMTLO rs Parallel Move To LO Register
2041 * PMFHL rd Parallel Move From HI/LO Register
2042 * PMTHL rs Parallel Move To HI/LO Register
2043 *
2044 * Pack/Extend (11 instructions)
2045 * -----------------------------
2046 * PPAC5 rd, rt Parallel Pack to 5 bits
2047 * PPACB rd, rs, rt Parallel Pack to Byte
2048 * PPACH rd, rs, rt Parallel Pack to Halfword
2049 * PPACW rd, rs, rt Parallel Pack to Word
2050 * PEXT5 rd, rt Parallel Extend Upper from 5 bits
2051 * PEXTUB rd, rs, rt Parallel Extend Upper from Byte
2052 * PEXTLB rd, rs, rt Parallel Extend Lower from Byte
2053 * PEXTUH rd, rs, rt Parallel Extend Upper from Halfword
2054 * PEXTLH rd, rs, rt Parallel Extend Lower from Halfword
2055 * PEXTUW rd, rs, rt Parallel Extend Upper from Word
2056 * PEXTLW rd, rs, rt Parallel Extend Lower from Word
2057 *
2058 * Others (16 instructions)
2059 * ------------------------
2060 * PCPYH rd, rt Parallel Copy Halfword
2061 * PCPYLD rd, rs, rt Parallel Copy Lower Doubleword
2062 * PCPYUD rd, rs, rt Parallel Copy Upper Doubleword
2063 * PREVH rd, rt Parallel Reverse Halfword
2064 * PINTH rd, rs, rt Parallel Interleave Halfword
2065 * PINTEH rd, rs, rt Parallel Interleave Even Halfword
2066 * PEXEH rd, rt Parallel Exchange Even Halfword
2067 * PEXCH rd, rt Parallel Exchange Center Halfword
2068 * PEXEW rd, rt Parallel Exchange Even Word
2069 * PEXCW rd, rt Parallel Exchange Center Word
2070 * QFSRV rd, rs, rt Quadword Funnel Shift Right Variable
2071 * MFSA rd Move from Shift Amount Register
2072 * MTSA rs Move to Shift Amount Register
2073 * MTSAB rs, immediate Move Byte Count to Shift Amount Register
2074 * MTSAH rs, immediate Move Halfword Count to Shift Amount Register
2075 * PROT3W rd, rt Parallel Rotate 3 Words
f99c0d6d
FN
2076 *
2077 * The TX79-specific Multimedia Instruction encodings
2078 * ==================================================
2079 *
2080 * TX79 Multimedia Instruction encoding table keys:
2081 *
2082 * * This code is reserved for future use. An attempt to execute it
2083 * causes a Reserved Instruction exception.
2084 * % This code indicates an instruction class. The instruction word
2085 * must be further decoded by examining additional tables that show
2086 * the values for other instruction fields.
2087 * # This code is reserved for the unsupported instructions DMULT,
2088 * DMULTU, DDIV, DDIVU, LL, LLD, SC, SCD, LWC2 and SWC2. An attempt
2089 * to execute it causes a Reserved Instruction exception.
2090 *
2091 * TX79 Multimedia Instructions encoded by opcode field (MMI, LQ, SQ):
2092 *
2093 * 31 26 0
2094 * +--------+----------------------------------------+
2095 * | opcode | |
2096 * +--------+----------------------------------------+
2097 *
2098 * opcode bits 28..26
2099 * bits | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7
2100 * 31..29 | 000 | 001 | 010 | 011 | 100 | 101 | 110 | 111
2101 * -------+-------+-------+-------+-------+-------+-------+-------+-------
2102 * 0 000 |SPECIAL| REGIMM| J | JAL | BEQ | BNE | BLEZ | BGTZ
2103 * 1 001 | ADDI | ADDIU | SLTI | SLTIU | ANDI | ORI | XORI | LUI
2104 * 2 010 | COP0 | COP1 | * | * | BEQL | BNEL | BLEZL | BGTZL
2105 * 3 011 | DADDI | DADDIU| LDL | LDR | MMI% | * | LQ | SQ
2106 * 4 100 | LB | LH | LWL | LW | LBU | LHU | LWR | LWU
2107 * 5 101 | SB | SH | SWL | SW | SDL | SDR | SWR | CACHE
2108 * 6 110 | # | LWC1 | # | PREF | # | LDC1 | # | LD
2109 * 7 111 | # | SWC1 | # | * | # | SDC1 | # | SD
497f072b 2110 */
b158d449 2111
f99c0d6d
FN
2112enum {
2113 TX79_CLASS_MMI = 0x1C << 26, /* Same as OPC_SPECIAL2 */
2114 TX79_LQ = 0x1E << 26, /* Same as OPC_MSA */
2115 TX79_SQ = 0x1F << 26, /* Same as OPC_SPECIAL3 */
2116};
2117
d3297211
FN
2118/*
2119 * TX79 Multimedia Instructions with opcode field = MMI:
2120 *
2121 * 31 26 5 0
2122 * +--------+-------------------------------+--------+
2123 * | MMI | |function|
2124 * +--------+-------------------------------+--------+
2125 *
2126 * function bits 2..0
2127 * bits | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7
2128 * 5..3 | 000 | 001 | 010 | 011 | 100 | 101 | 110 | 111
2129 * -------+-------+-------+-------+-------+-------+-------+-------+-------
2130 * 0 000 | MADD | MADDU | * | * | PLZCW | * | * | *
2131 * 1 001 | MMI0% | MMI2% | * | * | * | * | * | *
2132 * 2 010 | MFHI1 | MTHI1 | MFLO1 | MTLO1 | * | * | * | *
2133 * 3 011 | MULT1 | MULTU1| DIV1 | DIVU1 | * | * | * | *
2134 * 4 100 | MADD1 | MADDU1| * | * | * | * | * | *
2135 * 5 101 | MMI1% | MMI3% | * | * | * | * | * | *
2136 * 6 110 | PMFHL | PMTHL | * | * | PSLLH | * | PSRLH | PSRAH
2137 * 7 111 | * | * | * | * | PSLLW | * | PSRLW | PSRAW
2138 */
2139
2140#define MASK_TX79_MMI(op) (MASK_OP_MAJOR(op) | ((op) & 0x3F))
2141enum {
2142 TX79_MMI_MADD = 0x00 | TX79_CLASS_MMI, /* Same as OPC_MADD */
2143 TX79_MMI_MADDU = 0x01 | TX79_CLASS_MMI, /* Same as OPC_MADDU */
2144 TX79_MMI_PLZCW = 0x04 | TX79_CLASS_MMI,
2145 TX79_MMI_CLASS_MMI0 = 0x08 | TX79_CLASS_MMI,
2146 TX79_MMI_CLASS_MMI2 = 0x09 | TX79_CLASS_MMI,
2147 TX79_MMI_MFHI1 = 0x10 | TX79_CLASS_MMI, /* Same minor as OPC_MFHI */
2148 TX79_MMI_MTHI1 = 0x11 | TX79_CLASS_MMI, /* Same minor as OPC_MTHI */
2149 TX79_MMI_MFLO1 = 0x12 | TX79_CLASS_MMI, /* Same minor as OPC_MFLO */
2150 TX79_MMI_MTLO1 = 0x13 | TX79_CLASS_MMI, /* Same minor as OPC_MTLO */
2151 TX79_MMI_MULT1 = 0x18 | TX79_CLASS_MMI, /* Same minor as OPC_MULT */
2152 TX79_MMI_MULTU1 = 0x19 | TX79_CLASS_MMI, /* Same minor as OPC_MULTU */
2153 TX79_MMI_DIV1 = 0x1A | TX79_CLASS_MMI, /* Same minor as OPC_DIV */
2154 TX79_MMI_DIVU1 = 0x1B | TX79_CLASS_MMI, /* Same minor as OPC_DIVU */
2155 TX79_MMI_MADD1 = 0x20 | TX79_CLASS_MMI,
2156 TX79_MMI_MADDU1 = 0x21 | TX79_CLASS_MMI,
2157 TX79_MMI_CLASS_MMI1 = 0x28 | TX79_CLASS_MMI,
2158 TX79_MMI_CLASS_MMI3 = 0x29 | TX79_CLASS_MMI,
2159 TX79_MMI_PMFHL = 0x30 | TX79_CLASS_MMI,
2160 TX79_MMI_PMTHL = 0x31 | TX79_CLASS_MMI,
2161 TX79_MMI_PSLLH = 0x34 | TX79_CLASS_MMI,
2162 TX79_MMI_PSRLH = 0x36 | TX79_CLASS_MMI,
2163 TX79_MMI_PSRAH = 0x37 | TX79_CLASS_MMI,
2164 TX79_MMI_PSLLW = 0x3C | TX79_CLASS_MMI,
2165 TX79_MMI_PSRLW = 0x3E | TX79_CLASS_MMI,
2166 TX79_MMI_PSRAW = 0x3F | TX79_CLASS_MMI,
2167};
2168
3ef65697
FN
2169/*
2170 * TX79 Multimedia Instructions with opcode field = MMI and bits 5..0 = MMI0:
2171 *
2172 * 31 26 10 6 5 0
2173 * +--------+----------------------+--------+--------+
2174 * | MMI | |function| MMI0 |
2175 * +--------+----------------------+--------+--------+
2176 *
2177 * function bits 7..6
2178 * bits | 0 | 1 | 2 | 3
2179 * 10..8 | 00 | 01 | 10 | 11
2180 * -------+-------+-------+-------+-------
2181 * 0 000 | PADDW | PSUBW | PCGTW | PMAXW
2182 * 1 001 | PADDH | PSUBH | PCGTH | PMAXH
2183 * 2 010 | PADDB | PSUBB | PCGTB | *
2184 * 3 011 | * | * | * | *
2185 * 4 100 | PADDSW| PSUBSW| PEXTLW| PPACW
2186 * 5 101 | PADDSH| PSUBSH| PEXTLH| PPACH
2187 * 6 110 | PADDSB| PSUBSB| PEXTLB| PPACB
2188 * 7 111 | * | * | PEXT5 | PPAC5
2189 */
2190
2191#define MASK_TX79_MMI0(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
2192enum {
2193 TX79_MMI0_PADDW = (0x00 << 6) | TX79_MMI_CLASS_MMI0,
2194 TX79_MMI0_PSUBW = (0x01 << 6) | TX79_MMI_CLASS_MMI0,
2195 TX79_MMI0_PCGTW = (0x02 << 6) | TX79_MMI_CLASS_MMI0,
2196 TX79_MMI0_PMAXW = (0x03 << 6) | TX79_MMI_CLASS_MMI0,
2197 TX79_MMI0_PADDH = (0x04 << 6) | TX79_MMI_CLASS_MMI0,
2198 TX79_MMI0_PSUBH = (0x05 << 6) | TX79_MMI_CLASS_MMI0,
2199 TX79_MMI0_PCGTH = (0x06 << 6) | TX79_MMI_CLASS_MMI0,
2200 TX79_MMI0_PMAXH = (0x07 << 6) | TX79_MMI_CLASS_MMI0,
2201 TX79_MMI0_PADDB = (0x08 << 6) | TX79_MMI_CLASS_MMI0,
2202 TX79_MMI0_PSUBB = (0x09 << 6) | TX79_MMI_CLASS_MMI0,
2203 TX79_MMI0_PCGTB = (0x0A << 6) | TX79_MMI_CLASS_MMI0,
2204 TX79_MMI0_PADDSW = (0x10 << 6) | TX79_MMI_CLASS_MMI0,
2205 TX79_MMI0_PSUBSW = (0x11 << 6) | TX79_MMI_CLASS_MMI0,
2206 TX79_MMI0_PEXTLW = (0x12 << 6) | TX79_MMI_CLASS_MMI0,
2207 TX79_MMI0_PPACW = (0x13 << 6) | TX79_MMI_CLASS_MMI0,
2208 TX79_MMI0_PADDSH = (0x14 << 6) | TX79_MMI_CLASS_MMI0,
2209 TX79_MMI0_PSUBSH = (0x15 << 6) | TX79_MMI_CLASS_MMI0,
2210 TX79_MMI0_PEXTLH = (0x16 << 6) | TX79_MMI_CLASS_MMI0,
2211 TX79_MMI0_PPACH = (0x17 << 6) | TX79_MMI_CLASS_MMI0,
2212 TX79_MMI0_PADDSB = (0x18 << 6) | TX79_MMI_CLASS_MMI0,
2213 TX79_MMI0_PSUBSB = (0x19 << 6) | TX79_MMI_CLASS_MMI0,
2214 TX79_MMI0_PEXTLB = (0x1A << 6) | TX79_MMI_CLASS_MMI0,
2215 TX79_MMI0_PPACB = (0x1B << 6) | TX79_MMI_CLASS_MMI0,
2216 TX79_MMI0_PEXT5 = (0x1E << 6) | TX79_MMI_CLASS_MMI0,
2217 TX79_MMI0_PPAC5 = (0x1F << 6) | TX79_MMI_CLASS_MMI0,
2218};
2219
77596541
FN
2220/*
2221 * TX79 Multimedia Instructions with opcode field = MMI and bits 5..0 = MMI1:
2222 *
2223 * 31 26 10 6 5 0
2224 * +--------+----------------------+--------+--------+
2225 * | MMI | |function| MMI1 |
2226 * +--------+----------------------+--------+--------+
2227 *
2228 * function bits 7..6
2229 * bits | 0 | 1 | 2 | 3
2230 * 10..8 | 00 | 01 | 10 | 11
2231 * -------+-------+-------+-------+-------
2232 * 0 000 | * | PABSW | PCEQW | PMINW
2233 * 1 001 | PADSBH| PABSH | PCEQH | PMINH
2234 * 2 010 | * | * | PCEQB | *
2235 * 3 011 | * | * | * | *
2236 * 4 100 | PADDUW| PSUBUW| PEXTUW| *
2237 * 5 101 | PADDUH| PSUBUH| PEXTUH| *
2238 * 6 110 | PADDUB| PSUBUB| PEXTUB| QFSRV
2239 * 7 111 | * | * | * | *
2240 */
2241
2242#define MASK_TX79_MMI1(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
2243enum {
2244 TX79_MMI1_PABSW = (0x01 << 6) | TX79_MMI_CLASS_MMI1,
2245 TX79_MMI1_PCEQW = (0x02 << 6) | TX79_MMI_CLASS_MMI1,
2246 TX79_MMI1_PMINW = (0x03 << 6) | TX79_MMI_CLASS_MMI1,
2247 TX79_MMI1_PADSBH = (0x04 << 6) | TX79_MMI_CLASS_MMI1,
2248 TX79_MMI1_PABSH = (0x05 << 6) | TX79_MMI_CLASS_MMI1,
2249 TX79_MMI1_PCEQH = (0x06 << 6) | TX79_MMI_CLASS_MMI1,
2250 TX79_MMI1_PMINH = (0x07 << 6) | TX79_MMI_CLASS_MMI1,
2251 TX79_MMI1_PCEQB = (0x0A << 6) | TX79_MMI_CLASS_MMI1,
2252 TX79_MMI1_PADDUW = (0x10 << 6) | TX79_MMI_CLASS_MMI1,
2253 TX79_MMI1_PSUBUW = (0x11 << 6) | TX79_MMI_CLASS_MMI1,
2254 TX79_MMI1_PEXTUW = (0x12 << 6) | TX79_MMI_CLASS_MMI1,
2255 TX79_MMI1_PADDUH = (0x14 << 6) | TX79_MMI_CLASS_MMI1,
2256 TX79_MMI1_PSUBUH = (0x15 << 6) | TX79_MMI_CLASS_MMI1,
2257 TX79_MMI1_PEXTUH = (0x16 << 6) | TX79_MMI_CLASS_MMI1,
2258 TX79_MMI1_PADDUB = (0x18 << 6) | TX79_MMI_CLASS_MMI1,
2259 TX79_MMI1_PSUBUB = (0x19 << 6) | TX79_MMI_CLASS_MMI1,
2260 TX79_MMI1_PEXTUB = (0x1A << 6) | TX79_MMI_CLASS_MMI1,
2261 TX79_MMI1_QFSRV = (0x1B << 6) | TX79_MMI_CLASS_MMI1,
2262};
2263
6c03ef6a
FN
2264/*
2265 * TX79 Multimedia Instructions with opcode field = MMI and bits 5..0 = MMI2:
2266 *
2267 * 31 26 10 6 5 0
2268 * +--------+----------------------+--------+--------+
2269 * | MMI | |function| MMI2 |
2270 * +--------+----------------------+--------+--------+
2271 *
2272 * function bits 7..6
2273 * bits | 0 | 1 | 2 | 3
2274 * 10..8 | 00 | 01 | 10 | 11
2275 * -------+-------+-------+-------+-------
2276 * 0 000 | PMADDW| * | PSLLVW| PSRLVW
2277 * 1 001 | PMSUBW| * | * | *
2278 * 2 010 | PMFHI | PMFLO | PINTH | *
2279 * 3 011 | PMULTW| PDIVW | PCPYLD| *
2280 * 4 100 | PMADDH| PHMADH| PAND | PXOR
2281 * 5 101 | PMSUBH| PHMSBH| * | *
2282 * 6 110 | * | * | PEXEH | PREVH
2283 * 7 111 | PMULTH| PDIVBW| PEXEW | PROT3W
2284 */
2285
2286#define MASK_TX79_MMI2(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
2287enum {
2288 TX79_MMI2_PMADDW = (0x00 << 6) | TX79_MMI_CLASS_MMI2,
2289 TX79_MMI2_PSLLVW = (0x02 << 6) | TX79_MMI_CLASS_MMI2,
2290 TX79_MMI2_PSRLVW = (0x03 << 6) | TX79_MMI_CLASS_MMI2,
2291 TX79_MMI2_PMSUBW = (0x04 << 6) | TX79_MMI_CLASS_MMI2,
2292 TX79_MMI2_PMFHI = (0x08 << 6) | TX79_MMI_CLASS_MMI2,
2293 TX79_MMI2_PMFLO = (0x09 << 6) | TX79_MMI_CLASS_MMI2,
2294 TX79_MMI2_PINTH = (0x0A << 6) | TX79_MMI_CLASS_MMI2,
2295 TX79_MMI2_PMULTW = (0x0C << 6) | TX79_MMI_CLASS_MMI2,
2296 TX79_MMI2_PDIVW = (0x0D << 6) | TX79_MMI_CLASS_MMI2,
2297 TX79_MMI2_PCPYLD = (0x0E << 6) | TX79_MMI_CLASS_MMI2,
2298 TX79_MMI2_PMADDH = (0x10 << 6) | TX79_MMI_CLASS_MMI2,
2299 TX79_MMI2_PHMADH = (0x11 << 6) | TX79_MMI_CLASS_MMI2,
2300 TX79_MMI2_PAND = (0x12 << 6) | TX79_MMI_CLASS_MMI2,
2301 TX79_MMI2_PXOR = (0x13 << 6) | TX79_MMI_CLASS_MMI2,
2302 TX79_MMI2_PMSUBH = (0x14 << 6) | TX79_MMI_CLASS_MMI2,
2303 TX79_MMI2_PHMSBH = (0x15 << 6) | TX79_MMI_CLASS_MMI2,
2304 TX79_MMI2_PEXEH = (0x1A << 6) | TX79_MMI_CLASS_MMI2,
2305 TX79_MMI2_PREVH = (0x1B << 6) | TX79_MMI_CLASS_MMI2,
2306 TX79_MMI2_PMULTH = (0x1C << 6) | TX79_MMI_CLASS_MMI2,
2307 TX79_MMI2_PDIVBW = (0x1D << 6) | TX79_MMI_CLASS_MMI2,
2308 TX79_MMI2_PEXEW = (0x1E << 6) | TX79_MMI_CLASS_MMI2,
2309 TX79_MMI2_PROT3W = (0x1F << 6) | TX79_MMI_CLASS_MMI2,
2310};
2311
dd581bf9
FN
2312/*
2313 * TX79 Multimedia Instructions with opcode field = MMI and bits 5..0 = MMI3:
2314 *
2315 * 31 26 10 6 5 0
2316 * +--------+----------------------+--------+--------+
2317 * | MMI | |function| MMI3 |
2318 * +--------+----------------------+--------+--------+
2319 *
2320 * function bits 7..6
2321 * bits | 0 | 1 | 2 | 3
2322 * 10..8 | 00 | 01 | 10 | 11
2323 * -------+-------+-------+-------+-------
2324 * 0 000 |PMADDUW| * | * | PSRAVW
2325 * 1 001 | * | * | * | *
2326 * 2 010 | PMTHI | PMTLO | PINTEH| *
2327 * 3 011 |PMULTUW| PDIVUW| PCPYUD| *
2328 * 4 100 | * | * | POR | PNOR
2329 * 5 101 | * | * | * | *
2330 * 6 110 | * | * | PEXCH | PCPYH
2331 * 7 111 | * | * | PEXCW | *
2332 */
2333
2334#define MASK_TX79_MMI3(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
2335enum {
2336 TX79_MMI3_PMADDUW = (0x00 << 6) | TX79_MMI_CLASS_MMI3,
2337 TX79_MMI3_PSRAVW = (0x03 << 6) | TX79_MMI_CLASS_MMI3,
2338 TX79_MMI3_PMTHI = (0x08 << 6) | TX79_MMI_CLASS_MMI3,
2339 TX79_MMI3_PMTLO = (0x09 << 6) | TX79_MMI_CLASS_MMI3,
2340 TX79_MMI3_PINTEH = (0x0A << 6) | TX79_MMI_CLASS_MMI3,
2341 TX79_MMI3_PMULTUW = (0x0C << 6) | TX79_MMI_CLASS_MMI3,
2342 TX79_MMI3_PDIVUW = (0x0D << 6) | TX79_MMI_CLASS_MMI3,
2343 TX79_MMI3_PCPYUD = (0x0E << 6) | TX79_MMI_CLASS_MMI3,
2344 TX79_MMI3_POR = (0x12 << 6) | TX79_MMI_CLASS_MMI3,
2345 TX79_MMI3_PNOR = (0x13 << 6) | TX79_MMI_CLASS_MMI3,
2346 TX79_MMI3_PEXCH = (0x1A << 6) | TX79_MMI_CLASS_MMI3,
2347 TX79_MMI3_PCPYH = (0x1B << 6) | TX79_MMI_CLASS_MMI3,
2348 TX79_MMI3_PEXCW = (0x1E << 6) | TX79_MMI_CLASS_MMI3,
2349};
2350
39454628 2351/* global register indices */
a7812ae4 2352static TCGv cpu_gpr[32], cpu_PC;
340fff72 2353static TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC];
41db4607
AJ
2354static TCGv cpu_dspctrl, btarget, bcond;
2355static TCGv_i32 hflags;
a7812ae4 2356static TCGv_i32 fpu_fcr0, fpu_fcr31;
d73ee8a2 2357static TCGv_i64 fpu_f64[32];
863f264d 2358static TCGv_i64 msa_wr_d[64];
aa0bf00b 2359
eb5559f6
CJ
2360/* MXU registers */
2361static TCGv mxu_gpr[NUMBER_OF_MXU_REGISTERS - 1];
2362static TCGv mxu_CR;
2363
022c62cb 2364#include "exec/gen-icount.h"
2e70f6ef 2365
895c2d04 2366#define gen_helper_0e0i(name, arg) do { \
a7812ae4 2367 TCGv_i32 helper_tmp = tcg_const_i32(arg); \
895c2d04 2368 gen_helper_##name(cpu_env, helper_tmp); \
a7812ae4
PB
2369 tcg_temp_free_i32(helper_tmp); \
2370 } while(0)
be24bb4f 2371
895c2d04 2372#define gen_helper_0e1i(name, arg1, arg2) do { \
a7812ae4 2373 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
895c2d04 2374 gen_helper_##name(cpu_env, arg1, helper_tmp); \
a7812ae4
PB
2375 tcg_temp_free_i32(helper_tmp); \
2376 } while(0)
be24bb4f 2377
895c2d04
BS
2378#define gen_helper_1e0i(name, ret, arg1) do { \
2379 TCGv_i32 helper_tmp = tcg_const_i32(arg1); \
2380 gen_helper_##name(ret, cpu_env, helper_tmp); \
2381 tcg_temp_free_i32(helper_tmp); \
2382 } while(0)
2383
2384#define gen_helper_1e1i(name, ret, arg1, arg2) do { \
2385 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
2386 gen_helper_##name(ret, cpu_env, arg1, helper_tmp); \
2387 tcg_temp_free_i32(helper_tmp); \
2388 } while(0)
2389
2390#define gen_helper_0e2i(name, arg1, arg2, arg3) do { \
2391 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
2392 gen_helper_##name(cpu_env, arg1, arg2, helper_tmp); \
2393 tcg_temp_free_i32(helper_tmp); \
2394 } while(0)
2395
2396#define gen_helper_1e2i(name, ret, arg1, arg2, arg3) do { \
a7812ae4 2397 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
895c2d04 2398 gen_helper_##name(ret, cpu_env, arg1, arg2, helper_tmp); \
a7812ae4
PB
2399 tcg_temp_free_i32(helper_tmp); \
2400 } while(0)
be24bb4f 2401
895c2d04 2402#define gen_helper_0e3i(name, arg1, arg2, arg3, arg4) do { \
a7812ae4 2403 TCGv_i32 helper_tmp = tcg_const_i32(arg4); \
895c2d04 2404 gen_helper_##name(cpu_env, arg1, arg2, arg3, helper_tmp); \
a7812ae4
PB
2405 tcg_temp_free_i32(helper_tmp); \
2406 } while(0)
c239529e 2407
8e9ade68 2408typedef struct DisasContext {
eeb3bba8
EC
2409 DisasContextBase base;
2410 target_ulong saved_pc;
18f440ed 2411 target_ulong page_start;
8e9ade68 2412 uint32_t opcode;
f9c9cd63 2413 uint64_t insn_flags;
5ab5c041 2414 int32_t CP0_Config1;
49735f76 2415 int32_t CP0_Config2;
ab77fc61
DN
2416 int32_t CP0_Config3;
2417 int32_t CP0_Config5;
8e9ade68
TS
2418 /* Routine used to access memory */
2419 int mem_idx;
be3a8c53 2420 TCGMemOp default_tcg_memop_mask;
8e9ade68 2421 uint32_t hflags, saved_hflags;
8e9ade68 2422 target_ulong btarget;
d279279e 2423 bool ulri;
e98c0d17 2424 int kscrexist;
7207c7f9 2425 bool rxi;
9456c2fb 2426 int ie;
aea14095
LA
2427 bool bi;
2428 bool bp;
5204ea79
LA
2429 uint64_t PAMask;
2430 bool mvh;
76964147 2431 bool eva;
cec56a73 2432 bool sc;
5204ea79 2433 int CP0_LLAddr_shift;
e29c9628 2434 bool ps;
01bc435b 2435 bool vp;
c870e3f5 2436 bool cmgcr;
f6d4dd81 2437 bool mrp;
87552089 2438 bool nan2008;
6be77480 2439 bool abs2008;
8e9ade68
TS
2440} DisasContext;
2441
b28425ba
EC
2442#define DISAS_STOP DISAS_TARGET_0
2443#define DISAS_EXIT DISAS_TARGET_1
8e9ade68 2444
d73ee8a2
RH
2445static const char * const regnames[] = {
2446 "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
2447 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
2448 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
2449 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
2450};
6af0bf9c 2451
d73ee8a2
RH
2452static const char * const regnames_HI[] = {
2453 "HI0", "HI1", "HI2", "HI3",
2454};
4b2eb8d2 2455
d73ee8a2
RH
2456static const char * const regnames_LO[] = {
2457 "LO0", "LO1", "LO2", "LO3",
2458};
4b2eb8d2 2459
d73ee8a2
RH
2460static const char * const fregnames[] = {
2461 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
2462 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
2463 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
2464 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
2465};
958fb4a9 2466
863f264d
YK
2467static const char * const msaregnames[] = {
2468 "w0.d0", "w0.d1", "w1.d0", "w1.d1",
2469 "w2.d0", "w2.d1", "w3.d0", "w3.d1",
2470 "w4.d0", "w4.d1", "w5.d0", "w5.d1",
2471 "w6.d0", "w6.d1", "w7.d0", "w7.d1",
2472 "w8.d0", "w8.d1", "w9.d0", "w9.d1",
2473 "w10.d0", "w10.d1", "w11.d0", "w11.d1",
2474 "w12.d0", "w12.d1", "w13.d0", "w13.d1",
2475 "w14.d0", "w14.d1", "w15.d0", "w15.d1",
2476 "w16.d0", "w16.d1", "w17.d0", "w17.d1",
2477 "w18.d0", "w18.d1", "w19.d0", "w19.d1",
2478 "w20.d0", "w20.d1", "w21.d0", "w21.d1",
2479 "w22.d0", "w22.d1", "w23.d0", "w23.d1",
2480 "w24.d0", "w24.d1", "w25.d0", "w25.d1",
2481 "w26.d0", "w26.d1", "w27.d0", "w27.d1",
2482 "w28.d0", "w28.d1", "w29.d0", "w29.d1",
2483 "w30.d0", "w30.d1", "w31.d0", "w31.d1",
2484};
2485
eb5559f6
CJ
2486static const char * const mxuregnames[] = {
2487 "XR1", "XR2", "XR3", "XR4", "XR5", "XR6", "XR7", "XR8",
2488 "XR9", "XR10", "XR11", "XR12", "XR13", "XR14", "XR15", "MXU_CR",
2489};
2490
9d68ac14 2491#define LOG_DISAS(...) \
fb7729e2
RH
2492 do { \
2493 if (MIPS_DEBUG_DISAS) { \
9d68ac14 2494 qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__); \
fb7729e2
RH
2495 } \
2496 } while (0)
2497
9d68ac14 2498#define MIPS_INVAL(op) \
fb7729e2
RH
2499 do { \
2500 if (MIPS_DEBUG_DISAS) { \
9d68ac14
AJ
2501 qemu_log_mask(CPU_LOG_TB_IN_ASM, \
2502 TARGET_FMT_lx ": %08x Invalid %s %03x %03x %03x\n", \
eeb3bba8
EC
2503 ctx->base.pc_next, ctx->opcode, op, \
2504 ctx->opcode >> 26, ctx->opcode & 0x3F, \
2505 ((ctx->opcode >> 16) & 0x1F)); \
fb7729e2
RH
2506 } \
2507 } while (0)
958fb4a9 2508
8e9ade68
TS
2509/* General purpose registers moves. */
2510static inline void gen_load_gpr (TCGv t, int reg)
aaa9128a 2511{
8e9ade68
TS
2512 if (reg == 0)
2513 tcg_gen_movi_tl(t, 0);
2514 else
4b2eb8d2 2515 tcg_gen_mov_tl(t, cpu_gpr[reg]);
aaa9128a
TS
2516}
2517
8e9ade68 2518static inline void gen_store_gpr (TCGv t, int reg)
aaa9128a 2519{
8e9ade68 2520 if (reg != 0)
4b2eb8d2 2521 tcg_gen_mov_tl(cpu_gpr[reg], t);
aaa9128a
TS
2522}
2523
8e9ade68 2524/* Moves to/from shadow registers. */
be24bb4f 2525static inline void gen_load_srsgpr (int from, int to)
aaa9128a 2526{
d9bea114 2527 TCGv t0 = tcg_temp_new();
be24bb4f
TS
2528
2529 if (from == 0)
d9bea114 2530 tcg_gen_movi_tl(t0, 0);
8e9ade68 2531 else {
d9bea114 2532 TCGv_i32 t2 = tcg_temp_new_i32();
a7812ae4 2533 TCGv_ptr addr = tcg_temp_new_ptr();
aaa9128a 2534
7db13fae 2535 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
d9bea114
AJ
2536 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
2537 tcg_gen_andi_i32(t2, t2, 0xf);
2538 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
2539 tcg_gen_ext_i32_ptr(addr, t2);
a7812ae4 2540 tcg_gen_add_ptr(addr, cpu_env, addr);
aaa9128a 2541
d9bea114 2542 tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from);
a7812ae4 2543 tcg_temp_free_ptr(addr);
d9bea114 2544 tcg_temp_free_i32(t2);
8e9ade68 2545 }
d9bea114
AJ
2546 gen_store_gpr(t0, to);
2547 tcg_temp_free(t0);
aaa9128a
TS
2548}
2549
be24bb4f 2550static inline void gen_store_srsgpr (int from, int to)
aaa9128a 2551{
be24bb4f 2552 if (to != 0) {
d9bea114
AJ
2553 TCGv t0 = tcg_temp_new();
2554 TCGv_i32 t2 = tcg_temp_new_i32();
a7812ae4 2555 TCGv_ptr addr = tcg_temp_new_ptr();
be24bb4f 2556
d9bea114 2557 gen_load_gpr(t0, from);
7db13fae 2558 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
d9bea114
AJ
2559 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
2560 tcg_gen_andi_i32(t2, t2, 0xf);
2561 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
2562 tcg_gen_ext_i32_ptr(addr, t2);
a7812ae4 2563 tcg_gen_add_ptr(addr, cpu_env, addr);
be24bb4f 2564
d9bea114 2565 tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to);
a7812ae4 2566 tcg_temp_free_ptr(addr);
d9bea114
AJ
2567 tcg_temp_free_i32(t2);
2568 tcg_temp_free(t0);
8e9ade68 2569 }
aaa9128a
TS
2570}
2571
eab9944c
LA
2572/* Tests */
2573static inline void gen_save_pc(target_ulong pc)
2574{
2575 tcg_gen_movi_tl(cpu_PC, pc);
2576}
2577
2578static inline void save_cpu_state(DisasContext *ctx, int do_save_pc)
2579{
2580 LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
eeb3bba8
EC
2581 if (do_save_pc && ctx->base.pc_next != ctx->saved_pc) {
2582 gen_save_pc(ctx->base.pc_next);
2583 ctx->saved_pc = ctx->base.pc_next;
eab9944c
LA
2584 }
2585 if (ctx->hflags != ctx->saved_hflags) {
2586 tcg_gen_movi_i32(hflags, ctx->hflags);
2587 ctx->saved_hflags = ctx->hflags;
2588 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
2589 case MIPS_HFLAG_BR:
2590 break;
2591 case MIPS_HFLAG_BC:
2592 case MIPS_HFLAG_BL:
2593 case MIPS_HFLAG_B:
2594 tcg_gen_movi_tl(btarget, ctx->btarget);
2595 break;
2596 }
2597 }
2598}
2599
2600static inline void restore_cpu_state(CPUMIPSState *env, DisasContext *ctx)
2601{
2602 ctx->saved_hflags = ctx->hflags;
2603 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
2604 case MIPS_HFLAG_BR:
2605 break;
2606 case MIPS_HFLAG_BC:
2607 case MIPS_HFLAG_BL:
2608 case MIPS_HFLAG_B:
2609 ctx->btarget = env->btarget;
2610 break;
2611 }
2612}
2613
2614static inline void generate_exception_err(DisasContext *ctx, int excp, int err)
2615{
2616 TCGv_i32 texcp = tcg_const_i32(excp);
2617 TCGv_i32 terr = tcg_const_i32(err);
2618 save_cpu_state(ctx, 1);
2619 gen_helper_raise_exception_err(cpu_env, texcp, terr);
2620 tcg_temp_free_i32(terr);
2621 tcg_temp_free_i32(texcp);
eeb3bba8 2622 ctx->base.is_jmp = DISAS_NORETURN;
eab9944c
LA
2623}
2624
2625static inline void generate_exception(DisasContext *ctx, int excp)
2626{
eab9944c
LA
2627 gen_helper_0e0i(raise_exception, excp);
2628}
2629
9c708c7f
PD
2630static inline void generate_exception_end(DisasContext *ctx, int excp)
2631{
2632 generate_exception_err(ctx, excp, 0);
2633}
2634
aaa9128a 2635/* Floating point register moves. */
7c979afd 2636static void gen_load_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
aa0bf00b 2637{
7c979afd
LA
2638 if (ctx->hflags & MIPS_HFLAG_FRE) {
2639 generate_exception(ctx, EXCP_RI);
2640 }
ecc7b3aa 2641 tcg_gen_extrl_i64_i32(t, fpu_f64[reg]);
6ea83fed
FB
2642}
2643
7c979afd 2644static void gen_store_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
aa0bf00b 2645{
7c979afd
LA
2646 TCGv_i64 t64;
2647 if (ctx->hflags & MIPS_HFLAG_FRE) {
2648 generate_exception(ctx, EXCP_RI);
2649 }
2650 t64 = tcg_temp_new_i64();
d73ee8a2
RH
2651 tcg_gen_extu_i32_i64(t64, t);
2652 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 0, 32);
2653 tcg_temp_free_i64(t64);
6d066274
AJ
2654}
2655
7f6613ce 2656static void gen_load_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
6d066274 2657{
7f6613ce 2658 if (ctx->hflags & MIPS_HFLAG_F64) {
71f303cd 2659 tcg_gen_extrh_i64_i32(t, fpu_f64[reg]);
7f6613ce 2660 } else {
7c979afd 2661 gen_load_fpr32(ctx, t, reg | 1);
7f6613ce 2662 }
6d066274
AJ
2663}
2664
7f6613ce 2665static void gen_store_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
6d066274 2666{
7f6613ce
PJ
2667 if (ctx->hflags & MIPS_HFLAG_F64) {
2668 TCGv_i64 t64 = tcg_temp_new_i64();
2669 tcg_gen_extu_i32_i64(t64, t);
2670 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 32, 32);
2671 tcg_temp_free_i64(t64);
2672 } else {
7c979afd 2673 gen_store_fpr32(ctx, t, reg | 1);
7f6613ce 2674 }
aa0bf00b 2675}
6ea83fed 2676
d73ee8a2 2677static void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
aa0bf00b 2678{
f364515c 2679 if (ctx->hflags & MIPS_HFLAG_F64) {
d73ee8a2 2680 tcg_gen_mov_i64(t, fpu_f64[reg]);
f364515c 2681 } else {
d73ee8a2 2682 tcg_gen_concat32_i64(t, fpu_f64[reg & ~1], fpu_f64[reg | 1]);
aa0bf00b
TS
2683 }
2684}
6ea83fed 2685
d73ee8a2 2686static void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
aa0bf00b 2687{
f364515c 2688 if (ctx->hflags & MIPS_HFLAG_F64) {
d73ee8a2 2689 tcg_gen_mov_i64(fpu_f64[reg], t);
f364515c 2690 } else {
d73ee8a2
RH
2691 TCGv_i64 t0;
2692 tcg_gen_deposit_i64(fpu_f64[reg & ~1], fpu_f64[reg & ~1], t, 0, 32);
2693 t0 = tcg_temp_new_i64();
6d066274 2694 tcg_gen_shri_i64(t0, t, 32);
d73ee8a2 2695 tcg_gen_deposit_i64(fpu_f64[reg | 1], fpu_f64[reg | 1], t0, 0, 32);
6d066274 2696 tcg_temp_free_i64(t0);
aa0bf00b
TS
2697 }
2698}
6ea83fed 2699
d94536f4 2700static inline int get_fp_bit (int cc)
a16336e4 2701{
d94536f4
AJ
2702 if (cc)
2703 return 24 + cc;
2704 else
2705 return 23;
a16336e4
TS
2706}
2707
48d38ca5 2708/* Addresses computation */
941694d0 2709static inline void gen_op_addr_add (DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1)
4ad40f36 2710{
941694d0 2711 tcg_gen_add_tl(ret, arg0, arg1);
48d38ca5
TS
2712
2713#if defined(TARGET_MIPS64)
01f72885 2714 if (ctx->hflags & MIPS_HFLAG_AWRAP) {
941694d0 2715 tcg_gen_ext32s_i64(ret, ret);
48d38ca5
TS
2716 }
2717#endif
4ad40f36
FB
2718}
2719
bf0718c5
SM
2720static inline void gen_op_addr_addi(DisasContext *ctx, TCGv ret, TCGv base,
2721 target_long ofs)
2722{
2723 tcg_gen_addi_tl(ret, base, ofs);
2724
2725#if defined(TARGET_MIPS64)
2726 if (ctx->hflags & MIPS_HFLAG_AWRAP) {
2727 tcg_gen_ext32s_i64(ret, ret);
2728 }
2729#endif
2730}
2731
31837be3
YK
2732/* Addresses computation (translation time) */
2733static target_long addr_add(DisasContext *ctx, target_long base,
2734 target_long offset)
2735{
2736 target_long sum = base + offset;
2737
2738#if defined(TARGET_MIPS64)
2739 if (ctx->hflags & MIPS_HFLAG_AWRAP) {
2740 sum = (int32_t)sum;
2741 }
2742#endif
2743 return sum;
2744}
2745
71f303cd 2746/* Sign-extract the low 32-bits to a target_long. */
1f1b4c00
YK
2747static inline void gen_move_low32(TCGv ret, TCGv_i64 arg)
2748{
2749#if defined(TARGET_MIPS64)
71f303cd
RH
2750 tcg_gen_ext32s_i64(ret, arg);
2751#else
2752 tcg_gen_extrl_i64_i32(ret, arg);
2753#endif
2754}
2755
2756/* Sign-extract the high 32-bits to a target_long. */
2757static inline void gen_move_high32(TCGv ret, TCGv_i64 arg)
2758{
2759#if defined(TARGET_MIPS64)
2760 tcg_gen_sari_i64(ret, arg, 32);
1f1b4c00 2761#else
71f303cd 2762 tcg_gen_extrh_i64_i32(ret, arg);
1f1b4c00
YK
2763#endif
2764}
2765
356265ae 2766static inline void check_cp0_enabled(DisasContext *ctx)
387a8fe5 2767{
fe253235 2768 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
c2c65dab 2769 generate_exception_err(ctx, EXCP_CpU, 0);
387a8fe5
TS
2770}
2771
356265ae 2772static inline void check_cp1_enabled(DisasContext *ctx)
5e755519 2773{
fe253235 2774 if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
5e755519
TS
2775 generate_exception_err(ctx, EXCP_CpU, 1);
2776}
2777
b8aa4598
TS
2778/* Verify that the processor is running with COP1X instructions enabled.
2779 This is associated with the nabla symbol in the MIPS32 and MIPS64
2780 opcode tables. */
2781
356265ae 2782static inline void check_cop1x(DisasContext *ctx)
b8aa4598
TS
2783{
2784 if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
9c708c7f 2785 generate_exception_end(ctx, EXCP_RI);
b8aa4598
TS
2786}
2787
2788/* Verify that the processor is running with 64-bit floating-point
2789 operations enabled. */
2790
356265ae 2791static inline void check_cp1_64bitmode(DisasContext *ctx)
5e755519 2792{
b8aa4598 2793 if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
9c708c7f 2794 generate_exception_end(ctx, EXCP_RI);
5e755519
TS
2795}
2796
2797/*
2798 * Verify if floating point register is valid; an operation is not defined
2799 * if bit 0 of any register specification is set and the FR bit in the
2800 * Status register equals zero, since the register numbers specify an
2801 * even-odd pair of adjacent coprocessor general registers. When the FR bit
2802 * in the Status register equals one, both even and odd register numbers
2803 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
2804 *
2805 * Multiple 64 bit wide registers can be checked by calling
2806 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
2807 */
356265ae 2808static inline void check_cp1_registers(DisasContext *ctx, int regs)
5e755519 2809{
fe253235 2810 if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)))
9c708c7f 2811 generate_exception_end(ctx, EXCP_RI);
5e755519
TS
2812}
2813
853c3240
JL
2814/* Verify that the processor is running with DSP instructions enabled.
2815 This is enabled by CP0 Status register MX(24) bit.
2816 */
2817
2818static inline void check_dsp(DisasContext *ctx)
2819{
2820 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP))) {
ad153f15 2821 if (ctx->insn_flags & ASE_DSP) {
9c708c7f 2822 generate_exception_end(ctx, EXCP_DSPDIS);
ad153f15 2823 } else {
9c708c7f 2824 generate_exception_end(ctx, EXCP_RI);
ad153f15 2825 }
853c3240
JL
2826 }
2827}
2828
908f6be1 2829static inline void check_dsp_r2(DisasContext *ctx)
853c3240 2830{
908f6be1 2831 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP_R2))) {
ad153f15 2832 if (ctx->insn_flags & ASE_DSP) {
9c708c7f 2833 generate_exception_end(ctx, EXCP_DSPDIS);
ad153f15 2834 } else {
9c708c7f 2835 generate_exception_end(ctx, EXCP_RI);
ad153f15 2836 }
853c3240
JL
2837 }
2838}
2839
908f6be1 2840static inline void check_dsp_r3(DisasContext *ctx)
59e781fb 2841{
908f6be1 2842 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP_R3))) {
59e781fb
SM
2843 if (ctx->insn_flags & ASE_DSP) {
2844 generate_exception_end(ctx, EXCP_DSPDIS);
2845 } else {
2846 generate_exception_end(ctx, EXCP_RI);
2847 }
2848 }
2849}
2850
3a95e3a7 2851/* This code generates a "reserved instruction" exception if the
e189e748 2852 CPU does not support the instruction set corresponding to flags. */
f9c9cd63 2853static inline void check_insn(DisasContext *ctx, uint64_t flags)
3a95e3a7 2854{
d75c135e 2855 if (unlikely(!(ctx->insn_flags & flags))) {
9c708c7f 2856 generate_exception_end(ctx, EXCP_RI);
d75c135e 2857 }
3a95e3a7
TS
2858}
2859
fecd2646
LA
2860/* This code generates a "reserved instruction" exception if the
2861 CPU has corresponding flag set which indicates that the instruction
2862 has been removed. */
f9c9cd63 2863static inline void check_insn_opc_removed(DisasContext *ctx, uint64_t flags)
fecd2646
LA
2864{
2865 if (unlikely(ctx->insn_flags & flags)) {
9c708c7f 2866 generate_exception_end(ctx, EXCP_RI);
fecd2646
LA
2867 }
2868}
2869
96631327
FN
2870/*
2871 * The Linux kernel traps certain reserved instruction exceptions to
2872 * emulate the corresponding instructions. QEMU is the kernel in user
2873 * mode, so those traps are emulated by accepting the instructions.
2874 *
2875 * A reserved instruction exception is generated for flagged CPUs if
2876 * QEMU runs in system mode.
2877 */
2878static inline void check_insn_opc_user_only(DisasContext *ctx, uint64_t flags)
2879{
2880#ifndef CONFIG_USER_ONLY
2881 check_insn_opc_removed(ctx, flags);
2882#endif
2883}
2884
e29c9628
YK
2885/* This code generates a "reserved instruction" exception if the
2886 CPU does not support 64-bit paired-single (PS) floating point data type */
2887static inline void check_ps(DisasContext *ctx)
2888{
2889 if (unlikely(!ctx->ps)) {
2890 generate_exception(ctx, EXCP_RI);
2891 }
2892 check_cp1_64bitmode(ctx);
2893}
2894
c7986fd6 2895#ifdef TARGET_MIPS64
e189e748
TS
2896/* This code generates a "reserved instruction" exception if 64-bit
2897 instructions are not enabled. */
356265ae 2898static inline void check_mips_64(DisasContext *ctx)
e189e748 2899{
fe253235 2900 if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
9c708c7f 2901 generate_exception_end(ctx, EXCP_RI);
e189e748 2902}
c7986fd6 2903#endif
e189e748 2904
5204ea79
LA
2905#ifndef CONFIG_USER_ONLY
2906static inline void check_mvh(DisasContext *ctx)
2907{
2908 if (unlikely(!ctx->mvh)) {
2909 generate_exception(ctx, EXCP_RI);
2910 }
2911}
2912#endif
2913
0b16dcd1
AR
2914/*
2915 * This code generates a "reserved instruction" exception if the
2916 * Config5 XNP bit is set.
2917 */
2918static inline void check_xnp(DisasContext *ctx)
2919{
2920 if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_XNP))) {
2921 generate_exception_end(ctx, EXCP_RI);
2922 }
2923}
2924
5e31fdd5
YK
2925#ifndef CONFIG_USER_ONLY
2926/*
2927 * This code generates a "reserved instruction" exception if the
2928 * Config3 PW bit is NOT set.
2929 */
2930static inline void check_pw(DisasContext *ctx)
2931{
2932 if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_PW)))) {
2933 generate_exception_end(ctx, EXCP_RI);
2934 }
2935}
2936#endif
2937
9affc1c5
AR
2938/*
2939 * This code generates a "reserved instruction" exception if the
2940 * Config3 MT bit is NOT set.
2941 */
2942static inline void check_mt(DisasContext *ctx)
2943{
2944 if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_MT)))) {
2945 generate_exception_end(ctx, EXCP_RI);
2946 }
2947}
2948
2949#ifndef CONFIG_USER_ONLY
2950/*
2951 * This code generates a "coprocessor unusable" exception if CP0 is not
2952 * available, and, if that is not the case, generates a "reserved instruction"
2953 * exception if the Config5 MT bit is NOT set. This is needed for availability
2954 * control of some of MT ASE instructions.
2955 */
2956static inline void check_cp0_mt(DisasContext *ctx)
2957{
2958 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0))) {
2959 generate_exception_err(ctx, EXCP_CpU, 0);
2960 } else {
2961 if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_MT)))) {
2962 generate_exception_err(ctx, EXCP_RI, 0);
2963 }
2964 }
2965}
2966#endif
2967
fb32f8c8
DN
2968/*
2969 * This code generates a "reserved instruction" exception if the
2970 * Config5 NMS bit is set.
2971 */
2972static inline void check_nms(DisasContext *ctx)
2973{
2974 if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_NMS))) {
2975 generate_exception_end(ctx, EXCP_RI);
2976 }
2977}
2978
d046a9ea
DN
2979/*
2980 * This code generates a "reserved instruction" exception if the
2981 * Config5 NMS bit is set, and Config1 DL, Config1 IL, Config2 SL,
2982 * Config2 TL, and Config5 L2C are unset.
2983 */
2984static inline void check_nms_dl_il_sl_tl_l2c(DisasContext *ctx)
2985{
2986 if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_NMS)) &&
2987 !(ctx->CP0_Config1 & (1 << CP0C1_DL)) &&
2988 !(ctx->CP0_Config1 & (1 << CP0C1_IL)) &&
2989 !(ctx->CP0_Config2 & (1 << CP0C2_SL)) &&
2990 !(ctx->CP0_Config2 & (1 << CP0C2_TL)) &&
2991 !(ctx->CP0_Config5 & (1 << CP0C5_L2C)))
2992 {
2993 generate_exception_end(ctx, EXCP_RI);
2994 }
2995}
2996
2997/*
2998 * This code generates a "reserved instruction" exception if the
2999 * Config5 EVA bit is NOT set.
3000 */
3001static inline void check_eva(DisasContext *ctx)
3002{
3003 if (unlikely(!(ctx->CP0_Config5 & (1 << CP0C5_EVA)))) {
3004 generate_exception_end(ctx, EXCP_RI);
3005 }
3006}
3007
0b16dcd1 3008
8153667c
NF
3009/* Define small wrappers for gen_load_fpr* so that we have a uniform
3010 calling interface for 32 and 64-bit FPRs. No sense in changing
3011 all callers for gen_load_fpr32 when we need the CTX parameter for
3012 this one use. */
7c979afd 3013#define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(ctx, x, y)
8153667c
NF
3014#define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
3015#define FOP_CONDS(type, abs, fmt, ifmt, bits) \
3016static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \
3017 int ft, int fs, int cc) \
3018{ \
3019 TCGv_i##bits fp0 = tcg_temp_new_i##bits (); \
3020 TCGv_i##bits fp1 = tcg_temp_new_i##bits (); \
3021 switch (ifmt) { \
3022 case FMT_PS: \
e29c9628 3023 check_ps(ctx); \
8153667c
NF
3024 break; \
3025 case FMT_D: \
3026 if (abs) { \
3027 check_cop1x(ctx); \
3028 } \
3029 check_cp1_registers(ctx, fs | ft); \
3030 break; \
3031 case FMT_S: \
3032 if (abs) { \
3033 check_cop1x(ctx); \
3034 } \
3035 break; \
3036 } \
3037 gen_ldcmp_fpr##bits (ctx, fp0, fs); \
3038 gen_ldcmp_fpr##bits (ctx, fp1, ft); \
3039 switch (n) { \
895c2d04
BS
3040 case 0: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc); break;\
3041 case 1: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc); break;\
3042 case 2: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc); break;\
3043 case 3: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc); break;\
3044 case 4: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc); break;\
3045 case 5: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc); break;\
3046 case 6: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc); break;\
3047 case 7: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc); break;\
3048 case 8: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc); break;\
3049 case 9: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); break;\
3050 case 10: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc); break;\
3051 case 11: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc); break;\
3052 case 12: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc); break;\
3053 case 13: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc); break;\
3054 case 14: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc); break;\
3055 case 15: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc); break;\
8153667c
NF
3056 default: abort(); \
3057 } \
3058 tcg_temp_free_i##bits (fp0); \
3059 tcg_temp_free_i##bits (fp1); \
3060}
3061
3062FOP_CONDS(, 0, d, FMT_D, 64)
3063FOP_CONDS(abs, 1, d, FMT_D, 64)
3064FOP_CONDS(, 0, s, FMT_S, 32)
3065FOP_CONDS(abs, 1, s, FMT_S, 32)
3066FOP_CONDS(, 0, ps, FMT_PS, 64)
3067FOP_CONDS(abs, 1, ps, FMT_PS, 64)
3068#undef FOP_CONDS
3f493883
YK
3069
3070#define FOP_CONDNS(fmt, ifmt, bits, STORE) \
3071static inline void gen_r6_cmp_ ## fmt(DisasContext * ctx, int n, \
3072 int ft, int fs, int fd) \
3073{ \
3074 TCGv_i ## bits fp0 = tcg_temp_new_i ## bits(); \
3075 TCGv_i ## bits fp1 = tcg_temp_new_i ## bits(); \
00fb4a11 3076 if (ifmt == FMT_D) { \
3f493883 3077 check_cp1_registers(ctx, fs | ft | fd); \
3f493883
YK
3078 } \
3079 gen_ldcmp_fpr ## bits(ctx, fp0, fs); \
3080 gen_ldcmp_fpr ## bits(ctx, fp1, ft); \
3081 switch (n) { \
3082 case 0: \
3083 gen_helper_r6_cmp_ ## fmt ## _af(fp0, cpu_env, fp0, fp1); \
3084 break; \
3085 case 1: \
3086 gen_helper_r6_cmp_ ## fmt ## _un(fp0, cpu_env, fp0, fp1); \
3087 break; \
3088 case 2: \
3089 gen_helper_r6_cmp_ ## fmt ## _eq(fp0, cpu_env, fp0, fp1); \
3090 break; \
3091 case 3: \
3092 gen_helper_r6_cmp_ ## fmt ## _ueq(fp0, cpu_env, fp0, fp1); \
3093 break; \
3094 case 4: \
3095 gen_helper_r6_cmp_ ## fmt ## _lt(fp0, cpu_env, fp0, fp1); \
3096 break; \
3097 case 5: \
3098 gen_helper_r6_cmp_ ## fmt ## _ult(fp0, cpu_env, fp0, fp1); \
3099 break; \
3100 case 6: \
3101 gen_helper_r6_cmp_ ## fmt ## _le(fp0, cpu_env, fp0, fp1); \
3102 break; \
3103 case 7: \
3104 gen_helper_r6_cmp_ ## fmt ## _ule(fp0, cpu_env, fp0, fp1); \
3105 break; \
3106 case 8: \
3107 gen_helper_r6_cmp_ ## fmt ## _saf(fp0, cpu_env, fp0, fp1); \
3108 break; \
3109 case 9: \
3110 gen_helper_r6_cmp_ ## fmt ## _sun(fp0, cpu_env, fp0, fp1); \
3111 break; \
3112 case 10: \
3113 gen_helper_r6_cmp_ ## fmt ## _seq(fp0, cpu_env, fp0, fp1); \
3114 break; \
3115 case 11: \
3116 gen_helper_r6_cmp_ ## fmt ## _sueq(fp0, cpu_env, fp0, fp1); \
3117 break; \
3118 case 12: \
3119 gen_helper_r6_cmp_ ## fmt ## _slt(fp0, cpu_env, fp0, fp1); \
3120 break; \
3121 case 13: \
3122 gen_helper_r6_cmp_ ## fmt ## _sult(fp0, cpu_env, fp0, fp1); \
3123 break; \
3124 case 14: \
3125 gen_helper_r6_cmp_ ## fmt ## _sle(fp0, cpu_env, fp0, fp1); \
3126 break; \
3127 case 15: \
3128 gen_helper_r6_cmp_ ## fmt ## _sule(fp0, cpu_env, fp0, fp1); \
3129 break; \
3130 case 17: \
3131 gen_helper_r6_cmp_ ## fmt ## _or(fp0, cpu_env, fp0, fp1); \
3132 break; \
3133 case 18: \
3134 gen_helper_r6_cmp_ ## fmt ## _une(fp0, cpu_env, fp0, fp1); \
3135 break; \
3136 case 19: \
3137 gen_helper_r6_cmp_ ## fmt ## _ne(fp0, cpu_env, fp0, fp1); \
3138 break; \
3139 case 25: \
3140 gen_helper_r6_cmp_ ## fmt ## _sor(fp0, cpu_env, fp0, fp1); \
3141 break; \
3142 case 26: \
3143 gen_helper_r6_cmp_ ## fmt ## _sune(fp0, cpu_env, fp0, fp1); \
3144 break; \
3145 case 27: \
3146 gen_helper_r6_cmp_ ## fmt ## _sne(fp0, cpu_env, fp0, fp1); \
3147 break; \
3148 default: \
3149 abort(); \
3150 } \
3151 STORE; \
3152 tcg_temp_free_i ## bits (fp0); \
3153 tcg_temp_free_i ## bits (fp1); \
3154}
3155
3156FOP_CONDNS(d, FMT_D, 64, gen_store_fpr64(ctx, fp0, fd))
7c979afd 3157FOP_CONDNS(s, FMT_S, 32, gen_store_fpr32(ctx, fp0, fd))
3f493883 3158#undef FOP_CONDNS
8153667c
NF
3159#undef gen_ldcmp_fpr32
3160#undef gen_ldcmp_fpr64
3161
958fb4a9 3162/* load/store instructions. */
e7139c44 3163#ifdef CONFIG_USER_ONLY
d9bea114 3164#define OP_LD_ATOMIC(insn,fname) \
dd4096cd
JH
3165static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx, \
3166 DisasContext *ctx) \
d9bea114
AJ
3167{ \
3168 TCGv t0 = tcg_temp_new(); \
3169 tcg_gen_mov_tl(t0, arg1); \
3170 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
7db13fae
AF
3171 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
3172 tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval)); \
d9bea114 3173 tcg_temp_free(t0); \
aaa9128a 3174}
e7139c44
AJ
3175#else
3176#define OP_LD_ATOMIC(insn,fname) \
dd4096cd
JH
3177static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx, \
3178 DisasContext *ctx) \
e7139c44 3179{ \
dd4096cd 3180 gen_helper_1e1i(insn, ret, arg1, mem_idx); \
e7139c44
AJ
3181}
3182#endif
aaa9128a
TS
3183OP_LD_ATOMIC(ll,ld32s);
3184#if defined(TARGET_MIPS64)
3185OP_LD_ATOMIC(lld,ld64);
3186#endif
3187#undef OP_LD_ATOMIC
3188
590bc601
PB
3189#ifdef CONFIG_USER_ONLY
3190#define OP_ST_ATOMIC(insn,fname,ldname,almask) \
dd4096cd
JH
3191static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, int mem_idx, \
3192 DisasContext *ctx) \
590bc601
PB
3193{ \
3194 TCGv t0 = tcg_temp_new(); \
42a268c2
RH
3195 TCGLabel *l1 = gen_new_label(); \
3196 TCGLabel *l2 = gen_new_label(); \
590bc601
PB
3197 \
3198 tcg_gen_andi_tl(t0, arg2, almask); \
3199 tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1); \
7db13fae 3200 tcg_gen_st_tl(arg2, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr)); \
590bc601
PB
3201 generate_exception(ctx, EXCP_AdES); \
3202 gen_set_label(l1); \
7db13fae 3203 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
590bc601
PB
3204 tcg_gen_brcond_tl(TCG_COND_NE, arg2, t0, l2); \
3205 tcg_gen_movi_tl(t0, rt | ((almask << 3) & 0x20)); \
7db13fae
AF
3206 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, llreg)); \
3207 tcg_gen_st_tl(arg1, cpu_env, offsetof(CPUMIPSState, llnewval)); \
9c708c7f 3208 generate_exception_end(ctx, EXCP_SC); \
590bc601
PB
3209 gen_set_label(l2); \
3210 tcg_gen_movi_tl(t0, 0); \
3211 gen_store_gpr(t0, rt); \
3212 tcg_temp_free(t0); \
3213}
3214#else
3215#define OP_ST_ATOMIC(insn,fname,ldname,almask) \
dd4096cd
JH
3216static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, int mem_idx, \
3217 DisasContext *ctx) \
590bc601
PB
3218{ \
3219 TCGv t0 = tcg_temp_new(); \
dd4096cd 3220 gen_helper_1e2i(insn, t0, arg1, arg2, mem_idx); \
590bc601 3221 gen_store_gpr(t0, rt); \
590bc601
PB
3222 tcg_temp_free(t0); \
3223}
3224#endif
590bc601 3225OP_ST_ATOMIC(sc,st32,ld32s,0x3);
aaa9128a 3226#if defined(TARGET_MIPS64)
590bc601 3227OP_ST_ATOMIC(scd,st64,ld64,0x7);
aaa9128a
TS
3228#endif
3229#undef OP_ST_ATOMIC
3230
662d7485 3231static void gen_base_offset_addr (DisasContext *ctx, TCGv addr,
72e1f16f 3232 int base, int offset)
662d7485
NF
3233{
3234 if (base == 0) {
3235 tcg_gen_movi_tl(addr, offset);
3236 } else if (offset == 0) {
3237 gen_load_gpr(addr, base);
3238 } else {
3239 tcg_gen_movi_tl(addr, offset);
3240 gen_op_addr_add(ctx, addr, cpu_gpr[base], addr);
3241 }
3242}
3243
364d4831
NF
3244static target_ulong pc_relative_pc (DisasContext *ctx)
3245{
eeb3bba8 3246 target_ulong pc = ctx->base.pc_next;
364d4831
NF
3247
3248 if (ctx->hflags & MIPS_HFLAG_BMASK) {
3249 int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
3250
3251 pc -= branch_bytes;
3252 }
3253
3254 pc &= ~(target_ulong)3;
3255 return pc;
3256}
3257
5c13fdfd 3258/* Load */
d75c135e 3259static void gen_ld(DisasContext *ctx, uint32_t opc,
72e1f16f 3260 int rt, int base, int offset)
6af0bf9c 3261{
fc40787a 3262 TCGv t0, t1, t2;
dd4096cd 3263 int mem_idx = ctx->mem_idx;
afa88c3a 3264
d75c135e 3265 if (rt == 0 && ctx->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)) {
afa88c3a
AJ
3266 /* Loongson CPU uses a load to zero register for prefetch.
3267 We emulate it as a NOP. On other CPU we must perform the
3268 actual memory access. */
afa88c3a
AJ
3269 return;
3270 }
6af0bf9c 3271
afa88c3a 3272 t0 = tcg_temp_new();
662d7485 3273 gen_base_offset_addr(ctx, t0, base, offset);
afa88c3a 3274
6af0bf9c 3275 switch (opc) {
d26bc211 3276#if defined(TARGET_MIPS64)
6e473128 3277 case OPC_LWU:
dd4096cd 3278 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL |
be3a8c53 3279 ctx->default_tcg_memop_mask);
78723684 3280 gen_store_gpr(t0, rt);
6e473128 3281 break;
6af0bf9c 3282 case OPC_LD:
dd4096cd 3283 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ |
be3a8c53 3284 ctx->default_tcg_memop_mask);
78723684 3285 gen_store_gpr(t0, rt);
6af0bf9c 3286 break;
7a387fff 3287 case OPC_LLD:
bf7910c6 3288 case R6_OPC_LLD:
dd4096cd 3289 op_ld_lld(t0, t0, mem_idx, ctx);
78723684 3290 gen_store_gpr(t0, rt);
7a387fff 3291 break;
6af0bf9c 3292 case OPC_LDL:
3cee3050 3293 t1 = tcg_temp_new();
908680c6
AJ
3294 /* Do a byte access to possibly trigger a page
3295 fault with the unaligned address. */
dd4096cd 3296 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
fc40787a
AJ
3297 tcg_gen_andi_tl(t1, t0, 7);
3298#ifndef TARGET_WORDS_BIGENDIAN
3299 tcg_gen_xori_tl(t1, t1, 7);
3300#endif
3301 tcg_gen_shli_tl(t1, t1, 3);
3302 tcg_gen_andi_tl(t0, t0, ~7);
dd4096cd 3303 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
fc40787a 3304 tcg_gen_shl_tl(t0, t0, t1);
eb02cc3f
AJ
3305 t2 = tcg_const_tl(-1);
3306 tcg_gen_shl_tl(t2, t2, t1);
78723684 3307 gen_load_gpr(t1, rt);
eb02cc3f 3308 tcg_gen_andc_tl(t1, t1, t2);
fc40787a
AJ
3309 tcg_temp_free(t2);
3310 tcg_gen_or_tl(t0, t0, t1);
3cee3050 3311 tcg_temp_free(t1);
fc40787a 3312 gen_store_gpr(t0, rt);
6af0bf9c 3313 break;
6af0bf9c 3314 case OPC_LDR:
3cee3050 3315 t1 = tcg_temp_new();
908680c6
AJ
3316 /* Do a byte access to possibly trigger a page
3317 fault with the unaligned address. */
dd4096cd 3318 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
fc40787a
AJ
3319 tcg_gen_andi_tl(t1, t0, 7);
3320#ifdef TARGET_WORDS_BIGENDIAN
3321 tcg_gen_xori_tl(t1, t1, 7);
3322#endif
3323 tcg_gen_shli_tl(t1, t1, 3);
3324 tcg_gen_andi_tl(t0, t0, ~7);
dd4096cd 3325 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
fc40787a
AJ
3326 tcg_gen_shr_tl(t0, t0, t1);
3327 tcg_gen_xori_tl(t1, t1, 63);
3328 t2 = tcg_const_tl(0xfffffffffffffffeull);
3329 tcg_gen_shl_tl(t2, t2, t1);
78723684 3330 gen_load_gpr(t1, rt);
fc40787a
AJ
3331 tcg_gen_and_tl(t1, t1, t2);
3332 tcg_temp_free(t2);
3333 tcg_gen_or_tl(t0, t0, t1);
3cee3050 3334 tcg_temp_free(t1);
fc40787a 3335 gen_store_gpr(t0, rt);
6af0bf9c 3336 break;
364d4831 3337 case OPC_LDPC:
3cee3050 3338 t1 = tcg_const_tl(pc_relative_pc(ctx));
364d4831 3339 gen_op_addr_add(ctx, t0, t0, t1);
3cee3050 3340 tcg_temp_free(t1);
dd4096cd 3341 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
364d4831
NF
3342 gen_store_gpr(t0, rt);
3343 break;
6af0bf9c 3344#endif
364d4831 3345 case OPC_LWPC:
3cee3050 3346 t1 = tcg_const_tl(pc_relative_pc(ctx));
364d4831 3347 gen_op_addr_add(ctx, t0, t0, t1);
3cee3050 3348 tcg_temp_free(t1);
dd4096cd 3349 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESL);
364d4831
NF
3350 gen_store_gpr(t0, rt);
3351 break;
76964147
JH
3352 case OPC_LWE:
3353 mem_idx = MIPS_HFLAG_UM;
3354 /* fall through */
6af0bf9c 3355 case OPC_LW:
dd4096cd 3356 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESL |
be3a8c53 3357 ctx->default_tcg_memop_mask);
78723684 3358 gen_store_gpr(t0, rt);
6af0bf9c 3359 break;
76964147
JH
3360 case OPC_LHE:
3361 mem_idx = MIPS_HFLAG_UM;
3362 /* fall through */
6af0bf9c 3363 case OPC_LH:
dd4096cd 3364 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESW |
be3a8c53 3365 ctx->default_tcg_memop_mask);
78723684 3366 gen_store_gpr(t0, rt);
6af0bf9c 3367 break;
76964147
JH
3368 case OPC_LHUE:
3369 mem_idx = MIPS_HFLAG_UM;
3370 /* fall through */
6af0bf9c 3371 case OPC_LHU:
dd4096cd 3372 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUW |
be3a8c53 3373 ctx->default_tcg_memop_mask);
78723684 3374 gen_store_gpr(t0, rt);
6af0bf9c 3375 break;
76964147
JH
3376 case OPC_LBE:
3377 mem_idx = MIPS_HFLAG_UM;
3378 /* fall through */
6af0bf9c 3379 case OPC_LB:
dd4096cd 3380 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_SB);
78723684 3381 gen_store_gpr(t0, rt);
6af0bf9c 3382 break;
76964147
JH
3383 case OPC_LBUE:
3384 mem_idx = MIPS_HFLAG_UM;
3385 /* fall through */
6af0bf9c 3386 case OPC_LBU:
dd4096cd 3387 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_UB);
78723684 3388 gen_store_gpr(t0, rt);
6af0bf9c 3389 break;
76964147
JH
3390 case OPC_LWLE:
3391 mem_idx = MIPS_HFLAG_UM;
3392 /* fall through */
6af0bf9c 3393 case OPC_LWL:
3cee3050 3394 t1 = tcg_temp_new();
908680c6
AJ
3395 /* Do a byte access to possibly trigger a page
3396 fault with the unaligned address. */
dd4096cd 3397 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
fc40787a
AJ
3398 tcg_gen_andi_tl(t1, t0, 3);
3399#ifndef TARGET_WORDS_BIGENDIAN
3400 tcg_gen_xori_tl(t1, t1, 3);
3401#endif
3402 tcg_gen_shli_tl(t1, t1, 3);
3403 tcg_gen_andi_tl(t0, t0, ~3);
dd4096cd 3404 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL);
fc40787a 3405 tcg_gen_shl_tl(t0, t0, t1);
eb02cc3f
AJ
3406 t2 = tcg_const_tl(-1);
3407 tcg_gen_shl_tl(t2, t2, t1);
6958549d 3408 gen_load_gpr(t1, rt);
eb02cc3f 3409 tcg_gen_andc_tl(t1, t1, t2);
fc40787a
AJ
3410 tcg_temp_free(t2);
3411 tcg_gen_or_tl(t0, t0, t1);
3cee3050 3412 tcg_temp_free(t1);
fc40787a
AJ
3413 tcg_gen_ext32s_tl(t0, t0);
3414 gen_store_gpr(t0, rt);
6af0bf9c 3415 break;
76964147
JH
3416 case OPC_LWRE:
3417 mem_idx = MIPS_HFLAG_UM;
3418 /* fall through */
6af0bf9c 3419 case OPC_LWR:
3cee3050 3420 t1 = tcg_temp_new();
908680c6
AJ
3421 /* Do a byte access to possibly trigger a page
3422 fault with the unaligned address. */
dd4096cd 3423 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
fc40787a
AJ
3424 tcg_gen_andi_tl(t1, t0, 3);
3425#ifdef TARGET_WORDS_BIGENDIAN
3426 tcg_gen_xori_tl(t1, t1, 3);
3427#endif
3428 tcg_gen_shli_tl(t1, t1, 3);
3429 tcg_gen_andi_tl(t0, t0, ~3);
dd4096cd 3430 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL);
fc40787a
AJ
3431 tcg_gen_shr_tl(t0, t0, t1);
3432 tcg_gen_xori_tl(t1, t1, 31);
3433 t2 = tcg_const_tl(0xfffffffeull);
3434 tcg_gen_shl_tl(t2, t2, t1);
6958549d 3435 gen_load_gpr(t1, rt);
fc40787a
AJ
3436 tcg_gen_and_tl(t1, t1, t2);
3437 tcg_temp_free(t2);
3438 tcg_gen_or_tl(t0, t0, t1);
3cee3050 3439 tcg_temp_free(t1);
c728154b 3440 tcg_gen_ext32s_tl(t0, t0);
fc40787a 3441 gen_store_gpr(t0, rt);
6af0bf9c 3442 break;
76964147
JH
3443 case OPC_LLE:
3444 mem_idx = MIPS_HFLAG_UM;
3445 /* fall through */
6af0bf9c 3446 case OPC_LL:
4368b29a 3447 case R6_OPC_LL:
dd4096cd 3448 op_ld_ll(t0, t0, mem_idx, ctx);
78723684 3449 gen_store_gpr(t0, rt);
6af0bf9c 3450 break;
d66c7132 3451 }
d66c7132 3452 tcg_temp_free(t0);
d66c7132
AJ
3453}
3454
0b16dcd1
AR
3455static void gen_llwp(DisasContext *ctx, uint32_t base, int16_t offset,
3456 uint32_t reg1, uint32_t reg2)
3457{
3458 TCGv taddr = tcg_temp_new();
3459 TCGv_i64 tval = tcg_temp_new_i64();
3460 TCGv tmp1 = tcg_temp_new();
3461 TCGv tmp2 = tcg_temp_new();
3462
3463 gen_base_offset_addr(ctx, taddr, base, offset);
3464 tcg_gen_qemu_ld64(tval, taddr, ctx->mem_idx);
3465#ifdef TARGET_WORDS_BIGENDIAN
3466 tcg_gen_extr_i64_tl(tmp2, tmp1, tval);
3467#else
3468 tcg_gen_extr_i64_tl(tmp1, tmp2, tval);
3469#endif
3470 gen_store_gpr(tmp1, reg1);
3471 tcg_temp_free(tmp1);
3472 gen_store_gpr(tmp2, reg2);
3473 tcg_temp_free(tmp2);
3474 tcg_gen_st_i64(tval, cpu_env, offsetof(CPUMIPSState, llval_wp));
3475 tcg_temp_free_i64(tval);
3476 tcg_gen_st_tl(taddr, cpu_env, offsetof(CPUMIPSState, lladdr));
3477 tcg_temp_free(taddr);
3478}
3479
5c13fdfd
AJ
3480/* Store */
3481static void gen_st (DisasContext *ctx, uint32_t opc, int rt,
72e1f16f 3482 int base, int offset)
5c13fdfd 3483{
5c13fdfd
AJ
3484 TCGv t0 = tcg_temp_new();
3485 TCGv t1 = tcg_temp_new();
dd4096cd 3486 int mem_idx = ctx->mem_idx;
5c13fdfd
AJ
3487
3488 gen_base_offset_addr(ctx, t0, base, offset);
3489 gen_load_gpr(t1, rt);
3490 switch (opc) {
3491#if defined(TARGET_MIPS64)
3492 case OPC_SD:
dd4096cd 3493 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEQ |
be3a8c53 3494 ctx->default_tcg_memop_mask);
5c13fdfd
AJ
3495 break;
3496 case OPC_SDL:
dd4096cd 3497 gen_helper_0e2i(sdl, t1, t0, mem_idx);
5c13fdfd
AJ
3498 break;
3499 case OPC_SDR:
dd4096cd 3500 gen_helper_0e2i(sdr, t1, t0, mem_idx);
5c13fdfd
AJ
3501 break;
3502#endif
76964147
JH
3503 case OPC_SWE:
3504 mem_idx = MIPS_HFLAG_UM;
3505 /* fall through */
5c13fdfd 3506 case OPC_SW:
dd4096cd 3507 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUL |
be3a8c53 3508 ctx->default_tcg_memop_mask);
5c13fdfd 3509 break;
76964147
JH
3510 case OPC_SHE:
3511 mem_idx = MIPS_HFLAG_UM;
3512 /* fall through */
5c13fdfd 3513 case OPC_SH:
dd4096cd 3514 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUW |
be3a8c53 3515 ctx->default_tcg_memop_mask);
5c13fdfd 3516 break;
76964147
JH
3517 case OPC_SBE:
3518 mem_idx = MIPS_HFLAG_UM;
3519 /* fall through */
5c13fdfd 3520 case OPC_SB:
dd4096cd 3521 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_8);
5c13fdfd 3522 break;
76964147
JH
3523 case OPC_SWLE:
3524 mem_idx = MIPS_HFLAG_UM;
3525 /* fall through */
5c13fdfd 3526 case OPC_SWL:
dd4096cd 3527 gen_helper_0e2i(swl, t1, t0, mem_idx);
5c13fdfd 3528 break;
76964147
JH
3529 case OPC_SWRE:
3530 mem_idx = MIPS_HFLAG_UM;
3531 /* fall through */
5c13fdfd 3532 case OPC_SWR:
dd4096cd 3533 gen_helper_0e2i(swr, t1, t0, mem_idx);
5c13fdfd
AJ
3534 break;
3535 }
5c13fdfd
AJ
3536 tcg_temp_free(t0);
3537 tcg_temp_free(t1);
3538}
3539
3540
d66c7132
AJ
3541/* Store conditional */
3542static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt,
3543 int base, int16_t offset)
3544{
d66c7132 3545 TCGv t0, t1;
dd4096cd 3546 int mem_idx = ctx->mem_idx;
d66c7132 3547
2d2826b9 3548#ifdef CONFIG_USER_ONLY
d66c7132 3549 t0 = tcg_temp_local_new();
d66c7132 3550 t1 = tcg_temp_local_new();
2d2826b9
AJ
3551#else
3552 t0 = tcg_temp_new();
3553 t1 = tcg_temp_new();
3554#endif
3555 gen_base_offset_addr(ctx, t0, base, offset);
d66c7132
AJ
3556 gen_load_gpr(t1, rt);
3557 switch (opc) {
3558#if defined(TARGET_MIPS64)
3559 case OPC_SCD:
bf7910c6 3560 case R6_OPC_SCD:
dd4096cd 3561 op_st_scd(t1, t0, rt, mem_idx, ctx);
d66c7132
AJ
3562 break;
3563#endif
76964147
JH
3564 case OPC_SCE:
3565 mem_idx = MIPS_HFLAG_UM;
3566 /* fall through */
6af0bf9c 3567 case OPC_SC:
4368b29a 3568 case R6_OPC_SC:
dd4096cd 3569 op_st_sc(t1, t0, rt, mem_idx, ctx);
6af0bf9c 3570 break;
6af0bf9c 3571 }
78723684 3572 tcg_temp_free(t1);
d66c7132 3573 tcg_temp_free(t0);
6af0bf9c
FB
3574}
3575
0b16dcd1
AR
3576static void gen_scwp(DisasContext *ctx, uint32_t base, int16_t offset,
3577 uint32_t reg1, uint32_t reg2)
3578{
3579 TCGv taddr = tcg_temp_local_new();
3580 TCGv lladdr = tcg_temp_local_new();
3581 TCGv_i64 tval = tcg_temp_new_i64();
3582 TCGv_i64 llval = tcg_temp_new_i64();
3583 TCGv_i64 val = tcg_temp_new_i64();
3584 TCGv tmp1 = tcg_temp_new();
3585 TCGv tmp2 = tcg_temp_new();
3586 TCGLabel *lab_fail = gen_new_label();
3587 TCGLabel *lab_done = gen_new_label();
3588
3589 gen_base_offset_addr(ctx, taddr, base, offset);
3590
3591 tcg_gen_ld_tl(lladdr, cpu_env, offsetof(CPUMIPSState, lladdr));
3592 tcg_gen_brcond_tl(TCG_COND_NE, taddr, lladdr, lab_fail);
3593
3594 gen_load_gpr(tmp1, reg1);
3595 gen_load_gpr(tmp2, reg2);
3596
3597#ifdef TARGET_WORDS_BIGENDIAN
3598 tcg_gen_concat_tl_i64(tval, tmp2, tmp1);
3599#else
3600 tcg_gen_concat_tl_i64(tval, tmp1, tmp2);
3601#endif
3602
3603 tcg_gen_ld_i64(llval, cpu_env, offsetof(CPUMIPSState, llval_wp));
3604 tcg_gen_atomic_cmpxchg_i64(val, taddr, llval, tval,
3605 ctx->mem_idx, MO_64);
3606 if (reg1 != 0) {
3607 tcg_gen_movi_tl(cpu_gpr[reg1], 1);
3608 }
3609 tcg_gen_brcond_i64(TCG_COND_EQ, val, llval, lab_done);
3610
3611 gen_set_label(lab_fail);
3612
3613 if (reg1 != 0) {
3614 tcg_gen_movi_tl(cpu_gpr[reg1], 0);
3615 }
3616 gen_set_label(lab_done);
3617 tcg_gen_movi_tl(lladdr, -1);
3618 tcg_gen_st_tl(lladdr, cpu_env, offsetof(CPUMIPSState, lladdr));
3619}
3620
6ea83fed 3621/* Load and store */
7a387fff 3622static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
b52d3bfa 3623 TCGv t0)
6ea83fed 3624{
6ea83fed 3625 /* Don't do NOP if destination is zero: we must perform the actual
ead9360e 3626 memory access. */
6ea83fed
FB
3627 switch (opc) {
3628 case OPC_LWC1:
b6d96bed 3629 {
a7812ae4 3630 TCGv_i32 fp0 = tcg_temp_new_i32();
be3a8c53
YK
3631 tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, MO_TESL |
3632 ctx->default_tcg_memop_mask);
7c979afd 3633 gen_store_fpr32(ctx, fp0, ft);
a7812ae4 3634 tcg_temp_free_i32(fp0);
b6d96bed 3635 }
6ea83fed
FB
3636 break;
3637 case OPC_SWC1:
b6d96bed 3638 {
a7812ae4 3639 TCGv_i32 fp0 = tcg_temp_new_i32();
7c979afd 3640 gen_load_fpr32(ctx, fp0, ft);
be3a8c53
YK
3641 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL |
3642 ctx->default_tcg_memop_mask);
a7812ae4 3643 tcg_temp_free_i32(fp0);
b6d96bed 3644 }
6ea83fed
FB
3645 break;
3646 case OPC_LDC1:
b6d96bed 3647 {
a7812ae4 3648 TCGv_i64 fp0 = tcg_temp_new_i64();
be3a8c53
YK
3649 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ |
3650 ctx->default_tcg_memop_mask);
b6d96bed 3651 gen_store_fpr64(ctx, fp0, ft);
a7812ae4 3652 tcg_temp_free_i64(fp0);
b6d96bed 3653 }
6ea83fed
FB
3654 break;
3655 case OPC_SDC1:
b6d96bed 3656 {
a7812ae4 3657 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 3658 gen_load_fpr64(ctx, fp0, ft);
be3a8c53
YK
3659 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ |
3660 ctx->default_tcg_memop_mask);
a7812ae4 3661 tcg_temp_free_i64(fp0);
b6d96bed 3662 }
6ea83fed
FB
3663 break;
3664 default:
9d68ac14 3665 MIPS_INVAL("flt_ldst");
9c708c7f 3666 generate_exception_end(ctx, EXCP_RI);
b52d3bfa 3667 break;
6ea83fed 3668 }
6ea83fed 3669}
6ea83fed 3670
5ab5c041
AJ
3671static void gen_cop1_ldst(DisasContext *ctx, uint32_t op, int rt,
3672 int rs, int16_t imm)
26ebe468 3673{
b52d3bfa
YK
3674 TCGv t0 = tcg_temp_new();
3675
5ab5c041 3676 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
26ebe468 3677 check_cp1_enabled(ctx);
d9224450
MR
3678 switch (op) {
3679 case OPC_LDC1:
3680 case OPC_SDC1:
3681 check_insn(ctx, ISA_MIPS2);
3682 /* Fallthrough */
3683 default:
b52d3bfa
YK
3684 gen_base_offset_addr(ctx, t0, rs, imm);
3685 gen_flt_ldst(ctx, op, rt, t0);
d9224450 3686 }
26ebe468
NF
3687 } else {
3688 generate_exception_err(ctx, EXCP_CpU, 1);
3689 }
b52d3bfa 3690 tcg_temp_free(t0);
26ebe468
NF
3691}
3692
6af0bf9c 3693/* Arithmetic with immediate operand */
d75c135e 3694static void gen_arith_imm(DisasContext *ctx, uint32_t opc,
72e1f16f 3695 int rt, int rs, int imm)
6af0bf9c 3696{
324d9e32 3697 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
6af0bf9c 3698
7a387fff 3699 if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
ead9360e
TS
3700 /* If no destination, treat it as a NOP.
3701 For addi, we must generate the overflow exception when needed. */
324d9e32 3702 return;
6af0bf9c
FB
3703 }
3704 switch (opc) {
3705 case OPC_ADDI:
48d38ca5 3706 {
324d9e32
AJ
3707 TCGv t0 = tcg_temp_local_new();
3708 TCGv t1 = tcg_temp_new();
3709 TCGv t2 = tcg_temp_new();
42a268c2 3710 TCGLabel *l1 = gen_new_label();
48d38ca5 3711
324d9e32
AJ
3712 gen_load_gpr(t1, rs);
3713 tcg_gen_addi_tl(t0, t1, uimm);
3714 tcg_gen_ext32s_tl(t0, t0);
48d38ca5 3715
324d9e32
AJ
3716 tcg_gen_xori_tl(t1, t1, ~uimm);
3717 tcg_gen_xori_tl(t2, t0, uimm);
3718 tcg_gen_and_tl(t1, t1, t2);
3719 tcg_temp_free(t2);
3720 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
3721 tcg_temp_free(t1);
48d38ca5
TS
3722 /* operands of same sign, result different sign */
3723 generate_exception(ctx, EXCP_OVERFLOW);
3724 gen_set_label(l1);
78723684 3725 tcg_gen_ext32s_tl(t0, t0);
324d9e32
AJ
3726 gen_store_gpr(t0, rt);
3727 tcg_temp_free(t0);
48d38ca5 3728 }
6af0bf9c
FB
3729 break;
3730 case OPC_ADDIU:
324d9e32
AJ
3731 if (rs != 0) {
3732 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3733 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
3734 } else {
3735 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
3736 }
6af0bf9c 3737 break;
d26bc211 3738#if defined(TARGET_MIPS64)
7a387fff 3739 case OPC_DADDI:
48d38ca5 3740 {
324d9e32
AJ
3741 TCGv t0 = tcg_temp_local_new();
3742 TCGv t1 = tcg_temp_new();
3743 TCGv t2 = tcg_temp_new();
42a268c2 3744 TCGLabel *l1 = gen_new_label();
48d38ca5 3745
324d9e32
AJ
3746 gen_load_gpr(t1, rs);
3747 tcg_gen_addi_tl(t0, t1, uimm);
48d38ca5 3748
324d9e32
AJ
3749 tcg_gen_xori_tl(t1, t1, ~uimm);
3750 tcg_gen_xori_tl(t2, t0, uimm);
3751 tcg_gen_and_tl(t1, t1, t2);
3752 tcg_temp_free(t2);
3753 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
3754 tcg_temp_free(t1);
48d38ca5
TS
3755 /* operands of same sign, result different sign */
3756 generate_exception(ctx, EXCP_OVERFLOW);
3757 gen_set_label(l1);
324d9e32
AJ
3758 gen_store_gpr(t0, rt);
3759 tcg_temp_free(t0);
48d38ca5 3760 }
7a387fff
TS
3761 break;
3762 case OPC_DADDIU:
324d9e32
AJ
3763 if (rs != 0) {
3764 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3765 } else {
3766 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
3767 }
7a387fff
TS
3768 break;
3769#endif
324d9e32 3770 }
324d9e32
AJ
3771}
3772
3773/* Logic with immediate operand */
d75c135e 3774static void gen_logic_imm(DisasContext *ctx, uint32_t opc,
9fa77488 3775 int rt, int rs, int16_t imm)
324d9e32
AJ
3776{
3777 target_ulong uimm;
324d9e32
AJ
3778
3779 if (rt == 0) {
3780 /* If no destination, treat it as a NOP. */
324d9e32
AJ
3781 return;
3782 }
3783 uimm = (uint16_t)imm;
3784 switch (opc) {
6af0bf9c 3785 case OPC_ANDI:
324d9e32
AJ
3786 if (likely(rs != 0))
3787 tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3788 else
3789 tcg_gen_movi_tl(cpu_gpr[rt], 0);
6af0bf9c
FB
3790 break;
3791 case OPC_ORI:
324d9e32
AJ
3792 if (rs != 0)
3793 tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3794 else
3795 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
6af0bf9c
FB
3796 break;
3797 case OPC_XORI:
324d9e32
AJ
3798 if (likely(rs != 0))
3799 tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3800 else
3801 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
6af0bf9c
FB
3802 break;
3803 case OPC_LUI:
d4ea6acd
LA
3804 if (rs != 0 && (ctx->insn_flags & ISA_MIPS32R6)) {
3805 /* OPC_AUI */
3806 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm << 16);
3807 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
d4ea6acd
LA
3808 } else {
3809 tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
d4ea6acd 3810 }
7c2c3ea3
EJ
3811 break;
3812
3813 default:
6af0bf9c 3814 break;
324d9e32 3815 }
324d9e32
AJ
3816}
3817
3818/* Set on less than with immediate operand */
d75c135e 3819static void gen_slt_imm(DisasContext *ctx, uint32_t opc,
9fa77488 3820 int rt, int rs, int16_t imm)
324d9e32
AJ
3821{
3822 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
324d9e32
AJ
3823 TCGv t0;
3824
3825 if (rt == 0) {
3826 /* If no destination, treat it as a NOP. */
324d9e32
AJ
3827 return;
3828 }
3829 t0 = tcg_temp_new();
3830 gen_load_gpr(t0, rs);
3831 switch (opc) {
3832 case OPC_SLTI:
e68dd28f 3833 tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
324d9e32
AJ
3834 break;
3835 case OPC_SLTIU:
e68dd28f 3836 tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
324d9e32
AJ
3837 break;
3838 }
324d9e32
AJ
3839 tcg_temp_free(t0);
3840}
3841
3842/* Shifts with immediate operand */
d75c135e 3843static void gen_shift_imm(DisasContext *ctx, uint32_t opc,
324d9e32
AJ
3844 int rt, int rs, int16_t imm)
3845{
3846 target_ulong uimm = ((uint16_t)imm) & 0x1f;
324d9e32
AJ
3847 TCGv t0;
3848
3849 if (rt == 0) {
3850 /* If no destination, treat it as a NOP. */
324d9e32
AJ
3851 return;
3852 }
3853
3854 t0 = tcg_temp_new();
3855 gen_load_gpr(t0, rs);
3856 switch (opc) {
6af0bf9c 3857 case OPC_SLL:
78723684 3858 tcg_gen_shli_tl(t0, t0, uimm);
324d9e32 3859 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
6af0bf9c
FB
3860 break;
3861 case OPC_SRA:
324d9e32 3862 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
6af0bf9c
FB
3863 break;
3864 case OPC_SRL:
ea63e2c3
NF
3865 if (uimm != 0) {
3866 tcg_gen_ext32u_tl(t0, t0);
3867 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
3868 } else {
3869 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
5a63bcb2 3870 }
ea63e2c3
NF
3871 break;
3872 case OPC_ROTR:
3873 if (uimm != 0) {
3874 TCGv_i32 t1 = tcg_temp_new_i32();
3875
3876 tcg_gen_trunc_tl_i32(t1, t0);
3877 tcg_gen_rotri_i32(t1, t1, uimm);
3878 tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
3879 tcg_temp_free_i32(t1);
3399e30f
NF
3880 } else {
3881 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
ea63e2c3 3882 }
7a387fff 3883 break;
d26bc211 3884#if defined(TARGET_MIPS64)
7a387fff 3885 case OPC_DSLL:
324d9e32 3886 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
7a387fff
TS
3887 break;
3888 case OPC_DSRA:
324d9e32 3889 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
7a387fff
TS
3890 break;
3891 case OPC_DSRL:
ea63e2c3 3892 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
ea63e2c3
NF
3893 break;
3894 case OPC_DROTR:
3895 if (uimm != 0) {
3896 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
3399e30f
NF
3897 } else {
3898 tcg_gen_mov_tl(cpu_gpr[rt], t0);
5a63bcb2 3899 }
7a387fff
TS
3900 break;
3901 case OPC_DSLL32:
324d9e32 3902 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
7a387fff
TS
3903 break;
3904 case OPC_DSRA32:
324d9e32 3905 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
7a387fff
TS
3906 break;
3907 case OPC_DSRL32:
ea63e2c3 3908 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
ea63e2c3
NF
3909 break;
3910 case OPC_DROTR32:
3911 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
6af0bf9c 3912 break;
7a387fff 3913#endif
6af0bf9c 3914 }
78723684 3915 tcg_temp_free(t0);
6af0bf9c
FB
3916}
3917
3918/* Arithmetic */
d75c135e
AJ
3919static void gen_arith(DisasContext *ctx, uint32_t opc,
3920 int rd, int rs, int rt)
6af0bf9c 3921{
7a387fff
TS
3922 if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
3923 && opc != OPC_DADD && opc != OPC_DSUB) {
ead9360e
TS
3924 /* If no destination, treat it as a NOP.
3925 For add & sub, we must generate the overflow exception when needed. */
460f00c4 3926 return;
185f0762 3927 }
460f00c4 3928
6af0bf9c
FB
3929 switch (opc) {
3930 case OPC_ADD:
48d38ca5 3931 {
460f00c4
AJ
3932 TCGv t0 = tcg_temp_local_new();
3933 TCGv t1 = tcg_temp_new();
3934 TCGv t2 = tcg_temp_new();
42a268c2 3935 TCGLabel *l1 = gen_new_label();
48d38ca5 3936
460f00c4
AJ
3937 gen_load_gpr(t1, rs);
3938 gen_load_gpr(t2, rt);
3939 tcg_gen_add_tl(t0, t1, t2);
3940 tcg_gen_ext32s_tl(t0, t0);
3941 tcg_gen_xor_tl(t1, t1, t2);
460f00c4 3942 tcg_gen_xor_tl(t2, t0, t2);
deb4203d 3943 tcg_gen_andc_tl(t1, t2, t1);
460f00c4
AJ
3944 tcg_temp_free(t2);
3945 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
3946 tcg_temp_free(t1);
48d38ca5
TS
3947 /* operands of same sign, result different sign */
3948 generate_exception(ctx, EXCP_OVERFLOW);
3949 gen_set_label(l1);
460f00c4
AJ
3950 gen_store_gpr(t0, rd);
3951 tcg_temp_free(t0);
48d38ca5 3952 }
6af0bf9c
FB
3953 break;
3954 case OPC_ADDU:
460f00c4
AJ
3955 if (rs != 0 && rt != 0) {
3956 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
3957 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3958 } else if (rs == 0 && rt != 0) {
3959 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
3960 } else if (rs != 0 && rt == 0) {
3961 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
3962 } else {
3963 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3964 }
6af0bf9c
FB
3965 break;
3966 case OPC_SUB:
48d38ca5 3967 {
460f00c4
AJ
3968 TCGv t0 = tcg_temp_local_new();
3969 TCGv t1 = tcg_temp_new();
3970 TCGv t2 = tcg_temp_new();
42a268c2 3971 TCGLabel *l1 = gen_new_label();
48d38ca5 3972
460f00c4
AJ
3973 gen_load_gpr(t1, rs);
3974 gen_load_gpr(t2, rt);
3975 tcg_gen_sub_tl(t0, t1, t2);
3976 tcg_gen_ext32s_tl(t0, t0);
3977 tcg_gen_xor_tl(t2, t1, t2);
3978 tcg_gen_xor_tl(t1, t0, t1);
3979 tcg_gen_and_tl(t1, t1, t2);
3980 tcg_temp_free(t2);
3981 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
3982 tcg_temp_free(t1);
31e3104f 3983 /* operands of different sign, first operand and result different sign */
48d38ca5
TS
3984 generate_exception(ctx, EXCP_OVERFLOW);
3985 gen_set_label(l1);
460f00c4
AJ
3986 gen_store_gpr(t0, rd);
3987 tcg_temp_free(t0);
48d38ca5 3988 }
6af0bf9c
FB
3989 break;
3990 case OPC_SUBU:
460f00c4
AJ
3991 if (rs != 0 && rt != 0) {
3992 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
3993 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3994 } else if (rs == 0 && rt != 0) {
3995 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
6bb72b18 3996 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
460f00c4
AJ
3997 } else if (rs != 0 && rt == 0) {
3998 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
3999 } else {
4000 tcg_gen_movi_tl(cpu_gpr[rd], 0);
4001 }
6af0bf9c 4002 break;
d26bc211 4003#if defined(TARGET_MIPS64)
7a387fff 4004 case OPC_DADD:
48d38ca5 4005 {
460f00c4
AJ
4006 TCGv t0 = tcg_temp_local_new();
4007 TCGv t1 = tcg_temp_new();
4008 TCGv t2 = tcg_temp_new();
42a268c2 4009 TCGLabel *l1 = gen_new_label();
48d38ca5 4010
460f00c4
AJ
4011 gen_load_gpr(t1, rs);
4012 gen_load_gpr(t2, rt);
4013 tcg_gen_add_tl(t0, t1, t2);
4014 tcg_gen_xor_tl(t1, t1, t2);
460f00c4 4015 tcg_gen_xor_tl(t2, t0, t2);
deb4203d 4016 tcg_gen_andc_tl(t1, t2, t1);
460f00c4
AJ
4017 tcg_temp_free(t2);
4018 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
4019 tcg_temp_free(t1);
48d38ca5
TS
4020 /* operands of same sign, result different sign */
4021 generate_exception(ctx, EXCP_OVERFLOW);
4022 gen_set_label(l1);
460f00c4
AJ
4023 gen_store_gpr(t0, rd);
4024 tcg_temp_free(t0);
48d38ca5 4025 }
7a387fff
TS
4026 break;
4027 case OPC_DADDU:
460f00c4
AJ
4028 if (rs != 0 && rt != 0) {
4029 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4030 } else if (rs == 0 && rt != 0) {
4031 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
4032 } else if (rs != 0 && rt == 0) {
4033 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
4034 } else {
4035 tcg_gen_movi_tl(cpu_gpr[rd], 0);
4036 }
7a387fff
TS
4037 break;
4038 case OPC_DSUB:
48d38ca5 4039 {
460f00c4
AJ
4040 TCGv t0 = tcg_temp_local_new();
4041 TCGv t1 = tcg_temp_new();
4042 TCGv t2 = tcg_temp_new();
42a268c2 4043 TCGLabel *l1 = gen_new_label();
48d38ca5 4044
460f00c4
AJ
4045 gen_load_gpr(t1, rs);
4046 gen_load_gpr(t2, rt);
4047 tcg_gen_sub_tl(t0, t1, t2);
4048 tcg_gen_xor_tl(t2, t1, t2);
4049 tcg_gen_xor_tl(t1, t0, t1);
4050 tcg_gen_and_tl(t1, t1, t2);
4051 tcg_temp_free(t2);
4052 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
4053 tcg_temp_free(t1);
31e3104f 4054 /* operands of different sign, first operand and result different sign */
48d38ca5
TS
4055 generate_exception(ctx, EXCP_OVERFLOW);
4056 gen_set_label(l1);
460f00c4
AJ
4057 gen_store_gpr(t0, rd);
4058 tcg_temp_free(t0);
48d38ca5 4059 }
7a387fff
TS
4060 break;
4061 case OPC_DSUBU:
460f00c4
AJ
4062 if (rs != 0 && rt != 0) {
4063 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4064 } else if (rs == 0 && rt != 0) {
4065 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
4066 } else if (rs != 0 && rt == 0) {
4067 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
4068 } else {
4069 tcg_gen_movi_tl(cpu_gpr[rd], 0);
4070 }
7a387fff
TS
4071 break;
4072#endif
460f00c4
AJ
4073 case OPC_MUL:
4074 if (likely(rs != 0 && rt != 0)) {
4075 tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4076 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4077 } else {
4078 tcg_gen_movi_tl(cpu_gpr[rd], 0);
4079 }
6af0bf9c 4080 break;
460f00c4 4081 }
460f00c4
AJ
4082}
4083
4084/* Conditional move */
d75c135e 4085static void gen_cond_move(DisasContext *ctx, uint32_t opc,
9fa77488 4086 int rd, int rs, int rt)
460f00c4 4087{
acf12465 4088 TCGv t0, t1, t2;
460f00c4
AJ
4089
4090 if (rd == 0) {
acf12465 4091 /* If no destination, treat it as a NOP. */
460f00c4
AJ
4092 return;
4093 }
4094
acf12465
AJ
4095 t0 = tcg_temp_new();
4096 gen_load_gpr(t0, rt);
4097 t1 = tcg_const_tl(0);
4098 t2 = tcg_temp_new();
4099 gen_load_gpr(t2, rs);
460f00c4
AJ
4100 switch (opc) {
4101 case OPC_MOVN:
acf12465 4102 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
6af0bf9c 4103 break;
460f00c4 4104 case OPC_MOVZ:
acf12465 4105 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
460f00c4 4106 break;
b691d9d2
LA
4107 case OPC_SELNEZ:
4108 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, t1);
b691d9d2
LA
4109 break;
4110 case OPC_SELEQZ:
4111 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, t1);
b691d9d2 4112 break;
460f00c4 4113 }
acf12465
AJ
4114 tcg_temp_free(t2);
4115 tcg_temp_free(t1);
4116 tcg_temp_free(t0);
460f00c4
AJ
4117}
4118
4119/* Logic */
d75c135e 4120static void gen_logic(DisasContext *ctx, uint32_t opc,
9fa77488 4121 int rd, int rs, int rt)
460f00c4 4122{
460f00c4
AJ
4123 if (rd == 0) {
4124 /* If no destination, treat it as a NOP. */
460f00c4
AJ
4125 return;
4126 }
4127
4128 switch (opc) {
6af0bf9c 4129 case OPC_AND:
460f00c4
AJ
4130 if (likely(rs != 0 && rt != 0)) {
4131 tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4132 } else {
4133 tcg_gen_movi_tl(cpu_gpr[rd], 0);
4134 }
6af0bf9c
FB
4135 break;
4136 case OPC_NOR:
460f00c4
AJ
4137 if (rs != 0 && rt != 0) {
4138 tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4139 } else if (rs == 0 && rt != 0) {
4140 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
4141 } else if (rs != 0 && rt == 0) {
4142 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
4143 } else {
4144 tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
4145 }
6af0bf9c
FB
4146 break;
4147 case OPC_OR:
460f00c4
AJ
4148 if (likely(rs != 0 && rt != 0)) {
4149 tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4150 } else if (rs == 0 && rt != 0) {
4151 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
4152 } else if (rs != 0 && rt == 0) {
4153 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
4154 } else {
4155 tcg_gen_movi_tl(cpu_gpr[rd], 0);
4156 }
6af0bf9c
FB
4157 break;
4158 case OPC_XOR:
460f00c4
AJ
4159 if (likely(rs != 0 && rt != 0)) {
4160 tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4161 } else if (rs == 0 && rt != 0) {
4162 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
4163 } else if (rs != 0 && rt == 0) {
4164 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
4165 } else {
4166 tcg_gen_movi_tl(cpu_gpr[rd], 0);
4167 }
6af0bf9c 4168 break;
460f00c4 4169 }
460f00c4
AJ
4170}
4171
4172/* Set on lower than */
d75c135e 4173static void gen_slt(DisasContext *ctx, uint32_t opc,
9fa77488 4174 int rd, int rs, int rt)
460f00c4 4175{
460f00c4
AJ
4176 TCGv t0, t1;
4177
4178 if (rd == 0) {
4179 /* If no destination, treat it as a NOP. */
460f00c4
AJ
4180 return;
4181 }
4182
4183 t0 = tcg_temp_new();
4184 t1 = tcg_temp_new();
4185 gen_load_gpr(t0, rs);
4186 gen_load_gpr(t1, rt);
4187 switch (opc) {
4188 case OPC_SLT:
e68dd28f 4189 tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
6af0bf9c 4190 break;
460f00c4 4191 case OPC_SLTU:
e68dd28f 4192 tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
460f00c4
AJ
4193 break;
4194 }
460f00c4
AJ
4195 tcg_temp_free(t0);
4196 tcg_temp_free(t1);
4197}
20c4c97c 4198
460f00c4 4199/* Shifts */
d75c135e
AJ
4200static void gen_shift(DisasContext *ctx, uint32_t opc,
4201 int rd, int rs, int rt)
460f00c4 4202{
460f00c4 4203 TCGv t0, t1;
20c4c97c 4204
460f00c4
AJ
4205 if (rd == 0) {
4206 /* If no destination, treat it as a NOP.
4207 For add & sub, we must generate the overflow exception when needed. */
460f00c4
AJ
4208 return;
4209 }
4210
4211 t0 = tcg_temp_new();
4212 t1 = tcg_temp_new();
4213 gen_load_gpr(t0, rs);
4214 gen_load_gpr(t1, rt);
4215 switch (opc) {
6af0bf9c 4216 case OPC_SLLV:
78723684
TS
4217 tcg_gen_andi_tl(t0, t0, 0x1f);
4218 tcg_gen_shl_tl(t0, t1, t0);
460f00c4 4219 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
6af0bf9c
FB
4220 break;
4221 case OPC_SRAV:
78723684 4222 tcg_gen_andi_tl(t0, t0, 0x1f);
460f00c4 4223 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
6af0bf9c
FB
4224 break;
4225 case OPC_SRLV:
ea63e2c3
NF
4226 tcg_gen_ext32u_tl(t1, t1);
4227 tcg_gen_andi_tl(t0, t0, 0x1f);
4228 tcg_gen_shr_tl(t0, t1, t0);
4229 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
ea63e2c3
NF
4230 break;
4231 case OPC_ROTRV:
4232 {
4233 TCGv_i32 t2 = tcg_temp_new_i32();
4234 TCGv_i32 t3 = tcg_temp_new_i32();
4235
4236 tcg_gen_trunc_tl_i32(t2, t0);
4237 tcg_gen_trunc_tl_i32(t3, t1);
4238 tcg_gen_andi_i32(t2, t2, 0x1f);
4239 tcg_gen_rotr_i32(t2, t3, t2);
4240 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
4241 tcg_temp_free_i32(t2);
4242 tcg_temp_free_i32(t3);
5a63bcb2 4243 }
7a387fff 4244 break;
d26bc211 4245#if defined(TARGET_MIPS64)
7a387fff 4246 case OPC_DSLLV:
78723684 4247 tcg_gen_andi_tl(t0, t0, 0x3f);
460f00c4 4248 tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
7a387fff
TS
4249 break;
4250 case OPC_DSRAV:
78723684 4251 tcg_gen_andi_tl(t0, t0, 0x3f);
460f00c4 4252 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
7a387fff
TS
4253 break;
4254 case OPC_DSRLV:
ea63e2c3
NF
4255 tcg_gen_andi_tl(t0, t0, 0x3f);
4256 tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
ea63e2c3
NF
4257 break;
4258 case OPC_DROTRV:
4259 tcg_gen_andi_tl(t0, t0, 0x3f);
4260 tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
6af0bf9c 4261 break;
7a387fff 4262#endif
6af0bf9c 4263 }
78723684
TS
4264 tcg_temp_free(t0);
4265 tcg_temp_free(t1);
6af0bf9c
FB
4266}
4267
4268/* Arithmetic on HI/LO registers */
26135ead 4269static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg)
6af0bf9c 4270{
8d927f7c
FN
4271 if (reg == 0 && (opc == OPC_MFHI || opc == TX79_MMI_MFHI1 ||
4272 opc == OPC_MFLO || opc == TX79_MMI_MFLO1)) {
ead9360e 4273 /* Treat as NOP. */
a1f6684d 4274 return;
6af0bf9c 4275 }
4133498f 4276
4133498f 4277 if (acc != 0) {
8d927f7c
FN
4278 if (!(ctx->insn_flags & INSN_R5900)) {
4279 check_dsp(ctx);
4280 }
4133498f
JL
4281 }
4282
6af0bf9c
FB
4283 switch (opc) {
4284 case OPC_MFHI:
8d927f7c 4285 case TX79_MMI_MFHI1:
4133498f
JL
4286#if defined(TARGET_MIPS64)
4287 if (acc != 0) {
4288 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]);
4289 } else
4290#endif
4291 {
4292 tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]);
4293 }
6af0bf9c
FB
4294 break;
4295 case OPC_MFLO:
8d927f7c 4296 case TX79_MMI_MFLO1:
4133498f
JL
4297#if defined(TARGET_MIPS64)
4298 if (acc != 0) {
4299 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]);
4300 } else
4301#endif
4302 {
4303 tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]);
4304 }
6af0bf9c
FB
4305 break;
4306 case OPC_MTHI:
8d927f7c 4307 case TX79_MMI_MTHI1:
4133498f
JL
4308 if (reg != 0) {
4309#if defined(TARGET_MIPS64)
4310 if (acc != 0) {
4311 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_gpr[reg]);
4312 } else
4313#endif
4314 {
4315 tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]);
4316 }
4317 } else {
4318 tcg_gen_movi_tl(cpu_HI[acc], 0);
4319 }
6af0bf9c
FB
4320 break;
4321 case OPC_MTLO:
8d927f7c 4322 case TX79_MMI_MTLO1:
4133498f
JL
4323 if (reg != 0) {
4324#if defined(TARGET_MIPS64)
4325 if (acc != 0) {
4326 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_gpr[reg]);
4327 } else
4328#endif
4329 {
4330 tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]);
4331 }
4332 } else {
4333 tcg_gen_movi_tl(cpu_LO[acc], 0);
4334 }
6af0bf9c 4335 break;
6af0bf9c 4336 }
6af0bf9c
FB
4337}
4338
d4ea6acd
LA
4339static inline void gen_r6_ld(target_long addr, int reg, int memidx,
4340 TCGMemOp memop)
4341{
4342 TCGv t0 = tcg_const_tl(addr);
4343 tcg_gen_qemu_ld_tl(t0, t0, memidx, memop);
4344 gen_store_gpr(t0, reg);
4345 tcg_temp_free(t0);
4346}
4347
ab39ee45
YK
4348static inline void gen_pcrel(DisasContext *ctx, int opc, target_ulong pc,
4349 int rs)
d4ea6acd
LA
4350{
4351 target_long offset;
4352 target_long addr;
4353
ab39ee45 4354 switch (MASK_OPC_PCREL_TOP2BITS(opc)) {
d4ea6acd
LA
4355 case OPC_ADDIUPC:
4356 if (rs != 0) {
4357 offset = sextract32(ctx->opcode << 2, 0, 21);
ab39ee45 4358 addr = addr_add(ctx, pc, offset);
d4ea6acd
LA
4359 tcg_gen_movi_tl(cpu_gpr[rs], addr);
4360 }
4361 break;
4362 case R6_OPC_LWPC:
4363 offset = sextract32(ctx->opcode << 2, 0, 21);
ab39ee45 4364 addr = addr_add(ctx, pc, offset);
d4ea6acd
LA
4365 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TESL);
4366 break;
4367#if defined(TARGET_MIPS64)
4368 case OPC_LWUPC:
4369 check_mips_64(ctx);
4370 offset = sextract32(ctx->opcode << 2, 0, 21);
ab39ee45 4371 addr = addr_add(ctx, pc, offset);
d4ea6acd
LA
4372 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEUL);
4373 break;
4374#endif
4375 default:
ab39ee45 4376 switch (MASK_OPC_PCREL_TOP5BITS(opc)) {
d4ea6acd
LA
4377 case OPC_AUIPC:
4378 if (rs != 0) {
ab39ee45
YK
4379 offset = sextract32(ctx->opcode, 0, 16) << 16;
4380 addr = addr_add(ctx, pc, offset);
d4ea6acd
LA
4381 tcg_gen_movi_tl(cpu_gpr[rs], addr);
4382 }
4383 break;
4384 case OPC_ALUIPC:
4385 if (rs != 0) {
ab39ee45
YK
4386 offset = sextract32(ctx->opcode, 0, 16) << 16;
4387 addr = ~0xFFFF & addr_add(ctx, pc, offset);
d4ea6acd
LA
4388 tcg_gen_movi_tl(cpu_gpr[rs], addr);
4389 }
4390 break;
4391#if defined(TARGET_MIPS64)
4392 case R6_OPC_LDPC: /* bits 16 and 17 are part of immediate */
4393 case R6_OPC_LDPC + (1 << 16):
4394 case R6_OPC_LDPC + (2 << 16):
4395 case R6_OPC_LDPC + (3 << 16):
4396 check_mips_64(ctx);
4397 offset = sextract32(ctx->opcode << 3, 0, 21);
ab39ee45 4398 addr = addr_add(ctx, (pc & ~0x7), offset);
d4ea6acd
LA
4399 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEQ);
4400 break;
4401#endif
4402 default:
4403 MIPS_INVAL("OPC_PCREL");
9c708c7f 4404 generate_exception_end(ctx, EXCP_RI);
d4ea6acd
LA
4405 break;
4406 }
4407 break;
4408 }
4409}
4410
b42ee5e1
LA
4411static void gen_r6_muldiv(DisasContext *ctx, int opc, int rd, int rs, int rt)
4412{
b42ee5e1
LA
4413 TCGv t0, t1;
4414
4415 if (rd == 0) {
4416 /* Treat as NOP. */
b42ee5e1
LA
4417 return;
4418 }
4419
4420 t0 = tcg_temp_new();
4421 t1 = tcg_temp_new();
4422
4423 gen_load_gpr(t0, rs);
4424 gen_load_gpr(t1, rt);
4425
4426 switch (opc) {
4427 case R6_OPC_DIV:
4428 {
4429 TCGv t2 = tcg_temp_new();
4430 TCGv t3 = tcg_temp_new();
4431 tcg_gen_ext32s_tl(t0, t0);
4432 tcg_gen_ext32s_tl(t1, t1);
4433 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
4434 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
4435 tcg_gen_and_tl(t2, t2, t3);
4436 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4437 tcg_gen_or_tl(t2, t2, t3);
4438 tcg_gen_movi_tl(t3, 0);
4439 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4440 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
4441 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4442 tcg_temp_free(t3);
4443 tcg_temp_free(t2);
4444 }
b42ee5e1
LA
4445 break;
4446 case R6_OPC_MOD:
4447 {
4448 TCGv t2 = tcg_temp_new();
4449 TCGv t3 = tcg_temp_new();
4450 tcg_gen_ext32s_tl(t0, t0);
4451 tcg_gen_ext32s_tl(t1, t1);
4452 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
4453 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
4454 tcg_gen_and_tl(t2, t2, t3);
4455 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4456 tcg_gen_or_tl(t2, t2, t3);
4457 tcg_gen_movi_tl(t3, 0);
4458 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4459 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
4460 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4461 tcg_temp_free(t3);
4462 tcg_temp_free(t2);
4463 }
b42ee5e1
LA
4464 break;
4465 case R6_OPC_DIVU:
4466 {
4467 TCGv t2 = tcg_const_tl(0);
4468 TCGv t3 = tcg_const_tl(1);
4469 tcg_gen_ext32u_tl(t0, t0);
4470 tcg_gen_ext32u_tl(t1, t1);
4471 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4472 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
4473 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4474 tcg_temp_free(t3);
4475 tcg_temp_free(t2);
4476 }
b42ee5e1
LA
4477 break;
4478 case R6_OPC_MODU:
4479 {
4480 TCGv t2 = tcg_const_tl(0);
4481 TCGv t3 = tcg_const_tl(1);
4482 tcg_gen_ext32u_tl(t0, t0);
4483 tcg_gen_ext32u_tl(t1, t1);
4484 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4485 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
4486 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4487 tcg_temp_free(t3);
4488 tcg_temp_free(t2);
4489 }
b42ee5e1
LA
4490 break;
4491 case R6_OPC_MUL:
4492 {
4493 TCGv_i32 t2 = tcg_temp_new_i32();
4494 TCGv_i32 t3 = tcg_temp_new_i32();
4495 tcg_gen_trunc_tl_i32(t2, t0);
4496 tcg_gen_trunc_tl_i32(t3, t1);
4497 tcg_gen_mul_i32(t2, t2, t3);
4498 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
4499 tcg_temp_free_i32(t2);
4500 tcg_temp_free_i32(t3);
4501 }
b42ee5e1
LA
4502 break;
4503 case R6_OPC_MUH:
4504 {
4505 TCGv_i32 t2 = tcg_temp_new_i32();
4506 TCGv_i32 t3 = tcg_temp_new_i32();
4507 tcg_gen_trunc_tl_i32(t2, t0);
4508 tcg_gen_trunc_tl_i32(t3, t1);
4509 tcg_gen_muls2_i32(t2, t3, t2, t3);
4510 tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
4511 tcg_temp_free_i32(t2);
4512 tcg_temp_free_i32(t3);
4513 }
b42ee5e1
LA
4514 break;
4515 case R6_OPC_MULU:
4516 {
4517 TCGv_i32 t2 = tcg_temp_new_i32();
4518 TCGv_i32 t3 = tcg_temp_new_i32();
4519 tcg_gen_trunc_tl_i32(t2, t0);
4520 tcg_gen_trunc_tl_i32(t3, t1);
4521 tcg_gen_mul_i32(t2, t2, t3);
4522 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
4523 tcg_temp_free_i32(t2);
4524 tcg_temp_free_i32(t3);
4525 }
b42ee5e1
LA
4526 break;
4527 case R6_OPC_MUHU:
4528 {
4529 TCGv_i32 t2 = tcg_temp_new_i32();
4530 TCGv_i32 t3 = tcg_temp_new_i32();
4531 tcg_gen_trunc_tl_i32(t2, t0);
4532 tcg_gen_trunc_tl_i32(t3, t1);
4533 tcg_gen_mulu2_i32(t2, t3, t2, t3);
4534 tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
4535 tcg_temp_free_i32(t2);
4536 tcg_temp_free_i32(t3);
4537 }
b42ee5e1
LA
4538 break;
4539#if defined(TARGET_MIPS64)
4540 case R6_OPC_DDIV:
4541 {
4542 TCGv t2 = tcg_temp_new();
4543 TCGv t3 = tcg_temp_new();
4544 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
4545 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
4546 tcg_gen_and_tl(t2, t2, t3);
4547 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4548 tcg_gen_or_tl(t2, t2, t3);
4549 tcg_gen_movi_tl(t3, 0);
4550 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4551 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
4552 tcg_temp_free(t3);
4553 tcg_temp_free(t2);
4554 }
b42ee5e1
LA
4555 break;
4556 case R6_OPC_DMOD:
4557 {
4558 TCGv t2 = tcg_temp_new();
4559 TCGv t3 = tcg_temp_new();
4560 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
4561 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
4562 tcg_gen_and_tl(t2, t2, t3);
4563 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4564 tcg_gen_or_tl(t2, t2, t3);
4565 tcg_gen_movi_tl(t3, 0);
4566 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4567 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
4568 tcg_temp_free(t3);
4569 tcg_temp_free(t2);
4570 }
b42ee5e1
LA
4571 break;
4572 case R6_OPC_DDIVU:
4573 {
4574 TCGv t2 = tcg_const_tl(0);
4575 TCGv t3 = tcg_const_tl(1);
4576 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4577 tcg_gen_divu_i64(cpu_gpr[rd], t0, t1);
4578 tcg_temp_free(t3);
4579 tcg_temp_free(t2);
4580 }
b42ee5e1
LA
4581 break;
4582 case R6_OPC_DMODU:
4583 {
4584 TCGv t2 = tcg_const_tl(0);
4585 TCGv t3 = tcg_const_tl(1);
4586 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4587 tcg_gen_remu_i64(cpu_gpr[rd], t0, t1);
4588 tcg_temp_free(t3);
4589 tcg_temp_free(t2);
4590 }
b42ee5e1
LA
4591 break;
4592 case R6_OPC_DMUL:
4593 tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
b42ee5e1
LA
4594 break;
4595 case R6_OPC_DMUH:
4596 {
4597 TCGv t2 = tcg_temp_new();
4598 tcg_gen_muls2_i64(t2, cpu_gpr[rd], t0, t1);
4599 tcg_temp_free(t2);
4600 }
b42ee5e1
LA
4601 break;
4602 case R6_OPC_DMULU:
4603 tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
b42ee5e1
LA
4604 break;
4605 case R6_OPC_DMUHU:
4606 {
4607 TCGv t2 = tcg_temp_new();
4608 tcg_gen_mulu2_i64(t2, cpu_gpr[rd], t0, t1);
4609 tcg_temp_free(t2);
4610 }
b42ee5e1
LA
4611 break;
4612#endif
4613 default:
9d68ac14 4614 MIPS_INVAL("r6 mul/div");
9c708c7f 4615 generate_exception_end(ctx, EXCP_RI);
b42ee5e1
LA
4616 goto out;
4617 }
b42ee5e1
LA
4618 out:
4619 tcg_temp_free(t0);
4620 tcg_temp_free(t1);
4621}
4622
26135ead
RS
4623static void gen_muldiv(DisasContext *ctx, uint32_t opc,
4624 int acc, int rs, int rt)
6af0bf9c 4625{
d45f89f4
AJ
4626 TCGv t0, t1;
4627
51127181
AJ
4628 t0 = tcg_temp_new();
4629 t1 = tcg_temp_new();
6af0bf9c 4630
78723684
TS
4631 gen_load_gpr(t0, rs);
4632 gen_load_gpr(t1, rt);
51127181 4633
26135ead 4634 if (acc != 0) {
be9c42c9
FN
4635 if (!(ctx->insn_flags & INSN_R5900)) {
4636 check_dsp(ctx);
4637 }
26135ead
RS
4638 }
4639
6af0bf9c
FB
4640 switch (opc) {
4641 case OPC_DIV:
be9c42c9 4642 case TX79_MMI_DIV1:
48d38ca5 4643 {
51127181
AJ
4644 TCGv t2 = tcg_temp_new();
4645 TCGv t3 = tcg_temp_new();
d45f89f4
AJ
4646 tcg_gen_ext32s_tl(t0, t0);
4647 tcg_gen_ext32s_tl(t1, t1);
51127181
AJ
4648 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
4649 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
4650 tcg_gen_and_tl(t2, t2, t3);
4651 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4652 tcg_gen_or_tl(t2, t2, t3);
4653 tcg_gen_movi_tl(t3, 0);
4654 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
26135ead
RS
4655 tcg_gen_div_tl(cpu_LO[acc], t0, t1);
4656 tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
4657 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
4658 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
51127181
AJ
4659 tcg_temp_free(t3);
4660 tcg_temp_free(t2);
48d38ca5 4661 }
6af0bf9c
FB
4662 break;
4663 case OPC_DIVU:
be9c42c9 4664 case TX79_MMI_DIVU1:
48d38ca5 4665 {
51127181
AJ
4666 TCGv t2 = tcg_const_tl(0);
4667 TCGv t3 = tcg_const_tl(1);
0c0ed03b
AJ
4668 tcg_gen_ext32u_tl(t0, t0);
4669 tcg_gen_ext32u_tl(t1, t1);
51127181 4670 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
26135ead
RS
4671 tcg_gen_divu_tl(cpu_LO[acc], t0, t1);
4672 tcg_gen_remu_tl(cpu_HI[acc], t0, t1);
4673 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
4674 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
51127181
AJ
4675 tcg_temp_free(t3);
4676 tcg_temp_free(t2);
48d38ca5 4677 }
6af0bf9c
FB
4678 break;
4679 case OPC_MULT:
214c465f 4680 {
ce1dd5d1
RH
4681 TCGv_i32 t2 = tcg_temp_new_i32();
4682 TCGv_i32 t3 = tcg_temp_new_i32();
ce1dd5d1
RH
4683 tcg_gen_trunc_tl_i32(t2, t0);
4684 tcg_gen_trunc_tl_i32(t3, t1);
4685 tcg_gen_muls2_i32(t2, t3, t2, t3);
4686 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
4687 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
4688 tcg_temp_free_i32(t2);
4689 tcg_temp_free_i32(t3);
214c465f 4690 }
6af0bf9c
FB
4691 break;
4692 case OPC_MULTU:
214c465f 4693 {
ce1dd5d1
RH
4694 TCGv_i32 t2 = tcg_temp_new_i32();
4695 TCGv_i32 t3 = tcg_temp_new_i32();
ce1dd5d1
RH
4696 tcg_gen_trunc_tl_i32(t2, t0);
4697 tcg_gen_trunc_tl_i32(t3, t1);
4698 tcg_gen_mulu2_i32(t2, t3, t2, t3);
4699 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
4700 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
4701 tcg_temp_free_i32(t2);
4702 tcg_temp_free_i32(t3);
214c465f 4703 }
6af0bf9c 4704 break;
d26bc211 4705#if defined(TARGET_MIPS64)
7a387fff 4706 case OPC_DDIV:
48d38ca5 4707 {
51127181
AJ
4708 TCGv t2 = tcg_temp_new();
4709 TCGv t3 = tcg_temp_new();
4710 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
4711 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
4712 tcg_gen_and_tl(t2, t2, t3);
4713 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4714 tcg_gen_or_tl(t2, t2, t3);
4715 tcg_gen_movi_tl(t3, 0);
4716 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
26135ead
RS
4717 tcg_gen_div_tl(cpu_LO[acc], t0, t1);
4718 tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
51127181
AJ
4719 tcg_temp_free(t3);
4720 tcg_temp_free(t2);
48d38ca5 4721 }
7a387fff
TS
4722 break;
4723 case OPC_DDIVU:
48d38ca5 4724 {
51127181
AJ
4725 TCGv t2 = tcg_const_tl(0);
4726 TCGv t3 = tcg_const_tl(1);
4727 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
26135ead
RS
4728 tcg_gen_divu_i64(cpu_LO[acc], t0, t1);
4729 tcg_gen_remu_i64(cpu_HI[acc], t0, t1);
51127181
AJ
4730 tcg_temp_free(t3);
4731 tcg_temp_free(t2);
48d38ca5 4732 }
7a387fff
TS
4733 break;
4734 case OPC_DMULT:
26135ead 4735 tcg_gen_muls2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
7a387fff
TS
4736 break;
4737 case OPC_DMULTU:
26135ead 4738 tcg_gen_mulu2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
7a387fff
TS
4739 break;
4740#endif
6af0bf9c 4741 case OPC_MADD:
214c465f 4742 {
d45f89f4
AJ
4743 TCGv_i64 t2 = tcg_temp_new_i64();
4744 TCGv_i64 t3 = tcg_temp_new_i64();
4745
4746 tcg_gen_ext_tl_i64(t2, t0);
4747 tcg_gen_ext_tl_i64(t3, t1);
4748 tcg_gen_mul_i64(t2, t2, t3);
4133498f 4749 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
d45f89f4
AJ
4750 tcg_gen_add_i64(t2, t2, t3);
4751 tcg_temp_free_i64(t3);
71f303cd
RH
4752 gen_move_low32(cpu_LO[acc], t2);
4753 gen_move_high32(cpu_HI[acc], t2);
d45f89f4 4754 tcg_temp_free_i64(t2);
214c465f 4755 }
6af0bf9c
FB
4756 break;
4757 case OPC_MADDU:
4133498f 4758 {
d45f89f4
AJ
4759 TCGv_i64 t2 = tcg_temp_new_i64();
4760 TCGv_i64 t3 = tcg_temp_new_i64();
214c465f 4761
78723684
TS
4762 tcg_gen_ext32u_tl(t0, t0);
4763 tcg_gen_ext32u_tl(t1, t1);
d45f89f4
AJ
4764 tcg_gen_extu_tl_i64(t2, t0);
4765 tcg_gen_extu_tl_i64(t3, t1);
4766 tcg_gen_mul_i64(t2, t2, t3);
4133498f 4767 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
d45f89f4
AJ
4768 tcg_gen_add_i64(t2, t2, t3);
4769 tcg_temp_free_i64(t3);
71f303cd
RH
4770 gen_move_low32(cpu_LO[acc], t2);
4771 gen_move_high32(cpu_HI[acc], t2);
d45f89f4 4772 tcg_temp_free_i64(t2);
214c465f 4773 }
6af0bf9c
FB
4774 break;
4775 case OPC_MSUB:
214c465f 4776 {
d45f89f4
AJ
4777 TCGv_i64 t2 = tcg_temp_new_i64();
4778 TCGv_i64 t3 = tcg_temp_new_i64();
4779
4780 tcg_gen_ext_tl_i64(t2, t0);
4781 tcg_gen_ext_tl_i64(t3, t1);
4782 tcg_gen_mul_i64(t2, t2, t3);
4133498f 4783 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
98070ce0 4784 tcg_gen_sub_i64(t2, t3, t2);
d45f89f4 4785 tcg_temp_free_i64(t3);
71f303cd
RH
4786 gen_move_low32(cpu_LO[acc], t2);
4787 gen_move_high32(cpu_HI[acc], t2);
d45f89f4 4788 tcg_temp_free_i64(t2);
214c465f 4789 }
6af0bf9c
FB
4790 break;
4791 case OPC_MSUBU:
214c465f 4792 {
d45f89f4
AJ
4793 TCGv_i64 t2 = tcg_temp_new_i64();
4794 TCGv_i64 t3 = tcg_temp_new_i64();
214c465f 4795
78723684
TS
4796 tcg_gen_ext32u_tl(t0, t0);
4797 tcg_gen_ext32u_tl(t1, t1);
d45f89f4
AJ
4798 tcg_gen_extu_tl_i64(t2, t0);
4799 tcg_gen_extu_tl_i64(t3, t1);
4800 tcg_gen_mul_i64(t2, t2, t3);
4133498f 4801 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
98070ce0 4802 tcg_gen_sub_i64(t2, t3, t2);
d45f89f4 4803 tcg_temp_free_i64(t3);
71f303cd
RH
4804 gen_move_low32(cpu_LO[acc], t2);
4805 gen_move_high32(cpu_HI[acc], t2);
d45f89f4 4806 tcg_temp_free_i64(t2);
214c465f 4807 }
6af0bf9c
FB
4808 break;
4809 default:
9d68ac14 4810 MIPS_INVAL("mul/div");
9c708c7f 4811 generate_exception_end(ctx, EXCP_RI);
78723684 4812 goto out;
6af0bf9c 4813 }
78723684
TS
4814 out:
4815 tcg_temp_free(t0);
4816 tcg_temp_free(t1);
6af0bf9c
FB
4817}
4818
21e8e8b2
FN
4819/*
4820 * These MULT and MULTU instructions implemented in for example the
4821 * Toshiba/Sony R5900 and the Toshiba TX19, TX39 and TX79 core
4822 * architectures are special three-operand variants with the syntax
4823 *
06de726b 4824 * MULT[U][1] rd, rs, rt
21e8e8b2
FN
4825 *
4826 * such that
4827 *
4828 * (rd, LO, HI) <- rs * rt
4829 *
4830 * where the low-order 32-bits of the result is placed into both the
4831 * GPR rd and the special register LO. The high-order 32-bits of the
4832 * result is placed into the special register HI.
4833 *
4834 * If the GPR rd is omitted in assembly language, it is taken to be 0,
4835 * which is the zero register that always reads as 0.
4836 */
4837static void gen_mul_txx9(DisasContext *ctx, uint32_t opc,
4838 int rd, int rs, int rt)
4839{
4840 TCGv t0 = tcg_temp_new();
4841 TCGv t1 = tcg_temp_new();
4842 int acc = 0;
4843
4844 gen_load_gpr(t0, rs);
4845 gen_load_gpr(t1, rt);
4846
4847 switch (opc) {
06de726b
FN
4848 case TX79_MMI_MULT1:
4849 acc = 1;
4850 /* Fall through */
21e8e8b2
FN
4851 case OPC_MULT:
4852 {
4853 TCGv_i32 t2 = tcg_temp_new_i32();
4854 TCGv_i32 t3 = tcg_temp_new_i32();
4855 tcg_gen_trunc_tl_i32(t2, t0);
4856 tcg_gen_trunc_tl_i32(t3, t1);
4857 tcg_gen_muls2_i32(t2, t3, t2, t3);
4858 if (rd) {
4859 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
4860 }
4861 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
4862 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
4863 tcg_temp_free_i32(t2);
4864 tcg_temp_free_i32(t3);
4865 }
4866 break;
06de726b
FN
4867 case TX79_MMI_MULTU1:
4868 acc = 1;
4869 /* Fall through */
21e8e8b2
FN
4870 case OPC_MULTU:
4871 {
4872 TCGv_i32 t2 = tcg_temp_new_i32();
4873 TCGv_i32 t3 = tcg_temp_new_i32();
4874 tcg_gen_trunc_tl_i32(t2, t0);
4875 tcg_gen_trunc_tl_i32(t3, t1);
4876 tcg_gen_mulu2_i32(t2, t3, t2, t3);
4877 if (rd) {
4878 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
4879 }
4880 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
4881 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
4882 tcg_temp_free_i32(t2);
4883 tcg_temp_free_i32(t3);
4884 }
4885 break;
4886 default:
4887 MIPS_INVAL("mul TXx9");
4888 generate_exception_end(ctx, EXCP_RI);
4889 goto out;
4890 }
4891
4892 out:
4893 tcg_temp_free(t0);
4894 tcg_temp_free(t1);
4895}
4896
e9c71dd1
TS
4897static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
4898 int rd, int rs, int rt)
4899{
f157bfe1
AJ
4900 TCGv t0 = tcg_temp_new();
4901 TCGv t1 = tcg_temp_new();
e9c71dd1 4902
6c5c1e20
TS
4903 gen_load_gpr(t0, rs);
4904 gen_load_gpr(t1, rt);
e9c71dd1
TS
4905
4906 switch (opc) {
4907 case OPC_VR54XX_MULS:
895c2d04 4908 gen_helper_muls(t0, cpu_env, t0, t1);
6958549d 4909 break;
e9c71dd1 4910 case OPC_VR54XX_MULSU:
895c2d04 4911 gen_helper_mulsu(t0, cpu_env, t0, t1);
6958549d 4912 break;
e9c71dd1 4913 case OPC_VR54XX_MACC:
895c2d04 4914 gen_helper_macc(t0, cpu_env, t0, t1);
6958549d 4915 break;
e9c71dd1 4916 case OPC_VR54XX_MACCU:
895c2d04 4917 gen_helper_maccu(t0, cpu_env, t0, t1);
6958549d 4918 break;
e9c71dd1 4919 case OPC_VR54XX_MSAC:
895c2d04 4920 gen_helper_msac(t0, cpu_env, t0, t1);
6958549d 4921 break;
e9c71dd1 4922 case OPC_VR54XX_MSACU:
895c2d04 4923 gen_helper_msacu(t0, cpu_env, t0, t1);
6958549d 4924 break;
e9c71dd1 4925 case OPC_VR54XX_MULHI:
895c2d04 4926 gen_helper_mulhi(t0, cpu_env, t0, t1);
6958549d 4927 break;
e9c71dd1 4928 case OPC_VR54XX_MULHIU:
895c2d04 4929 gen_helper_mulhiu(t0, cpu_env, t0, t1);
6958549d 4930 break;
e9c71dd1 4931 case OPC_VR54XX_MULSHI:
895c2d04 4932 gen_helper_mulshi(t0, cpu_env, t0, t1);
6958549d 4933 break;
e9c71dd1 4934 case OPC_VR54XX_MULSHIU:
895c2d04 4935 gen_helper_mulshiu(t0, cpu_env, t0, t1);
6958549d 4936 break;
e9c71dd1 4937 case OPC_VR54XX_MACCHI:
895c2d04 4938 gen_helper_macchi(t0, cpu_env, t0, t1);
6958549d 4939 break;
e9c71dd1 4940 case OPC_VR54XX_MACCHIU:
895c2d04 4941 gen_helper_macchiu(t0, cpu_env, t0, t1);
6958549d 4942 break;
e9c71dd1 4943 case OPC_VR54XX_MSACHI:
895c2d04 4944 gen_helper_msachi(t0, cpu_env, t0, t1);
6958549d 4945 break;
e9c71dd1 4946 case OPC_VR54XX_MSACHIU:
895c2d04 4947 gen_helper_msachiu(t0, cpu_env, t0, t1);
6958549d 4948 break;
e9c71dd1
TS
4949 default:
4950 MIPS_INVAL("mul vr54xx");
9c708c7f 4951 generate_exception_end(ctx, EXCP_RI);
6c5c1e20 4952 goto out;
e9c71dd1 4953 }
6c5c1e20 4954 gen_store_gpr(t0, rd);
6c5c1e20
TS
4955
4956 out:
4957 tcg_temp_free(t0);
4958 tcg_temp_free(t1);
e9c71dd1
TS
4959}
4960
7a387fff 4961static void gen_cl (DisasContext *ctx, uint32_t opc,
6af0bf9c
FB
4962 int rd, int rs)
4963{
20e1fb52 4964 TCGv t0;
6c5c1e20 4965
6af0bf9c 4966 if (rd == 0) {
ead9360e 4967 /* Treat as NOP. */
20e1fb52 4968 return;
6af0bf9c 4969 }
1a0196c5 4970 t0 = cpu_gpr[rd];
6c5c1e20 4971 gen_load_gpr(t0, rs);
1a0196c5 4972
6af0bf9c
FB
4973 switch (opc) {
4974 case OPC_CLO:
4267d3e6 4975 case R6_OPC_CLO:
1a0196c5
RH
4976#if defined(TARGET_MIPS64)
4977 case OPC_DCLO:
4978 case R6_OPC_DCLO:
4979#endif
4980 tcg_gen_not_tl(t0, t0);
6af0bf9c 4981 break;
1a0196c5
RH
4982 }
4983
4984 switch (opc) {
4985 case OPC_CLO:
4986 case R6_OPC_CLO:
6af0bf9c 4987 case OPC_CLZ:
4267d3e6 4988 case R6_OPC_CLZ:
1a0196c5
RH
4989 tcg_gen_ext32u_tl(t0, t0);
4990 tcg_gen_clzi_tl(t0, t0, TARGET_LONG_BITS);
4991 tcg_gen_subi_tl(t0, t0, TARGET_LONG_BITS - 32);
6af0bf9c 4992 break;
d26bc211 4993#if defined(TARGET_MIPS64)
7a387fff 4994 case OPC_DCLO:
4267d3e6 4995 case R6_OPC_DCLO:
7a387fff 4996 case OPC_DCLZ:
4267d3e6 4997 case R6_OPC_DCLZ:
1a0196c5 4998 tcg_gen_clzi_i64(t0, t0, 64);
7a387fff
TS
4999 break;
5000#endif
6af0bf9c 5001 }
6af0bf9c
FB
5002}
5003
161f85e6 5004/* Godson integer instructions */
bd277fa1
RH
5005static void gen_loongson_integer(DisasContext *ctx, uint32_t opc,
5006 int rd, int rs, int rt)
161f85e6 5007{
161f85e6
AJ
5008 TCGv t0, t1;
5009
5010 if (rd == 0) {
5011 /* Treat as NOP. */
161f85e6
AJ
5012 return;
5013 }
5014
5015 switch (opc) {
5016 case OPC_MULT_G_2E:
5017 case OPC_MULT_G_2F:
5018 case OPC_MULTU_G_2E:
5019 case OPC_MULTU_G_2F:
5020#if defined(TARGET_MIPS64)
5021 case OPC_DMULT_G_2E:
5022 case OPC_DMULT_G_2F:
5023 case OPC_DMULTU_G_2E:
5024 case OPC_DMULTU_G_2F:
5025#endif
5026 t0 = tcg_temp_new();
5027 t1 = tcg_temp_new();
5028 break;
5029 default:
5030 t0 = tcg_temp_local_new();
5031 t1 = tcg_temp_local_new();
5032 break;
5033 }
5034
5035 gen_load_gpr(t0, rs);
5036 gen_load_gpr(t1, rt);
5037
5038 switch (opc) {
5039 case OPC_MULT_G_2E:
5040 case OPC_MULT_G_2F:
5041 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
5042 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
161f85e6
AJ
5043 break;
5044 case OPC_MULTU_G_2E:
5045 case OPC_MULTU_G_2F:
5046 tcg_gen_ext32u_tl(t0, t0);
5047 tcg_gen_ext32u_tl(t1, t1);
5048 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
5049 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
161f85e6
AJ
5050 break;
5051 case OPC_DIV_G_2E:
5052 case OPC_DIV_G_2F:
5053 {
42a268c2
RH
5054 TCGLabel *l1 = gen_new_label();
5055 TCGLabel *l2 = gen_new_label();
5056 TCGLabel *l3 = gen_new_label();
161f85e6
AJ
5057 tcg_gen_ext32s_tl(t0, t0);
5058 tcg_gen_ext32s_tl(t1, t1);
5059 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5060 tcg_gen_movi_tl(cpu_gpr[rd], 0);
5061 tcg_gen_br(l3);
5062 gen_set_label(l1);
5063 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
5064 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
5065 tcg_gen_mov_tl(cpu_gpr[rd], t0);
5066 tcg_gen_br(l3);
5067 gen_set_label(l2);
5068 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
5069 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5070 gen_set_label(l3);
5071 }
161f85e6
AJ
5072 break;
5073 case OPC_DIVU_G_2E:
5074 case OPC_DIVU_G_2F:
5075 {
42a268c2
RH
5076 TCGLabel *l1 = gen_new_label();
5077 TCGLabel *l2 = gen_new_label();
161f85e6
AJ
5078 tcg_gen_ext32u_tl(t0, t0);
5079 tcg_gen_ext32u_tl(t1, t1);
5080 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5081 tcg_gen_movi_tl(cpu_gpr[rd], 0);
5082 tcg_gen_br(l2);
5083 gen_set_label(l1);
5084 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
5085 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5086 gen_set_label(l2);
5087 }
161f85e6
AJ
5088 break;
5089 case OPC_MOD_G_2E:
5090 case OPC_MOD_G_2F:
5091 {
42a268c2
RH
5092 TCGLabel *l1 = gen_new_label();
5093 TCGLabel *l2 = gen_new_label();
5094 TCGLabel *l3 = gen_new_label();
161f85e6
AJ
5095 tcg_gen_ext32u_tl(t0, t0);
5096 tcg_gen_ext32u_tl(t1, t1);
5097 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
5098 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
5099 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
5100 gen_set_label(l1);
5101 tcg_gen_movi_tl(cpu_gpr[rd], 0);
5102 tcg_gen_br(l3);
5103 gen_set_label(l2);
5104 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
5105 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5106 gen_set_label(l3);
5107 }
161f85e6
AJ
5108 break;
5109 case OPC_MODU_G_2E:
5110 case OPC_MODU_G_2F:
5111 {
42a268c2
RH
5112 TCGLabel *l1 = gen_new_label();
5113 TCGLabel *l2 = gen_new_label();
161f85e6
AJ
5114 tcg_gen_ext32u_tl(t0, t0);
5115 tcg_gen_ext32u_tl(t1, t1);
5116 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5117 tcg_gen_movi_tl(cpu_gpr[rd], 0);
5118 tcg_gen_br(l2);
5119 gen_set_label(l1);
5120 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
5121 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5122 gen_set_label(l2);
5123 }
161f85e6
AJ
5124 break;
5125#if defined(TARGET_MIPS64)
5126 case OPC_DMULT_G_2E:
5127 case OPC_DMULT_G_2F:
5128 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
161f85e6
AJ
5129 break;
5130 case OPC_DMULTU_G_2E:
5131 case OPC_DMULTU_G_2F:
5132 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
161f85e6
AJ
5133 break;
5134 case OPC_DDIV_G_2E:
5135 case OPC_DDIV_G_2F:
5136 {
42a268c2
RH
5137 TCGLabel *l1 = gen_new_label();
5138 TCGLabel *l2 = gen_new_label();
5139 TCGLabel *l3 = gen_new_label();
161f85e6
AJ
5140 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5141 tcg_gen_movi_tl(cpu_gpr[rd], 0);
5142 tcg_gen_br(l3);
5143 gen_set_label(l1);
5144 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
5145 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
5146 tcg_gen_mov_tl(cpu_gpr[rd], t0);
5147 tcg_gen_br(l3);
5148 gen_set_label(l2);
5149 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
5150 gen_set_label(l3);
5151 }
161f85e6
AJ
5152 break;
5153 case OPC_DDIVU_G_2E:
5154 case OPC_DDIVU_G_2F:
5155 {
42a268c2
RH
5156 TCGLabel *l1 = gen_new_label();
5157 TCGLabel *l2 = gen_new_label();
161f85e6
AJ
5158 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5159 tcg_gen_movi_tl(cpu_gpr[rd], 0);
5160 tcg_gen_br(l2);
5161 gen_set_label(l1);
5162 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
5163 gen_set_label(l2);
5164 }
161f85e6
AJ
5165 break;
5166 case OPC_DMOD_G_2E:
5167 case OPC_DMOD_G_2F:
5168 {
42a268c2
RH
5169 TCGLabel *l1 = gen_new_label();
5170 TCGLabel *l2 = gen_new_label();
5171 TCGLabel *l3 = gen_new_label();
161f85e6
AJ
5172 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
5173 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
5174 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
5175 gen_set_label(l1);
5176 tcg_gen_movi_tl(cpu_gpr[rd], 0);
5177 tcg_gen_br(l3);
5178 gen_set_label(l2);
5179 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
5180 gen_set_label(l3);
5181 }
161f85e6
AJ
5182 break;
5183 case OPC_DMODU_G_2E:
5184 case OPC_DMODU_G_2F:
5185 {
42a268c2
RH
5186 TCGLabel *l1 = gen_new_label();
5187 TCGLabel *l2 = gen_new_label();
161f85e6
AJ
5188 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5189 tcg_gen_movi_tl(cpu_gpr[rd], 0);
5190 tcg_gen_br(l2);
5191 gen_set_label(l1);
5192 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
5193 gen_set_label(l2);
5194 }
161f85e6
AJ
5195 break;
5196#endif
5197 }
5198
161f85e6
AJ
5199 tcg_temp_free(t0);
5200 tcg_temp_free(t1);
5201}
5202
bd277fa1
RH
5203/* Loongson multimedia instructions */
5204static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt)
5205{
bd277fa1
RH
5206 uint32_t opc, shift_max;
5207 TCGv_i64 t0, t1;
5208
5209 opc = MASK_LMI(ctx->opcode);
5210 switch (opc) {
5211 case OPC_ADD_CP2:
5212 case OPC_SUB_CP2:
5213 case OPC_DADD_CP2:
5214 case OPC_DSUB_CP2:
5215 t0 = tcg_temp_local_new_i64();
5216 t1 = tcg_temp_local_new_i64();
5217 break;
5218 default:
5219 t0 = tcg_temp_new_i64();
5220 t1 = tcg_temp_new_i64();
5221 break;
5222 }
5223
b5a587b6 5224 check_cp1_enabled(ctx);
bd277fa1
RH
5225 gen_load_fpr64(ctx, t0, rs);
5226 gen_load_fpr64(ctx, t1, rt);
5227
5228#define LMI_HELPER(UP, LO) \
9d68ac14 5229 case OPC_##UP: gen_helper_##LO(t0, t0, t1); break
bd277fa1 5230#define LMI_HELPER_1(UP, LO) \
9d68ac14 5231 case OPC_##UP: gen_helper_##LO(t0, t0); break
bd277fa1 5232#define LMI_DIRECT(UP, LO, OP) \
9d68ac14 5233 case OPC_##UP: tcg_gen_##OP##_i64(t0, t0, t1); break
bd277fa1
RH
5234
5235 switch (opc) {
5236 LMI_HELPER(PADDSH, paddsh);
5237 LMI_HELPER(PADDUSH, paddush);
5238 LMI_HELPER(PADDH, paddh);
5239 LMI_HELPER(PADDW, paddw);
5240 LMI_HELPER(PADDSB, paddsb);
5241 LMI_HELPER(PADDUSB, paddusb);
5242 LMI_HELPER(PADDB, paddb);
5243
5244 LMI_HELPER(PSUBSH, psubsh);
5245 LMI_HELPER(PSUBUSH, psubush);
5246 LMI_HELPER(PSUBH, psubh);
5247 LMI_HELPER(PSUBW, psubw);
5248 LMI_HELPER(PSUBSB, psubsb);
5249 LMI_HELPER(PSUBUSB, psubusb);
5250 LMI_HELPER(PSUBB, psubb);
5251
5252 LMI_HELPER(PSHUFH, pshufh);
5253 LMI_HELPER(PACKSSWH, packsswh);
5254 LMI_HELPER(PACKSSHB, packsshb);
5255 LMI_HELPER(PACKUSHB, packushb);
5256
5257 LMI_HELPER(PUNPCKLHW, punpcklhw);
5258 LMI_HELPER(PUNPCKHHW, punpckhhw);
5259 LMI_HELPER(PUNPCKLBH, punpcklbh);
5260 LMI_HELPER(PUNPCKHBH, punpckhbh);
5261 LMI_HELPER(PUNPCKLWD, punpcklwd);
5262 LMI_HELPER(PUNPCKHWD, punpckhwd);
5263
5264 LMI_HELPER(PAVGH, pavgh);
5265 LMI_HELPER(PAVGB, pavgb);
5266 LMI_HELPER(PMAXSH, pmaxsh);
5267 LMI_HELPER(PMINSH, pminsh);
5268 LMI_HELPER(PMAXUB, pmaxub);
5269 LMI_HELPER(PMINUB, pminub);
5270
5271 LMI_HELPER(PCMPEQW, pcmpeqw);
5272 LMI_HELPER(PCMPGTW, pcmpgtw);
5273 LMI_HELPER(PCMPEQH, pcmpeqh);
5274 LMI_HELPER(PCMPGTH, pcmpgth);
5275 LMI_HELPER(PCMPEQB, pcmpeqb);
5276 LMI_HELPER(PCMPGTB, pcmpgtb);
5277
5278 LMI_HELPER(PSLLW, psllw);
5279 LMI_HELPER(PSLLH, psllh);
5280 LMI_HELPER(PSRLW, psrlw);
5281 LMI_HELPER(PSRLH, psrlh);
5282 LMI_HELPER(PSRAW, psraw);
5283 LMI_HELPER(PSRAH, psrah);
5284
5285 LMI_HELPER(PMULLH, pmullh);
5286 LMI_HELPER(PMULHH, pmulhh);
5287 LMI_HELPER(PMULHUH, pmulhuh);
5288 LMI_HELPER(PMADDHW, pmaddhw);
5289
5290 LMI_HELPER(PASUBUB, pasubub);
5291 LMI_HELPER_1(BIADD, biadd);
5292 LMI_HELPER_1(PMOVMSKB, pmovmskb);
5293
5294 LMI_DIRECT(PADDD, paddd, add);
5295 LMI_DIRECT(PSUBD, psubd, sub);
5296 LMI_DIRECT(XOR_CP2, xor, xor);
5297 LMI_DIRECT(NOR_CP2, nor, nor);
5298 LMI_DIRECT(AND_CP2, and, and);
bb7cab5f 5299 LMI_DIRECT(OR_CP2, or, or);
bd277fa1 5300
9099a36b
H
5301 case OPC_PANDN:
5302 tcg_gen_andc_i64(t0, t1, t0);
5303 break;
5304
bd277fa1
RH
5305 case OPC_PINSRH_0:
5306 tcg_gen_deposit_i64(t0, t0, t1, 0, 16);
bd277fa1
RH
5307 break;
5308 case OPC_PINSRH_1:
5309 tcg_gen_deposit_i64(t0, t0, t1, 16, 16);
bd277fa1
RH
5310 break;
5311 case OPC_PINSRH_2:
5312 tcg_gen_deposit_i64(t0, t0, t1, 32, 16);
bd277fa1
RH
5313 break;
5314 case OPC_PINSRH_3:
5315 tcg_gen_deposit_i64(t0, t0, t1, 48, 16);
bd277fa1
RH
5316 break;
5317
5318 case OPC_PEXTRH:
5319 tcg_gen_andi_i64(t1, t1, 3);
5320 tcg_gen_shli_i64(t1, t1, 4);
5321 tcg_gen_shr_i64(t0, t0, t1);
5322 tcg_gen_ext16u_i64(t0, t0);
bd277fa1
RH
5323 break;
5324
5325 case OPC_ADDU_CP2:
5326 tcg_gen_add_i64(t0, t0, t1);
5327 tcg_gen_ext32s_i64(t0, t0);
bd277fa1
RH
5328 break;
5329 case OPC_SUBU_CP2:
5330 tcg_gen_sub_i64(t0, t0, t1);
5331 tcg_gen_ext32s_i64(t0, t0);
bd277fa1
RH
5332 break;
5333
5334 case OPC_SLL_CP2:
bd277fa1
RH
5335 shift_max = 32;
5336 goto do_shift;
5337 case OPC_SRL_CP2:
bd277fa1
RH
5338 shift_max = 32;
5339 goto do_shift;
5340 case OPC_SRA_CP2:
bd277fa1
RH
5341 shift_max = 32;
5342 goto do_shift;
5343 case OPC_DSLL_CP2:
bd277fa1
RH
5344 shift_max = 64;
5345 goto do_shift;
5346 case OPC_DSRL_CP2:
bd277fa1
RH
5347 shift_max = 64;
5348 goto do_shift;
5349 case OPC_DSRA_CP2:
bd277fa1
RH
5350 shift_max = 64;
5351 goto do_shift;
5352 do_shift:
5353 /* Make sure shift count isn't TCG undefined behaviour. */
5354 tcg_gen_andi_i64(t1, t1, shift_max - 1);
5355
5356 switch (opc) {
5357 case OPC_SLL_CP2:
5358 case OPC_DSLL_CP2:
5359 tcg_gen_shl_i64(t0, t0, t1);
5360 break;
5361 case OPC_SRA_CP2:
5362 case OPC_DSRA_CP2:
5363 /* Since SRA is UndefinedResult without sign-extended inputs,
5364 we can treat SRA and DSRA the same. */
5365 tcg_gen_sar_i64(t0, t0, t1);
5366 break;
5367 case OPC_SRL_CP2:
5368 /* We want to shift in zeros for SRL; zero-extend first. */
5369 tcg_gen_ext32u_i64(t0, t0);
5370 /* FALLTHRU */
5371 case OPC_DSRL_CP2:
5372 tcg_gen_shr_i64(t0, t0, t1);
5373 break;
5374 }
5375
5376 if (shift_max == 32) {
5377 tcg_gen_ext32s_i64(t0, t0);
5378 }
5379
5380 /* Shifts larger than MAX produce zero. */
5381 tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max);
5382 tcg_gen_neg_i64(t1, t1);
5383 tcg_gen_and_i64(t0, t0, t1);
5384 break;
5385
5386 case OPC_ADD_CP2:
5387 case OPC_DADD_CP2:
5388 {
5389 TCGv_i64 t2 = tcg_temp_new_i64();
42a268c2 5390 TCGLabel *lab = gen_new_label();
bd277fa1
RH
5391
5392 tcg_gen_mov_i64(t2, t0);
5393 tcg_gen_add_i64(t0, t1, t2);
5394 if (opc == OPC_ADD_CP2) {
5395 tcg_gen_ext32s_i64(t0, t0);
5396 }
5397 tcg_gen_xor_i64(t1, t1, t2);
5398 tcg_gen_xor_i64(t2, t2, t0);
5399 tcg_gen_andc_i64(t1, t2, t1);
5400 tcg_temp_free_i64(t2);
5401 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
5402 generate_exception(ctx, EXCP_OVERFLOW);
5403 gen_set_label(lab);
bd277fa1
RH
5404 break;
5405 }
5406
5407 case OPC_SUB_CP2:
5408 case OPC_DSUB_CP2:
5409 {
5410 TCGv_i64 t2 = tcg_temp_new_i64();
42a268c2 5411 TCGLabel *lab = gen_new_label();
bd277fa1
RH
5412
5413 tcg_gen_mov_i64(t2, t0);
5414 tcg_gen_sub_i64(t0, t1, t2);
5415 if (opc == OPC_SUB_CP2) {
5416 tcg_gen_ext32s_i64(t0, t0);
5417 }
5418 tcg_gen_xor_i64(t1, t1, t2);
5419 tcg_gen_xor_i64(t2, t2, t0);
5420 tcg_gen_and_i64(t1, t1, t2);
5421 tcg_temp_free_i64(t2);
5422 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
5423 generate_exception(ctx, EXCP_OVERFLOW);
5424 gen_set_label(lab);
bd277fa1
RH
5425 break;
5426 }
5427
5428 case OPC_PMULUW:
5429 tcg_gen_ext32u_i64(t0, t0);
5430 tcg_gen_ext32u_i64(t1, t1);
5431 tcg_gen_mul_i64(t0, t0, t1);
bd277fa1
RH
5432 break;
5433
5434 case OPC_SEQU_CP2:
5435 case OPC_SEQ_CP2:
5436 case OPC_SLTU_CP2:
5437 case OPC_SLT_CP2:
5438 case OPC_SLEU_CP2:
5439 case OPC_SLE_CP2:
5440 /* ??? Document is unclear: Set FCC[CC]. Does that mean the
5441 FD field is the CC field? */
5442 default:
9d68ac14 5443 MIPS_INVAL("loongson_cp2");
9c708c7f 5444 generate_exception_end(ctx, EXCP_RI);
bd277fa1
RH
5445 return;
5446 }
5447
5448#undef LMI_HELPER
5449#undef LMI_DIRECT
5450
5451 gen_store_fpr64(ctx, t0, rd);
5452
bd277fa1
RH
5453 tcg_temp_free_i64(t0);
5454 tcg_temp_free_i64(t1);
5455}
5456
6af0bf9c 5457/* Traps */
7a387fff 5458static void gen_trap (DisasContext *ctx, uint32_t opc,
6af0bf9c
FB
5459 int rs, int rt, int16_t imm)
5460{
5461 int cond;
cdc0faa6 5462 TCGv t0 = tcg_temp_new();
1ba74fb8 5463 TCGv t1 = tcg_temp_new();
6af0bf9c
FB
5464
5465 cond = 0;
5466 /* Load needed operands */
5467 switch (opc) {
5468 case OPC_TEQ:
5469 case OPC_TGE:
5470 case OPC_TGEU:
5471 case OPC_TLT:
5472 case OPC_TLTU:
5473 case OPC_TNE:
5474 /* Compare two registers */
5475 if (rs != rt) {
be24bb4f
TS
5476 gen_load_gpr(t0, rs);
5477 gen_load_gpr(t1, rt);
6af0bf9c
FB
5478 cond = 1;
5479 }
179e32bb 5480 break;
6af0bf9c
FB
5481 case OPC_TEQI:
5482 case OPC_TGEI:
5483 case OPC_TGEIU:
5484 case OPC_TLTI:
5485 case OPC_TLTIU:
5486 case OPC_TNEI:
5487 /* Compare register to immediate */
5488 if (rs != 0 || imm != 0) {
be24bb4f
TS
5489 gen_load_gpr(t0, rs);
5490 tcg_gen_movi_tl(t1, (int32_t)imm);
6af0bf9c
FB
5491 cond = 1;
5492 }
5493 break;
5494 }
5495 if (cond == 0) {
5496 switch (opc) {
5497 case OPC_TEQ: /* rs == rs */
5498 case OPC_TEQI: /* r0 == 0 */
5499 case OPC_TGE: /* rs >= rs */
5500 case OPC_TGEI: /* r0 >= 0 */
5501 case OPC_TGEU: /* rs >= rs unsigned */
5502 case OPC_TGEIU: /* r0 >= 0 unsigned */
5503 /* Always trap */
9c708c7f 5504 generate_exception_end(ctx, EXCP_TRAP);
6af0bf9c
FB
5505 break;
5506 case OPC_TLT: /* rs < rs */
5507 case OPC_TLTI: /* r0 < 0 */
5508 case OPC_TLTU: /* rs < rs unsigned */
5509 case OPC_TLTIU: /* r0 < 0 unsigned */
5510 case OPC_TNE: /* rs != rs */
5511 case OPC_TNEI: /* r0 != 0 */
ead9360e 5512 /* Never trap: treat as NOP. */
cdc0faa6 5513 break;
6af0bf9c
FB
5514 }
5515 } else {
42a268c2 5516 TCGLabel *l1 = gen_new_label();
cdc0faa6 5517
6af0bf9c
FB
5518 switch (opc) {
5519 case OPC_TEQ:
5520 case OPC_TEQI:
cdc0faa6 5521 tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
6af0bf9c
FB
5522 break;
5523 case OPC_TGE:
5524 case OPC_TGEI:
cdc0faa6 5525 tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
6af0bf9c
FB
5526 break;
5527 case OPC_TGEU:
5528 case OPC_TGEIU:
cdc0faa6 5529 tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
6af0bf9c
FB
5530 break;
5531 case OPC_TLT:
5532 case OPC_TLTI:
cdc0faa6 5533 tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
6af0bf9c
FB
5534 break;
5535 case OPC_TLTU:
5536 case OPC_TLTIU:
cdc0faa6 5537 tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
6af0bf9c
FB
5538 break;
5539 case OPC_TNE:
5540 case OPC_TNEI:
cdc0faa6 5541 tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
6af0bf9c 5542 break;
6af0bf9c 5543 }
cdc0faa6 5544 generate_exception(ctx, EXCP_TRAP);
08ba7963
TS
5545 gen_set_label(l1);
5546 }
be24bb4f
TS
5547 tcg_temp_free(t0);
5548 tcg_temp_free(t1);
6af0bf9c
FB
5549}
5550
90aa39a1
SF
5551static inline bool use_goto_tb(DisasContext *ctx, target_ulong dest)
5552{
eeb3bba8 5553 if (unlikely(ctx->base.singlestep_enabled)) {
90aa39a1
SF
5554 return false;
5555 }
5556
5557#ifndef CONFIG_USER_ONLY
eeb3bba8 5558 return (ctx->base.tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
90aa39a1
SF
5559#else
5560 return true;
5561#endif
5562}
5563
356265ae 5564static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
c53be334 5565{
90aa39a1 5566 if (use_goto_tb(ctx, dest)) {
57fec1fe 5567 tcg_gen_goto_tb(n);
9b9e4393 5568 gen_save_pc(dest);
07ea28b4 5569 tcg_gen_exit_tb(ctx->base.tb, n);
6e256c93 5570 } else {
9b9e4393 5571 gen_save_pc(dest);
eeb3bba8 5572 if (ctx->base.singlestep_enabled) {
7b270ef2 5573 save_cpu_state(ctx, 0);
9c708c7f 5574 gen_helper_raise_exception_debug(cpu_env);
7b270ef2 5575 }
7f11636d 5576 tcg_gen_lookup_and_goto_ptr();
6e256c93 5577 }
c53be334
FB
5578}
5579
6af0bf9c 5580/* Branches (before delay slot) */
7a387fff 5581static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
7dca4ad0 5582 int insn_bytes,
b231c103
YK
5583 int rs, int rt, int32_t offset,
5584 int delayslot_size)
6af0bf9c 5585{
d077b6f7 5586 target_ulong btgt = -1;
3ad4bb2d 5587 int blink = 0;
2fdbad25 5588 int bcond_compute = 0;
1ba74fb8
AJ
5589 TCGv t0 = tcg_temp_new();
5590 TCGv t1 = tcg_temp_new();
3ad4bb2d
TS
5591
5592 if (ctx->hflags & MIPS_HFLAG_BMASK) {
923617a3 5593#ifdef MIPS_DEBUG_DISAS
339cd2a8 5594 LOG_DISAS("Branch in delay / forbidden slot at PC 0x"
eeb3bba8 5595 TARGET_FMT_lx "\n", ctx->base.pc_next);
923617a3 5596#endif
9c708c7f 5597 generate_exception_end(ctx, EXCP_RI);
6c5c1e20 5598 goto out;
3ad4bb2d 5599 }
6af0bf9c 5600
6af0bf9c
FB
5601 /* Load needed operands */
5602 switch (opc) {
5603 case OPC_BEQ:
5604 case OPC_BEQL:
5605 case OPC_BNE:
5606 case OPC_BNEL:
5607 /* Compare two registers */
5608 if (rs != rt) {
6c5c1e20
TS
5609 gen_load_gpr(t0, rs);
5610 gen_load_gpr(t1, rt);
2fdbad25 5611 bcond_compute = 1;
6af0bf9c 5612 }
eeb3bba8 5613 btgt = ctx->base.pc_next + insn_bytes + offset;
6af0bf9c
FB
5614 break;
5615 case OPC_BGEZ:
5616 case OPC_BGEZAL:
5617 case OPC_BGEZALL:
5618 case OPC_BGEZL:
5619 case OPC_BGTZ:
5620 case OPC_BGTZL:
5621 case OPC_BLEZ:
5622 case OPC_BLEZL:
5623 case OPC_BLTZ:
5624 case OPC_BLTZAL:
5625 case OPC_BLTZALL:
5626 case OPC_BLTZL:
5627 /* Compare to zero */
5628 if (rs != 0) {
6c5c1e20 5629 gen_load_gpr(t0, rs);
2fdbad25 5630 bcond_compute = 1;
6af0bf9c 5631 }
eeb3bba8 5632 btgt = ctx->base.pc_next + insn_bytes + offset;
6af0bf9c 5633 break;
e45a93e2
JL
5634 case OPC_BPOSGE32:
5635#if defined(TARGET_MIPS64)
5636 case OPC_BPOSGE64:
5637 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x7F);
5638#else
5639 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
5640#endif
5641 bcond_compute = 1;
eeb3bba8 5642 btgt = ctx->base.pc_next + insn_bytes + offset;
e45a93e2 5643 break;
6af0bf9c
FB
5644 case OPC_J:
5645 case OPC_JAL:
364d4831 5646 case OPC_JALX:
6af0bf9c 5647 /* Jump to immediate */
eeb3bba8
EC
5648 btgt = ((ctx->base.pc_next + insn_bytes) & (int32_t)0xF0000000) |
5649 (uint32_t)offset;
6af0bf9c
FB
5650 break;
5651 case OPC_JR:
5652 case OPC_JALR:
5653 /* Jump to register */
7a387fff
TS
5654 if (offset != 0 && offset != 16) {
5655 /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
cbeb0857 5656 others are reserved. */
923617a3 5657 MIPS_INVAL("jump hint");
9c708c7f 5658 generate_exception_end(ctx, EXCP_RI);
6c5c1e20 5659 goto out;
6af0bf9c 5660 }
d077b6f7 5661 gen_load_gpr(btarget, rs);
6af0bf9c
FB
5662 break;
5663 default:
5664 MIPS_INVAL("branch/jump");
9c708c7f 5665 generate_exception_end(ctx, EXCP_RI);
6c5c1e20 5666 goto out;
6af0bf9c 5667 }
2fdbad25 5668 if (bcond_compute == 0) {
6af0bf9c
FB
5669 /* No condition to be computed */
5670 switch (opc) {
5671 case OPC_BEQ: /* rx == rx */
5672 case OPC_BEQL: /* rx == rx likely */
5673 case OPC_BGEZ: /* 0 >= 0 */
5674 case OPC_BGEZL: /* 0 >= 0 likely */
5675 case OPC_BLEZ: /* 0 <= 0 */
5676 case OPC_BLEZL: /* 0 <= 0 likely */
5677 /* Always take */
4ad40f36 5678 ctx->hflags |= MIPS_HFLAG_B;
6af0bf9c
FB
5679 break;
5680 case OPC_BGEZAL: /* 0 >= 0 */
5681 case OPC_BGEZALL: /* 0 >= 0 likely */
5682 /* Always take and link */
5683 blink = 31;
4ad40f36 5684 ctx->hflags |= MIPS_HFLAG_B;
6af0bf9c
FB
5685 break;
5686 case OPC_BNE: /* rx != rx */
5687 case OPC_BGTZ: /* 0 > 0 */
5688 case OPC_BLTZ: /* 0 < 0 */
ead9360e 5689 /* Treat as NOP. */
6c5c1e20 5690 goto out;
eeef26cd 5691 case OPC_BLTZAL: /* 0 < 0 */
3c824109
NF
5692 /* Handle as an unconditional branch to get correct delay
5693 slot checking. */
5694 blink = 31;
eeb3bba8 5695 btgt = ctx->base.pc_next + insn_bytes + delayslot_size;
3c824109 5696 ctx->hflags |= MIPS_HFLAG_B;
3c824109 5697 break;
eeef26cd 5698 case OPC_BLTZALL: /* 0 < 0 likely */
eeb3bba8 5699 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 8);
9898128f 5700 /* Skip the instruction in the delay slot */
eeb3bba8 5701 ctx->base.pc_next += 4;
6c5c1e20 5702 goto out;
6af0bf9c
FB
5703 case OPC_BNEL: /* rx != rx likely */
5704 case OPC_BGTZL: /* 0 > 0 likely */
6af0bf9c
FB
5705 case OPC_BLTZL: /* 0 < 0 likely */
5706 /* Skip the instruction in the delay slot */
eeb3bba8 5707 ctx->base.pc_next += 4;
6c5c1e20 5708 goto out;
6af0bf9c 5709 case OPC_J:
4ad40f36 5710 ctx->hflags |= MIPS_HFLAG_B;
6af0bf9c 5711 break;
364d4831
NF
5712 case OPC_JALX:
5713 ctx->hflags |= MIPS_HFLAG_BX;
5714 /* Fallthrough */
6af0bf9c
FB
5715 case OPC_JAL:
5716 blink = 31;
4ad40f36 5717 ctx->hflags |= MIPS_HFLAG_B;
6af0bf9c
FB
5718 break;
5719 case OPC_JR:
4ad40f36 5720 ctx->hflags |= MIPS_HFLAG_BR;
6af0bf9c
FB
5721 break;
5722 case OPC_JALR:
5723 blink = rt;
4ad40f36 5724 ctx->hflags |= MIPS_HFLAG_BR;
6af0bf9c
FB
5725 break;
5726 default:
5727 MIPS_INVAL("branch/jump");
9c708c7f 5728 generate_exception_end(ctx, EXCP_RI);
6c5c1e20 5729 goto out;
6af0bf9c
FB
5730 }
5731 } else {
5732 switch (opc) {
5733 case OPC_BEQ:
e68dd28f 5734 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
6af0bf9c
FB
5735 goto not_likely;
5736 case OPC_BEQL:
e68dd28f 5737 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
6af0bf9c
FB
5738 goto likely;
5739 case OPC_BNE:
e68dd28f 5740 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
6af0bf9c
FB
5741 goto not_likely;
5742 case OPC_BNEL:
e68dd28f 5743 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
6af0bf9c
FB
5744 goto likely;
5745 case OPC_BGEZ:
e68dd28f 5746 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6af0bf9c
FB
5747 goto not_likely;
5748 case OPC_BGEZL:
e68dd28f 5749 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6af0bf9c
FB
5750 goto likely;
5751 case OPC_BGEZAL:
e68dd28f 5752 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6af0bf9c
FB
5753 blink = 31;
5754 goto not_likely;
5755 case OPC_BGEZALL:
e68dd28f 5756 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6af0bf9c 5757 blink = 31;
6af0bf9c
FB
5758 goto likely;
5759 case OPC_BGTZ:
e68dd28f 5760 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
6af0bf9c
FB
5761 goto not_likely;
5762 case OPC_BGTZL:
e68dd28f 5763 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
6af0bf9c
FB
5764 goto likely;
5765 case OPC_BLEZ:
e68dd28f 5766 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
6af0bf9c
FB
5767 goto not_likely;
5768 case OPC_BLEZL:
e68dd28f 5769 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
6af0bf9c
FB
5770 goto likely;
5771 case OPC_BLTZ:
e68dd28f 5772 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6af0bf9c
FB
5773 goto not_likely;
5774 case OPC_BLTZL:
e68dd28f 5775 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6af0bf9c 5776 goto likely;
e45a93e2
JL
5777 case OPC_BPOSGE32:
5778 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
e45a93e2
JL
5779 goto not_likely;
5780#if defined(TARGET_MIPS64)
5781 case OPC_BPOSGE64:
5782 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 64);
e45a93e2
JL
5783 goto not_likely;
5784#endif
6af0bf9c 5785 case OPC_BLTZAL:
e68dd28f 5786 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6af0bf9c 5787 blink = 31;
6af0bf9c 5788 not_likely:
4ad40f36 5789 ctx->hflags |= MIPS_HFLAG_BC;
6af0bf9c
FB
5790 break;
5791 case OPC_BLTZALL:
e68dd28f 5792 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6af0bf9c 5793 blink = 31;
6af0bf9c 5794 likely:
4ad40f36 5795 ctx->hflags |= MIPS_HFLAG_BL;
6af0bf9c 5796 break;
c53f4a62
TS
5797 default:
5798 MIPS_INVAL("conditional branch/jump");
9c708c7f 5799 generate_exception_end(ctx, EXCP_RI);
6c5c1e20 5800 goto out;
6af0bf9c 5801 }
6af0bf9c 5802 }
9b9e4393 5803
d077b6f7 5804 ctx->btarget = btgt;
b231c103
YK
5805
5806 switch (delayslot_size) {
5807 case 2:
5808 ctx->hflags |= MIPS_HFLAG_BDS16;
5809 break;
5810 case 4:
5811 ctx->hflags |= MIPS_HFLAG_BDS32;
5812 break;
5813 }
5814
6af0bf9c 5815 if (blink > 0) {
b231c103 5816 int post_delay = insn_bytes + delayslot_size;
364d4831
NF
5817 int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
5818
eeb3bba8
EC
5819 tcg_gen_movi_tl(cpu_gpr[blink],
5820 ctx->base.pc_next + post_delay + lowbit);
6af0bf9c 5821 }
6c5c1e20
TS
5822
5823 out:
364d4831
NF
5824 if (insn_bytes == 2)
5825 ctx->hflags |= MIPS_HFLAG_B16;
6c5c1e20
TS
5826 tcg_temp_free(t0);
5827 tcg_temp_free(t1);
6af0bf9c
FB
5828}
5829
764371d2
SM
5830
5831/* nanoMIPS Branches */
5832static void gen_compute_branch_nm(DisasContext *ctx, uint32_t opc,
5833 int insn_bytes,
5834 int rs, int rt, int32_t offset)
5835{
5836 target_ulong btgt = -1;
5837 int bcond_compute = 0;
5838 TCGv t0 = tcg_temp_new();
5839 TCGv t1 = tcg_temp_new();
5840
5841 /* Load needed operands */
5842 switch (opc) {
5843 case OPC_BEQ:
5844 case OPC_BNE:
5845 /* Compare two registers */
5846 if (rs != rt) {
5847 gen_load_gpr(t0, rs);
5848 gen_load_gpr(t1, rt);
5849 bcond_compute = 1;
5850 }
5851 btgt = ctx->base.pc_next + insn_bytes + offset;
5852 break;
5853 case OPC_BGEZAL:
5854 /* Compare to zero */
5855 if (rs != 0) {
5856 gen_load_gpr(t0, rs);
5857 bcond_compute = 1;
5858 }
5859 btgt = ctx->base.pc_next + insn_bytes + offset;
5860 break;
5861 case OPC_BPOSGE32:
5862 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
5863 bcond_compute = 1;
5864 btgt = ctx->base.pc_next + insn_bytes + offset;
5865 break;
5866 case OPC_JR:
5867 case OPC_JALR:
5868 /* Jump to register */
5869 if (offset != 0 && offset != 16) {
5870 /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
5871 others are reserved. */
5872 MIPS_INVAL("jump hint");
5873 generate_exception_end(ctx, EXCP_RI);
5874 goto out;
5875 }
5876 gen_load_gpr(btarget, rs);
5877 break;
5878 default:
5879 MIPS_INVAL("branch/jump");
5880 generate_exception_end(ctx, EXCP_RI);
5881 goto out;
5882 }
5883 if (bcond_compute == 0) {
5884 /* No condition to be computed */
5885 switch (opc) {
5886 case OPC_BEQ: /* rx == rx */
5887 /* Always take */
5888 ctx->hflags |= MIPS_HFLAG_B;
5889 break;
5890 case OPC_BGEZAL: /* 0 >= 0 */
5891 /* Always take and link */
5892 tcg_gen_movi_tl(cpu_gpr[31],
5893 ctx->base.pc_next + insn_bytes);
5894 ctx->hflags |= MIPS_HFLAG_B;
5895 break;
5896 case OPC_BNE: /* rx != rx */
5897 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 8);
5898 /* Skip the instruction in the delay slot */
5899 ctx->base.pc_next += 4;
5900 goto out;
5901 case OPC_JR:
5902 ctx->hflags |= MIPS_HFLAG_BR;
5903 break;
5904 case OPC_JALR:
5905 if (rt > 0) {
5906 tcg_gen_movi_tl(cpu_gpr[rt],
5907 ctx->base.pc_next + insn_bytes);
5908 }
5909 ctx->hflags |= MIPS_HFLAG_BR;
5910 break;
5911 default:
5912 MIPS_INVAL("branch/jump");
5913 generate_exception_end(ctx, EXCP_RI);
5914 goto out;
5915 }
5916 } else {
5917 switch (opc) {
5918 case OPC_BEQ:
5919 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
5920 goto not_likely;
5921 case OPC_BNE:
5922 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
5923 goto not_likely;
5924 case OPC_BGEZAL:
5925 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
5926 tcg_gen_movi_tl(cpu_gpr[31],
5927 ctx->base.pc_next + insn_bytes);
5928 goto not_likely;
5929 case OPC_BPOSGE32:
5930 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
5931 not_likely:
5932 ctx->hflags |= MIPS_HFLAG_BC;
5933 break;
5934 default:
5935 MIPS_INVAL("conditional branch/jump");
5936 generate_exception_end(ctx, EXCP_RI);
5937 goto out;
5938 }
5939 }
5940
5941 ctx->btarget = btgt;
5942
5943 out:
5944 if (insn_bytes == 2) {
5945 ctx->hflags |= MIPS_HFLAG_B16;
5946 }
5947 tcg_temp_free(t0);
5948 tcg_temp_free(t1);
5949}
5950
5951
7a387fff
TS
5952/* special3 bitfield operations */
5953static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
356265ae 5954 int rs, int lsb, int msb)
7a387fff 5955{
a7812ae4
PB
5956 TCGv t0 = tcg_temp_new();
5957 TCGv t1 = tcg_temp_new();
6c5c1e20
TS
5958
5959 gen_load_gpr(t1, rs);
7a387fff
TS
5960 switch (opc) {
5961 case OPC_EXT:
b7f26e52 5962 if (lsb + msb > 31) {
7a387fff 5963 goto fail;
b7f26e52 5964 }
505ad7c2 5965 if (msb != 31) {
6eebb7a4 5966 tcg_gen_extract_tl(t0, t1, lsb, msb + 1);
505ad7c2 5967 } else {
6eebb7a4
RH
5968 /* The two checks together imply that lsb == 0,
5969 so this is a simple sign-extension. */
5970 tcg_gen_ext32s_tl(t0, t1);
505ad7c2 5971 }
7a387fff 5972 break;
c6d6dd7c 5973#if defined(TARGET_MIPS64)
7a387fff 5974 case OPC_DEXTU:
b7f26e52
RH
5975 lsb += 32;
5976 goto do_dext;
5977 case OPC_DEXTM:
5978 msb += 32;
5979 goto do_dext;
7a387fff 5980 case OPC_DEXT:
b7f26e52
RH
5981 do_dext:
5982 if (lsb + msb > 63) {
5983 goto fail;
5984 }
6eebb7a4 5985 tcg_gen_extract_tl(t0, t1, lsb, msb + 1);
7a387fff 5986 break;
c6d6dd7c 5987#endif
7a387fff 5988 case OPC_INS:
b7f26e52 5989 if (lsb > msb) {
7a387fff 5990 goto fail;
b7f26e52 5991 }
6c5c1e20 5992 gen_load_gpr(t0, rt);
e0d002f1 5993 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
505ad7c2 5994 tcg_gen_ext32s_tl(t0, t0);
7a387fff 5995 break;
c6d6dd7c 5996#if defined(TARGET_MIPS64)
7a387fff 5997 case OPC_DINSU:
b7f26e52
RH
5998 lsb += 32;
5999 /* FALLTHRU */
6000 case OPC_DINSM:
6001 msb += 32;
6002 /* FALLTHRU */
7a387fff 6003 case OPC_DINS:
b7f26e52
RH
6004 if (lsb > msb) {
6005 goto fail;
6006 }
6c5c1e20 6007 gen_load_gpr(t0, rt);
e0d002f1 6008 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
7a387fff 6009 break;
c6d6dd7c 6010#endif
7a387fff
TS
6011 default:
6012fail:
6013 MIPS_INVAL("bitops");
9c708c7f 6014 generate_exception_end(ctx, EXCP_RI);
6c5c1e20
TS
6015 tcg_temp_free(t0);
6016 tcg_temp_free(t1);
7a387fff
TS
6017 return;
6018 }
6c5c1e20
TS
6019 gen_store_gpr(t0, rt);
6020 tcg_temp_free(t0);
6021 tcg_temp_free(t1);
7a387fff
TS
6022}
6023
49bcf33c
AJ
6024static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
6025{
3a55fa47 6026 TCGv t0;
49bcf33c 6027
3a55fa47
AJ
6028 if (rd == 0) {
6029 /* If no destination, treat it as a NOP. */
3a55fa47
AJ
6030 return;
6031 }
6032
6033 t0 = tcg_temp_new();
6034 gen_load_gpr(t0, rt);
49bcf33c
AJ
6035 switch (op2) {
6036 case OPC_WSBH:
3a55fa47
AJ
6037 {
6038 TCGv t1 = tcg_temp_new();
06a57e5c 6039 TCGv t2 = tcg_const_tl(0x00FF00FF);
3a55fa47
AJ
6040
6041 tcg_gen_shri_tl(t1, t0, 8);
06a57e5c
AJ
6042 tcg_gen_and_tl(t1, t1, t2);
6043 tcg_gen_and_tl(t0, t0, t2);
3a55fa47 6044 tcg_gen_shli_tl(t0, t0, 8);
3a55fa47 6045 tcg_gen_or_tl(t0, t0, t1);
06a57e5c 6046 tcg_temp_free(t2);
3a55fa47
AJ
6047 tcg_temp_free(t1);
6048 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
6049 }
49bcf33c
AJ
6050 break;
6051 case OPC_SEB:
3a55fa47 6052 tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
49bcf33c
AJ
6053 break;
6054 case OPC_SEH:
3a55fa47 6055 tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
49bcf33c
AJ
6056 break;
6057#if defined(TARGET_MIPS64)
6058 case OPC_DSBH:
3a55fa47
AJ
6059 {
6060 TCGv t1 = tcg_temp_new();
06a57e5c 6061 TCGv t2 = tcg_const_tl(0x00FF00FF00FF00FFULL);
3a55fa47
AJ
6062
6063 tcg_gen_shri_tl(t1, t0, 8);
06a57e5c
AJ
6064 tcg_gen_and_tl(t1, t1, t2);
6065 tcg_gen_and_tl(t0, t0, t2);
3a55fa47 6066 tcg_gen_shli_tl(t0, t0, 8);
3a55fa47 6067 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
06a57e5c 6068 tcg_temp_free(t2);
3a55fa47
AJ
6069 tcg_temp_free(t1);
6070 }
49bcf33c
AJ
6071 break;
6072 case OPC_DSHD:
3a55fa47
AJ
6073 {
6074 TCGv t1 = tcg_temp_new();
06a57e5c 6075 TCGv t2 = tcg_const_tl(0x0000FFFF0000FFFFULL);
3a55fa47
AJ
6076
6077 tcg_gen_shri_tl(t1, t0, 16);
06a57e5c
AJ
6078 tcg_gen_and_tl(t1, t1, t2);
6079 tcg_gen_and_tl(t0, t0, t2);
3a55fa47 6080 tcg_gen_shli_tl(t0, t0, 16);
3a55fa47
AJ
6081 tcg_gen_or_tl(t0, t0, t1);
6082 tcg_gen_shri_tl(t1, t0, 32);
6083 tcg_gen_shli_tl(t0, t0, 32);
6084 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
06a57e5c 6085 tcg_temp_free(t2);
3a55fa47
AJ
6086 tcg_temp_free(t1);
6087 }
49bcf33c
AJ
6088 break;
6089#endif
6090 default:
6091 MIPS_INVAL("bsfhl");
9c708c7f 6092 generate_exception_end(ctx, EXCP_RI);
49bcf33c 6093 tcg_temp_free(t0);
49bcf33c
AJ
6094 return;
6095 }
49bcf33c 6096 tcg_temp_free(t0);
49bcf33c
AJ
6097}
6098
1f1b4c00
YK
6099static void gen_lsa(DisasContext *ctx, int opc, int rd, int rs, int rt,
6100 int imm2)
6101{
6102 TCGv t0;
6103 TCGv t1;
6104 if (rd == 0) {
6105 /* Treat as NOP. */
6106 return;
6107 }
6108 t0 = tcg_temp_new();
6109 t1 = tcg_temp_new();
6110 gen_load_gpr(t0, rs);
6111 gen_load_gpr(t1, rt);
6112 tcg_gen_shli_tl(t0, t0, imm2 + 1);
6113 tcg_gen_add_tl(cpu_gpr[rd], t0, t1);
6114 if (opc == OPC_LSA) {
6115 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
6116 }
6117
6118 tcg_temp_free(t1);
6119 tcg_temp_free(t0);
6120
6121 return;
6122}
6123
821f2008
JH
6124static void gen_align_bits(DisasContext *ctx, int wordsz, int rd, int rs,
6125 int rt, int bits)
284b731a 6126{
1f1b4c00
YK
6127 TCGv t0;
6128 if (rd == 0) {
6129 /* Treat as NOP. */
6130 return;
6131 }
6132 t0 = tcg_temp_new();
821f2008
JH
6133 if (bits == 0 || bits == wordsz) {
6134 if (bits == 0) {
6135 gen_load_gpr(t0, rt);
6136 } else {
6137 gen_load_gpr(t0, rs);
6138 }
6139 switch (wordsz) {
6140 case 32:
51243852
MD
6141 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
6142 break;
6143#if defined(TARGET_MIPS64)
821f2008 6144 case 64:
51243852
MD
6145 tcg_gen_mov_tl(cpu_gpr[rd], t0);
6146 break;
6147#endif
6148 }
1f1b4c00
YK
6149 } else {
6150 TCGv t1 = tcg_temp_new();
821f2008 6151 gen_load_gpr(t0, rt);
1f1b4c00 6152 gen_load_gpr(t1, rs);
821f2008
JH
6153 switch (wordsz) {
6154 case 32:
1f1b4c00
YK
6155 {
6156 TCGv_i64 t2 = tcg_temp_new_i64();
6157 tcg_gen_concat_tl_i64(t2, t1, t0);
821f2008 6158 tcg_gen_shri_i64(t2, t2, 32 - bits);
1f1b4c00
YK
6159 gen_move_low32(cpu_gpr[rd], t2);
6160 tcg_temp_free_i64(t2);
6161 }
6162 break;
284b731a 6163#if defined(TARGET_MIPS64)
821f2008
JH
6164 case 64:
6165 tcg_gen_shli_tl(t0, t0, bits);
6166 tcg_gen_shri_tl(t1, t1, 64 - bits);
1f1b4c00
YK
6167 tcg_gen_or_tl(cpu_gpr[rd], t1, t0);
6168 break;
284b731a 6169#endif
1f1b4c00
YK
6170 }
6171 tcg_temp_free(t1);
6172 }
6173
6174 tcg_temp_free(t0);
6175}
6176
821f2008
JH
6177static void gen_align(DisasContext *ctx, int wordsz, int rd, int rs, int rt,
6178 int bp)
6179{
6180 gen_align_bits(ctx, wordsz, rd, rs, rt, bp * 8);
6181}
6182
6183static void gen_ext(DisasContext *ctx, int wordsz, int rd, int rs, int rt,
6184 int shift)
6185{
6186 gen_align_bits(ctx, wordsz, rd, rs, rt, wordsz - shift);
6187}
6188
1f1b4c00
YK
6189static void gen_bitswap(DisasContext *ctx, int opc, int rd, int rt)
6190{
6191 TCGv t0;
6192 if (rd == 0) {
6193 /* Treat as NOP. */
6194 return;
6195 }
6196 t0 = tcg_temp_new();
6197 gen_load_gpr(t0, rt);
6198 switch (opc) {
6199 case OPC_BITSWAP:
6200 gen_helper_bitswap(cpu_gpr[rd], t0);
6201 break;
6202#if defined(TARGET_MIPS64)
6203 case OPC_DBITSWAP:
6204 gen_helper_dbitswap(cpu_gpr[rd], t0);
6205 break;
6206#endif
6207 }
6208 tcg_temp_free(t0);
284b731a
LA
6209}
6210
1f1b4c00
YK
6211#ifndef CONFIG_USER_ONLY
6212/* CP0 (MMU and control) */
5204ea79
LA
6213static inline void gen_mthc0_entrylo(TCGv arg, target_ulong off)
6214{
6215 TCGv_i64 t0 = tcg_temp_new_i64();
6216 TCGv_i64 t1 = tcg_temp_new_i64();
6217
6218 tcg_gen_ext_tl_i64(t0, arg);
6219 tcg_gen_ld_i64(t1, cpu_env, off);
6220#if defined(TARGET_MIPS64)
6221 tcg_gen_deposit_i64(t1, t1, t0, 30, 32);
6222#else
6223 tcg_gen_concat32_i64(t1, t1, t0);
6224#endif
6225 tcg_gen_st_i64(t1, cpu_env, off);
6226 tcg_temp_free_i64(t1);
6227 tcg_temp_free_i64(t0);
6228}
6229
6230static inline void gen_mthc0_store64(TCGv arg, target_ulong off)
6231{
6232 TCGv_i64 t0 = tcg_temp_new_i64();
6233 TCGv_i64 t1 = tcg_temp_new_i64();
6234
6235 tcg_gen_ext_tl_i64(t0, arg);
6236 tcg_gen_ld_i64(t1, cpu_env, off);
6237 tcg_gen_concat32_i64(t1, t1, t0);
6238 tcg_gen_st_i64(t1, cpu_env, off);
6239 tcg_temp_free_i64(t1);
6240 tcg_temp_free_i64(t0);
6241}
6242
6243static inline void gen_mfhc0_entrylo(TCGv arg, target_ulong off)
6244{
6245 TCGv_i64 t0 = tcg_temp_new_i64();
6246
6247 tcg_gen_ld_i64(t0, cpu_env, off);
6248#if defined(TARGET_MIPS64)
6249 tcg_gen_shri_i64(t0, t0, 30);
6250#else
6251 tcg_gen_shri_i64(t0, t0, 32);
6252#endif
6253 gen_move_low32(arg, t0);
6254 tcg_temp_free_i64(t0);
6255}
6256
6257static inline void gen_mfhc0_load64(TCGv arg, target_ulong off, int shift)
6258{
6259 TCGv_i64 t0 = tcg_temp_new_i64();
6260
6261 tcg_gen_ld_i64(t0, cpu_env, off);
6262 tcg_gen_shri_i64(t0, t0, 32 + shift);
6263 gen_move_low32(arg, t0);
6264 tcg_temp_free_i64(t0);
6265}
6266
d9bea114 6267static inline void gen_mfc0_load32 (TCGv arg, target_ulong off)
4f57689a 6268{
d9bea114 6269 TCGv_i32 t0 = tcg_temp_new_i32();
4f57689a 6270
d9bea114
AJ
6271 tcg_gen_ld_i32(t0, cpu_env, off);
6272 tcg_gen_ext_i32_tl(arg, t0);
6273 tcg_temp_free_i32(t0);
4f57689a
TS
6274}
6275
d9bea114 6276static inline void gen_mfc0_load64 (TCGv arg, target_ulong off)
4f57689a 6277{
d9bea114
AJ
6278 tcg_gen_ld_tl(arg, cpu_env, off);
6279 tcg_gen_ext32s_tl(arg, arg);
4f57689a
TS
6280}
6281
d9bea114 6282static inline void gen_mtc0_store32 (TCGv arg, target_ulong off)
f1aa6320 6283{
d9bea114 6284 TCGv_i32 t0 = tcg_temp_new_i32();
f1aa6320 6285
d9bea114
AJ
6286 tcg_gen_trunc_tl_i32(t0, arg);
6287 tcg_gen_st_i32(t0, cpu_env, off);
6288 tcg_temp_free_i32(t0);
f1aa6320
TS
6289}
6290
c98d3d79
YK
6291#define CP0_CHECK(c) \
6292 do { \
6293 if (!(c)) { \
6294 goto cp0_unimplemented; \
6295 } \
6296 } while (0)
6297
5204ea79
LA
6298static void gen_mfhc0(DisasContext *ctx, TCGv arg, int reg, int sel)
6299{
6300 const char *rn = "invalid";
6301
5204ea79
LA
6302 switch (reg) {
6303 case 2:
6304 switch (sel) {
6305 case 0:
59488dda 6306 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
5204ea79
LA
6307 gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
6308 rn = "EntryLo0";
6309 break;
6310 default:
c98d3d79 6311 goto cp0_unimplemented;
5204ea79
LA
6312 }
6313 break;
6314 case 3:
6315 switch (sel) {
6316 case 0:
59488dda 6317 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
5204ea79
LA
6318 gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
6319 rn = "EntryLo1";
6320 break;
6321 default:
c98d3d79 6322 goto cp0_unimplemented;
5204ea79
LA
6323 }
6324 break;
6325 case 17:
6326 switch (sel) {
6327 case 0:
6328 gen_mfhc0_load64(arg, offsetof(CPUMIPSState, lladdr),
6329 ctx->CP0_LLAddr_shift);
6330 rn = "LLAddr";
6331 break;
f6d4dd81
YK
6332 case 1:
6333 CP0_CHECK(ctx->mrp);
6334 gen_helper_mfhc0_maar(arg, cpu_env);
6335 rn = "MAAR";
6336 break;
5204ea79 6337 default:
c98d3d79 6338 goto cp0_unimplemented;
5204ea79
LA
6339 }
6340 break;
6341 case 28:
6342 switch (sel) {
6343 case 0:
6344 case 2:
6345 case 4:
6346 case 6:
6347 gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_TagLo), 0);
6348 rn = "TagLo";
6349 break;
6350 default:
c98d3d79 6351 goto cp0_unimplemented;
5204ea79
LA
6352 }
6353 break;
6354 default:
c98d3d79 6355 goto cp0_unimplemented;
5204ea79 6356 }
b44a7fb1 6357 trace_mips_translate_c0("mfhc0", rn, reg, sel);
5204ea79
LA
6358 return;
6359
c98d3d79 6360cp0_unimplemented:
965447ee 6361 qemu_log_mask(LOG_UNIMP, "mfhc0 %s (reg %d sel %d)\n", rn, reg, sel);
5204ea79
LA
6362 tcg_gen_movi_tl(arg, 0);
6363}
6364
6365static void gen_mthc0(DisasContext *ctx, TCGv arg, int reg, int sel)
6366{
6367 const char *rn = "invalid";
6368 uint64_t mask = ctx->PAMask >> 36;
6369
5204ea79
LA
6370 switch (reg) {
6371 case 2:
6372 switch (sel) {
6373 case 0:
59488dda 6374 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
5204ea79
LA
6375 tcg_gen_andi_tl(arg, arg, mask);
6376 gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
6377 rn = "EntryLo0";
6378 break;
6379 default:
c98d3d79 6380 goto cp0_unimplemented;
5204ea79
LA
6381 }
6382 break;
6383 case 3:
6384 switch (sel) {
6385 case 0:
59488dda 6386 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
5204ea79
LA
6387 tcg_gen_andi_tl(arg, arg, mask);
6388 gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
6389 rn = "EntryLo1";
6390 break;
6391 default:
c98d3d79 6392 goto cp0_unimplemented;
5204ea79
LA
6393 }
6394 break;
6395 case 17:
6396 switch (sel) {
6397 case 0:
6398 /* LLAddr is read-only (the only exception is bit 0 if LLB is
6399 supported); the CP0_LLAddr_rw_bitmask does not seem to be
6400 relevant for modern MIPS cores supporting MTHC0, therefore
6401 treating MTHC0 to LLAddr as NOP. */
6402 rn = "LLAddr";
6403 break;
f6d4dd81
YK
6404 case 1:
6405 CP0_CHECK(ctx->mrp);
6406 gen_helper_mthc0_maar(cpu_env, arg);
6407 rn = "MAAR";
6408 break;
5204ea79 6409 default:
c98d3d79 6410 goto cp0_unimplemented;
5204ea79
LA
6411 }
6412 break;
6413 case 28:
6414 switch (sel) {
6415 case 0:
6416 case 2:
6417 case 4:
6418 case 6:
6419 tcg_gen_andi_tl(arg, arg, mask);
6420 gen_mthc0_store64(arg, offsetof(CPUMIPSState, CP0_TagLo));
6421 rn = "TagLo";
6422 break;
6423 default:
c98d3d79 6424 goto cp0_unimplemented;
5204ea79
LA
6425 }
6426 break;
6427 default:
c98d3d79 6428 goto cp0_unimplemented;
5204ea79 6429 }
b44a7fb1 6430 trace_mips_translate_c0("mthc0", rn, reg, sel);
5204ea79 6431
c98d3d79 6432cp0_unimplemented:
965447ee 6433 qemu_log_mask(LOG_UNIMP, "mthc0 %s (reg %d sel %d)\n", rn, reg, sel);
5204ea79
LA
6434}
6435
e98c0d17
LA
6436static inline void gen_mfc0_unimplemented(DisasContext *ctx, TCGv arg)
6437{
6438 if (ctx->insn_flags & ISA_MIPS32R6) {
6439 tcg_gen_movi_tl(arg, 0);
6440 } else {
6441 tcg_gen_movi_tl(arg, ~0);
6442 }
6443}
6444
d75c135e 6445static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
873eb012 6446{
7a387fff 6447 const char *rn = "invalid";
873eb012 6448
e189e748 6449 if (sel != 0)
d75c135e 6450 check_insn(ctx, ISA_MIPS32);
e189e748 6451
873eb012
TS
6452 switch (reg) {
6453 case 0:
7a387fff
TS
6454 switch (sel) {
6455 case 0:
7db13fae 6456 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
7a387fff
TS
6457 rn = "Index";
6458 break;
6459 case 1:
f31b035a 6460 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6461 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
7a387fff 6462 rn = "MVPControl";
ead9360e 6463 break;
7a387fff 6464 case 2:
f31b035a 6465 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6466 gen_helper_mfc0_mvpconf0(arg, cpu_env);
7a387fff 6467 rn = "MVPConf0";
ead9360e 6468 break;
7a387fff 6469 case 3:
f31b035a 6470 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6471 gen_helper_mfc0_mvpconf1(arg, cpu_env);
7a387fff 6472 rn = "MVPConf1";
ead9360e 6473 break;
01bc435b
YK
6474 case 4:
6475 CP0_CHECK(ctx->vp);
6476 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl));
6477 rn = "VPControl";
6478 break;
7a387fff 6479 default:
f31b035a 6480 goto cp0_unimplemented;
7a387fff 6481 }
873eb012
TS
6482 break;
6483 case 1:
7a387fff
TS
6484 switch (sel) {
6485 case 0:
f31b035a 6486 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
895c2d04 6487 gen_helper_mfc0_random(arg, cpu_env);
7a387fff 6488 rn = "Random";
2423f660 6489 break;
7a387fff 6490 case 1:
f31b035a 6491 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6492 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
7a387fff 6493 rn = "VPEControl";
ead9360e 6494 break;
7a387fff 6495 case 2:
f31b035a 6496 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6497 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
7a387fff 6498 rn = "VPEConf0";
ead9360e 6499 break;
7a387fff 6500 case 3:
f31b035a 6501 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6502 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
7a387fff 6503 rn = "VPEConf1";
ead9360e 6504 break;
7a387fff 6505 case 4:
f31b035a 6506 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6507 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask));
7a387fff 6508 rn = "YQMask";
ead9360e 6509 break;
7a387fff 6510 case 5:
f31b035a 6511 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6512 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
7a387fff 6513 rn = "VPESchedule";
ead9360e 6514 break;
7a387fff 6515 case 6:
f31b035a 6516 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6517 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
7a387fff 6518 rn = "VPEScheFBack";
ead9360e 6519 break;
7a387fff 6520 case 7:
f31b035a 6521 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6522 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
7a387fff 6523 rn = "VPEOpt";
ead9360e 6524 break;
7a387fff 6525 default:
f31b035a 6526 goto cp0_unimplemented;
7a387fff 6527 }
873eb012
TS
6528 break;
6529 case 2:
7a387fff
TS
6530 switch (sel) {
6531 case 0:
284b731a
LA
6532 {
6533 TCGv_i64 tmp = tcg_temp_new_i64();
6534 tcg_gen_ld_i64(tmp, cpu_env,
6535 offsetof(CPUMIPSState, CP0_EntryLo0));
7207c7f9 6536#if defined(TARGET_MIPS64)
284b731a
LA
6537 if (ctx->rxi) {
6538 /* Move RI/XI fields to bits 31:30 */
6539 tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
6540 tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
6541 }
7207c7f9 6542#endif
284b731a
LA
6543 gen_move_low32(arg, tmp);
6544 tcg_temp_free_i64(tmp);
6545 }
2423f660
TS
6546 rn = "EntryLo0";
6547 break;
7a387fff 6548 case 1:
f31b035a 6549 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6550 gen_helper_mfc0_tcstatus(arg, cpu_env);
2423f660 6551 rn = "TCStatus";
ead9360e 6552 break;
7a387fff 6553 case 2:
f31b035a 6554 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6555 gen_helper_mfc0_tcbind(arg, cpu_env);
2423f660 6556 rn = "TCBind";
ead9360e 6557 break;
7a387fff 6558 case 3:
f31b035a 6559 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6560 gen_helper_mfc0_tcrestart(arg, cpu_env);
2423f660 6561 rn = "TCRestart";
ead9360e 6562 break;
7a387fff 6563 case 4:
f31b035a 6564 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6565 gen_helper_mfc0_tchalt(arg, cpu_env);
2423f660 6566 rn = "TCHalt";
ead9360e 6567 break;
7a387fff 6568 case 5:
f31b035a 6569 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6570 gen_helper_mfc0_tccontext(arg, cpu_env);
2423f660 6571 rn = "TCContext";
ead9360e 6572 break;
7a387fff 6573 case 6:
f31b035a 6574 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6575 gen_helper_mfc0_tcschedule(arg, cpu_env);
2423f660 6576 rn = "TCSchedule";
ead9360e 6577 break;
7a387fff 6578 case 7:
f31b035a 6579 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6580 gen_helper_mfc0_tcschefback(arg, cpu_env);
2423f660 6581 rn = "TCScheFBack";
ead9360e 6582 break;
7a387fff 6583 default:
f31b035a 6584 goto cp0_unimplemented;
7a387fff 6585 }
873eb012
TS
6586 break;
6587 case 3:
7a387fff
TS
6588 switch (sel) {
6589 case 0:
284b731a
LA
6590 {
6591 TCGv_i64 tmp = tcg_temp_new_i64();
6592 tcg_gen_ld_i64(tmp, cpu_env,
6593 offsetof(CPUMIPSState, CP0_EntryLo1));
7207c7f9 6594#if defined(TARGET_MIPS64)
284b731a
LA
6595 if (ctx->rxi) {
6596 /* Move RI/XI fields to bits 31:30 */
6597 tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
6598 tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
6599 }
7207c7f9 6600#endif
284b731a
LA
6601 gen_move_low32(arg, tmp);
6602 tcg_temp_free_i64(tmp);
6603 }
2423f660
TS
6604 rn = "EntryLo1";
6605 break;
01bc435b
YK
6606 case 1:
6607 CP0_CHECK(ctx->vp);
6608 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber));
6609 rn = "GlobalNumber";
6610 break;
7a387fff 6611 default:
f31b035a 6612 goto cp0_unimplemented;
1579a72e 6613 }
873eb012
TS
6614 break;
6615 case 4:
7a387fff
TS
6616 switch (sel) {
6617 case 0:
7db13fae 6618 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
d9bea114 6619 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
6620 rn = "Context";
6621 break;
7a387fff 6622 case 1:
d9bea114 6623// gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
2423f660 6624 rn = "ContextConfig";
f31b035a 6625 goto cp0_unimplemented;
d279279e 6626 case 2:
f31b035a 6627 CP0_CHECK(ctx->ulri);
e40df9a8
JH
6628 tcg_gen_ld_tl(arg, cpu_env,
6629 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
6630 tcg_gen_ext32s_tl(arg, arg);
f31b035a 6631 rn = "UserLocal";
d279279e 6632 break;
7a387fff 6633 default:
f31b035a 6634 goto cp0_unimplemented;
1579a72e 6635 }
873eb012
TS
6636 break;
6637 case 5:
7a387fff
TS
6638 switch (sel) {
6639 case 0:
7db13fae 6640 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
2423f660
TS
6641 rn = "PageMask";
6642 break;
7a387fff 6643 case 1:
d75c135e 6644 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6645 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
2423f660
TS
6646 rn = "PageGrain";
6647 break;
cec56a73
JH
6648 case 2:
6649 CP0_CHECK(ctx->sc);
6650 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl0));
6651 tcg_gen_ext32s_tl(arg, arg);
6652 rn = "SegCtl0";
6653 break;
6654 case 3:
6655 CP0_CHECK(ctx->sc);
6656 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl1));
6657 tcg_gen_ext32s_tl(arg, arg);
6658 rn = "SegCtl1";
6659 break;
6660 case 4:
6661 CP0_CHECK(ctx->sc);
6662 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl2));
6663 tcg_gen_ext32s_tl(arg, arg);
6664 rn = "SegCtl2";
6665 break;
5e31fdd5
YK
6666 case 5:
6667 check_pw(ctx);
6668 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWBase));
6669 rn = "PWBase";
6670 break;
fa75ad14
YK
6671 case 6:
6672 check_pw(ctx);
6673 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWField));
6674 rn = "PWField";
6675 break;
20b28ebc
YK
6676 case 7:
6677 check_pw(ctx);
6678 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWSize));
6679 rn = "PWSize";
6680 break;
7a387fff 6681 default:
f31b035a 6682 goto cp0_unimplemented;
1579a72e 6683 }
873eb012
TS
6684 break;
6685 case 6:
7a387fff
TS
6686 switch (sel) {
6687 case 0:
7db13fae 6688 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
2423f660
TS
6689 rn = "Wired";
6690 break;
7a387fff 6691 case 1:
d75c135e 6692 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6693 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
2423f660 6694 rn = "SRSConf0";
ead9360e 6695 break;
7a387fff 6696 case 2:
d75c135e 6697 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6698 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
2423f660 6699 rn = "SRSConf1";
ead9360e 6700 break;
7a387fff 6701 case 3:
d75c135e 6702 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6703 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
2423f660 6704 rn = "SRSConf2";
ead9360e 6705 break;
7a387fff 6706 case 4:
d75c135e 6707 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6708 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
2423f660 6709 rn = "SRSConf3";
ead9360e 6710 break;
7a387fff 6711 case 5:
d75c135e 6712 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6713 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
2423f660 6714 rn = "SRSConf4";
ead9360e 6715 break;
103be64c
YK
6716 case 6:
6717 check_pw(ctx);
6718 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWCtl));
6719 rn = "PWCtl";
6720 break;
7a387fff 6721 default:
f31b035a 6722 goto cp0_unimplemented;
1579a72e 6723 }
873eb012 6724 break;
8c0fdd85 6725 case 7:
7a387fff
TS
6726 switch (sel) {
6727 case 0:
d75c135e 6728 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6729 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
2423f660
TS
6730 rn = "HWREna";
6731 break;
7a387fff 6732 default:
f31b035a 6733 goto cp0_unimplemented;
1579a72e 6734 }
8c0fdd85 6735 break;
873eb012 6736 case 8:
7a387fff
TS
6737 switch (sel) {
6738 case 0:
7db13fae 6739 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
d9bea114 6740 tcg_gen_ext32s_tl(arg, arg);
f0b3f3ae 6741 rn = "BadVAddr";
2423f660 6742 break;
aea14095 6743 case 1:
f31b035a
LA
6744 CP0_CHECK(ctx->bi);
6745 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
6746 rn = "BadInstr";
aea14095
LA
6747 break;
6748 case 2:
f31b035a
LA
6749 CP0_CHECK(ctx->bp);
6750 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
6751 rn = "BadInstrP";
aea14095 6752 break;
25beba9b
SM
6753 case 3:
6754 CP0_CHECK(ctx->bi);
6755 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrX));
6756 tcg_gen_andi_tl(arg, arg, ~0xffff);
6757 rn = "BadInstrX";
6758 break;
6759 default:
f31b035a 6760 goto cp0_unimplemented;
aea14095 6761 }
873eb012
TS
6762 break;
6763 case 9:
7a387fff
TS
6764 switch (sel) {
6765 case 0:
2e70f6ef 6766 /* Mark as an IO operation because we read the time. */
eeb3bba8 6767 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
2e70f6ef 6768 gen_io_start();
bd79255d 6769 }
895c2d04 6770 gen_helper_mfc0_count(arg, cpu_env);
eeb3bba8 6771 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
2e70f6ef 6772 gen_io_end();
2e70f6ef 6773 }
55807224 6774 /* Break the TB to be able to take timer interrupts immediately
b28425ba
EC
6775 after reading count. DISAS_STOP isn't sufficient, we need to
6776 ensure we break completely out of translated code. */
eeb3bba8
EC
6777 gen_save_pc(ctx->base.pc_next + 4);
6778 ctx->base.is_jmp = DISAS_EXIT;
2423f660
TS
6779 rn = "Count";
6780 break;
6781 /* 6,7 are implementation dependent */
7a387fff 6782 default:
f31b035a 6783 goto cp0_unimplemented;
2423f660 6784 }
873eb012
TS
6785 break;
6786 case 10:
7a387fff
TS
6787 switch (sel) {
6788 case 0:
7db13fae 6789 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
d9bea114 6790 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
6791 rn = "EntryHi";
6792 break;
7a387fff 6793 default:
f31b035a 6794 goto cp0_unimplemented;
1579a72e 6795 }
873eb012
TS
6796 break;
6797 case 11:
7a387fff
TS
6798 switch (sel) {
6799 case 0:
7db13fae 6800 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
2423f660
TS
6801 rn = "Compare";
6802 break;
6803 /* 6,7 are implementation dependent */
7a387fff 6804 default:
f31b035a 6805 goto cp0_unimplemented;
2423f660 6806 }
873eb012
TS
6807 break;
6808 case 12:
7a387fff
TS
6809 switch (sel) {
6810 case 0:
7db13fae 6811 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
2423f660
TS
6812 rn = "Status";
6813 break;
7a387fff 6814 case 1:
d75c135e 6815 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6816 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
2423f660
TS
6817 rn = "IntCtl";
6818 break;
7a387fff 6819 case 2:
d75c135e 6820 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6821 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
2423f660
TS
6822 rn = "SRSCtl";
6823 break;
7a387fff 6824 case 3:
d75c135e 6825 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6826 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
2423f660 6827 rn = "SRSMap";
fd88b6ab 6828 break;
7a387fff 6829 default:
f31b035a 6830 goto cp0_unimplemented;
7a387fff 6831 }
873eb012
TS
6832 break;
6833 case 13:
7a387fff
TS
6834 switch (sel) {
6835 case 0:
7db13fae 6836 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
2423f660
TS
6837 rn = "Cause";
6838 break;
7a387fff 6839 default:
f31b035a 6840 goto cp0_unimplemented;
7a387fff 6841 }
873eb012
TS
6842 break;
6843 case 14:
7a387fff
TS
6844 switch (sel) {
6845 case 0:
7db13fae 6846 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
d9bea114 6847 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
6848 rn = "EPC";
6849 break;
7a387fff 6850 default:
f31b035a 6851 goto cp0_unimplemented;
1579a72e 6852 }
873eb012
TS
6853 break;
6854 case 15:
7a387fff
TS
6855 switch (sel) {
6856 case 0:
7db13fae 6857 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
2423f660
TS
6858 rn = "PRid";
6859 break;
7a387fff 6860 case 1:
d75c135e 6861 check_insn(ctx, ISA_MIPS32R2);
74dbf824
JH
6862 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EBase));
6863 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
6864 rn = "EBase";
6865 break;
c870e3f5
YK
6866 case 3:
6867 check_insn(ctx, ISA_MIPS32R2);
6868 CP0_CHECK(ctx->cmgcr);
6869 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase));
6870 tcg_gen_ext32s_tl(arg, arg);
6871 rn = "CMGCRBase";
6872 break;
7a387fff 6873 default:
f31b035a 6874 goto cp0_unimplemented;
7a387fff 6875 }
873eb012
TS
6876 break;
6877 case 16:
6878 switch (sel) {
6879 case 0:
7db13fae 6880 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
873eb012
TS
6881 rn = "Config";
6882 break;
6883 case 1:
7db13fae 6884 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
873eb012
TS
6885 rn = "Config1";
6886 break;
7a387fff 6887 case 2:
7db13fae 6888 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
7a387fff
TS
6889 rn = "Config2";
6890 break;
6891 case 3:
7db13fae 6892 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
7a387fff
TS
6893 rn = "Config3";
6894 break;
b4160af1
PJ
6895 case 4:
6896 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
6897 rn = "Config4";
6898 break;
b4dd99a3
PJ
6899 case 5:
6900 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
6901 rn = "Config5";
6902 break;
e397ee33
TS
6903 /* 6,7 are implementation dependent */
6904 case 6:
7db13fae 6905 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
e397ee33
TS
6906 rn = "Config6";
6907 break;
6908 case 7:
7db13fae 6909 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
e397ee33
TS
6910 rn = "Config7";
6911 break;
873eb012 6912 default:
f31b035a 6913 goto cp0_unimplemented;
873eb012
TS
6914 }
6915 break;
6916 case 17:
7a387fff
TS
6917 switch (sel) {
6918 case 0:
895c2d04 6919 gen_helper_mfc0_lladdr(arg, cpu_env);
2423f660
TS
6920 rn = "LLAddr";
6921 break;
f6d4dd81
YK
6922 case 1:
6923 CP0_CHECK(ctx->mrp);
6924 gen_helper_mfc0_maar(arg, cpu_env);
6925 rn = "MAAR";
6926 break;
6927 case 2:
6928 CP0_CHECK(ctx->mrp);
6929 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI));
6930 rn = "MAARI";
6931 break;
7a387fff 6932 default:
f31b035a 6933 goto cp0_unimplemented;
7a387fff 6934 }
873eb012
TS
6935 break;
6936 case 18:
7a387fff 6937 switch (sel) {
c2e19f3c
AM
6938 case 0:
6939 case 1:
6940 case 2:
6941 case 3:
6942 case 4:
6943 case 5:
6944 case 6:
6945 case 7:
fa192d49 6946 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
895c2d04 6947 gen_helper_1e0i(mfc0_watchlo, arg, sel);
2423f660
TS
6948 rn = "WatchLo";
6949 break;
7a387fff 6950 default:
f31b035a 6951 goto cp0_unimplemented;
7a387fff 6952 }
873eb012
TS
6953 break;
6954 case 19:
7a387fff 6955 switch (sel) {
c2e19f3c
AM
6956 case 0:
6957 case 1:
6958 case 2:
6959 case 3:
6960 case 4:
6961 case 5:
6962 case 6:
6963 case 7:
fa192d49 6964 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
895c2d04 6965 gen_helper_1e0i(mfc0_watchhi, arg, sel);
2423f660
TS
6966 rn = "WatchHi";
6967 break;
7a387fff 6968 default:
f31b035a 6969 goto cp0_unimplemented;
7a387fff 6970 }
873eb012 6971 break;
8c0fdd85 6972 case 20:
7a387fff
TS
6973 switch (sel) {
6974 case 0:
d26bc211 6975#if defined(TARGET_MIPS64)
d75c135e 6976 check_insn(ctx, ISA_MIPS3);
7db13fae 6977 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
d9bea114 6978 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
6979 rn = "XContext";
6980 break;
703eaf37 6981#endif
7a387fff 6982 default:
f31b035a 6983 goto cp0_unimplemented;
7a387fff 6984 }
8c0fdd85
TS
6985 break;
6986 case 21:
7a387fff 6987 /* Officially reserved, but sel 0 is used for R1x000 framemask */
f31b035a 6988 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
7a387fff
TS
6989 switch (sel) {
6990 case 0:
7db13fae 6991 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
2423f660
TS
6992 rn = "Framemask";
6993 break;
7a387fff 6994 default:
f31b035a 6995 goto cp0_unimplemented;
7a387fff 6996 }
8c0fdd85
TS
6997 break;
6998 case 22:
d9bea114 6999 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
7000 rn = "'Diagnostic"; /* implementation dependent */
7001 break;
873eb012 7002 case 23:
7a387fff
TS
7003 switch (sel) {
7004 case 0:
895c2d04 7005 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
2423f660
TS
7006 rn = "Debug";
7007 break;
7a387fff 7008 case 1:
d9bea114 7009// gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
2423f660 7010 rn = "TraceControl";
3570d7f6 7011 goto cp0_unimplemented;
7a387fff 7012 case 2:
d9bea114 7013// gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
2423f660 7014 rn = "TraceControl2";
3570d7f6 7015 goto cp0_unimplemented;
7a387fff 7016 case 3:
d9bea114 7017// gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
2423f660 7018 rn = "UserTraceData";
3570d7f6 7019 goto cp0_unimplemented;
7a387fff 7020 case 4:
d9bea114 7021// gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
2423f660 7022 rn = "TraceBPC";
3570d7f6 7023 goto cp0_unimplemented;
7a387fff 7024 default:
f31b035a 7025 goto cp0_unimplemented;
7a387fff 7026 }
873eb012
TS
7027 break;
7028 case 24:
7a387fff
TS
7029 switch (sel) {
7030 case 0:
f0b3f3ae 7031 /* EJTAG support */
7db13fae 7032 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
d9bea114 7033 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
7034 rn = "DEPC";
7035 break;
7a387fff 7036 default:
f31b035a 7037 goto cp0_unimplemented;
7a387fff 7038 }
873eb012 7039 break;
8c0fdd85 7040 case 25:
7a387fff
TS
7041 switch (sel) {
7042 case 0:
7db13fae 7043 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
2423f660 7044 rn = "Performance0";
7a387fff
TS
7045 break;
7046 case 1:
d9bea114 7047// gen_helper_mfc0_performance1(arg);
2423f660 7048 rn = "Performance1";
3570d7f6 7049 goto cp0_unimplemented;
7a387fff 7050 case 2:
d9bea114 7051// gen_helper_mfc0_performance2(arg);
2423f660 7052 rn = "Performance2";
3570d7f6 7053 goto cp0_unimplemented;
7a387fff 7054 case 3:
d9bea114 7055// gen_helper_mfc0_performance3(arg);
2423f660 7056 rn = "Performance3";
3570d7f6 7057 goto cp0_unimplemented;
7a387fff 7058 case 4:
d9bea114 7059// gen_helper_mfc0_performance4(arg);
2423f660 7060 rn = "Performance4";
3570d7f6 7061 goto cp0_unimplemented;
7a387fff 7062 case 5:
d9bea114 7063// gen_helper_mfc0_performance5(arg);
2423f660 7064 rn = "Performance5";
3570d7f6 7065 goto cp0_unimplemented;
7a387fff 7066 case 6:
d9bea114 7067// gen_helper_mfc0_performance6(arg);
2423f660 7068 rn = "Performance6";
3570d7f6 7069 goto cp0_unimplemented;
7a387fff 7070 case 7:
d9bea114 7071// gen_helper_mfc0_performance7(arg);
2423f660 7072 rn = "Performance7";
3570d7f6 7073 goto cp0_unimplemented;
7a387fff 7074 default:
f31b035a 7075 goto cp0_unimplemented;
7a387fff 7076 }
8c0fdd85
TS
7077 break;
7078 case 26:
0d74a222
LA
7079 switch (sel) {
7080 case 0:
7081 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl));
7082 rn = "ErrCtl";
7083 break;
7084 default:
7085 goto cp0_unimplemented;
7086 }
da80682b 7087 break;
8c0fdd85 7088 case 27:
7a387fff 7089 switch (sel) {
c2e19f3c
AM
7090 case 0:
7091 case 1:
7092 case 2:
7093 case 3:
d9bea114 7094 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
7095 rn = "CacheErr";
7096 break;
7a387fff 7097 default:
f31b035a 7098 goto cp0_unimplemented;
7a387fff 7099 }
8c0fdd85 7100 break;
873eb012
TS
7101 case 28:
7102 switch (sel) {
7103 case 0:
7a387fff
TS
7104 case 2:
7105 case 4:
7106 case 6:
284b731a
LA
7107 {
7108 TCGv_i64 tmp = tcg_temp_new_i64();
7109 tcg_gen_ld_i64(tmp, cpu_env, offsetof(CPUMIPSState, CP0_TagLo));
7110 gen_move_low32(arg, tmp);
7111 tcg_temp_free_i64(tmp);
7112 }
873eb012
TS
7113 rn = "TagLo";
7114 break;
7115 case 1:
7a387fff
TS
7116 case 3:
7117 case 5:
7118 case 7:
7db13fae 7119 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
873eb012
TS
7120 rn = "DataLo";
7121 break;
7122 default:
f31b035a 7123 goto cp0_unimplemented;
873eb012
TS
7124 }
7125 break;
8c0fdd85 7126 case 29:
7a387fff
TS
7127 switch (sel) {
7128 case 0:
7129 case 2:
7130 case 4:
7131 case 6:
7db13fae 7132 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
7a387fff
TS
7133 rn = "TagHi";
7134 break;
7135 case 1:
7136 case 3:
7137 case 5:
7138 case 7:
7db13fae 7139 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
7a387fff
TS
7140 rn = "DataHi";
7141 break;
7142 default:
f31b035a 7143 goto cp0_unimplemented;
7a387fff 7144 }
8c0fdd85 7145 break;
873eb012 7146 case 30:
7a387fff
TS
7147 switch (sel) {
7148 case 0:
7db13fae 7149 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
d9bea114 7150 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
7151 rn = "ErrorEPC";
7152 break;
7a387fff 7153 default:
f31b035a 7154 goto cp0_unimplemented;
7a387fff 7155 }
873eb012
TS
7156 break;
7157 case 31:
7a387fff
TS
7158 switch (sel) {
7159 case 0:
f0b3f3ae 7160 /* EJTAG support */
7db13fae 7161 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
7162 rn = "DESAVE";
7163 break;
c2e19f3c
AM
7164 case 2:
7165 case 3:
7166 case 4:
7167 case 5:
7168 case 6:
7169 case 7:
f31b035a
LA
7170 CP0_CHECK(ctx->kscrexist & (1 << sel));
7171 tcg_gen_ld_tl(arg, cpu_env,
7172 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
7173 tcg_gen_ext32s_tl(arg, arg);
7174 rn = "KScratch";
e98c0d17 7175 break;
7a387fff 7176 default:
f31b035a 7177 goto cp0_unimplemented;
7a387fff 7178 }
873eb012
TS
7179 break;
7180 default:
f31b035a 7181 goto cp0_unimplemented;
873eb012 7182 }
b44a7fb1 7183 trace_mips_translate_c0("mfc0", rn, reg, sel);
873eb012
TS
7184 return;
7185
f31b035a 7186cp0_unimplemented:
965447ee 7187 qemu_log_mask(LOG_UNIMP, "mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
f31b035a 7188 gen_mfc0_unimplemented(ctx, arg);
873eb012
TS
7189}
7190
d75c135e 7191static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
8c0fdd85 7192{
7a387fff
TS
7193 const char *rn = "invalid";
7194
e189e748 7195 if (sel != 0)
d75c135e 7196 check_insn(ctx, ISA_MIPS32);
e189e748 7197
eeb3bba8 7198 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
2e70f6ef 7199 gen_io_start();
bd79255d 7200 }
2e70f6ef 7201
8c0fdd85
TS
7202 switch (reg) {
7203 case 0:
7a387fff
TS
7204 switch (sel) {
7205 case 0:
895c2d04 7206 gen_helper_mtc0_index(cpu_env, arg);
7a387fff
TS
7207 rn = "Index";
7208 break;
7209 case 1:
f31b035a 7210 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7211 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
7a387fff 7212 rn = "MVPControl";
ead9360e 7213 break;
7a387fff 7214 case 2:
f31b035a 7215 CP0_CHECK(ctx->insn_flags & ASE_MT);
ead9360e 7216 /* ignored */
7a387fff 7217 rn = "MVPConf0";
ead9360e 7218 break;
7a387fff 7219 case 3:
f31b035a 7220 CP0_CHECK(ctx->insn_flags & ASE_MT);
ead9360e 7221 /* ignored */
7a387fff 7222 rn = "MVPConf1";
ead9360e 7223 break;
01bc435b
YK
7224 case 4:
7225 CP0_CHECK(ctx->vp);
7226 /* ignored */
7227 rn = "VPControl";
7228 break;
7a387fff 7229 default:
f31b035a 7230 goto cp0_unimplemented;
7a387fff 7231 }
8c0fdd85
TS
7232 break;
7233 case 1:
7a387fff
TS
7234 switch (sel) {
7235 case 0:
2423f660 7236 /* ignored */
7a387fff 7237 rn = "Random";
2423f660 7238 break;
7a387fff 7239 case 1:
f31b035a 7240 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7241 gen_helper_mtc0_vpecontrol(cpu_env, arg);
7a387fff 7242 rn = "VPEControl";
ead9360e 7243 break;
7a387fff 7244 case 2:
f31b035a 7245 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7246 gen_helper_mtc0_vpeconf0(cpu_env, arg);
7a387fff 7247 rn = "VPEConf0";
ead9360e 7248 break;
7a387fff 7249 case 3:
f31b035a 7250 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7251 gen_helper_mtc0_vpeconf1(cpu_env, arg);
7a387fff 7252 rn = "VPEConf1";
ead9360e 7253 break;
7a387fff 7254 case 4:
f31b035a 7255 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7256 gen_helper_mtc0_yqmask(cpu_env, arg);
7a387fff 7257 rn = "YQMask";
ead9360e 7258 break;
7a387fff 7259 case 5:
f31b035a 7260 CP0_CHECK(ctx->insn_flags & ASE_MT);
d54a299b
LA
7261 tcg_gen_st_tl(arg, cpu_env,
7262 offsetof(CPUMIPSState, CP0_VPESchedule));
7a387fff 7263 rn = "VPESchedule";
ead9360e 7264 break;
7a387fff 7265 case 6:
f31b035a 7266 CP0_CHECK(ctx->insn_flags & ASE_MT);
d54a299b
LA
7267 tcg_gen_st_tl(arg, cpu_env,
7268 offsetof(CPUMIPSState, CP0_VPEScheFBack));
7a387fff 7269 rn = "VPEScheFBack";
ead9360e 7270 break;
7a387fff 7271 case 7:
f31b035a 7272 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7273 gen_helper_mtc0_vpeopt(cpu_env, arg);
7a387fff 7274 rn = "VPEOpt";
ead9360e 7275 break;
7a387fff 7276 default:
f31b035a 7277 goto cp0_unimplemented;
7a387fff 7278 }
8c0fdd85
TS
7279 break;
7280 case 2:
7a387fff
TS
7281 switch (sel) {
7282 case 0:
895c2d04 7283 gen_helper_mtc0_entrylo0(cpu_env, arg);
2423f660
TS
7284 rn = "EntryLo0";
7285 break;
7a387fff 7286 case 1:
f31b035a 7287 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7288 gen_helper_mtc0_tcstatus(cpu_env, arg);
2423f660 7289 rn = "TCStatus";
ead9360e 7290 break;
7a387fff 7291 case 2:
f31b035a 7292 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7293 gen_helper_mtc0_tcbind(cpu_env, arg);
2423f660 7294 rn = "TCBind";
ead9360e 7295 break;
7a387fff 7296 case 3:
f31b035a 7297 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7298 gen_helper_mtc0_tcrestart(cpu_env, arg);
2423f660 7299 rn = "TCRestart";
ead9360e 7300 break;
7a387fff 7301 case 4:
f31b035a 7302 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7303 gen_helper_mtc0_tchalt(cpu_env, arg);
2423f660 7304 rn = "TCHalt";
ead9360e 7305 break;
7a387fff 7306 case 5:
f31b035a 7307 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7308 gen_helper_mtc0_tccontext(cpu_env, arg);
2423f660 7309 rn = "TCContext";
ead9360e 7310 break;
7a387fff 7311 case 6:
f31b035a 7312 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7313 gen_helper_mtc0_tcschedule(cpu_env, arg);
2423f660 7314 rn = "TCSchedule";
ead9360e 7315 break;
7a387fff 7316 case 7:
f31b035a 7317 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7318 gen_helper_mtc0_tcschefback(cpu_env, arg);
2423f660 7319 rn = "TCScheFBack";
ead9360e 7320 break;
7a387fff 7321 default:
f31b035a 7322 goto cp0_unimplemented;
7a387fff 7323 }
8c0fdd85
TS
7324 break;
7325 case 3:
7a387fff
TS
7326 switch (sel) {
7327 case 0:
895c2d04 7328 gen_helper_mtc0_entrylo1(cpu_env, arg);
2423f660
TS
7329 rn = "EntryLo1";
7330 break;
01bc435b
YK
7331 case 1:
7332 CP0_CHECK(ctx->vp);
7333 /* ignored */
7334 rn = "GlobalNumber";
7335 break;
7a387fff 7336 default:
f31b035a 7337 goto cp0_unimplemented;
876d4b07 7338 }
8c0fdd85
TS
7339 break;
7340 case 4:
7a387fff
TS
7341 switch (sel) {
7342 case 0:
895c2d04 7343 gen_helper_mtc0_context(cpu_env, arg);
2423f660
TS
7344 rn = "Context";
7345 break;
7a387fff 7346 case 1:
895c2d04 7347// gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
2423f660 7348 rn = "ContextConfig";
f31b035a 7349 goto cp0_unimplemented;
d279279e 7350 case 2:
f31b035a
LA
7351 CP0_CHECK(ctx->ulri);
7352 tcg_gen_st_tl(arg, cpu_env,
7353 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
7354 rn = "UserLocal";
d279279e 7355 break;
7a387fff 7356 default:
f31b035a 7357 goto cp0_unimplemented;
876d4b07 7358 }
8c0fdd85
TS
7359 break;
7360 case 5:
7a387fff
TS
7361 switch (sel) {
7362 case 0:
895c2d04 7363 gen_helper_mtc0_pagemask(cpu_env, arg);
2423f660
TS
7364 rn = "PageMask";
7365 break;
7a387fff 7366 case 1:
d75c135e 7367 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7368 gen_helper_mtc0_pagegrain(cpu_env, arg);
2423f660 7369 rn = "PageGrain";
eeb3bba8 7370 ctx->base.is_jmp = DISAS_STOP;
2423f660 7371 break;
cec56a73
JH
7372 case 2:
7373 CP0_CHECK(ctx->sc);
7374 gen_helper_mtc0_segctl0(cpu_env, arg);
7375 rn = "SegCtl0";
7376 break;
7377 case 3:
7378 CP0_CHECK(ctx->sc);
7379 gen_helper_mtc0_segctl1(cpu_env, arg);
7380 rn = "SegCtl1";
7381 break;
7382 case 4:
7383 CP0_CHECK(ctx->sc);
7384 gen_helper_mtc0_segctl2(cpu_env, arg);
7385 rn = "SegCtl2";
7386 break;
5e31fdd5
YK
7387 case 5:
7388 check_pw(ctx);
7389 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_PWBase));
7390 rn = "PWBase";
7391 break;
fa75ad14
YK
7392 case 6:
7393 check_pw(ctx);
7394 gen_helper_mtc0_pwfield(cpu_env, arg);
7395 rn = "PWField";
7396 break;
20b28ebc
YK
7397 case 7:
7398 check_pw(ctx);
7399 gen_helper_mtc0_pwsize(cpu_env, arg);
7400 rn = "PWSize";
7401 break;
7a387fff 7402 default:
f31b035a 7403 goto cp0_unimplemented;
876d4b07 7404 }
8c0fdd85
TS
7405 break;
7406 case 6:
7a387fff
TS
7407 switch (sel) {
7408 case 0:
895c2d04 7409 gen_helper_mtc0_wired(cpu_env, arg);
2423f660
TS
7410 rn = "Wired";
7411 break;
7a387fff 7412 case 1:
d75c135e 7413 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7414 gen_helper_mtc0_srsconf0(cpu_env, arg);
2423f660 7415 rn = "SRSConf0";
ead9360e 7416 break;
7a387fff 7417 case 2:
d75c135e 7418 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7419 gen_helper_mtc0_srsconf1(cpu_env, arg);
2423f660 7420 rn = "SRSConf1";
ead9360e 7421 break;
7a387fff 7422 case 3:
d75c135e 7423 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7424 gen_helper_mtc0_srsconf2(cpu_env, arg);
2423f660 7425 rn = "SRSConf2";
ead9360e 7426 break;
7a387fff 7427 case 4:
d75c135e 7428 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7429 gen_helper_mtc0_srsconf3(cpu_env, arg);
2423f660 7430 rn = "SRSConf3";
ead9360e 7431 break;
7a387fff 7432 case 5:
d75c135e 7433 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7434 gen_helper_mtc0_srsconf4(cpu_env, arg);
2423f660 7435 rn = "SRSConf4";
ead9360e 7436 break;
103be64c
YK
7437 case 6:
7438 check_pw(ctx);
7439 gen_helper_mtc0_pwctl(cpu_env, arg);
7440 rn = "PWCtl";
7441 break;
7a387fff 7442 default:
f31b035a 7443 goto cp0_unimplemented;
876d4b07 7444 }
8c0fdd85
TS
7445 break;
7446 case 7:
7a387fff
TS
7447 switch (sel) {
7448 case 0:
d75c135e 7449 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7450 gen_helper_mtc0_hwrena(cpu_env, arg);
eeb3bba8 7451 ctx->base.is_jmp = DISAS_STOP;
2423f660
TS
7452 rn = "HWREna";
7453 break;
7a387fff 7454 default:
f31b035a 7455 goto cp0_unimplemented;
876d4b07 7456 }
8c0fdd85
TS
7457 break;
7458 case 8:
aea14095
LA
7459 switch (sel) {
7460 case 0:
7461 /* ignored */
7462 rn = "BadVAddr";
7463 break;
7464 case 1:
7465 /* ignored */
7466 rn = "BadInstr";
7467 break;
7468 case 2:
7469 /* ignored */
7470 rn = "BadInstrP";
7471 break;
25beba9b
SM
7472 case 3:
7473 /* ignored */
7474 rn = "BadInstrX";
7475 break;
aea14095 7476 default:
f31b035a 7477 goto cp0_unimplemented;
aea14095 7478 }
8c0fdd85
TS
7479 break;
7480 case 9:
7a387fff
TS
7481 switch (sel) {
7482 case 0:
895c2d04 7483 gen_helper_mtc0_count(cpu_env, arg);
2423f660
TS
7484 rn = "Count";
7485 break;
876d4b07 7486 /* 6,7 are implementation dependent */
7a387fff 7487 default:
f31b035a 7488 goto cp0_unimplemented;
876d4b07 7489 }
8c0fdd85
TS
7490 break;
7491 case 10:
7a387fff
TS
7492 switch (sel) {
7493 case 0:
895c2d04 7494 gen_helper_mtc0_entryhi(cpu_env, arg);
2423f660
TS
7495 rn = "EntryHi";
7496 break;
7a387fff 7497 default:
f31b035a 7498 goto cp0_unimplemented;
876d4b07 7499 }
8c0fdd85
TS
7500 break;
7501 case 11:
7a387fff
TS
7502 switch (sel) {
7503 case 0:
895c2d04 7504 gen_helper_mtc0_compare(cpu_env, arg);
2423f660
TS
7505 rn = "Compare";
7506 break;
7507 /* 6,7 are implementation dependent */
7a387fff 7508 default:
f31b035a 7509 goto cp0_unimplemented;
876d4b07 7510 }
8c0fdd85
TS
7511 break;
7512 case 12:
7a387fff
TS
7513 switch (sel) {
7514 case 0:
867abc7e 7515 save_cpu_state(ctx, 1);
895c2d04 7516 gen_helper_mtc0_status(cpu_env, arg);
b28425ba 7517 /* DISAS_STOP isn't good enough here, hflags may have changed. */
eeb3bba8
EC
7518 gen_save_pc(ctx->base.pc_next + 4);
7519 ctx->base.is_jmp = DISAS_EXIT;
2423f660
TS
7520 rn = "Status";
7521 break;
7a387fff 7522 case 1:
d75c135e 7523 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7524 gen_helper_mtc0_intctl(cpu_env, arg);
8487327a 7525 /* Stop translation as we may have switched the execution mode */
eeb3bba8 7526 ctx->base.is_jmp = DISAS_STOP;
2423f660
TS
7527 rn = "IntCtl";
7528 break;
7a387fff 7529 case 2:
d75c135e 7530 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7531 gen_helper_mtc0_srsctl(cpu_env, arg);
8487327a 7532 /* Stop translation as we may have switched the execution mode */
eeb3bba8 7533 ctx->base.is_jmp = DISAS_STOP;
2423f660
TS
7534 rn = "SRSCtl";
7535 break;
7a387fff 7536 case 3:
d75c135e 7537 check_insn(ctx, ISA_MIPS32R2);
7db13fae 7538 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
8487327a 7539 /* Stop translation as we may have switched the execution mode */
eeb3bba8 7540 ctx->base.is_jmp = DISAS_STOP;
2423f660 7541 rn = "SRSMap";
fd88b6ab 7542 break;
7a387fff 7543 default:
f31b035a 7544 goto cp0_unimplemented;
876d4b07 7545 }
8c0fdd85
TS
7546 break;
7547 case 13:
7a387fff
TS
7548 switch (sel) {
7549 case 0:
867abc7e 7550 save_cpu_state(ctx, 1);
895c2d04 7551 gen_helper_mtc0_cause(cpu_env, arg);
b28425ba
EC
7552 /* Stop translation as we may have triggered an interrupt.
7553 * DISAS_STOP isn't sufficient, we need to ensure we break out of
7554 * translated code to check for pending interrupts. */
eeb3bba8
EC
7555 gen_save_pc(ctx->base.pc_next + 4);
7556 ctx->base.is_jmp = DISAS_EXIT;
2423f660
TS
7557 rn = "Cause";
7558 break;
7a387fff 7559 default:
f31b035a 7560 goto cp0_unimplemented;
876d4b07 7561 }
8c0fdd85
TS
7562 break;
7563 case 14:
7a387fff
TS
7564 switch (sel) {
7565 case 0:
d54a299b 7566 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
2423f660
TS
7567 rn = "EPC";
7568 break;
7a387fff 7569 default:
f31b035a 7570 goto cp0_unimplemented;
876d4b07 7571 }
8c0fdd85
TS
7572 break;
7573 case 15:
7a387fff
TS
7574 switch (sel) {
7575 case 0:
2423f660
TS
7576 /* ignored */
7577 rn = "PRid";
7578 break;
7a387fff 7579 case 1:
d75c135e 7580 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7581 gen_helper_mtc0_ebase(cpu_env, arg);
2423f660
TS
7582 rn = "EBase";
7583 break;
7a387fff 7584 default:
f31b035a 7585 goto cp0_unimplemented;
1579a72e 7586 }
8c0fdd85
TS
7587 break;
7588 case 16:
7589 switch (sel) {
7590 case 0:
895c2d04 7591 gen_helper_mtc0_config0(cpu_env, arg);
7a387fff 7592 rn = "Config";
2423f660 7593 /* Stop translation as we may have switched the execution mode */
eeb3bba8 7594 ctx->base.is_jmp = DISAS_STOP;
7a387fff
TS
7595 break;
7596 case 1:
e397ee33 7597 /* ignored, read only */
7a387fff
TS
7598 rn = "Config1";
7599 break;
7600 case 2:
895c2d04 7601 gen_helper_mtc0_config2(cpu_env, arg);
7a387fff 7602 rn = "Config2";
2423f660 7603 /* Stop translation as we may have switched the execution mode */
eeb3bba8 7604 ctx->base.is_jmp = DISAS_STOP;
8c0fdd85 7605 break;
7a387fff 7606 case 3:
90f12d73 7607 gen_helper_mtc0_config3(cpu_env, arg);
7a387fff 7608 rn = "Config3";
90f12d73 7609 /* Stop translation as we may have switched the execution mode */
eeb3bba8 7610 ctx->base.is_jmp = DISAS_STOP;
7a387fff 7611 break;
b4160af1
PJ
7612 case 4:
7613 gen_helper_mtc0_config4(cpu_env, arg);
7614 rn = "Config4";
eeb3bba8 7615 ctx->base.is_jmp = DISAS_STOP;
b4160af1 7616 break;
b4dd99a3
PJ
7617 case 5:
7618 gen_helper_mtc0_config5(cpu_env, arg);
7619 rn = "Config5";
7620 /* Stop translation as we may have switched the execution mode */
eeb3bba8 7621 ctx->base.is_jmp = DISAS_STOP;
b4dd99a3 7622 break;
e397ee33
TS
7623 /* 6,7 are implementation dependent */
7624 case 6:
7625 /* ignored */
7626 rn = "Config6";
7627 break;
7628 case 7:
7629 /* ignored */
7630 rn = "Config7";
7631 break;
8c0fdd85
TS
7632 default:
7633 rn = "Invalid config selector";
f31b035a 7634 goto cp0_unimplemented;
8c0fdd85
TS
7635 }
7636 break;
7637 case 17:
7a387fff
TS
7638 switch (sel) {
7639 case 0:
895c2d04 7640 gen_helper_mtc0_lladdr(cpu_env, arg);
2423f660
TS
7641 rn = "LLAddr";
7642 break;
f6d4dd81
YK
7643 case 1:
7644 CP0_CHECK(ctx->mrp);
7645 gen_helper_mtc0_maar(cpu_env, arg);
7646 rn = "MAAR";
7647 break;
7648 case 2:
7649 CP0_CHECK(ctx->mrp);
7650 gen_helper_mtc0_maari(cpu_env, arg);
7651 rn = "MAARI";
7652 break;
7a387fff 7653 default:
f31b035a 7654 goto cp0_unimplemented;
7a387fff 7655 }
8c0fdd85
TS
7656 break;
7657 case 18:
7a387fff 7658 switch (sel) {
c2e19f3c
AM
7659 case 0:
7660 case 1:
7661 case 2:
7662 case 3:
7663 case 4:
7664 case 5:
7665 case 6:
7666 case 7:
fa192d49 7667 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
895c2d04 7668 gen_helper_0e1i(mtc0_watchlo, arg, sel);
2423f660
TS
7669 rn = "WatchLo";
7670 break;
7a387fff 7671 default:
f31b035a 7672 goto cp0_unimplemented;
7a387fff 7673 }
8c0fdd85
TS
7674 break;
7675 case 19:
7a387fff 7676 switch (sel) {
c2e19f3c
AM
7677 case 0:
7678 case 1:
7679 case 2:
7680 case 3:
7681 case 4:
7682 case 5:
7683 case 6:
7684 case 7:
fa192d49 7685 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
895c2d04 7686 gen_helper_0e1i(mtc0_watchhi, arg, sel);
2423f660
TS
7687 rn = "WatchHi";
7688 break;
7a387fff 7689 default:
f31b035a 7690 goto cp0_unimplemented;
7a387fff 7691 }
8c0fdd85
TS
7692 break;
7693 case 20:
7a387fff
TS
7694 switch (sel) {
7695 case 0:
d26bc211 7696#if defined(TARGET_MIPS64)
d75c135e 7697 check_insn(ctx, ISA_MIPS3);
895c2d04 7698 gen_helper_mtc0_xcontext(cpu_env, arg);
2423f660
TS
7699 rn = "XContext";
7700 break;
703eaf37 7701#endif
7a387fff 7702 default:
f31b035a 7703 goto cp0_unimplemented;
7a387fff 7704 }
8c0fdd85
TS
7705 break;
7706 case 21:
7a387fff 7707 /* Officially reserved, but sel 0 is used for R1x000 framemask */
f31b035a 7708 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
7a387fff
TS
7709 switch (sel) {
7710 case 0:
895c2d04 7711 gen_helper_mtc0_framemask(cpu_env, arg);
2423f660
TS
7712 rn = "Framemask";
7713 break;
7a387fff 7714 default:
f31b035a 7715 goto cp0_unimplemented;
7a387fff
TS
7716 }
7717 break;
8c0fdd85 7718 case 22:
7a387fff
TS
7719 /* ignored */
7720 rn = "Diagnostic"; /* implementation dependent */
2423f660 7721 break;
8c0fdd85 7722 case 23:
7a387fff
TS
7723 switch (sel) {
7724 case 0:
895c2d04 7725 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
b28425ba 7726 /* DISAS_STOP isn't good enough here, hflags may have changed. */
eeb3bba8
EC
7727 gen_save_pc(ctx->base.pc_next + 4);
7728 ctx->base.is_jmp = DISAS_EXIT;
2423f660
TS
7729 rn = "Debug";
7730 break;
7a387fff 7731 case 1:
895c2d04 7732// gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
2423f660 7733 rn = "TraceControl";
8487327a 7734 /* Stop translation as we may have switched the execution mode */
eeb3bba8 7735 ctx->base.is_jmp = DISAS_STOP;
3570d7f6 7736 goto cp0_unimplemented;
7a387fff 7737 case 2:
895c2d04 7738// gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
2423f660 7739 rn = "TraceControl2";
8487327a 7740 /* Stop translation as we may have switched the execution mode */
eeb3bba8 7741 ctx->base.is_jmp = DISAS_STOP;
3570d7f6 7742 goto cp0_unimplemented;
7a387fff 7743 case 3:
8487327a 7744 /* Stop translation as we may have switched the execution mode */
eeb3bba8 7745 ctx->base.is_jmp = DISAS_STOP;
895c2d04 7746// gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
2423f660 7747 rn = "UserTraceData";
8487327a 7748 /* Stop translation as we may have switched the execution mode */
eeb3bba8 7749 ctx->base.is_jmp = DISAS_STOP;
3570d7f6 7750 goto cp0_unimplemented;
7a387fff 7751 case 4:
895c2d04 7752// gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
8487327a 7753 /* Stop translation as we may have switched the execution mode */
eeb3bba8 7754 ctx->base.is_jmp = DISAS_STOP;
2423f660 7755 rn = "TraceBPC";
3570d7f6 7756 goto cp0_unimplemented;
7a387fff 7757 default:
f31b035a 7758 goto cp0_unimplemented;
7a387fff 7759 }
8c0fdd85
TS
7760 break;
7761 case 24:
7a387fff
TS
7762 switch (sel) {
7763 case 0:
f1aa6320 7764 /* EJTAG support */
d54a299b 7765 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
2423f660
TS
7766 rn = "DEPC";
7767 break;
7a387fff 7768 default:
f31b035a 7769 goto cp0_unimplemented;
7a387fff 7770 }
8c0fdd85
TS
7771 break;
7772 case 25:
7a387fff
TS
7773 switch (sel) {
7774 case 0:
895c2d04 7775 gen_helper_mtc0_performance0(cpu_env, arg);
2423f660
TS
7776 rn = "Performance0";
7777 break;
7a387fff 7778 case 1:
d9bea114 7779// gen_helper_mtc0_performance1(arg);
2423f660 7780 rn = "Performance1";
3570d7f6 7781 goto cp0_unimplemented;
7a387fff 7782 case 2:
d9bea114 7783// gen_helper_mtc0_performance2(arg);
2423f660 7784 rn = "Performance2";
3570d7f6 7785 goto cp0_unimplemented;
7a387fff 7786 case 3:
d9bea114 7787// gen_helper_mtc0_performance3(arg);
2423f660 7788 rn = "Performance3";
3570d7f6 7789 goto cp0_unimplemented;
7a387fff 7790 case 4:
d9bea114 7791// gen_helper_mtc0_performance4(arg);
2423f660 7792 rn = "Performance4";
3570d7f6 7793 goto cp0_unimplemented;
7a387fff 7794 case 5:
d9bea114 7795// gen_helper_mtc0_performance5(arg);
2423f660 7796 rn = "Performance5";
3570d7f6 7797 goto cp0_unimplemented;
7a387fff 7798 case 6:
d9bea114 7799// gen_helper_mtc0_performance6(arg);
2423f660 7800 rn = "Performance6";
3570d7f6 7801 goto cp0_unimplemented;
7a387fff 7802 case 7:
d9bea114 7803// gen_helper_mtc0_performance7(arg);
2423f660 7804 rn = "Performance7";
3570d7f6 7805 goto cp0_unimplemented;
7a387fff 7806 default:
f31b035a 7807 goto cp0_unimplemented;
7a387fff 7808 }
8c0fdd85
TS
7809 break;
7810 case 26:
0d74a222
LA
7811 switch (sel) {
7812 case 0:
7813 gen_helper_mtc0_errctl(cpu_env, arg);
eeb3bba8 7814 ctx->base.is_jmp = DISAS_STOP;
0d74a222
LA
7815 rn = "ErrCtl";
7816 break;
7817 default:
7818 goto cp0_unimplemented;
7819 }
2423f660 7820 break;
8c0fdd85 7821 case 27:
7a387fff 7822 switch (sel) {
c2e19f3c
AM
7823 case 0:
7824 case 1:
7825 case 2:
7826 case 3:
2423f660
TS
7827 /* ignored */
7828 rn = "CacheErr";
7829 break;
7a387fff 7830 default:
f31b035a 7831 goto cp0_unimplemented;
7a387fff 7832 }
8c0fdd85
TS
7833 break;
7834 case 28:
7835 switch (sel) {
7836 case 0:
7a387fff
TS
7837 case 2:
7838 case 4:
7839 case 6:
895c2d04 7840 gen_helper_mtc0_taglo(cpu_env, arg);
8c0fdd85
TS
7841 rn = "TagLo";
7842 break;
7a387fff
TS
7843 case 1:
7844 case 3:
7845 case 5:
7846 case 7:
895c2d04 7847 gen_helper_mtc0_datalo(cpu_env, arg);
7a387fff
TS
7848 rn = "DataLo";
7849 break;
8c0fdd85 7850 default:
f31b035a 7851 goto cp0_unimplemented;
8c0fdd85
TS
7852 }
7853 break;
7854 case 29:
7a387fff
TS
7855 switch (sel) {
7856 case 0:
7857 case 2:
7858 case 4:
7859 case 6:
895c2d04 7860 gen_helper_mtc0_taghi(cpu_env, arg);
7a387fff
TS
7861 rn = "TagHi";
7862 break;
7863 case 1:
7864 case 3:
7865 case 5:
7866 case 7:
895c2d04 7867 gen_helper_mtc0_datahi(cpu_env, arg);
7a387fff
TS
7868 rn = "DataHi";
7869 break;
7870 default:
7871 rn = "invalid sel";
f31b035a 7872 goto cp0_unimplemented;
7a387fff 7873 }
8c0fdd85
TS
7874 break;
7875 case 30:
7a387fff
TS
7876 switch (sel) {
7877 case 0:
d54a299b 7878 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
2423f660
TS
7879 rn = "ErrorEPC";
7880 break;
7a387fff 7881 default:
f31b035a 7882 goto cp0_unimplemented;
7a387fff 7883 }
8c0fdd85
TS
7884 break;
7885 case 31:
7a387fff
TS
7886 switch (sel) {
7887 case 0:
f1aa6320 7888 /* EJTAG support */
7db13fae 7889 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
7890 rn = "DESAVE";
7891 break;
c2e19f3c
AM
7892 case 2:
7893 case 3:
7894 case 4:
7895 case 5:
7896 case 6:
7897 case 7:
f31b035a
LA
7898 CP0_CHECK(ctx->kscrexist & (1 << sel));
7899 tcg_gen_st_tl(arg, cpu_env,
7900 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
7901 rn = "KScratch";
e98c0d17 7902 break;
7a387fff 7903 default:
f31b035a 7904 goto cp0_unimplemented;
7a387fff 7905 }
8c0fdd85
TS
7906 break;
7907 default:
f31b035a 7908 goto cp0_unimplemented;
8c0fdd85 7909 }
b44a7fb1
PMD
7910 trace_mips_translate_c0("mtc0", rn, reg, sel);
7911
bf20dc07 7912 /* For simplicity assume that all writes can cause interrupts. */
eeb3bba8 7913 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
2e70f6ef 7914 gen_io_end();
b28425ba 7915 /* DISAS_STOP isn't sufficient, we need to ensure we break out of
b74cddcb 7916 * translated code to check for pending interrupts. */
eeb3bba8
EC
7917 gen_save_pc(ctx->base.pc_next + 4);
7918 ctx->base.is_jmp = DISAS_EXIT;
2e70f6ef 7919 }
8c0fdd85
TS
7920 return;
7921
f31b035a 7922cp0_unimplemented:
965447ee 7923 qemu_log_mask(LOG_UNIMP, "mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
8c0fdd85
TS
7924}
7925
d26bc211 7926#if defined(TARGET_MIPS64)
d75c135e 7927static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
9c2149c8
TS
7928{
7929 const char *rn = "invalid";
7930
e189e748 7931 if (sel != 0)
d75c135e 7932 check_insn(ctx, ISA_MIPS64);
e189e748 7933
9c2149c8
TS
7934 switch (reg) {
7935 case 0:
7936 switch (sel) {
7937 case 0:
7db13fae 7938 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
9c2149c8
TS
7939 rn = "Index";
7940 break;
7941 case 1:
f31b035a 7942 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7943 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
9c2149c8 7944 rn = "MVPControl";
ead9360e 7945 break;
9c2149c8 7946 case 2:
f31b035a 7947 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7948 gen_helper_mfc0_mvpconf0(arg, cpu_env);
9c2149c8 7949 rn = "MVPConf0";
ead9360e 7950 break;
9c2149c8 7951 case 3:
f31b035a 7952 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7953 gen_helper_mfc0_mvpconf1(arg, cpu_env);
9c2149c8 7954 rn = "MVPConf1";
ead9360e 7955 break;
01bc435b
YK
7956 case 4:
7957 CP0_CHECK(ctx->vp);
7958 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl));
7959 rn = "VPControl";
7960 break;
9c2149c8 7961 default:
f31b035a 7962 goto cp0_unimplemented;
9c2149c8
TS
7963 }
7964 break;
7965 case 1:
7966 switch (sel) {
7967 case 0:
f31b035a 7968 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
895c2d04 7969 gen_helper_mfc0_random(arg, cpu_env);
9c2149c8 7970 rn = "Random";
2423f660 7971 break;
9c2149c8 7972 case 1:
f31b035a 7973 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 7974 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
9c2149c8 7975 rn = "VPEControl";
ead9360e 7976 break;
9c2149c8 7977 case 2:
f31b035a 7978 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 7979 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
9c2149c8 7980 rn = "VPEConf0";
ead9360e 7981 break;
9c2149c8 7982 case 3:
f31b035a 7983 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 7984 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
9c2149c8 7985 rn = "VPEConf1";
ead9360e 7986 break;
9c2149c8 7987 case 4:
f31b035a 7988 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 7989 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_YQMask));
9c2149c8 7990 rn = "YQMask";
ead9360e 7991 break;
9c2149c8 7992 case 5:
f31b035a 7993 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 7994 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
9c2149c8 7995 rn = "VPESchedule";
ead9360e 7996 break;
9c2149c8 7997 case 6:
f31b035a 7998 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 7999 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
9c2149c8 8000 rn = "VPEScheFBack";
ead9360e 8001 break;
9c2149c8 8002 case 7:
f31b035a 8003 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 8004 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
9c2149c8 8005 rn = "VPEOpt";
ead9360e 8006 break;
9c2149c8 8007 default:
f31b035a 8008 goto cp0_unimplemented;
9c2149c8
TS
8009 }
8010 break;
8011 case 2:
8012 switch (sel) {
8013 case 0:
7db13fae 8014 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
2423f660
TS
8015 rn = "EntryLo0";
8016 break;
9c2149c8 8017 case 1:
f31b035a 8018 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 8019 gen_helper_mfc0_tcstatus(arg, cpu_env);
2423f660 8020 rn = "TCStatus";
ead9360e 8021 break;
9c2149c8 8022 case 2:
f31b035a 8023 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 8024 gen_helper_mfc0_tcbind(arg, cpu_env);
2423f660 8025 rn = "TCBind";
ead9360e 8026 break;
9c2149c8 8027 case 3:
f31b035a 8028 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 8029 gen_helper_dmfc0_tcrestart(arg, cpu_env);
2423f660 8030 rn = "TCRestart";
ead9360e 8031 break;
9c2149c8 8032 case 4:
f31b035a 8033 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 8034 gen_helper_dmfc0_tchalt(arg, cpu_env);
2423f660 8035 rn = "TCHalt";
ead9360e 8036 break;
9c2149c8 8037 case 5:
f31b035a 8038 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 8039 gen_helper_dmfc0_tccontext(arg, cpu_env);
2423f660 8040 rn = "TCContext";
ead9360e 8041 break;
9c2149c8 8042 case 6:
f31b035a 8043 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 8044 gen_helper_dmfc0_tcschedule(arg, cpu_env);
2423f660 8045 rn = "TCSchedule";
ead9360e 8046 break;
9c2149c8 8047 case 7:
f31b035a 8048 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 8049 gen_helper_dmfc0_tcschefback(arg, cpu_env);
2423f660 8050 rn = "TCScheFBack";
ead9360e 8051 break;
9c2149c8 8052 default:
f31b035a 8053 goto cp0_unimplemented;
9c2149c8
TS
8054 }
8055 break;
8056 case 3:
8057 switch (sel) {
8058 case 0:
7db13fae 8059 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
2423f660
TS
8060 rn = "EntryLo1";
8061 break;
01bc435b
YK
8062 case 1:
8063 CP0_CHECK(ctx->vp);
8064 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber));
8065 rn = "GlobalNumber";
8066 break;
9c2149c8 8067 default:
f31b035a 8068 goto cp0_unimplemented;
1579a72e 8069 }
9c2149c8
TS
8070 break;
8071 case 4:
8072 switch (sel) {
8073 case 0:
7db13fae 8074 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
2423f660
TS
8075 rn = "Context";
8076 break;
9c2149c8 8077 case 1:
d9bea114 8078// gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
2423f660 8079 rn = "ContextConfig";
f31b035a 8080 goto cp0_unimplemented;
d279279e 8081 case 2:
f31b035a
LA
8082 CP0_CHECK(ctx->ulri);
8083 tcg_gen_ld_tl(arg, cpu_env,
8084 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
8085 rn = "UserLocal";
d279279e 8086 break;
9c2149c8 8087 default:
f31b035a 8088 goto cp0_unimplemented;
876d4b07 8089 }
9c2149c8
TS
8090 break;
8091 case 5:
8092 switch (sel) {
8093 case 0:
7db13fae 8094 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
2423f660
TS
8095 rn = "PageMask";
8096 break;
9c2149c8 8097 case 1:
d75c135e 8098 check_insn(ctx, ISA_MIPS32R2);
7db13fae 8099 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
2423f660
TS
8100 rn = "PageGrain";
8101 break;
cec56a73
JH
8102 case 2:
8103 CP0_CHECK(ctx->sc);
8104 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl0));
8105 rn = "SegCtl0";
8106 break;
8107 case 3:
8108 CP0_CHECK(ctx->sc);
8109 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl1));
8110 rn = "SegCtl1";
8111 break;
8112 case 4:
8113 CP0_CHECK(ctx->sc);
8114 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl2));
8115 rn = "SegCtl2";
8116 break;
5e31fdd5
YK
8117 case 5:
8118 check_pw(ctx);
8119 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWBase));
8120 rn = "PWBase";
8121 break;
fa75ad14
YK
8122 case 6:
8123 check_pw(ctx);
8124 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWField));
8125 rn = "PWField";
8126 break;
20b28ebc
YK
8127 case 7:
8128 check_pw(ctx);
8129 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWSize));
8130 rn = "PWSize";
8131 break;
9c2149c8 8132 default:
f31b035a 8133 goto cp0_unimplemented;
876d4b07 8134 }
9c2149c8
TS
8135 break;
8136 case 6:
8137 switch (sel) {
8138 case 0:
7db13fae 8139 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
2423f660
TS
8140 rn = "Wired";
8141 break;
9c2149c8 8142 case 1:
d75c135e 8143 check_insn(ctx, ISA_MIPS32R2);
7db13fae 8144 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
2423f660 8145 rn = "SRSConf0";
ead9360e 8146 break;
9c2149c8 8147 case 2:
d75c135e 8148 check_insn(ctx, ISA_MIPS32R2);
7db13fae 8149 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
2423f660 8150 rn = "SRSConf1";
ead9360e 8151 break;
9c2149c8 8152 case 3:
d75c135e 8153 check_insn(ctx, ISA_MIPS32R2);
7db13fae 8154 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
2423f660 8155 rn = "SRSConf2";
ead9360e 8156 break;
9c2149c8 8157 case 4:
d75c135e 8158 check_insn(ctx, ISA_MIPS32R2);
7db13fae 8159 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
2423f660 8160 rn = "SRSConf3";
ead9360e 8161 break;
9c2149c8 8162 case 5:
d75c135e 8163 check_insn(ctx, ISA_MIPS32R2);
7db13fae 8164 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
2423f660 8165 rn = "SRSConf4";
ead9360e 8166 break;
103be64c
YK
8167 case 6:
8168 check_pw(ctx);
8169 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWCtl));
8170 rn = "PWCtl";
8171 break;
9c2149c8 8172 default:
f31b035a 8173 goto cp0_unimplemented;
876d4b07 8174 }
9c2149c8
TS
8175 break;
8176 case 7:
8177 switch (sel) {
8178 case 0:
d75c135e 8179 check_insn(ctx, ISA_MIPS32R2);
7db13fae 8180 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
2423f660
TS
8181 rn = "HWREna";
8182 break;
9c2149c8 8183 default:
f31b035a 8184 goto cp0_unimplemented;
876d4b07 8185 }
9c2149c8
TS
8186 break;
8187 case 8:
8188 switch (sel) {
8189 case 0:
7db13fae 8190 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
f0b3f3ae 8191 rn = "BadVAddr";
2423f660 8192 break;
aea14095 8193 case 1:
f31b035a
LA
8194 CP0_CHECK(ctx->bi);
8195 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
8196 rn = "BadInstr";
aea14095
LA
8197 break;
8198 case 2:
f31b035a
LA
8199 CP0_CHECK(ctx->bp);
8200 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
8201 rn = "BadInstrP";
aea14095 8202 break;
25beba9b
SM
8203 case 3:
8204 CP0_CHECK(ctx->bi);
8205 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrX));
8206 tcg_gen_andi_tl(arg, arg, ~0xffff);
8207 rn = "BadInstrX";
8208 break;
9c2149c8 8209 default:
f31b035a 8210 goto cp0_unimplemented;
876d4b07 8211 }
9c2149c8
TS
8212 break;
8213 case 9:
8214 switch (sel) {
8215 case 0:
2e70f6ef 8216 /* Mark as an IO operation because we read the time. */
eeb3bba8 8217 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
2e70f6ef 8218 gen_io_start();
bd79255d 8219 }
895c2d04 8220 gen_helper_mfc0_count(arg, cpu_env);
eeb3bba8 8221 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
2e70f6ef 8222 gen_io_end();
2e70f6ef 8223 }
55807224 8224 /* Break the TB to be able to take timer interrupts immediately
b28425ba
EC
8225 after reading count. DISAS_STOP isn't sufficient, we need to
8226 ensure we break completely out of translated code. */
eeb3bba8
EC
8227 gen_save_pc(ctx->base.pc_next + 4);
8228 ctx->base.is_jmp = DISAS_EXIT;
2423f660
TS
8229 rn = "Count";
8230 break;
8231 /* 6,7 are implementation dependent */
9c2149c8 8232 default:
f31b035a 8233 goto cp0_unimplemented;
876d4b07 8234 }
9c2149c8
TS
8235 break;
8236 case 10:
8237 switch (sel) {
8238 case 0:
7db13fae 8239 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
2423f660
TS
8240 rn = "EntryHi";
8241 break;
9c2149c8 8242 default:
f31b035a 8243 goto cp0_unimplemented;
876d4b07 8244 }
9c2149c8
TS
8245 break;
8246 case 11:
8247 switch (sel) {
8248 case 0:
7db13fae 8249 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
2423f660
TS
8250 rn = "Compare";
8251 break;
876d4b07 8252 /* 6,7 are implementation dependent */
9c2149c8 8253 default:
f31b035a 8254 goto cp0_unimplemented;
876d4b07 8255 }
9c2149c8
TS
8256 break;
8257 case 12:
8258 switch (sel) {
8259 case 0:
7db13fae 8260 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
2423f660
TS
8261 rn = "Status";
8262 break;
9c2149c8 8263 case 1:
d75c135e 8264 check_insn(ctx, ISA_MIPS32R2);
7db13fae 8265 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
2423f660
TS
8266 rn = "IntCtl";
8267 break;
9c2149c8 8268 case 2:
d75c135e 8269 check_insn(ctx, ISA_MIPS32R2);
7db13fae 8270 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
2423f660
TS
8271 rn = "SRSCtl";
8272 break;
9c2149c8 8273 case 3:
d75c135e 8274 check_insn(ctx, ISA_MIPS32R2);
7db13fae 8275 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
2423f660
TS
8276 rn = "SRSMap";
8277 break;
9c2149c8 8278 default:
f31b035a 8279 goto cp0_unimplemented;
876d4b07 8280 }
9c2149c8
TS
8281 break;
8282 case 13:
8283 switch (sel) {
8284 case 0:
7db13fae 8285 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
2423f660
TS
8286 rn = "Cause";
8287 break;
9c2149c8 8288 default:
f31b035a 8289 goto cp0_unimplemented;
876d4b07 8290 }
9c2149c8
TS
8291 break;
8292 case 14:
8293 switch (sel) {
8294 case 0:
7db13fae 8295 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
2423f660
TS
8296 rn = "EPC";
8297 break;
9c2149c8 8298 default:
f31b035a 8299 goto cp0_unimplemented;
876d4b07 8300 }
9c2149c8
TS
8301 break;
8302 case 15:
8303 switch (sel) {
8304 case 0:
7db13fae 8305 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
2423f660
TS
8306 rn = "PRid";
8307 break;
9c2149c8 8308 case 1:
d75c135e 8309 check_insn(ctx, ISA_MIPS32R2);
74dbf824 8310 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EBase));
2423f660
TS
8311 rn = "EBase";
8312 break;
c870e3f5
YK
8313 case 3:
8314 check_insn(ctx, ISA_MIPS32R2);
8315 CP0_CHECK(ctx->cmgcr);
8316 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase));
8317 rn = "CMGCRBase";
8318 break;
9c2149c8 8319 default:
f31b035a 8320 goto cp0_unimplemented;
876d4b07 8321 }
9c2149c8
TS
8322 break;
8323 case 16:
8324 switch (sel) {
8325 case 0:
7db13fae 8326 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
9c2149c8
TS
8327 rn = "Config";
8328 break;
8329 case 1:
7db13fae 8330 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
9c2149c8
TS
8331 rn = "Config1";
8332 break;
8333 case 2:
7db13fae 8334 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
9c2149c8
TS
8335 rn = "Config2";
8336 break;
8337 case 3:
7db13fae 8338 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
9c2149c8
TS
8339 rn = "Config3";
8340 break;
faf1f68b
LA
8341 case 4:
8342 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
8343 rn = "Config4";
8344 break;
8345 case 5:
8346 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
8347 rn = "Config5";
8348 break;
9c2149c8 8349 /* 6,7 are implementation dependent */
f0b3f3ae 8350 case 6:
7db13fae 8351 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
f0b3f3ae
TS
8352 rn = "Config6";
8353 break;
8354 case 7:
7db13fae 8355 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
f0b3f3ae
TS
8356 rn = "Config7";
8357 break;
9c2149c8 8358 default:
f31b035a 8359 goto cp0_unimplemented;
9c2149c8
TS
8360 }
8361 break;
8362 case 17:
8363 switch (sel) {
8364 case 0:
895c2d04 8365 gen_helper_dmfc0_lladdr(arg, cpu_env);
2423f660
TS
8366 rn = "LLAddr";
8367 break;
f6d4dd81
YK
8368 case 1:
8369 CP0_CHECK(ctx->mrp);
8370 gen_helper_dmfc0_maar(arg, cpu_env);
8371 rn = "MAAR";
8372 break;
8373 case 2:
8374 CP0_CHECK(ctx->mrp);
8375 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI));
8376 rn = "MAARI";
8377 break;
9c2149c8 8378 default:
f31b035a 8379 goto cp0_unimplemented;
9c2149c8
TS
8380 }
8381 break;
8382 case 18:
8383 switch (sel) {
c2e19f3c
AM
8384 case 0:
8385 case 1:
8386 case 2:
8387 case 3:
8388 case 4:
8389 case 5:
8390 case 6:
8391 case 7:
fa192d49 8392 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
895c2d04 8393 gen_helper_1e0i(dmfc0_watchlo, arg, sel);
2423f660
TS
8394 rn = "WatchLo";
8395 break;
9c2149c8 8396 default:
f31b035a 8397 goto cp0_unimplemented;
9c2149c8
TS
8398 }
8399 break;
8400 case 19:
8401 switch (sel) {
c2e19f3c
AM
8402 case 0:
8403 case 1:
8404 case 2:
8405 case 3:
8406 case 4:
8407 case 5:
8408 case 6:
8409 case 7:
fa192d49 8410 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
895c2d04 8411 gen_helper_1e0i(mfc0_watchhi, arg, sel);
2423f660
TS
8412 rn = "WatchHi";
8413 break;
9c2149c8 8414 default:
f31b035a 8415 goto cp0_unimplemented;
9c2149c8
TS
8416 }
8417 break;
8418 case 20:
8419 switch (sel) {
8420 case 0:
d75c135e 8421 check_insn(ctx, ISA_MIPS3);
7db13fae 8422 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
2423f660
TS
8423 rn = "XContext";
8424 break;
9c2149c8 8425 default:
f31b035a 8426 goto cp0_unimplemented;
9c2149c8
TS
8427 }
8428 break;
8429 case 21:
8430 /* Officially reserved, but sel 0 is used for R1x000 framemask */
f31b035a 8431 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
9c2149c8
TS
8432 switch (sel) {
8433 case 0:
7db13fae 8434 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
2423f660
TS
8435 rn = "Framemask";
8436 break;
9c2149c8 8437 default:
f31b035a 8438 goto cp0_unimplemented;
9c2149c8
TS
8439 }
8440 break;
8441 case 22:
d9bea114 8442 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
8443 rn = "'Diagnostic"; /* implementation dependent */
8444 break;
9c2149c8
TS
8445 case 23:
8446 switch (sel) {
8447 case 0:
895c2d04 8448 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
2423f660
TS
8449 rn = "Debug";
8450 break;
9c2149c8 8451 case 1:
895c2d04 8452// gen_helper_dmfc0_tracecontrol(arg, cpu_env); /* PDtrace support */
2423f660 8453 rn = "TraceControl";
3570d7f6 8454 goto cp0_unimplemented;
9c2149c8 8455 case 2:
895c2d04 8456// gen_helper_dmfc0_tracecontrol2(arg, cpu_env); /* PDtrace support */
2423f660 8457 rn = "TraceControl2";
3570d7f6 8458 goto cp0_unimplemented;
9c2149c8 8459 case 3:
895c2d04 8460// gen_helper_dmfc0_usertracedata(arg, cpu_env); /* PDtrace support */
2423f660 8461 rn = "UserTraceData";
3570d7f6 8462 goto cp0_unimplemented;
9c2149c8 8463 case 4:
895c2d04 8464// gen_helper_dmfc0_tracebpc(arg, cpu_env); /* PDtrace support */
2423f660 8465 rn = "TraceBPC";
3570d7f6 8466 goto cp0_unimplemented;
9c2149c8 8467 default:
f31b035a 8468 goto cp0_unimplemented;
9c2149c8
TS
8469 }
8470 break;
8471 case 24:
8472 switch (sel) {
8473 case 0:
f0b3f3ae 8474 /* EJTAG support */
7db13fae 8475 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
2423f660
TS
8476 rn = "DEPC";
8477 break;
9c2149c8 8478 default:
f31b035a 8479 goto cp0_unimplemented;
9c2149c8
TS
8480 }
8481 break;
8482 case 25:
8483 switch (sel) {
8484 case 0:
7db13fae 8485 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
2423f660 8486 rn = "Performance0";
9c2149c8
TS
8487 break;
8488 case 1:
d9bea114 8489// gen_helper_dmfc0_performance1(arg);
2423f660 8490 rn = "Performance1";
3570d7f6 8491 goto cp0_unimplemented;
9c2149c8 8492 case 2:
d9bea114 8493// gen_helper_dmfc0_performance2(arg);
2423f660 8494 rn = "Performance2";
3570d7f6 8495 goto cp0_unimplemented;
9c2149c8 8496 case 3:
d9bea114 8497// gen_helper_dmfc0_performance3(arg);
2423f660 8498 rn = "Performance3";
3570d7f6 8499 goto cp0_unimplemented;
9c2149c8 8500 case 4:
d9bea114 8501// gen_helper_dmfc0_performance4(arg);
2423f660 8502 rn = "Performance4";
3570d7f6 8503 goto cp0_unimplemented;
9c2149c8 8504 case 5:
d9bea114 8505// gen_helper_dmfc0_performance5(arg);
2423f660 8506 rn = "Performance5";
3570d7f6 8507 goto cp0_unimplemented;
9c2149c8 8508 case 6:
d9bea114 8509// gen_helper_dmfc0_performance6(arg);
2423f660 8510 rn = "Performance6";
3570d7f6 8511 goto cp0_unimplemented;
9c2149c8 8512 case 7:
d9bea114 8513// gen_helper_dmfc0_performance7(arg);
2423f660 8514 rn = "Performance7";
3570d7f6 8515 goto cp0_unimplemented;
9c2149c8 8516 default:
f31b035a 8517 goto cp0_unimplemented;
9c2149c8
TS
8518 }
8519 break;
8520 case 26:
0d74a222
LA
8521 switch (sel) {
8522 case 0:
8523 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl));
8524 rn = "ErrCtl";
8525 break;
8526 default:
8527 goto cp0_unimplemented;
8528 }
da80682b 8529 break;
9c2149c8
TS
8530 case 27:
8531 switch (sel) {
8532 /* ignored */
c2e19f3c
AM
8533 case 0:
8534 case 1:
8535 case 2:
8536 case 3:
d9bea114 8537 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
8538 rn = "CacheErr";
8539 break;
9c2149c8 8540 default:
f31b035a 8541 goto cp0_unimplemented;
9c2149c8
TS
8542 }
8543 break;
8544 case 28:
8545 switch (sel) {
8546 case 0:
8547 case 2:
8548 case 4:
8549 case 6:
7db13fae 8550 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
9c2149c8
TS
8551 rn = "TagLo";
8552 break;
8553 case 1:
8554 case 3:
8555 case 5:
8556 case 7:
7db13fae 8557 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
9c2149c8
TS
8558 rn = "DataLo";
8559 break;
8560 default:
f31b035a 8561 goto cp0_unimplemented;
9c2149c8
TS
8562 }
8563 break;
8564 case 29:
8565 switch (sel) {
8566 case 0:
8567 case 2:
8568 case 4:
8569 case 6:
7db13fae 8570 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
9c2149c8
TS
8571 rn = "TagHi";
8572 break;
8573 case 1:
8574 case 3:
8575 case 5:
8576 case 7:
7db13fae 8577 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
9c2149c8
TS
8578 rn = "DataHi";
8579 break;
8580 default:
f31b035a 8581 goto cp0_unimplemented;
9c2149c8
TS
8582 }
8583 break;
8584 case 30:
8585 switch (sel) {
8586 case 0:
7db13fae 8587 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
2423f660
TS
8588 rn = "ErrorEPC";
8589 break;
9c2149c8 8590 default:
f31b035a 8591 goto cp0_unimplemented;
9c2149c8
TS
8592 }
8593 break;
8594 case 31:
8595 switch (sel) {
8596 case 0:
f0b3f3ae 8597 /* EJTAG support */
7db13fae 8598 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
8599 rn = "DESAVE";
8600 break;
c2e19f3c
AM
8601 case 2:
8602 case 3:
8603 case 4:
8604 case 5:
8605 case 6:
8606 case 7:
f31b035a
LA
8607 CP0_CHECK(ctx->kscrexist & (1 << sel));
8608 tcg_gen_ld_tl(arg, cpu_env,
8609 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
8610 rn = "KScratch";
e98c0d17 8611 break;
9c2149c8 8612 default:
f31b035a 8613 goto cp0_unimplemented;
9c2149c8
TS
8614 }
8615 break;
8616 default:
f31b035a 8617 goto cp0_unimplemented;
9c2149c8 8618 }
b44a7fb1 8619 trace_mips_translate_c0("dmfc0", rn, reg, sel);
9c2149c8
TS
8620 return;
8621
f31b035a 8622cp0_unimplemented:
965447ee 8623 qemu_log_mask(LOG_UNIMP, "dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
f31b035a 8624 gen_mfc0_unimplemented(ctx, arg);
9c2149c8
TS
8625}
8626
d75c135e 8627static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
9c2149c8
TS
8628{
8629 const char *rn = "invalid";
8630
e189e748 8631 if (sel != 0)
d75c135e 8632 check_insn(ctx, ISA_MIPS64);
e189e748 8633
eeb3bba8 8634 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
2e70f6ef 8635 gen_io_start();
bd79255d 8636 }
2e70f6ef 8637
9c2149c8
TS
8638 switch (reg) {
8639 case 0:
8640 switch (sel) {
8641 case 0:
895c2d04 8642 gen_helper_mtc0_index(cpu_env, arg);
9c2149c8
TS
8643 rn = "Index";
8644 break;
8645 case 1:
f31b035a 8646 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 8647 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
9c2149c8 8648 rn = "MVPControl";
ead9360e 8649 break;
9c2149c8 8650 case 2:
f31b035a 8651 CP0_CHECK(ctx->insn_flags & ASE_MT);
ead9360e 8652 /* ignored */
9c2149c8 8653 rn = "MVPConf0";
ead9360e 8654 break;
9c2149c8 8655 case 3:
f31b035a 8656 CP0_CHECK(ctx->insn_flags & ASE_MT);
ead9360e 8657 /* ignored */
9c2149c8 8658 rn = "MVPConf1";
ead9360e 8659 break;
01bc435b
YK
8660 case 4:
8661 CP0_CHECK(ctx->vp);
8662 /* ignored */
8663 rn = "VPControl";
8664 break;
9c2149c8 8665 default:
f31b035a 8666 goto cp0_unimplemented;
9c2149c8
TS
8667 }
8668 break;
8669 case 1:
8670 switch (sel) {
8671 case 0:
2423f660 8672 /* ignored */
9c2149c8 8673 rn = "Random";
2423f660 8674 break;
9c2149c8 8675 case 1:
f31b035a 8676 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 8677 gen_helper_mtc0_vpecontrol(cpu_env, arg);
9c2149c8 8678 rn = "VPEControl";
ead9360e 8679 break;
9c2149c8 8680 case 2:
f31b035a 8681 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 8682 gen_helper_mtc0_vpeconf0(cpu_env, arg);
9c2149c8 8683 rn = "VPEConf0";
ead9360e 8684 break;
9c2149c8 8685 case 3:
f31b035a 8686 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 8687 gen_helper_mtc0_vpeconf1(cpu_env, arg);
9c2149c8 8688 rn = "VPEConf1";
ead9360e 8689 break;
9c2149c8 8690 case 4:
f31b035a 8691 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 8692 gen_helper_mtc0_yqmask(cpu_env, arg);
9c2149c8 8693 rn = "YQMask";
ead9360e 8694 break;
9c2149c8 8695 case 5:
f31b035a 8696 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 8697 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
9c2149c8 8698 rn = "VPESchedule";
ead9360e 8699 break;
9c2149c8 8700 case 6:
f31b035a 8701 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 8702 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
9c2149c8 8703 rn = "VPEScheFBack";
ead9360e 8704 break;
9c2149c8 8705 case 7:
f31b035a 8706 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 8707 gen_helper_mtc0_vpeopt(cpu_env, arg);
9c2149c8 8708 rn = "VPEOpt";
ead9360e 8709 break;
9c2149c8 8710 default:
f31b035a 8711 goto cp0_unimplemented;
9c2149c8
TS
8712 }
8713 break;
8714 case 2:
8715 switch (sel) {
8716 case 0:
7207c7f9 8717 gen_helper_dmtc0_entrylo0(cpu_env, arg);
2423f660
TS
8718 rn = "EntryLo0";
8719 break;
9c2149c8 8720 case 1:
f31b035a 8721 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 8722 gen_helper_mtc0_tcstatus(cpu_env, arg);
2423f660 8723 rn = "TCStatus";
ead9360e 8724 break;
9c2149c8 8725 case 2:
f31b035a 8726 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 8727 gen_helper_mtc0_tcbind(cpu_env, arg);
2423f660 8728 rn = "TCBind";
ead9360e 8729 break;
9c2149c8 8730 case 3:
f31b035a 8731 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 8732 gen_helper_mtc0_tcrestart(cpu_env, arg);
2423f660 8733 rn = "TCRestart";
ead9360e 8734 break;
9c2149c8 8735 case 4:
f31b035a 8736 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 8737 gen_helper_mtc0_tchalt(cpu_env, arg);
2423f660 8738 rn = "TCHalt";
ead9360e 8739 break;
9c2149c8 8740 case 5:
f31b035a 8741 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 8742 gen_helper_mtc0_tccontext(cpu_env, arg);
2423f660 8743 rn = "TCContext";
ead9360e 8744 break;
9c2149c8 8745 case 6:
f31b035a 8746 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 8747 gen_helper_mtc0_tcschedule(cpu_env, arg);
2423f660 8748 rn = "TCSchedule";
ead9360e 8749 break;
9c2149c8 8750 case 7:
f31b035a 8751 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 8752 gen_helper_mtc0_tcschefback(cpu_env, arg);
2423f660 8753 rn = "TCScheFBack";
ead9360e 8754 break;
9c2149c8 8755 default:
f31b035a 8756 goto cp0_unimplemented;
9c2149c8
TS
8757 }
8758 break;
8759 case 3:
8760 switch (sel) {
8761 case 0:
7207c7f9 8762 gen_helper_dmtc0_entrylo1(cpu_env, arg);
2423f660
TS
8763 rn = "EntryLo1";
8764 break;
01bc435b
YK
8765 case 1:
8766 CP0_CHECK(ctx->vp);
8767 /* ignored */
8768 rn = "GlobalNumber";
8769 break;
9c2149c8 8770 default:
f31b035a 8771 goto cp0_unimplemented;
876d4b07 8772 }
9c2149c8
TS
8773 break;
8774 case 4:
8775 switch (sel) {
8776 case 0:
895c2d04 8777 gen_helper_mtc0_context(cpu_env, arg);
2423f660
TS
8778 rn = "Context";
8779 break;
9c2149c8 8780 case 1:
895c2d04 8781// gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
2423f660 8782 rn = "ContextConfig";
f31b035a 8783 goto cp0_unimplemented;
d279279e 8784 case 2:
f31b035a
LA
8785 CP0_CHECK(ctx->ulri);
8786 tcg_gen_st_tl(arg, cpu_env,
8787 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
8788 rn = "UserLocal";
d279279e 8789 break;
9c2149c8 8790 default:
f31b035a 8791 goto cp0_unimplemented;
876d4b07 8792 }
9c2149c8
TS
8793 break;
8794 case 5:
8795 switch (sel) {
8796 case 0:
895c2d04 8797 gen_helper_mtc0_pagemask(cpu_env, arg);
2423f660
TS
8798 rn = "PageMask";
8799 break;
9c2149c8 8800 case 1:
d75c135e 8801 check_insn(ctx, ISA_MIPS32R2);
895c2d04 8802 gen_helper_mtc0_pagegrain(cpu_env, arg);
2423f660
TS
8803 rn = "PageGrain";
8804 break;
cec56a73
JH
8805 case 2:
8806 CP0_CHECK(ctx->sc);
8807 gen_helper_mtc0_segctl0(cpu_env, arg);
8808 rn = "SegCtl0";
8809 break;
8810 case 3:
8811 CP0_CHECK(ctx->sc);
8812 gen_helper_mtc0_segctl1(cpu_env, arg);
8813 rn = "SegCtl1";
8814 break;
8815 case 4:
8816 CP0_CHECK(ctx->sc);
8817 gen_helper_mtc0_segctl2(cpu_env, arg);
8818 rn = "SegCtl2";
8819 break;
5e31fdd5
YK
8820 case 5:
8821 check_pw(ctx);
8822 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWBase));
8823 rn = "PWBase";
8824 break;
fa75ad14
YK
8825 case 6:
8826 check_pw(ctx);
8827 gen_helper_mtc0_pwfield(cpu_env, arg);
8828 rn = "PWField";
8829 break;
20b28ebc
YK
8830 case 7:
8831 check_pw(ctx);
8832 gen_helper_mtc0_pwsize(cpu_env, arg);
8833 rn = "PWSize";
8834 break;
9c2149c8 8835 default:
f31b035a 8836 goto cp0_unimplemented;
876d4b07 8837 }
9c2149c8
TS
8838 break;
8839 case 6:
8840 switch (sel) {
8841 case 0:
895c2d04 8842 gen_helper_mtc0_wired(cpu_env, arg);
2423f660
TS
8843 rn = "Wired";
8844 break;
9c2149c8 8845 case 1:
d75c135e 8846 check_insn(ctx, ISA_MIPS32R2);
895c2d04 8847 gen_helper_mtc0_srsconf0(cpu_env, arg);
2423f660 8848 rn = "SRSConf0";
ead9360e 8849 break;
9c2149c8 8850 case 2:
d75c135e 8851 check_insn(ctx, ISA_MIPS32R2);
895c2d04 8852 gen_helper_mtc0_srsconf1(cpu_env, arg);
2423f660 8853 rn = "SRSConf1";
ead9360e 8854 break;
9c2149c8 8855 case 3:
d75c135e 8856 check_insn(ctx, ISA_MIPS32R2);
895c2d04 8857 gen_helper_mtc0_srsconf2(cpu_env, arg);
2423f660 8858 rn = "SRSConf2";
ead9360e 8859 break;
9c2149c8 8860 case 4:
d75c135e 8861 check_insn(ctx, ISA_MIPS32R2);
895c2d04 8862 gen_helper_mtc0_srsconf3(cpu_env, arg);
2423f660 8863 rn = "SRSConf3";
ead9360e 8864 break;
9c2149c8 8865 case 5:
d75c135e 8866 check_insn(ctx, ISA_MIPS32R2);
895c2d04 8867 gen_helper_mtc0_srsconf4(cpu_env, arg);
2423f660 8868 rn = "SRSConf4";
ead9360e 8869 break;
103be64c
YK
8870 case 6:
8871 check_pw(ctx);
8872 gen_helper_mtc0_pwctl(cpu_env, arg);
8873 rn = "PWCtl";
8874 break;
9c2149c8 8875 default:
f31b035a 8876 goto cp0_unimplemented;
876d4b07 8877 }
9c2149c8
TS
8878 break;
8879 case 7:
8880 switch (sel) {
8881 case 0:
d75c135e 8882 check_insn(ctx, ISA_MIPS32R2);
895c2d04 8883 gen_helper_mtc0_hwrena(cpu_env, arg);
eeb3bba8 8884 ctx->base.is_jmp = DISAS_STOP;
2423f660
TS
8885 rn = "HWREna";
8886 break;
9c2149c8 8887 default:
f31b035a 8888 goto cp0_unimplemented;
876d4b07 8889 }
9c2149c8
TS
8890 break;
8891 case 8:
aea14095
LA
8892 switch (sel) {
8893 case 0:
8894 /* ignored */
8895 rn = "BadVAddr";
8896 break;
8897 case 1:
8898 /* ignored */
8899 rn = "BadInstr";
8900 break;
8901 case 2:
8902 /* ignored */
8903 rn = "BadInstrP";
8904 break;
25beba9b
SM
8905 case 3:
8906 /* ignored */
8907 rn = "BadInstrX";
8908 break;
aea14095 8909 default:
f31b035a 8910 goto cp0_unimplemented;
aea14095 8911 }
9c2149c8
TS
8912 break;
8913 case 9:
8914 switch (sel) {
8915 case 0:
895c2d04 8916 gen_helper_mtc0_count(cpu_env, arg);
2423f660
TS
8917 rn = "Count";
8918 break;
876d4b07 8919 /* 6,7 are implementation dependent */
9c2149c8 8920 default:
f31b035a 8921 goto cp0_unimplemented;
876d4b07
TS
8922 }
8923 /* Stop translation as we may have switched the execution mode */
eeb3bba8 8924 ctx->base.is_jmp = DISAS_STOP;
9c2149c8
TS
8925 break;
8926 case 10:
8927 switch (sel) {
8928 case 0:
895c2d04 8929 gen_helper_mtc0_entryhi(cpu_env, arg);
2423f660
TS
8930 rn = "EntryHi";
8931 break;
9c2149c8 8932 default:
f31b035a 8933 goto cp0_unimplemented;
876d4b07 8934 }
9c2149c8
TS
8935 break;
8936 case 11:
8937 switch (sel) {
8938 case 0:
895c2d04 8939 gen_helper_mtc0_compare(cpu_env, arg);
2423f660
TS
8940 rn = "Compare";
8941 break;
876d4b07 8942 /* 6,7 are implementation dependent */
9c2149c8 8943 default:
f31b035a 8944 goto cp0_unimplemented;
876d4b07 8945 }
de9a95f0 8946 /* Stop translation as we may have switched the execution mode */
eeb3bba8 8947 ctx->base.is_jmp = DISAS_STOP;
9c2149c8
TS
8948 break;
8949 case 12:
8950 switch (sel) {
8951 case 0:
867abc7e 8952 save_cpu_state(ctx, 1);
895c2d04 8953 gen_helper_mtc0_status(cpu_env, arg);
b28425ba 8954 /* DISAS_STOP isn't good enough here, hflags may have changed. */
eeb3bba8
EC
8955 gen_save_pc(ctx->base.pc_next + 4);
8956 ctx->base.is_jmp = DISAS_EXIT;
2423f660
TS
8957 rn = "Status";
8958 break;
9c2149c8 8959 case 1:
d75c135e 8960 check_insn(ctx, ISA_MIPS32R2);
895c2d04 8961 gen_helper_mtc0_intctl(cpu_env, arg);
8487327a 8962 /* Stop translation as we may have switched the execution mode */
eeb3bba8 8963 ctx->base.is_jmp = DISAS_STOP;
2423f660
TS
8964 rn = "IntCtl";
8965 break;
9c2149c8 8966 case 2:
d75c135e 8967 check_insn(ctx, ISA_MIPS32R2);
895c2d04 8968 gen_helper_mtc0_srsctl(cpu_env, arg);
8487327a 8969 /* Stop translation as we may have switched the execution mode */
eeb3bba8 8970 ctx->base.is_jmp = DISAS_STOP;
2423f660
TS
8971 rn = "SRSCtl";
8972 break;
9c2149c8 8973 case 3:
d75c135e 8974 check_insn(ctx, ISA_MIPS32R2);
7db13fae 8975 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
8487327a 8976 /* Stop translation as we may have switched the execution mode */
eeb3bba8 8977 ctx->base.is_jmp = DISAS_STOP;
2423f660
TS
8978 rn = "SRSMap";
8979 break;
8980 default:
f31b035a 8981 goto cp0_unimplemented;
876d4b07 8982 }
9c2149c8
TS
8983 break;
8984 case 13:
8985 switch (sel) {
8986 case 0:
867abc7e 8987 save_cpu_state(ctx, 1);
895c2d04 8988 gen_helper_mtc0_cause(cpu_env, arg);
b28425ba
EC
8989 /* Stop translation as we may have triggered an interrupt.
8990 * DISAS_STOP isn't sufficient, we need to ensure we break out of
8991 * translated code to check for pending interrupts. */
eeb3bba8
EC
8992 gen_save_pc(ctx->base.pc_next + 4);
8993 ctx->base.is_jmp = DISAS_EXIT;
2423f660
TS
8994 rn = "Cause";
8995 break;
9c2149c8 8996 default:
f31b035a 8997 goto cp0_unimplemented;
876d4b07 8998 }
9c2149c8
TS
8999 break;
9000 case 14:
9001 switch (sel) {
9002 case 0:
7db13fae 9003 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
2423f660
TS
9004 rn = "EPC";
9005 break;
9c2149c8 9006 default:
f31b035a 9007 goto cp0_unimplemented;
876d4b07 9008 }
9c2149c8
TS
9009 break;
9010 case 15:
9011 switch (sel) {
9012 case 0:
2423f660
TS
9013 /* ignored */
9014 rn = "PRid";
9015 break;
9c2149c8 9016 case 1:
d75c135e 9017 check_insn(ctx, ISA_MIPS32R2);
895c2d04 9018 gen_helper_mtc0_ebase(cpu_env, arg);
2423f660
TS
9019 rn = "EBase";
9020 break;
9c2149c8 9021 default:
f31b035a 9022 goto cp0_unimplemented;
876d4b07 9023 }
9c2149c8
TS
9024 break;
9025 case 16:
9026 switch (sel) {
9027 case 0:
895c2d04 9028 gen_helper_mtc0_config0(cpu_env, arg);
9c2149c8 9029 rn = "Config";
2423f660 9030 /* Stop translation as we may have switched the execution mode */
eeb3bba8 9031 ctx->base.is_jmp = DISAS_STOP;
9c2149c8
TS
9032 break;
9033 case 1:
1fc7bf6e 9034 /* ignored, read only */
9c2149c8
TS
9035 rn = "Config1";
9036 break;
9037 case 2:
895c2d04 9038 gen_helper_mtc0_config2(cpu_env, arg);
9c2149c8 9039 rn = "Config2";
2423f660 9040 /* Stop translation as we may have switched the execution mode */
eeb3bba8 9041 ctx->base.is_jmp = DISAS_STOP;
9c2149c8
TS
9042 break;
9043 case 3:
90f12d73 9044 gen_helper_mtc0_config3(cpu_env, arg);
9c2149c8 9045 rn = "Config3";
90f12d73 9046 /* Stop translation as we may have switched the execution mode */
eeb3bba8 9047 ctx->base.is_jmp = DISAS_STOP;
9c2149c8 9048 break;
faf1f68b
LA
9049 case 4:
9050 /* currently ignored */
9051 rn = "Config4";
9052 break;
9053 case 5:
9054 gen_helper_mtc0_config5(cpu_env, arg);
9055 rn = "Config5";
9056 /* Stop translation as we may have switched the execution mode */
eeb3bba8 9057 ctx->base.is_jmp = DISAS_STOP;
faf1f68b 9058 break;
9c2149c8
TS
9059 /* 6,7 are implementation dependent */
9060 default:
9061 rn = "Invalid config selector";
f31b035a 9062 goto cp0_unimplemented;
9c2149c8 9063 }
9c2149c8
TS
9064 break;
9065 case 17:
9066 switch (sel) {
9067 case 0:
895c2d04 9068 gen_helper_mtc0_lladdr(cpu_env, arg);
2423f660
TS
9069 rn = "LLAddr";
9070 break;
f6d4dd81
YK
9071 case 1:
9072 CP0_CHECK(ctx->mrp);
9073 gen_helper_mtc0_maar(cpu_env, arg);
9074 rn = "MAAR";
9075 break;
9076 case 2:
9077 CP0_CHECK(ctx->mrp);
9078 gen_helper_mtc0_maari(cpu_env, arg);
9079 rn = "MAARI";
9080 break;
9c2149c8 9081 default:
f31b035a 9082 goto cp0_unimplemented;
9c2149c8
TS
9083 }
9084 break;
9085 case 18:
9086 switch (sel) {
c2e19f3c
AM
9087 case 0:
9088 case 1:
9089 case 2:
9090 case 3:
9091 case 4:
9092 case 5:
9093 case 6:
9094 case 7:
fa192d49 9095 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
895c2d04 9096 gen_helper_0e1i(mtc0_watchlo, arg, sel);
2423f660
TS
9097 rn = "WatchLo";
9098 break;
9c2149c8 9099 default:
f31b035a 9100 goto cp0_unimplemented;
9c2149c8
TS
9101 }
9102 break;
9103 case 19:
9104 switch (sel) {
c2e19f3c
AM
9105 case 0:
9106 case 1:
9107 case 2:
9108 case 3:
9109 case 4:
9110 case 5:
9111 case 6:
9112 case 7:
fa192d49 9113 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
895c2d04 9114 gen_helper_0e1i(mtc0_watchhi, arg, sel);
2423f660
TS
9115 rn = "WatchHi";
9116 break;
9c2149c8 9117 default:
f31b035a 9118 goto cp0_unimplemented;
9c2149c8
TS
9119 }
9120 break;
9121 case 20:
9122 switch (sel) {
9123 case 0:
d75c135e 9124 check_insn(ctx, ISA_MIPS3);
895c2d04 9125 gen_helper_mtc0_xcontext(cpu_env, arg);
2423f660
TS
9126 rn = "XContext";
9127 break;
9c2149c8 9128 default:
f31b035a 9129 goto cp0_unimplemented;
9c2149c8
TS
9130 }
9131 break;
9132 case 21:
9133 /* Officially reserved, but sel 0 is used for R1x000 framemask */
f31b035a 9134 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
9c2149c8
TS
9135 switch (sel) {
9136 case 0:
895c2d04 9137 gen_helper_mtc0_framemask(cpu_env, arg);
2423f660
TS
9138 rn = "Framemask";
9139 break;
9c2149c8 9140 default:
f31b035a 9141 goto cp0_unimplemented;
9c2149c8
TS
9142 }
9143 break;
9144 case 22:
9145 /* ignored */
9146 rn = "Diagnostic"; /* implementation dependent */
876d4b07 9147 break;
9c2149c8
TS
9148 case 23:
9149 switch (sel) {
9150 case 0:
895c2d04 9151 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
b28425ba 9152 /* DISAS_STOP isn't good enough here, hflags may have changed. */
eeb3bba8
EC
9153 gen_save_pc(ctx->base.pc_next + 4);
9154 ctx->base.is_jmp = DISAS_EXIT;
2423f660
TS
9155 rn = "Debug";
9156 break;
9c2149c8 9157 case 1:
895c2d04 9158// gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
8487327a 9159 /* Stop translation as we may have switched the execution mode */
eeb3bba8 9160 ctx->base.is_jmp = DISAS_STOP;
2423f660 9161 rn = "TraceControl";
3570d7f6 9162 goto cp0_unimplemented;
9c2149c8 9163 case 2:
895c2d04 9164// gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
8487327a 9165 /* Stop translation as we may have switched the execution mode */
eeb3bba8 9166 ctx->base.is_jmp = DISAS_STOP;
2423f660 9167 rn = "TraceControl2";
3570d7f6 9168 goto cp0_unimplemented;
9c2149c8 9169 case 3:
895c2d04 9170// gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
8487327a 9171 /* Stop translation as we may have switched the execution mode */
eeb3bba8 9172 ctx->base.is_jmp = DISAS_STOP;
2423f660 9173 rn = "UserTraceData";
3570d7f6 9174 goto cp0_unimplemented;
9c2149c8 9175 case 4:
895c2d04 9176// gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
8487327a 9177 /* Stop translation as we may have switched the execution mode */
eeb3bba8 9178 ctx->base.is_jmp = DISAS_STOP;
2423f660 9179 rn = "TraceBPC";
3570d7f6 9180 goto cp0_unimplemented;
9c2149c8 9181 default:
f31b035a 9182 goto cp0_unimplemented;
9c2149c8 9183 }
9c2149c8
TS
9184 break;
9185 case 24:
9186 switch (sel) {
9187 case 0:
f1aa6320 9188 /* EJTAG support */
7db13fae 9189 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
2423f660
TS
9190 rn = "DEPC";
9191 break;
9c2149c8 9192 default:
f31b035a 9193 goto cp0_unimplemented;
9c2149c8
TS
9194 }
9195 break;
9196 case 25:
9197 switch (sel) {
9198 case 0:
895c2d04 9199 gen_helper_mtc0_performance0(cpu_env, arg);
2423f660
TS
9200 rn = "Performance0";
9201 break;
9c2149c8 9202 case 1:
895c2d04 9203// gen_helper_mtc0_performance1(cpu_env, arg);
2423f660 9204 rn = "Performance1";
3570d7f6 9205 goto cp0_unimplemented;
9c2149c8 9206 case 2:
895c2d04 9207// gen_helper_mtc0_performance2(cpu_env, arg);
2423f660 9208 rn = "Performance2";
3570d7f6 9209 goto cp0_unimplemented;
9c2149c8 9210 case 3:
895c2d04 9211// gen_helper_mtc0_performance3(cpu_env, arg);
2423f660 9212 rn = "Performance3";
3570d7f6 9213 goto cp0_unimplemented;
9c2149c8 9214 case 4:
895c2d04 9215// gen_helper_mtc0_performance4(cpu_env, arg);
2423f660 9216 rn = "Performance4";
3570d7f6 9217 goto cp0_unimplemented;
9c2149c8 9218 case 5:
895c2d04 9219// gen_helper_mtc0_performance5(cpu_env, arg);
2423f660 9220 rn = "Performance5";
3570d7f6 9221 goto cp0_unimplemented;
9c2149c8 9222 case 6:
895c2d04 9223// gen_helper_mtc0_performance6(cpu_env, arg);
2423f660 9224 rn = "Performance6";
3570d7f6 9225 goto cp0_unimplemented;
9c2149c8 9226 case 7:
895c2d04 9227// gen_helper_mtc0_performance7(cpu_env, arg);
2423f660 9228 rn = "Performance7";
3570d7f6 9229 goto cp0_unimplemented;
9c2149c8 9230 default:
f31b035a 9231 goto cp0_unimplemented;
9c2149c8 9232 }
876d4b07 9233 break;
9c2149c8 9234 case 26:
0d74a222
LA
9235 switch (sel) {
9236 case 0:
9237 gen_helper_mtc0_errctl(cpu_env, arg);
eeb3bba8 9238 ctx->base.is_jmp = DISAS_STOP;
0d74a222
LA
9239 rn = "ErrCtl";
9240 break;
9241 default:
9242 goto cp0_unimplemented;
9243 }
876d4b07 9244 break;
9c2149c8
TS
9245 case 27:
9246 switch (sel) {
c2e19f3c
AM
9247 case 0:
9248 case 1:
9249 case 2:
9250 case 3:
2423f660
TS
9251 /* ignored */
9252 rn = "CacheErr";
9253 break;
9c2149c8 9254 default:
f31b035a 9255 goto cp0_unimplemented;
9c2149c8 9256 }
876d4b07 9257 break;
9c2149c8
TS
9258 case 28:
9259 switch (sel) {
9260 case 0:
9261 case 2:
9262 case 4:
9263 case 6:
895c2d04 9264 gen_helper_mtc0_taglo(cpu_env, arg);
9c2149c8
TS
9265 rn = "TagLo";
9266 break;
9267 case 1:
9268 case 3:
9269 case 5:
9270 case 7:
895c2d04 9271 gen_helper_mtc0_datalo(cpu_env, arg);
9c2149c8
TS
9272 rn = "DataLo";
9273 break;
9274 default:
f31b035a 9275 goto cp0_unimplemented;
9c2149c8
TS
9276 }
9277 break;
9278 case 29:
9279 switch (sel) {
9280 case 0:
9281 case 2:
9282 case 4:
9283 case 6:
895c2d04 9284 gen_helper_mtc0_taghi(cpu_env, arg);
9c2149c8
TS
9285 rn = "TagHi";
9286 break;
9287 case 1:
9288 case 3:
9289 case 5:
9290 case 7:
895c2d04 9291 gen_helper_mtc0_datahi(cpu_env, arg);
9c2149c8
TS
9292 rn = "DataHi";
9293 break;
9294 default:
9295 rn = "invalid sel";
f31b035a 9296 goto cp0_unimplemented;
9c2149c8 9297 }
876d4b07 9298 break;
9c2149c8
TS
9299 case 30:
9300 switch (sel) {
9301 case 0:
7db13fae 9302 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
2423f660
TS
9303 rn = "ErrorEPC";
9304 break;
9c2149c8 9305 default:
f31b035a 9306 goto cp0_unimplemented;
9c2149c8
TS
9307 }
9308 break;
9309 case 31:
9310 switch (sel) {
9311 case 0:
f1aa6320 9312 /* EJTAG support */
7db13fae 9313 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
9314 rn = "DESAVE";
9315 break;
c2e19f3c
AM
9316 case 2:
9317 case 3:
9318 case 4:
9319 case 5:
9320 case 6:
9321 case 7:
f31b035a
LA
9322 CP0_CHECK(ctx->kscrexist & (1 << sel));
9323 tcg_gen_st_tl(arg, cpu_env,
9324 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
9325 rn = "KScratch";
e98c0d17 9326 break;
9c2149c8 9327 default:
f31b035a 9328 goto cp0_unimplemented;
9c2149c8 9329 }
9c2149c8
TS
9330 break;
9331 default:
f31b035a 9332 goto cp0_unimplemented;
9c2149c8 9333 }
b44a7fb1
PMD
9334 trace_mips_translate_c0("dmtc0", rn, reg, sel);
9335
bf20dc07 9336 /* For simplicity assume that all writes can cause interrupts. */
eeb3bba8 9337 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
2e70f6ef 9338 gen_io_end();
b28425ba 9339 /* DISAS_STOP isn't sufficient, we need to ensure we break out of
b74cddcb 9340 * translated code to check for pending interrupts. */
eeb3bba8
EC
9341 gen_save_pc(ctx->base.pc_next + 4);
9342 ctx->base.is_jmp = DISAS_EXIT;
2e70f6ef 9343 }
9c2149c8
TS
9344 return;
9345
f31b035a 9346cp0_unimplemented:
965447ee 9347 qemu_log_mask(LOG_UNIMP, "dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
9c2149c8 9348}
d26bc211 9349#endif /* TARGET_MIPS64 */
9c2149c8 9350
7db13fae 9351static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
ead9360e
TS
9352 int u, int sel, int h)
9353{
9354 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
a7812ae4 9355 TCGv t0 = tcg_temp_local_new();
ead9360e
TS
9356
9357 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
b5dc7732
TS
9358 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
9359 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
1a3fd9c3 9360 tcg_gen_movi_tl(t0, -1);
ead9360e
TS
9361 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
9362 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
1a3fd9c3 9363 tcg_gen_movi_tl(t0, -1);
ead9360e
TS
9364 else if (u == 0) {
9365 switch (rt) {
5a25ce94
EI
9366 case 1:
9367 switch (sel) {
9368 case 1:
895c2d04 9369 gen_helper_mftc0_vpecontrol(t0, cpu_env);
5a25ce94
EI
9370 break;
9371 case 2:
895c2d04 9372 gen_helper_mftc0_vpeconf0(t0, cpu_env);
5a25ce94
EI
9373 break;
9374 default:
9375 goto die;
9376 break;
9377 }
9378 break;
ead9360e
TS
9379 case 2:
9380 switch (sel) {
9381 case 1:
895c2d04 9382 gen_helper_mftc0_tcstatus(t0, cpu_env);
ead9360e
TS
9383 break;
9384 case 2:
895c2d04 9385 gen_helper_mftc0_tcbind(t0, cpu_env);
ead9360e
TS
9386 break;
9387 case 3:
895c2d04 9388 gen_helper_mftc0_tcrestart(t0, cpu_env);
ead9360e
TS
9389 break;
9390 case 4:
895c2d04 9391 gen_helper_mftc0_tchalt(t0, cpu_env);
ead9360e
TS
9392 break;
9393 case 5:
895c2d04 9394 gen_helper_mftc0_tccontext(t0, cpu_env);
ead9360e
TS
9395 break;
9396 case 6:
895c2d04 9397 gen_helper_mftc0_tcschedule(t0, cpu_env);
ead9360e
TS
9398 break;
9399 case 7:
895c2d04 9400 gen_helper_mftc0_tcschefback(t0, cpu_env);
ead9360e
TS
9401 break;
9402 default:
d75c135e 9403 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
9404 break;
9405 }
9406 break;
9407 case 10:
9408 switch (sel) {
9409 case 0:
895c2d04 9410 gen_helper_mftc0_entryhi(t0, cpu_env);
ead9360e
TS
9411 break;
9412 default:
d75c135e 9413 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
9414 break;
9415 }
9416 case 12:
9417 switch (sel) {
9418 case 0:
895c2d04 9419 gen_helper_mftc0_status(t0, cpu_env);
ead9360e
TS
9420 break;
9421 default:
d75c135e 9422 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
9423 break;
9424 }
5a25ce94
EI
9425 case 13:
9426 switch (sel) {
9427 case 0:
895c2d04 9428 gen_helper_mftc0_cause(t0, cpu_env);
5a25ce94
EI
9429 break;
9430 default:
9431 goto die;
9432 break;
9433 }
9434 break;
9435 case 14:
9436 switch (sel) {
9437 case 0:
895c2d04 9438 gen_helper_mftc0_epc(t0, cpu_env);
5a25ce94
EI
9439 break;
9440 default:
9441 goto die;
9442 break;
9443 }
9444 break;
9445 case 15:
9446 switch (sel) {
9447 case 1:
895c2d04 9448 gen_helper_mftc0_ebase(t0, cpu_env);
5a25ce94
EI
9449 break;
9450 default:
9451 goto die;
9452 break;
9453 }
9454 break;
9455 case 16:
9456 switch (sel) {
c2e19f3c
AM
9457 case 0:
9458 case 1:
9459 case 2:
9460 case 3:
9461 case 4:
9462 case 5:
9463 case 6:
9464 case 7:
895c2d04 9465 gen_helper_mftc0_configx(t0, cpu_env, tcg_const_tl(sel));
5a25ce94
EI
9466 break;
9467 default:
9468 goto die;
9469 break;
9470 }
9471 break;
ead9360e
TS
9472 case 23:
9473 switch (sel) {
9474 case 0:
895c2d04 9475 gen_helper_mftc0_debug(t0, cpu_env);
ead9360e
TS
9476 break;
9477 default:
d75c135e 9478 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
9479 break;
9480 }
9481 break;
9482 default:
d75c135e 9483 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
9484 }
9485 } else switch (sel) {
9486 /* GPR registers. */
9487 case 0:
895c2d04 9488 gen_helper_1e0i(mftgpr, t0, rt);
ead9360e
TS
9489 break;
9490 /* Auxiliary CPU registers */
9491 case 1:
9492 switch (rt) {
9493 case 0:
895c2d04 9494 gen_helper_1e0i(mftlo, t0, 0);
ead9360e
TS
9495 break;
9496 case 1:
895c2d04 9497 gen_helper_1e0i(mfthi, t0, 0);
ead9360e
TS
9498 break;
9499 case 2:
895c2d04 9500 gen_helper_1e0i(mftacx, t0, 0);
ead9360e
TS
9501 break;
9502 case 4:
895c2d04 9503 gen_helper_1e0i(mftlo, t0, 1);
ead9360e
TS
9504 break;
9505 case 5:
895c2d04 9506 gen_helper_1e0i(mfthi, t0, 1);
ead9360e
TS
9507 break;
9508 case 6:
895c2d04 9509 gen_helper_1e0i(mftacx, t0, 1);
ead9360e
TS
9510 break;
9511 case 8:
895c2d04 9512 gen_helper_1e0i(mftlo, t0, 2);
ead9360e
TS
9513 break;
9514 case 9:
895c2d04 9515 gen_helper_1e0i(mfthi, t0, 2);
ead9360e
TS
9516 break;
9517 case 10:
895c2d04 9518 gen_helper_1e0i(mftacx, t0, 2);
ead9360e
TS
9519 break;
9520 case 12:
895c2d04 9521 gen_helper_1e0i(mftlo, t0, 3);
ead9360e
TS
9522 break;
9523 case 13:
895c2d04 9524 gen_helper_1e0i(mfthi, t0, 3);
ead9360e
TS
9525 break;
9526 case 14:
895c2d04 9527 gen_helper_1e0i(mftacx, t0, 3);
ead9360e
TS
9528 break;
9529 case 16:
895c2d04 9530 gen_helper_mftdsp(t0, cpu_env);
ead9360e
TS
9531 break;
9532 default:
9533 goto die;
9534 }
9535 break;
9536 /* Floating point (COP1). */
9537 case 2:
9538 /* XXX: For now we support only a single FPU context. */
9539 if (h == 0) {
a7812ae4 9540 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9541
7c979afd 9542 gen_load_fpr32(ctx, fp0, rt);
b6d96bed 9543 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 9544 tcg_temp_free_i32(fp0);
ead9360e 9545 } else {
a7812ae4 9546 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9547
7f6613ce 9548 gen_load_fpr32h(ctx, fp0, rt);
b6d96bed 9549 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 9550 tcg_temp_free_i32(fp0);
ead9360e
TS
9551 }
9552 break;
9553 case 3:
9554 /* XXX: For now we support only a single FPU context. */
895c2d04 9555 gen_helper_1e0i(cfc1, t0, rt);
ead9360e
TS
9556 break;
9557 /* COP2: Not implemented. */
9558 case 4:
9559 case 5:
9560 /* fall through */
9561 default:
9562 goto die;
9563 }
b44a7fb1 9564 trace_mips_translate_tr("mftr", rt, u, sel, h);
1a3fd9c3
TS
9565 gen_store_gpr(t0, rd);
9566 tcg_temp_free(t0);
ead9360e
TS
9567 return;
9568
9569die:
1a3fd9c3 9570 tcg_temp_free(t0);
d12d51d5 9571 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
9c708c7f 9572 generate_exception_end(ctx, EXCP_RI);
ead9360e
TS
9573}
9574
7db13fae 9575static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
ead9360e
TS
9576 int u, int sel, int h)
9577{
9578 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
a7812ae4 9579 TCGv t0 = tcg_temp_local_new();
ead9360e 9580
1a3fd9c3 9581 gen_load_gpr(t0, rt);
ead9360e 9582 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
b5dc7732
TS
9583 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
9584 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
ead9360e
TS
9585 /* NOP */ ;
9586 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
9587 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
9588 /* NOP */ ;
9589 else if (u == 0) {
9590 switch (rd) {
5a25ce94
EI
9591 case 1:
9592 switch (sel) {
9593 case 1:
895c2d04 9594 gen_helper_mttc0_vpecontrol(cpu_env, t0);
5a25ce94
EI
9595 break;
9596 case 2:
895c2d04 9597 gen_helper_mttc0_vpeconf0(cpu_env, t0);
5a25ce94
EI
9598 break;
9599 default:
9600 goto die;
9601 break;
9602 }
9603 break;
ead9360e
TS
9604 case 2:
9605 switch (sel) {
9606 case 1:
895c2d04 9607 gen_helper_mttc0_tcstatus(cpu_env, t0);
ead9360e
TS
9608 break;
9609 case 2:
895c2d04 9610 gen_helper_mttc0_tcbind(cpu_env, t0);
ead9360e
TS
9611 break;
9612 case 3:
895c2d04 9613 gen_helper_mttc0_tcrestart(cpu_env, t0);
ead9360e
TS
9614 break;
9615 case 4:
895c2d04 9616 gen_helper_mttc0_tchalt(cpu_env, t0);
ead9360e
TS
9617 break;
9618 case 5:
895c2d04 9619 gen_helper_mttc0_tccontext(cpu_env, t0);
ead9360e
TS
9620 break;
9621 case 6:
895c2d04 9622 gen_helper_mttc0_tcschedule(cpu_env, t0);
ead9360e
TS
9623 break;
9624 case 7:
895c2d04 9625 gen_helper_mttc0_tcschefback(cpu_env, t0);
ead9360e
TS
9626 break;
9627 default:
d75c135e 9628 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
9629 break;
9630 }
9631 break;
9632 case 10:
9633 switch (sel) {
9634 case 0:
895c2d04 9635 gen_helper_mttc0_entryhi(cpu_env, t0);
ead9360e
TS
9636 break;
9637 default:
d75c135e 9638 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
9639 break;
9640 }
9641 case 12:
9642 switch (sel) {
9643 case 0:
895c2d04 9644 gen_helper_mttc0_status(cpu_env, t0);
ead9360e
TS
9645 break;
9646 default:
d75c135e 9647 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
9648 break;
9649 }
5a25ce94
EI
9650 case 13:
9651 switch (sel) {
9652 case 0:
895c2d04 9653 gen_helper_mttc0_cause(cpu_env, t0);
5a25ce94
EI
9654 break;
9655 default:
9656 goto die;
9657 break;
9658 }
9659 break;
9660 case 15:
9661 switch (sel) {
9662 case 1:
895c2d04 9663 gen_helper_mttc0_ebase(cpu_env, t0);
5a25ce94
EI
9664 break;
9665 default:
9666 goto die;
9667 break;
9668 }
9669 break;
ead9360e
TS
9670 case 23:
9671 switch (sel) {
9672 case 0:
895c2d04 9673 gen_helper_mttc0_debug(cpu_env, t0);
ead9360e
TS
9674 break;
9675 default:
d75c135e 9676 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
9677 break;
9678 }
9679 break;
9680 default:
d75c135e 9681 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
9682 }
9683 } else switch (sel) {
9684 /* GPR registers. */
9685 case 0:
895c2d04 9686 gen_helper_0e1i(mttgpr, t0, rd);
ead9360e
TS
9687 break;
9688 /* Auxiliary CPU registers */
9689 case 1:
9690 switch (rd) {
9691 case 0:
895c2d04 9692 gen_helper_0e1i(mttlo, t0, 0);
ead9360e
TS
9693 break;
9694 case 1:
895c2d04 9695 gen_helper_0e1i(mtthi, t0, 0);
ead9360e
TS
9696 break;
9697 case 2:
895c2d04 9698 gen_helper_0e1i(mttacx, t0, 0);
ead9360e
TS
9699 break;
9700 case 4:
895c2d04 9701 gen_helper_0e1i(mttlo, t0, 1);
ead9360e
TS
9702 break;
9703 case 5:
895c2d04 9704 gen_helper_0e1i(mtthi, t0, 1);
ead9360e
TS
9705 break;
9706 case 6:
895c2d04 9707 gen_helper_0e1i(mttacx, t0, 1);
ead9360e
TS
9708 break;
9709 case 8:
895c2d04 9710 gen_helper_0e1i(mttlo, t0, 2);
ead9360e
TS
9711 break;
9712 case 9:
895c2d04 9713 gen_helper_0e1i(mtthi, t0, 2);
ead9360e
TS
9714 break;
9715 case 10:
895c2d04 9716 gen_helper_0e1i(mttacx, t0, 2);
ead9360e
TS
9717 break;
9718 case 12:
895c2d04 9719 gen_helper_0e1i(mttlo, t0, 3);
ead9360e
TS
9720 break;
9721 case 13:
895c2d04 9722 gen_helper_0e1i(mtthi, t0, 3);
ead9360e
TS
9723 break;
9724 case 14:
895c2d04 9725 gen_helper_0e1i(mttacx, t0, 3);
ead9360e
TS
9726 break;
9727 case 16:
895c2d04 9728 gen_helper_mttdsp(cpu_env, t0);
ead9360e
TS
9729 break;
9730 default:
9731 goto die;
9732 }
9733 break;
9734 /* Floating point (COP1). */
9735 case 2:
9736 /* XXX: For now we support only a single FPU context. */
9737 if (h == 0) {
a7812ae4 9738 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
9739
9740 tcg_gen_trunc_tl_i32(fp0, t0);
7c979afd 9741 gen_store_fpr32(ctx, fp0, rd);
a7812ae4 9742 tcg_temp_free_i32(fp0);
ead9360e 9743 } else {
a7812ae4 9744 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
9745
9746 tcg_gen_trunc_tl_i32(fp0, t0);
7f6613ce 9747 gen_store_fpr32h(ctx, fp0, rd);
a7812ae4 9748 tcg_temp_free_i32(fp0);
ead9360e
TS
9749 }
9750 break;
9751 case 3:
9752 /* XXX: For now we support only a single FPU context. */
736d120a
PJ
9753 {
9754 TCGv_i32 fs_tmp = tcg_const_i32(rd);
9755
9756 gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
9757 tcg_temp_free_i32(fs_tmp);
9758 }
4cf8a45f 9759 /* Stop translation as we may have changed hflags */
eeb3bba8 9760 ctx->base.is_jmp = DISAS_STOP;
ead9360e
TS
9761 break;
9762 /* COP2: Not implemented. */
9763 case 4:
9764 case 5:
9765 /* fall through */
9766 default:
9767 goto die;
9768 }
b44a7fb1 9769 trace_mips_translate_tr("mttr", rd, u, sel, h);
1a3fd9c3 9770 tcg_temp_free(t0);
ead9360e
TS
9771 return;
9772
9773die:
1a3fd9c3 9774 tcg_temp_free(t0);
d12d51d5 9775 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
9c708c7f 9776 generate_exception_end(ctx, EXCP_RI);
ead9360e
TS
9777}
9778
7db13fae 9779static void gen_cp0 (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
6af0bf9c 9780{
287c4b84 9781 const char *opn = "ldst";
6af0bf9c 9782
2e15497c 9783 check_cp0_enabled(ctx);
6af0bf9c
FB
9784 switch (opc) {
9785 case OPC_MFC0:
9786 if (rt == 0) {
ead9360e 9787 /* Treat as NOP. */
6af0bf9c
FB
9788 return;
9789 }
d75c135e 9790 gen_mfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
6af0bf9c
FB
9791 opn = "mfc0";
9792 break;
9793 case OPC_MTC0:
1a3fd9c3 9794 {
1fc7bf6e 9795 TCGv t0 = tcg_temp_new();
1a3fd9c3
TS
9796
9797 gen_load_gpr(t0, rt);
d75c135e 9798 gen_mtc0(ctx, t0, rd, ctx->opcode & 0x7);
1a3fd9c3
TS
9799 tcg_temp_free(t0);
9800 }
6af0bf9c
FB
9801 opn = "mtc0";
9802 break;
d26bc211 9803#if defined(TARGET_MIPS64)
9c2149c8 9804 case OPC_DMFC0:
d75c135e 9805 check_insn(ctx, ISA_MIPS3);
9c2149c8 9806 if (rt == 0) {
ead9360e 9807 /* Treat as NOP. */
9c2149c8
TS
9808 return;
9809 }
d75c135e 9810 gen_dmfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
9c2149c8
TS
9811 opn = "dmfc0";
9812 break;
9813 case OPC_DMTC0:
d75c135e 9814 check_insn(ctx, ISA_MIPS3);
1a3fd9c3 9815 {
1fc7bf6e 9816 TCGv t0 = tcg_temp_new();
1a3fd9c3
TS
9817
9818 gen_load_gpr(t0, rt);
d75c135e 9819 gen_dmtc0(ctx, t0, rd, ctx->opcode & 0x7);
1a3fd9c3
TS
9820 tcg_temp_free(t0);
9821 }
9c2149c8
TS
9822 opn = "dmtc0";
9823 break;
534ce69f 9824#endif
5204ea79
LA
9825 case OPC_MFHC0:
9826 check_mvh(ctx);
9827 if (rt == 0) {
9828 /* Treat as NOP. */
9829 return;
9830 }
9831 gen_mfhc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
9832 opn = "mfhc0";
9833 break;
9834 case OPC_MTHC0:
9835 check_mvh(ctx);
9836 {
9837 TCGv t0 = tcg_temp_new();
9838 gen_load_gpr(t0, rt);
9839 gen_mthc0(ctx, t0, rd, ctx->opcode & 0x7);
9840 tcg_temp_free(t0);
9841 }
9842 opn = "mthc0";
9843 break;
ead9360e 9844 case OPC_MFTR:
9affc1c5 9845 check_cp0_enabled(ctx);
ead9360e
TS
9846 if (rd == 0) {
9847 /* Treat as NOP. */
9848 return;
9849 }
6c5c1e20 9850 gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
ead9360e 9851 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
ead9360e
TS
9852 opn = "mftr";
9853 break;
9854 case OPC_MTTR:
9affc1c5 9855 check_cp0_enabled(ctx);
6c5c1e20 9856 gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
ead9360e
TS
9857 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
9858 opn = "mttr";
9859 break;
6af0bf9c 9860 case OPC_TLBWI:
6af0bf9c 9861 opn = "tlbwi";
c01fccd2 9862 if (!env->tlb->helper_tlbwi)
29929e34 9863 goto die;
895c2d04 9864 gen_helper_tlbwi(cpu_env);
6af0bf9c 9865 break;
9456c2fb
LA
9866 case OPC_TLBINV:
9867 opn = "tlbinv";
9868 if (ctx->ie >= 2) {
9869 if (!env->tlb->helper_tlbinv) {
9870 goto die;
9871 }
9872 gen_helper_tlbinv(cpu_env);
9873 } /* treat as nop if TLBINV not supported */
9874 break;
9875 case OPC_TLBINVF:
9876 opn = "tlbinvf";
9877 if (ctx->ie >= 2) {
9878 if (!env->tlb->helper_tlbinvf) {
9879 goto die;
9880 }
9881 gen_helper_tlbinvf(cpu_env);
9882 } /* treat as nop if TLBINV not supported */
9883 break;
6af0bf9c 9884 case OPC_TLBWR:
6af0bf9c 9885 opn = "tlbwr";
c01fccd2 9886 if (!env->tlb->helper_tlbwr)
29929e34 9887 goto die;
895c2d04 9888 gen_helper_tlbwr(cpu_env);
6af0bf9c
FB
9889 break;
9890 case OPC_TLBP:
6af0bf9c 9891 opn = "tlbp";
c01fccd2 9892 if (!env->tlb->helper_tlbp)
29929e34 9893 goto die;
895c2d04 9894 gen_helper_tlbp(cpu_env);
6af0bf9c
FB
9895 break;
9896 case OPC_TLBR:
6af0bf9c 9897 opn = "tlbr";
c01fccd2 9898 if (!env->tlb->helper_tlbr)
29929e34 9899 goto die;
895c2d04 9900 gen_helper_tlbr(cpu_env);
6af0bf9c 9901 break;
ce9782f4 9902 case OPC_ERET: /* OPC_ERETNC */
339cd2a8
LA
9903 if ((ctx->insn_flags & ISA_MIPS32R6) &&
9904 (ctx->hflags & MIPS_HFLAG_BMASK)) {
339cd2a8 9905 goto die;
ce9782f4
LA
9906 } else {
9907 int bit_shift = (ctx->hflags & MIPS_HFLAG_M16) ? 16 : 6;
9908 if (ctx->opcode & (1 << bit_shift)) {
9909 /* OPC_ERETNC */
9910 opn = "eretnc";
9911 check_insn(ctx, ISA_MIPS32R5);
9912 gen_helper_eretnc(cpu_env);
9913 } else {
9914 /* OPC_ERET */
9915 opn = "eret";
9916 check_insn(ctx, ISA_MIPS2);
9917 gen_helper_eret(cpu_env);
9918 }
eeb3bba8 9919 ctx->base.is_jmp = DISAS_EXIT;
339cd2a8 9920 }
6af0bf9c
FB
9921 break;
9922 case OPC_DERET:
9923 opn = "deret";
d75c135e 9924 check_insn(ctx, ISA_MIPS32);
339cd2a8
LA
9925 if ((ctx->insn_flags & ISA_MIPS32R6) &&
9926 (ctx->hflags & MIPS_HFLAG_BMASK)) {
339cd2a8
LA
9927 goto die;
9928 }
6af0bf9c 9929 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
923617a3 9930 MIPS_INVAL(opn);
9c708c7f 9931 generate_exception_end(ctx, EXCP_RI);
6af0bf9c 9932 } else {
895c2d04 9933 gen_helper_deret(cpu_env);
eeb3bba8 9934 ctx->base.is_jmp = DISAS_EXIT;
6af0bf9c
FB
9935 }
9936 break;
4ad40f36
FB
9937 case OPC_WAIT:
9938 opn = "wait";
d75c135e 9939 check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
339cd2a8
LA
9940 if ((ctx->insn_flags & ISA_MIPS32R6) &&
9941 (ctx->hflags & MIPS_HFLAG_BMASK)) {
339cd2a8
LA
9942 goto die;
9943 }
4ad40f36 9944 /* If we get an exception, we want to restart at next instruction */
eeb3bba8 9945 ctx->base.pc_next += 4;
4ad40f36 9946 save_cpu_state(ctx, 1);
eeb3bba8 9947 ctx->base.pc_next -= 4;
895c2d04 9948 gen_helper_wait(cpu_env);
eeb3bba8 9949 ctx->base.is_jmp = DISAS_NORETURN;
4ad40f36 9950 break;
6af0bf9c 9951 default:
29929e34 9952 die:
923617a3 9953 MIPS_INVAL(opn);
9c708c7f 9954 generate_exception_end(ctx, EXCP_RI);
6af0bf9c
FB
9955 return;
9956 }
2abf314d 9957 (void)opn; /* avoid a compiler warning */
6af0bf9c 9958}
f1aa6320 9959#endif /* !CONFIG_USER_ONLY */
6af0bf9c 9960
6ea83fed 9961/* CP1 Branches (before delay slot) */
d75c135e
AJ
9962static void gen_compute_branch1(DisasContext *ctx, uint32_t op,
9963 int32_t cc, int32_t offset)
6ea83fed
FB
9964{
9965 target_ulong btarget;
a7812ae4 9966 TCGv_i32 t0 = tcg_temp_new_i32();
6ea83fed 9967
339cd2a8 9968 if ((ctx->insn_flags & ISA_MIPS32R6) && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9c708c7f 9969 generate_exception_end(ctx, EXCP_RI);
339cd2a8
LA
9970 goto out;
9971 }
9972
e189e748 9973 if (cc != 0)
d75c135e 9974 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
e189e748 9975
eeb3bba8 9976 btarget = ctx->base.pc_next + 4 + offset;
6ea83fed 9977
7a387fff
TS
9978 switch (op) {
9979 case OPC_BC1F:
d94536f4
AJ
9980 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9981 tcg_gen_not_i32(t0, t0);
9982 tcg_gen_andi_i32(t0, t0, 1);
9983 tcg_gen_extu_i32_tl(bcond, t0);
6ea83fed 9984 goto not_likely;
7a387fff 9985 case OPC_BC1FL:
d94536f4
AJ
9986 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9987 tcg_gen_not_i32(t0, t0);
9988 tcg_gen_andi_i32(t0, t0, 1);
9989 tcg_gen_extu_i32_tl(bcond, t0);
6ea83fed 9990 goto likely;
7a387fff 9991 case OPC_BC1T:
d94536f4
AJ
9992 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9993 tcg_gen_andi_i32(t0, t0, 1);
9994 tcg_gen_extu_i32_tl(bcond, t0);
5a5012ec 9995 goto not_likely;
7a387fff 9996 case OPC_BC1TL:
d94536f4
AJ
9997 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9998 tcg_gen_andi_i32(t0, t0, 1);
9999 tcg_gen_extu_i32_tl(bcond, t0);
6ea83fed
FB
10000 likely:
10001 ctx->hflags |= MIPS_HFLAG_BL;
10002 break;
5a5012ec 10003 case OPC_BC1FANY2:
a16336e4 10004 {
d94536f4
AJ
10005 TCGv_i32 t1 = tcg_temp_new_i32();
10006 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10007 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
d7f66b52 10008 tcg_gen_nand_i32(t0, t0, t1);
d94536f4 10009 tcg_temp_free_i32(t1);
d94536f4
AJ
10010 tcg_gen_andi_i32(t0, t0, 1);
10011 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 10012 }
5a5012ec
TS
10013 goto not_likely;
10014 case OPC_BC1TANY2:
a16336e4 10015 {
d94536f4
AJ
10016 TCGv_i32 t1 = tcg_temp_new_i32();
10017 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10018 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
10019 tcg_gen_or_i32(t0, t0, t1);
10020 tcg_temp_free_i32(t1);
10021 tcg_gen_andi_i32(t0, t0, 1);
10022 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 10023 }
5a5012ec
TS
10024 goto not_likely;
10025 case OPC_BC1FANY4:
a16336e4 10026 {
d94536f4
AJ
10027 TCGv_i32 t1 = tcg_temp_new_i32();
10028 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10029 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
d7f66b52 10030 tcg_gen_and_i32(t0, t0, t1);
d94536f4 10031 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
d7f66b52 10032 tcg_gen_and_i32(t0, t0, t1);
d94536f4 10033 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
d7f66b52 10034 tcg_gen_nand_i32(t0, t0, t1);
d94536f4 10035 tcg_temp_free_i32(t1);
d94536f4
AJ
10036 tcg_gen_andi_i32(t0, t0, 1);
10037 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 10038 }
5a5012ec
TS
10039 goto not_likely;
10040 case OPC_BC1TANY4:
a16336e4 10041 {
d94536f4
AJ
10042 TCGv_i32 t1 = tcg_temp_new_i32();
10043 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10044 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
10045 tcg_gen_or_i32(t0, t0, t1);
10046 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
10047 tcg_gen_or_i32(t0, t0, t1);
10048 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
10049 tcg_gen_or_i32(t0, t0, t1);
10050 tcg_temp_free_i32(t1);
10051 tcg_gen_andi_i32(t0, t0, 1);
10052 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 10053 }
5a5012ec
TS
10054 not_likely:
10055 ctx->hflags |= MIPS_HFLAG_BC;
5a5012ec
TS
10056 break;
10057 default:
9d68ac14 10058 MIPS_INVAL("cp1 cond branch");
9c708c7f 10059 generate_exception_end(ctx, EXCP_RI);
6c5c1e20 10060 goto out;
6ea83fed 10061 }
6ea83fed 10062 ctx->btarget = btarget;
b231c103 10063 ctx->hflags |= MIPS_HFLAG_BDS32;
6c5c1e20 10064 out:
a7812ae4 10065 tcg_temp_free_i32(t0);
6ea83fed
FB
10066}
10067
31837be3
YK
10068/* R6 CP1 Branches */
10069static void gen_compute_branch1_r6(DisasContext *ctx, uint32_t op,
65935f07
YK
10070 int32_t ft, int32_t offset,
10071 int delayslot_size)
31837be3
YK
10072{
10073 target_ulong btarget;
31837be3
YK
10074 TCGv_i64 t0 = tcg_temp_new_i64();
10075
10076 if (ctx->hflags & MIPS_HFLAG_BMASK) {
10077#ifdef MIPS_DEBUG_DISAS
339cd2a8 10078 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
eeb3bba8 10079 "\n", ctx->base.pc_next);
31837be3 10080#endif
9c708c7f 10081 generate_exception_end(ctx, EXCP_RI);
31837be3
YK
10082 goto out;
10083 }
10084
10085 gen_load_fpr64(ctx, t0, ft);
10086 tcg_gen_andi_i64(t0, t0, 1);
10087
eeb3bba8 10088 btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
31837be3
YK
10089
10090 switch (op) {
10091 case OPC_BC1EQZ:
10092 tcg_gen_xori_i64(t0, t0, 1);
31837be3
YK
10093 ctx->hflags |= MIPS_HFLAG_BC;
10094 break;
10095 case OPC_BC1NEZ:
10096 /* t0 already set */
31837be3
YK
10097 ctx->hflags |= MIPS_HFLAG_BC;
10098 break;
10099 default:
9d68ac14 10100 MIPS_INVAL("cp1 cond branch");
9c708c7f 10101 generate_exception_end(ctx, EXCP_RI);
31837be3
YK
10102 goto out;
10103 }
10104
10105 tcg_gen_trunc_i64_tl(bcond, t0);
10106
31837be3 10107 ctx->btarget = btarget;
65935f07
YK
10108
10109 switch (delayslot_size) {
10110 case 2:
10111 ctx->hflags |= MIPS_HFLAG_BDS16;
10112 break;
10113 case 4:
10114 ctx->hflags |= MIPS_HFLAG_BDS32;
10115 break;
10116 }
31837be3
YK
10117
10118out:
10119 tcg_temp_free_i64(t0);
10120}
10121
6af0bf9c 10122/* Coprocessor 1 (FPU) */
5a5012ec 10123
5a5012ec
TS
10124#define FOP(func, fmt) (((fmt) << 21) | (func))
10125
bf4120ad
NF
10126enum fopcode {
10127 OPC_ADD_S = FOP(0, FMT_S),
10128 OPC_SUB_S = FOP(1, FMT_S),
10129 OPC_MUL_S = FOP(2, FMT_S),
10130 OPC_DIV_S = FOP(3, FMT_S),
10131 OPC_SQRT_S = FOP(4, FMT_S),
10132 OPC_ABS_S = FOP(5, FMT_S),
10133 OPC_MOV_S = FOP(6, FMT_S),
10134 OPC_NEG_S = FOP(7, FMT_S),
10135 OPC_ROUND_L_S = FOP(8, FMT_S),
10136 OPC_TRUNC_L_S = FOP(9, FMT_S),
10137 OPC_CEIL_L_S = FOP(10, FMT_S),
10138 OPC_FLOOR_L_S = FOP(11, FMT_S),
10139 OPC_ROUND_W_S = FOP(12, FMT_S),
10140 OPC_TRUNC_W_S = FOP(13, FMT_S),
10141 OPC_CEIL_W_S = FOP(14, FMT_S),
10142 OPC_FLOOR_W_S = FOP(15, FMT_S),
e7f16abb 10143 OPC_SEL_S = FOP(16, FMT_S),
bf4120ad
NF
10144 OPC_MOVCF_S = FOP(17, FMT_S),
10145 OPC_MOVZ_S = FOP(18, FMT_S),
10146 OPC_MOVN_S = FOP(19, FMT_S),
e7f16abb 10147 OPC_SELEQZ_S = FOP(20, FMT_S),
bf4120ad
NF
10148 OPC_RECIP_S = FOP(21, FMT_S),
10149 OPC_RSQRT_S = FOP(22, FMT_S),
e7f16abb
LA
10150 OPC_SELNEZ_S = FOP(23, FMT_S),
10151 OPC_MADDF_S = FOP(24, FMT_S),
10152 OPC_MSUBF_S = FOP(25, FMT_S),
10153 OPC_RINT_S = FOP(26, FMT_S),
10154 OPC_CLASS_S = FOP(27, FMT_S),
10155 OPC_MIN_S = FOP(28, FMT_S),
bf4120ad 10156 OPC_RECIP2_S = FOP(28, FMT_S),
e7f16abb 10157 OPC_MINA_S = FOP(29, FMT_S),
bf4120ad 10158 OPC_RECIP1_S = FOP(29, FMT_S),
e7f16abb 10159 OPC_MAX_S = FOP(30, FMT_S),
bf4120ad 10160 OPC_RSQRT1_S = FOP(30, FMT_S),
e7f16abb 10161 OPC_MAXA_S = FOP(31, FMT_S),
bf4120ad
NF
10162 OPC_RSQRT2_S = FOP(31, FMT_S),
10163 OPC_CVT_D_S = FOP(33, FMT_S),
10164 OPC_CVT_W_S = FOP(36, FMT_S),
10165 OPC_CVT_L_S = FOP(37, FMT_S),
10166 OPC_CVT_PS_S = FOP(38, FMT_S),
10167 OPC_CMP_F_S = FOP (48, FMT_S),
10168 OPC_CMP_UN_S = FOP (49, FMT_S),
10169 OPC_CMP_EQ_S = FOP (50, FMT_S),
10170 OPC_CMP_UEQ_S = FOP (51, FMT_S),
10171 OPC_CMP_OLT_S = FOP (52, FMT_S),
10172 OPC_CMP_ULT_S = FOP (53, FMT_S),
10173 OPC_CMP_OLE_S = FOP (54, FMT_S),
10174 OPC_CMP_ULE_S = FOP (55, FMT_S),
10175 OPC_CMP_SF_S = FOP (56, FMT_S),
10176 OPC_CMP_NGLE_S = FOP (57, FMT_S),
10177 OPC_CMP_SEQ_S = FOP (58, FMT_S),
10178 OPC_CMP_NGL_S = FOP (59, FMT_S),
10179 OPC_CMP_LT_S = FOP (60, FMT_S),
10180 OPC_CMP_NGE_S = FOP (61, FMT_S),
10181 OPC_CMP_LE_S = FOP (62, FMT_S),
10182 OPC_CMP_NGT_S = FOP (63, FMT_S),
10183
10184 OPC_ADD_D = FOP(0, FMT_D),
10185 OPC_SUB_D = FOP(1, FMT_D),
10186 OPC_MUL_D = FOP(2, FMT_D),
10187 OPC_DIV_D = FOP(3, FMT_D),
10188 OPC_SQRT_D = FOP(4, FMT_D),
10189 OPC_ABS_D = FOP(5, FMT_D),
10190 OPC_MOV_D = FOP(6, FMT_D),
10191 OPC_NEG_D = FOP(7, FMT_D),
10192 OPC_ROUND_L_D = FOP(8, FMT_D),
10193 OPC_TRUNC_L_D = FOP(9, FMT_D),
10194 OPC_CEIL_L_D = FOP(10, FMT_D),
10195 OPC_FLOOR_L_D = FOP(11, FMT_D),
10196 OPC_ROUND_W_D = FOP(12, FMT_D),
10197 OPC_TRUNC_W_D = FOP(13, FMT_D),
10198 OPC_CEIL_W_D = FOP(14, FMT_D),
10199 OPC_FLOOR_W_D = FOP(15, FMT_D),
e7f16abb 10200 OPC_SEL_D = FOP(16, FMT_D),
bf4120ad
NF
10201 OPC_MOVCF_D = FOP(17, FMT_D),
10202 OPC_MOVZ_D = FOP(18, FMT_D),
10203 OPC_MOVN_D = FOP(19, FMT_D),
e7f16abb 10204 OPC_SELEQZ_D = FOP(20, FMT_D),
bf4120ad
NF
10205 OPC_RECIP_D = FOP(21, FMT_D),
10206 OPC_RSQRT_D = FOP(22, FMT_D),
e7f16abb
LA
10207 OPC_SELNEZ_D = FOP(23, FMT_D),
10208 OPC_MADDF_D = FOP(24, FMT_D),
10209 OPC_MSUBF_D = FOP(25, FMT_D),
10210 OPC_RINT_D = FOP(26, FMT_D),
10211 OPC_CLASS_D = FOP(27, FMT_D),
10212 OPC_MIN_D = FOP(28, FMT_D),
bf4120ad 10213 OPC_RECIP2_D = FOP(28, FMT_D),
e7f16abb 10214 OPC_MINA_D = FOP(29, FMT_D),
bf4120ad 10215 OPC_RECIP1_D = FOP(29, FMT_D),
e7f16abb 10216 OPC_MAX_D = FOP(30, FMT_D),
bf4120ad 10217 OPC_RSQRT1_D = FOP(30, FMT_D),
e7f16abb 10218 OPC_MAXA_D = FOP(31, FMT_D),
bf4120ad
NF
10219 OPC_RSQRT2_D = FOP(31, FMT_D),
10220 OPC_CVT_S_D = FOP(32, FMT_D),
10221 OPC_CVT_W_D = FOP(36, FMT_D),
10222 OPC_CVT_L_D = FOP(37, FMT_D),
10223 OPC_CMP_F_D = FOP (48, FMT_D),
10224 OPC_CMP_UN_D = FOP (49, FMT_D),
10225 OPC_CMP_EQ_D = FOP (50, FMT_D),
10226 OPC_CMP_UEQ_D = FOP (51, FMT_D),
10227 OPC_CMP_OLT_D = FOP (52, FMT_D),
10228 OPC_CMP_ULT_D = FOP (53, FMT_D),
10229 OPC_CMP_OLE_D = FOP (54, FMT_D),
10230 OPC_CMP_ULE_D = FOP (55, FMT_D),
10231 OPC_CMP_SF_D = FOP (56, FMT_D),
10232 OPC_CMP_NGLE_D = FOP (57, FMT_D),
10233 OPC_CMP_SEQ_D = FOP (58, FMT_D),
10234 OPC_CMP_NGL_D = FOP (59, FMT_D),
10235 OPC_CMP_LT_D = FOP (60, FMT_D),
10236 OPC_CMP_NGE_D = FOP (61, FMT_D),
10237 OPC_CMP_LE_D = FOP (62, FMT_D),
10238 OPC_CMP_NGT_D = FOP (63, FMT_D),
10239
10240 OPC_CVT_S_W = FOP(32, FMT_W),
10241 OPC_CVT_D_W = FOP(33, FMT_W),
10242 OPC_CVT_S_L = FOP(32, FMT_L),
10243 OPC_CVT_D_L = FOP(33, FMT_L),
10244 OPC_CVT_PS_PW = FOP(38, FMT_W),
10245
10246 OPC_ADD_PS = FOP(0, FMT_PS),
10247 OPC_SUB_PS = FOP(1, FMT_PS),
10248 OPC_MUL_PS = FOP(2, FMT_PS),
10249 OPC_DIV_PS = FOP(3, FMT_PS),
10250 OPC_ABS_PS = FOP(5, FMT_PS),
10251 OPC_MOV_PS = FOP(6, FMT_PS),
10252 OPC_NEG_PS = FOP(7, FMT_PS),
10253 OPC_MOVCF_PS = FOP(17, FMT_PS),
10254 OPC_MOVZ_PS = FOP(18, FMT_PS),
10255 OPC_MOVN_PS = FOP(19, FMT_PS),
10256 OPC_ADDR_PS = FOP(24, FMT_PS),
10257 OPC_MULR_PS = FOP(26, FMT_PS),
10258 OPC_RECIP2_PS = FOP(28, FMT_PS),
10259 OPC_RECIP1_PS = FOP(29, FMT_PS),
10260 OPC_RSQRT1_PS = FOP(30, FMT_PS),
10261 OPC_RSQRT2_PS = FOP(31, FMT_PS),
10262
10263 OPC_CVT_S_PU = FOP(32, FMT_PS),
10264 OPC_CVT_PW_PS = FOP(36, FMT_PS),
10265 OPC_CVT_S_PL = FOP(40, FMT_PS),
10266 OPC_PLL_PS = FOP(44, FMT_PS),
10267 OPC_PLU_PS = FOP(45, FMT_PS),
10268 OPC_PUL_PS = FOP(46, FMT_PS),
10269 OPC_PUU_PS = FOP(47, FMT_PS),
10270 OPC_CMP_F_PS = FOP (48, FMT_PS),
10271 OPC_CMP_UN_PS = FOP (49, FMT_PS),
10272 OPC_CMP_EQ_PS = FOP (50, FMT_PS),
10273 OPC_CMP_UEQ_PS = FOP (51, FMT_PS),
10274 OPC_CMP_OLT_PS = FOP (52, FMT_PS),
10275 OPC_CMP_ULT_PS = FOP (53, FMT_PS),
10276 OPC_CMP_OLE_PS = FOP (54, FMT_PS),
10277 OPC_CMP_ULE_PS = FOP (55, FMT_PS),
10278 OPC_CMP_SF_PS = FOP (56, FMT_PS),
10279 OPC_CMP_NGLE_PS = FOP (57, FMT_PS),
10280 OPC_CMP_SEQ_PS = FOP (58, FMT_PS),
10281 OPC_CMP_NGL_PS = FOP (59, FMT_PS),
10282 OPC_CMP_LT_PS = FOP (60, FMT_PS),
10283 OPC_CMP_NGE_PS = FOP (61, FMT_PS),
10284 OPC_CMP_LE_PS = FOP (62, FMT_PS),
10285 OPC_CMP_NGT_PS = FOP (63, FMT_PS),
10286};
10287
3f493883
YK
10288enum r6_f_cmp_op {
10289 R6_OPC_CMP_AF_S = FOP(0, FMT_W),
10290 R6_OPC_CMP_UN_S = FOP(1, FMT_W),
10291 R6_OPC_CMP_EQ_S = FOP(2, FMT_W),
10292 R6_OPC_CMP_UEQ_S = FOP(3, FMT_W),
10293 R6_OPC_CMP_LT_S = FOP(4, FMT_W),
10294 R6_OPC_CMP_ULT_S = FOP(5, FMT_W),
10295 R6_OPC_CMP_LE_S = FOP(6, FMT_W),
10296 R6_OPC_CMP_ULE_S = FOP(7, FMT_W),
10297 R6_OPC_CMP_SAF_S = FOP(8, FMT_W),
10298 R6_OPC_CMP_SUN_S = FOP(9, FMT_W),
10299 R6_OPC_CMP_SEQ_S = FOP(10, FMT_W),
10300 R6_OPC_CMP_SEUQ_S = FOP(11, FMT_W),
10301 R6_OPC_CMP_SLT_S = FOP(12, FMT_W),
10302 R6_OPC_CMP_SULT_S = FOP(13, FMT_W),
10303 R6_OPC_CMP_SLE_S = FOP(14, FMT_W),
10304 R6_OPC_CMP_SULE_S = FOP(15, FMT_W),
10305 R6_OPC_CMP_OR_S = FOP(17, FMT_W),
10306 R6_OPC_CMP_UNE_S = FOP(18, FMT_W),
10307 R6_OPC_CMP_NE_S = FOP(19, FMT_W),
10308 R6_OPC_CMP_SOR_S = FOP(25, FMT_W),
10309 R6_OPC_CMP_SUNE_S = FOP(26, FMT_W),
10310 R6_OPC_CMP_SNE_S = FOP(27, FMT_W),
10311
10312 R6_OPC_CMP_AF_D = FOP(0, FMT_L),
10313 R6_OPC_CMP_UN_D = FOP(1, FMT_L),
10314 R6_OPC_CMP_EQ_D = FOP(2, FMT_L),
10315 R6_OPC_CMP_UEQ_D = FOP(3, FMT_L),
10316 R6_OPC_CMP_LT_D = FOP(4, FMT_L),
10317 R6_OPC_CMP_ULT_D = FOP(5, FMT_L),
10318 R6_OPC_CMP_LE_D = FOP(6, FMT_L),
10319 R6_OPC_CMP_ULE_D = FOP(7, FMT_L),
10320 R6_OPC_CMP_SAF_D = FOP(8, FMT_L),
10321 R6_OPC_CMP_SUN_D = FOP(9, FMT_L),
10322 R6_OPC_CMP_SEQ_D = FOP(10, FMT_L),
10323 R6_OPC_CMP_SEUQ_D = FOP(11, FMT_L),
10324 R6_OPC_CMP_SLT_D = FOP(12, FMT_L),
10325 R6_OPC_CMP_SULT_D = FOP(13, FMT_L),
10326 R6_OPC_CMP_SLE_D = FOP(14, FMT_L),
10327 R6_OPC_CMP_SULE_D = FOP(15, FMT_L),
10328 R6_OPC_CMP_OR_D = FOP(17, FMT_L),
10329 R6_OPC_CMP_UNE_D = FOP(18, FMT_L),
10330 R6_OPC_CMP_NE_D = FOP(19, FMT_L),
10331 R6_OPC_CMP_SOR_D = FOP(25, FMT_L),
10332 R6_OPC_CMP_SUNE_D = FOP(26, FMT_L),
10333 R6_OPC_CMP_SNE_D = FOP(27, FMT_L),
10334};
7a387fff 10335static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
6ea83fed 10336{
72c3a3ee 10337 TCGv t0 = tcg_temp_new();
6ea83fed
FB
10338
10339 switch (opc) {
10340 case OPC_MFC1:
b6d96bed 10341 {
a7812ae4 10342 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 10343
7c979afd 10344 gen_load_fpr32(ctx, fp0, fs);
b6d96bed 10345 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 10346 tcg_temp_free_i32(fp0);
6958549d 10347 }
6c5c1e20 10348 gen_store_gpr(t0, rt);
6ea83fed
FB
10349 break;
10350 case OPC_MTC1:
6c5c1e20 10351 gen_load_gpr(t0, rt);
b6d96bed 10352 {
a7812ae4 10353 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
10354
10355 tcg_gen_trunc_tl_i32(fp0, t0);
7c979afd 10356 gen_store_fpr32(ctx, fp0, fs);
a7812ae4 10357 tcg_temp_free_i32(fp0);
6958549d 10358 }
6ea83fed
FB
10359 break;
10360 case OPC_CFC1:
895c2d04 10361 gen_helper_1e0i(cfc1, t0, fs);
6c5c1e20 10362 gen_store_gpr(t0, rt);
6ea83fed
FB
10363 break;
10364 case OPC_CTC1:
6c5c1e20 10365 gen_load_gpr(t0, rt);
9c708c7f 10366 save_cpu_state(ctx, 0);
736d120a
PJ
10367 {
10368 TCGv_i32 fs_tmp = tcg_const_i32(fs);
10369
10370 gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
10371 tcg_temp_free_i32(fs_tmp);
10372 }
4cf8a45f 10373 /* Stop translation as we may have changed hflags */
eeb3bba8 10374 ctx->base.is_jmp = DISAS_STOP;
6ea83fed 10375 break;
72c3a3ee 10376#if defined(TARGET_MIPS64)
9c2149c8 10377 case OPC_DMFC1:
72c3a3ee 10378 gen_load_fpr64(ctx, t0, fs);
6c5c1e20 10379 gen_store_gpr(t0, rt);
5a5012ec 10380 break;
9c2149c8 10381 case OPC_DMTC1:
6c5c1e20 10382 gen_load_gpr(t0, rt);
72c3a3ee 10383 gen_store_fpr64(ctx, t0, fs);
5a5012ec 10384 break;
72c3a3ee 10385#endif
5a5012ec 10386 case OPC_MFHC1:
b6d96bed 10387 {
a7812ae4 10388 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 10389
7f6613ce 10390 gen_load_fpr32h(ctx, fp0, fs);
b6d96bed 10391 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 10392 tcg_temp_free_i32(fp0);
6958549d 10393 }
6c5c1e20 10394 gen_store_gpr(t0, rt);
5a5012ec
TS
10395 break;
10396 case OPC_MTHC1:
6c5c1e20 10397 gen_load_gpr(t0, rt);
b6d96bed 10398 {
a7812ae4 10399 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
10400
10401 tcg_gen_trunc_tl_i32(fp0, t0);
7f6613ce 10402 gen_store_fpr32h(ctx, fp0, fs);
a7812ae4 10403 tcg_temp_free_i32(fp0);
6958549d 10404 }
5a5012ec 10405 break;
6ea83fed 10406 default:
9d68ac14 10407 MIPS_INVAL("cp1 move");
9c708c7f 10408 generate_exception_end(ctx, EXCP_RI);
6c5c1e20 10409 goto out;
6ea83fed 10410 }
6c5c1e20
TS
10411
10412 out:
10413 tcg_temp_free(t0);
6ea83fed
FB
10414}
10415
5a5012ec
TS
10416static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
10417{
42a268c2 10418 TCGLabel *l1;
e214b9bb 10419 TCGCond cond;
af58f9ca
AJ
10420 TCGv_i32 t0;
10421
10422 if (rd == 0) {
10423 /* Treat as NOP. */
10424 return;
10425 }
6ea83fed 10426
e214b9bb 10427 if (tf)
e214b9bb 10428 cond = TCG_COND_EQ;
27848470
TS
10429 else
10430 cond = TCG_COND_NE;
10431
af58f9ca
AJ
10432 l1 = gen_new_label();
10433 t0 = tcg_temp_new_i32();
fa31af0e 10434 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
af58f9ca 10435 tcg_gen_brcondi_i32(cond, t0, 0, l1);
a4e8338d 10436 tcg_temp_free_i32(t0);
af58f9ca
AJ
10437 if (rs == 0) {
10438 tcg_gen_movi_tl(cpu_gpr[rd], 0);
10439 } else {
10440 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
10441 }
e214b9bb 10442 gen_set_label(l1);
5a5012ec
TS
10443}
10444
7c979afd
LA
10445static inline void gen_movcf_s(DisasContext *ctx, int fs, int fd, int cc,
10446 int tf)
a16336e4 10447{
a16336e4 10448 int cond;
cbc37b28 10449 TCGv_i32 t0 = tcg_temp_new_i32();
42a268c2 10450 TCGLabel *l1 = gen_new_label();
a16336e4 10451
a16336e4
TS
10452 if (tf)
10453 cond = TCG_COND_EQ;
10454 else
10455 cond = TCG_COND_NE;
10456
fa31af0e 10457 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
cbc37b28 10458 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7c979afd
LA
10459 gen_load_fpr32(ctx, t0, fs);
10460 gen_store_fpr32(ctx, t0, fd);
a16336e4 10461 gen_set_label(l1);
cbc37b28 10462 tcg_temp_free_i32(t0);
5a5012ec 10463}
a16336e4 10464
b6d96bed 10465static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
a16336e4 10466{
a16336e4 10467 int cond;
cbc37b28
AJ
10468 TCGv_i32 t0 = tcg_temp_new_i32();
10469 TCGv_i64 fp0;
42a268c2 10470 TCGLabel *l1 = gen_new_label();
a16336e4 10471
a16336e4
TS
10472 if (tf)
10473 cond = TCG_COND_EQ;
10474 else
10475 cond = TCG_COND_NE;
10476
fa31af0e 10477 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
cbc37b28 10478 tcg_gen_brcondi_i32(cond, t0, 0, l1);
a4e8338d 10479 tcg_temp_free_i32(t0);
11f94258 10480 fp0 = tcg_temp_new_i64();
9bf3eb2c 10481 gen_load_fpr64(ctx, fp0, fs);
9bf3eb2c 10482 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10483 tcg_temp_free_i64(fp0);
cbc37b28 10484 gen_set_label(l1);
a16336e4
TS
10485}
10486
7f6613ce
PJ
10487static inline void gen_movcf_ps(DisasContext *ctx, int fs, int fd,
10488 int cc, int tf)
a16336e4
TS
10489{
10490 int cond;
cbc37b28 10491 TCGv_i32 t0 = tcg_temp_new_i32();
42a268c2
RH
10492 TCGLabel *l1 = gen_new_label();
10493 TCGLabel *l2 = gen_new_label();
a16336e4
TS
10494
10495 if (tf)
10496 cond = TCG_COND_EQ;
10497 else
10498 cond = TCG_COND_NE;
10499
fa31af0e 10500 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
cbc37b28 10501 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7c979afd
LA
10502 gen_load_fpr32(ctx, t0, fs);
10503 gen_store_fpr32(ctx, t0, fd);
a16336e4 10504 gen_set_label(l1);
9bf3eb2c 10505
fa31af0e 10506 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc+1));
cbc37b28 10507 tcg_gen_brcondi_i32(cond, t0, 0, l2);
7f6613ce
PJ
10508 gen_load_fpr32h(ctx, t0, fs);
10509 gen_store_fpr32h(ctx, t0, fd);
52a0e9eb 10510 tcg_temp_free_i32(t0);
a16336e4 10511 gen_set_label(l2);
a16336e4
TS
10512}
10513
e7f16abb
LA
10514static void gen_sel_s(DisasContext *ctx, enum fopcode op1, int fd, int ft,
10515 int fs)
10516{
10517 TCGv_i32 t1 = tcg_const_i32(0);
10518 TCGv_i32 fp0 = tcg_temp_new_i32();
10519 TCGv_i32 fp1 = tcg_temp_new_i32();
10520 TCGv_i32 fp2 = tcg_temp_new_i32();
7c979afd
LA
10521 gen_load_fpr32(ctx, fp0, fd);
10522 gen_load_fpr32(ctx, fp1, ft);
10523 gen_load_fpr32(ctx, fp2, fs);
e7f16abb
LA
10524
10525 switch (op1) {
10526 case OPC_SEL_S:
10527 tcg_gen_andi_i32(fp0, fp0, 1);
10528 tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
10529 break;
10530 case OPC_SELEQZ_S:
10531 tcg_gen_andi_i32(fp1, fp1, 1);
10532 tcg_gen_movcond_i32(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
10533 break;
10534 case OPC_SELNEZ_S:
10535 tcg_gen_andi_i32(fp1, fp1, 1);
10536 tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
10537 break;
10538 default:
10539 MIPS_INVAL("gen_sel_s");
9c708c7f 10540 generate_exception_end(ctx, EXCP_RI);
e7f16abb
LA
10541 break;
10542 }
10543
7c979afd 10544 gen_store_fpr32(ctx, fp0, fd);
e7f16abb
LA
10545 tcg_temp_free_i32(fp2);
10546 tcg_temp_free_i32(fp1);
10547 tcg_temp_free_i32(fp0);
10548 tcg_temp_free_i32(t1);
10549}
10550
10551static void gen_sel_d(DisasContext *ctx, enum fopcode op1, int fd, int ft,
10552 int fs)
10553{
10554 TCGv_i64 t1 = tcg_const_i64(0);
10555 TCGv_i64 fp0 = tcg_temp_new_i64();
10556 TCGv_i64 fp1 = tcg_temp_new_i64();
10557 TCGv_i64 fp2 = tcg_temp_new_i64();
10558 gen_load_fpr64(ctx, fp0, fd);
10559 gen_load_fpr64(ctx, fp1, ft);
10560 gen_load_fpr64(ctx, fp2, fs);
10561
10562 switch (op1) {
10563 case OPC_SEL_D:
10564 tcg_gen_andi_i64(fp0, fp0, 1);
10565 tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
10566 break;
10567 case OPC_SELEQZ_D:
10568 tcg_gen_andi_i64(fp1, fp1, 1);
10569 tcg_gen_movcond_i64(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
10570 break;
10571 case OPC_SELNEZ_D:
10572 tcg_gen_andi_i64(fp1, fp1, 1);
10573 tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
10574 break;
10575 default:
10576 MIPS_INVAL("gen_sel_d");
9c708c7f 10577 generate_exception_end(ctx, EXCP_RI);
e7f16abb
LA
10578 break;
10579 }
10580
10581 gen_store_fpr64(ctx, fp0, fd);
10582 tcg_temp_free_i64(fp2);
10583 tcg_temp_free_i64(fp1);
10584 tcg_temp_free_i64(fp0);
10585 tcg_temp_free_i64(t1);
10586}
6ea83fed 10587
bf4120ad 10588static void gen_farith (DisasContext *ctx, enum fopcode op1,
5e755519 10589 int ft, int fs, int fd, int cc)
6ea83fed 10590{
7a387fff 10591 uint32_t func = ctx->opcode & 0x3f;
bf4120ad
NF
10592 switch (op1) {
10593 case OPC_ADD_S:
b6d96bed 10594 {
a7812ae4
PB
10595 TCGv_i32 fp0 = tcg_temp_new_i32();
10596 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 10597
7c979afd
LA
10598 gen_load_fpr32(ctx, fp0, fs);
10599 gen_load_fpr32(ctx, fp1, ft);
895c2d04 10600 gen_helper_float_add_s(fp0, cpu_env, fp0, fp1);
a7812ae4 10601 tcg_temp_free_i32(fp1);
7c979afd 10602 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 10603 tcg_temp_free_i32(fp0);
b6d96bed 10604 }
5a5012ec 10605 break;
bf4120ad 10606 case OPC_SUB_S:
b6d96bed 10607 {
a7812ae4
PB
10608 TCGv_i32 fp0 = tcg_temp_new_i32();
10609 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 10610
7c979afd
LA
10611 gen_load_fpr32(ctx, fp0, fs);
10612 gen_load_fpr32(ctx, fp1, ft);
895c2d04 10613 gen_helper_float_sub_s(fp0, cpu_env, fp0, fp1);
a7812ae4 10614 tcg_temp_free_i32(fp1);
7c979afd 10615 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 10616 tcg_temp_free_i32(fp0);
b6d96bed 10617 }
5a5012ec 10618 break;
bf4120ad 10619 case OPC_MUL_S:
b6d96bed 10620 {
a7812ae4
PB
10621 TCGv_i32 fp0 = tcg_temp_new_i32();
10622 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 10623
7c979afd
LA
10624 gen_load_fpr32(ctx, fp0, fs);
10625 gen_load_fpr32(ctx, fp1, ft);
895c2d04 10626 gen_helper_float_mul_s(fp0, cpu_env, fp0, fp1);
a7812ae4 10627 tcg_temp_free_i32(fp1);
7c979afd 10628 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 10629 tcg_temp_free_i32(fp0);
b6d96bed 10630 }
5a5012ec 10631 break;
bf4120ad 10632 case OPC_DIV_S:
b6d96bed 10633 {
a7812ae4
PB
10634 TCGv_i32 fp0 = tcg_temp_new_i32();
10635 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 10636
7c979afd
LA
10637 gen_load_fpr32(ctx, fp0, fs);
10638 gen_load_fpr32(ctx, fp1, ft);
895c2d04 10639 gen_helper_float_div_s(fp0, cpu_env, fp0, fp1);
a7812ae4 10640 tcg_temp_free_i32(fp1);
7c979afd 10641 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 10642 tcg_temp_free_i32(fp0);
b6d96bed 10643 }
5a5012ec 10644 break;
bf4120ad 10645 case OPC_SQRT_S:
b6d96bed 10646 {
a7812ae4 10647 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 10648
7c979afd 10649 gen_load_fpr32(ctx, fp0, fs);
895c2d04 10650 gen_helper_float_sqrt_s(fp0, cpu_env, fp0);
7c979afd 10651 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 10652 tcg_temp_free_i32(fp0);
b6d96bed 10653 }
5a5012ec 10654 break;
bf4120ad 10655 case OPC_ABS_S:
b6d96bed 10656 {
a7812ae4 10657 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 10658
7c979afd 10659 gen_load_fpr32(ctx, fp0, fs);
6be77480
AM
10660 if (ctx->abs2008) {
10661 tcg_gen_andi_i32(fp0, fp0, 0x7fffffffUL);
10662 } else {
10663 gen_helper_float_abs_s(fp0, fp0);
10664 }
7c979afd 10665 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 10666 tcg_temp_free_i32(fp0);
b6d96bed 10667 }
5a5012ec 10668 break;
bf4120ad 10669 case OPC_MOV_S:
b6d96bed 10670 {
a7812ae4 10671 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 10672
7c979afd
LA
10673 gen_load_fpr32(ctx, fp0, fs);
10674 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 10675 tcg_temp_free_i32(fp0);
b6d96bed 10676 }
5a5012ec 10677 break;
bf4120ad 10678 case OPC_NEG_S:
b6d96bed 10679 {
a7812ae4 10680 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 10681
7c979afd 10682 gen_load_fpr32(ctx, fp0, fs);
6be77480
AM
10683 if (ctx->abs2008) {
10684 tcg_gen_xori_i32(fp0, fp0, 1UL << 31);
10685 } else {
10686 gen_helper_float_chs_s(fp0, fp0);
10687 }
7c979afd 10688 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 10689 tcg_temp_free_i32(fp0);
b6d96bed 10690 }
5a5012ec 10691 break;
bf4120ad 10692 case OPC_ROUND_L_S:
5e755519 10693 check_cp1_64bitmode(ctx);
b6d96bed 10694 {
a7812ae4
PB
10695 TCGv_i32 fp32 = tcg_temp_new_i32();
10696 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 10697
7c979afd 10698 gen_load_fpr32(ctx, fp32, fs);
87552089
AM
10699 if (ctx->nan2008) {
10700 gen_helper_float_round_2008_l_s(fp64, cpu_env, fp32);
10701 } else {
10702 gen_helper_float_round_l_s(fp64, cpu_env, fp32);
10703 }
a7812ae4 10704 tcg_temp_free_i32(fp32);
b6d96bed 10705 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 10706 tcg_temp_free_i64(fp64);
b6d96bed 10707 }
5a5012ec 10708 break;
bf4120ad 10709 case OPC_TRUNC_L_S:
5e755519 10710 check_cp1_64bitmode(ctx);
b6d96bed 10711 {
a7812ae4
PB
10712 TCGv_i32 fp32 = tcg_temp_new_i32();
10713 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 10714
7c979afd 10715 gen_load_fpr32(ctx, fp32, fs);
87552089
AM
10716 if (ctx->nan2008) {
10717 gen_helper_float_trunc_2008_l_s(fp64, cpu_env, fp32);
10718 } else {
10719 gen_helper_float_trunc_l_s(fp64, cpu_env, fp32);
10720 }
a7812ae4 10721 tcg_temp_free_i32(fp32);
b6d96bed 10722 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 10723 tcg_temp_free_i64(fp64);
b6d96bed 10724 }
5a5012ec 10725 break;
bf4120ad 10726 case OPC_CEIL_L_S:
5e755519 10727 check_cp1_64bitmode(ctx);
b6d96bed 10728 {
a7812ae4
PB
10729 TCGv_i32 fp32 = tcg_temp_new_i32();
10730 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 10731
7c979afd 10732 gen_load_fpr32(ctx, fp32, fs);
87552089
AM
10733 if (ctx->nan2008) {
10734 gen_helper_float_ceil_2008_l_s(fp64, cpu_env, fp32);
10735 } else {
10736 gen_helper_float_ceil_l_s(fp64, cpu_env, fp32);
10737 }
a7812ae4 10738 tcg_temp_free_i32(fp32);
b6d96bed 10739 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 10740 tcg_temp_free_i64(fp64);
b6d96bed 10741 }
5a5012ec 10742 break;
bf4120ad 10743 case OPC_FLOOR_L_S:
5e755519 10744 check_cp1_64bitmode(ctx);
b6d96bed 10745 {
a7812ae4
PB
10746 TCGv_i32 fp32 = tcg_temp_new_i32();
10747 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 10748
7c979afd 10749 gen_load_fpr32(ctx, fp32, fs);
87552089
AM
10750 if (ctx->nan2008) {
10751 gen_helper_float_floor_2008_l_s(fp64, cpu_env, fp32);
10752 } else {
10753 gen_helper_float_floor_l_s(fp64, cpu_env, fp32);
10754 }
a7812ae4 10755 tcg_temp_free_i32(fp32);
b6d96bed 10756 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 10757 tcg_temp_free_i64(fp64);
b6d96bed 10758 }
5a5012ec 10759 break;
bf4120ad 10760 case OPC_ROUND_W_S:
b6d96bed 10761 {
a7812ae4 10762 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 10763
7c979afd 10764 gen_load_fpr32(ctx, fp0, fs);
87552089
AM
10765 if (ctx->nan2008) {
10766 gen_helper_float_round_2008_w_s(fp0, cpu_env, fp0);
10767 } else {
10768 gen_helper_float_round_w_s(fp0, cpu_env, fp0);
10769 }
7c979afd 10770 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 10771 tcg_temp_free_i32(fp0);
b6d96bed 10772 }
5a5012ec 10773 break;
bf4120ad 10774 case OPC_TRUNC_W_S:
b6d96bed 10775 {
a7812ae4 10776 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 10777
7c979afd 10778 gen_load_fpr32(ctx, fp0, fs);
87552089
AM
10779 if (ctx->nan2008) {
10780 gen_helper_float_trunc_2008_w_s(fp0, cpu_env, fp0);
10781 } else {
10782 gen_helper_float_trunc_w_s(fp0, cpu_env, fp0);
10783 }
7c979afd 10784 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 10785 tcg_temp_free_i32(fp0);
b6d96bed 10786 }
5a5012ec 10787 break;
bf4120ad 10788 case OPC_CEIL_W_S:
b6d96bed 10789 {
a7812ae4 10790 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 10791
7c979afd 10792 gen_load_fpr32(ctx, fp0, fs);
87552089
AM
10793 if (ctx->nan2008) {
10794 gen_helper_float_ceil_2008_w_s(fp0, cpu_env, fp0);
10795 } else {
10796 gen_helper_float_ceil_w_s(fp0, cpu_env, fp0);
10797 }
7c979afd 10798 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 10799 tcg_temp_free_i32(fp0);
b6d96bed 10800 }
5a5012ec 10801 break;
bf4120ad 10802 case OPC_FLOOR_W_S:
b6d96bed 10803 {
a7812ae4 10804 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 10805
7c979afd 10806 gen_load_fpr32(ctx, fp0, fs);
87552089
AM
10807 if (ctx->nan2008) {
10808 gen_helper_float_floor_2008_w_s(fp0, cpu_env, fp0);
10809 } else {
10810 gen_helper_float_floor_w_s(fp0, cpu_env, fp0);
10811 }
7c979afd 10812 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 10813 tcg_temp_free_i32(fp0);
b6d96bed 10814 }
5a5012ec 10815 break;
e7f16abb
LA
10816 case OPC_SEL_S:
10817 check_insn(ctx, ISA_MIPS32R6);
10818 gen_sel_s(ctx, op1, fd, ft, fs);
e7f16abb
LA
10819 break;
10820 case OPC_SELEQZ_S:
10821 check_insn(ctx, ISA_MIPS32R6);
10822 gen_sel_s(ctx, op1, fd, ft, fs);
e7f16abb
LA
10823 break;
10824 case OPC_SELNEZ_S:
10825 check_insn(ctx, ISA_MIPS32R6);
10826 gen_sel_s(ctx, op1, fd, ft, fs);
e7f16abb 10827 break;
bf4120ad 10828 case OPC_MOVCF_S:
fecd2646 10829 check_insn_opc_removed(ctx, ISA_MIPS32R6);
7c979afd 10830 gen_movcf_s(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
5a5012ec 10831 break;
bf4120ad 10832 case OPC_MOVZ_S:
fecd2646 10833 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a16336e4 10834 {
42a268c2 10835 TCGLabel *l1 = gen_new_label();
c9297f4d 10836 TCGv_i32 fp0;
a16336e4 10837
c9297f4d
AJ
10838 if (ft != 0) {
10839 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
10840 }
10841 fp0 = tcg_temp_new_i32();
7c979afd
LA
10842 gen_load_fpr32(ctx, fp0, fs);
10843 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 10844 tcg_temp_free_i32(fp0);
a16336e4
TS
10845 gen_set_label(l1);
10846 }
5a5012ec 10847 break;
bf4120ad 10848 case OPC_MOVN_S:
fecd2646 10849 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a16336e4 10850 {
42a268c2 10851 TCGLabel *l1 = gen_new_label();
c9297f4d
AJ
10852 TCGv_i32 fp0;
10853
10854 if (ft != 0) {
10855 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
10856 fp0 = tcg_temp_new_i32();
7c979afd
LA
10857 gen_load_fpr32(ctx, fp0, fs);
10858 gen_store_fpr32(ctx, fp0, fd);
c9297f4d
AJ
10859 tcg_temp_free_i32(fp0);
10860 gen_set_label(l1);
10861 }
a16336e4 10862 }
5a5012ec 10863 break;
bf4120ad 10864 case OPC_RECIP_S:
b6d96bed 10865 {
a7812ae4 10866 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 10867
7c979afd 10868 gen_load_fpr32(ctx, fp0, fs);
895c2d04 10869 gen_helper_float_recip_s(fp0, cpu_env, fp0);
7c979afd 10870 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 10871 tcg_temp_free_i32(fp0);
b6d96bed 10872 }
57fa1fb3 10873 break;
bf4120ad 10874 case OPC_RSQRT_S:
b6d96bed 10875 {
a7812ae4 10876 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 10877
7c979afd 10878 gen_load_fpr32(ctx, fp0, fs);
895c2d04 10879 gen_helper_float_rsqrt_s(fp0, cpu_env, fp0);
7c979afd 10880 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 10881 tcg_temp_free_i32(fp0);
b6d96bed 10882 }
57fa1fb3 10883 break;
e7f16abb
LA
10884 case OPC_MADDF_S:
10885 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 10886 {
a7812ae4
PB
10887 TCGv_i32 fp0 = tcg_temp_new_i32();
10888 TCGv_i32 fp1 = tcg_temp_new_i32();
e7f16abb 10889 TCGv_i32 fp2 = tcg_temp_new_i32();
7c979afd
LA
10890 gen_load_fpr32(ctx, fp0, fs);
10891 gen_load_fpr32(ctx, fp1, ft);
10892 gen_load_fpr32(ctx, fp2, fd);
e7f16abb 10893 gen_helper_float_maddf_s(fp2, cpu_env, fp0, fp1, fp2);
7c979afd 10894 gen_store_fpr32(ctx, fp2, fd);
e7f16abb 10895 tcg_temp_free_i32(fp2);
a7812ae4 10896 tcg_temp_free_i32(fp1);
a7812ae4 10897 tcg_temp_free_i32(fp0);
b6d96bed 10898 }
57fa1fb3 10899 break;
e7f16abb
LA
10900 case OPC_MSUBF_S:
10901 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 10902 {
a7812ae4 10903 TCGv_i32 fp0 = tcg_temp_new_i32();
e7f16abb
LA
10904 TCGv_i32 fp1 = tcg_temp_new_i32();
10905 TCGv_i32 fp2 = tcg_temp_new_i32();
7c979afd
LA
10906 gen_load_fpr32(ctx, fp0, fs);
10907 gen_load_fpr32(ctx, fp1, ft);
10908 gen_load_fpr32(ctx, fp2, fd);
e7f16abb 10909 gen_helper_float_msubf_s(fp2, cpu_env, fp0, fp1, fp2);
7c979afd 10910 gen_store_fpr32(ctx, fp2, fd);
e7f16abb
LA
10911 tcg_temp_free_i32(fp2);
10912 tcg_temp_free_i32(fp1);
a7812ae4 10913 tcg_temp_free_i32(fp0);
b6d96bed 10914 }
57fa1fb3 10915 break;
e7f16abb
LA
10916 case OPC_RINT_S:
10917 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 10918 {
a7812ae4 10919 TCGv_i32 fp0 = tcg_temp_new_i32();
7c979afd 10920 gen_load_fpr32(ctx, fp0, fs);
e7f16abb 10921 gen_helper_float_rint_s(fp0, cpu_env, fp0);
7c979afd 10922 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 10923 tcg_temp_free_i32(fp0);
b6d96bed 10924 }
57fa1fb3 10925 break;
e7f16abb
LA
10926 case OPC_CLASS_S:
10927 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 10928 {
e7f16abb 10929 TCGv_i32 fp0 = tcg_temp_new_i32();
7c979afd 10930 gen_load_fpr32(ctx, fp0, fs);
af39bc8c 10931 gen_helper_float_class_s(fp0, cpu_env, fp0);
7c979afd 10932 gen_store_fpr32(ctx, fp0, fd);
e7f16abb 10933 tcg_temp_free_i32(fp0);
e7f16abb
LA
10934 }
10935 break;
10936 case OPC_MIN_S: /* OPC_RECIP2_S */
10937 if (ctx->insn_flags & ISA_MIPS32R6) {
10938 /* OPC_MIN_S */
a7812ae4
PB
10939 TCGv_i32 fp0 = tcg_temp_new_i32();
10940 TCGv_i32 fp1 = tcg_temp_new_i32();
e7f16abb 10941 TCGv_i32 fp2 = tcg_temp_new_i32();
7c979afd
LA
10942 gen_load_fpr32(ctx, fp0, fs);
10943 gen_load_fpr32(ctx, fp1, ft);
e7f16abb 10944 gen_helper_float_min_s(fp2, cpu_env, fp0, fp1);
7c979afd 10945 gen_store_fpr32(ctx, fp2, fd);
e7f16abb
LA
10946 tcg_temp_free_i32(fp2);
10947 tcg_temp_free_i32(fp1);
10948 tcg_temp_free_i32(fp0);
e7f16abb
LA
10949 } else {
10950 /* OPC_RECIP2_S */
10951 check_cp1_64bitmode(ctx);
10952 {
10953 TCGv_i32 fp0 = tcg_temp_new_i32();
10954 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 10955
7c979afd
LA
10956 gen_load_fpr32(ctx, fp0, fs);
10957 gen_load_fpr32(ctx, fp1, ft);
e7f16abb
LA
10958 gen_helper_float_recip2_s(fp0, cpu_env, fp0, fp1);
10959 tcg_temp_free_i32(fp1);
7c979afd 10960 gen_store_fpr32(ctx, fp0, fd);
e7f16abb
LA
10961 tcg_temp_free_i32(fp0);
10962 }
e7f16abb
LA
10963 }
10964 break;
10965 case OPC_MINA_S: /* OPC_RECIP1_S */
10966 if (ctx->insn_flags & ISA_MIPS32R6) {
10967 /* OPC_MINA_S */
10968 TCGv_i32 fp0 = tcg_temp_new_i32();
10969 TCGv_i32 fp1 = tcg_temp_new_i32();
10970 TCGv_i32 fp2 = tcg_temp_new_i32();
7c979afd
LA
10971 gen_load_fpr32(ctx, fp0, fs);
10972 gen_load_fpr32(ctx, fp1, ft);
e7f16abb 10973 gen_helper_float_mina_s(fp2, cpu_env, fp0, fp1);
7c979afd 10974 gen_store_fpr32(ctx, fp2, fd);
e7f16abb
LA
10975 tcg_temp_free_i32(fp2);
10976 tcg_temp_free_i32(fp1);
10977 tcg_temp_free_i32(fp0);
e7f16abb
LA
10978 } else {
10979 /* OPC_RECIP1_S */
10980 check_cp1_64bitmode(ctx);
10981 {
10982 TCGv_i32 fp0 = tcg_temp_new_i32();
10983
7c979afd 10984 gen_load_fpr32(ctx, fp0, fs);
e7f16abb 10985 gen_helper_float_recip1_s(fp0, cpu_env, fp0);
7c979afd 10986 gen_store_fpr32(ctx, fp0, fd);
e7f16abb
LA
10987 tcg_temp_free_i32(fp0);
10988 }
e7f16abb
LA
10989 }
10990 break;
10991 case OPC_MAX_S: /* OPC_RSQRT1_S */
10992 if (ctx->insn_flags & ISA_MIPS32R6) {
10993 /* OPC_MAX_S */
10994 TCGv_i32 fp0 = tcg_temp_new_i32();
10995 TCGv_i32 fp1 = tcg_temp_new_i32();
7c979afd
LA
10996 gen_load_fpr32(ctx, fp0, fs);
10997 gen_load_fpr32(ctx, fp1, ft);
e7f16abb 10998 gen_helper_float_max_s(fp1, cpu_env, fp0, fp1);
7c979afd 10999 gen_store_fpr32(ctx, fp1, fd);
e7f16abb
LA
11000 tcg_temp_free_i32(fp1);
11001 tcg_temp_free_i32(fp0);
e7f16abb
LA
11002 } else {
11003 /* OPC_RSQRT1_S */
11004 check_cp1_64bitmode(ctx);
11005 {
11006 TCGv_i32 fp0 = tcg_temp_new_i32();
11007
7c979afd 11008 gen_load_fpr32(ctx, fp0, fs);
e7f16abb 11009 gen_helper_float_rsqrt1_s(fp0, cpu_env, fp0);
7c979afd 11010 gen_store_fpr32(ctx, fp0, fd);
e7f16abb
LA
11011 tcg_temp_free_i32(fp0);
11012 }
e7f16abb
LA
11013 }
11014 break;
11015 case OPC_MAXA_S: /* OPC_RSQRT2_S */
11016 if (ctx->insn_flags & ISA_MIPS32R6) {
11017 /* OPC_MAXA_S */
11018 TCGv_i32 fp0 = tcg_temp_new_i32();
11019 TCGv_i32 fp1 = tcg_temp_new_i32();
7c979afd
LA
11020 gen_load_fpr32(ctx, fp0, fs);
11021 gen_load_fpr32(ctx, fp1, ft);
e7f16abb 11022 gen_helper_float_maxa_s(fp1, cpu_env, fp0, fp1);
7c979afd 11023 gen_store_fpr32(ctx, fp1, fd);
a7812ae4 11024 tcg_temp_free_i32(fp1);
a7812ae4 11025 tcg_temp_free_i32(fp0);
e7f16abb
LA
11026 } else {
11027 /* OPC_RSQRT2_S */
11028 check_cp1_64bitmode(ctx);
11029 {
11030 TCGv_i32 fp0 = tcg_temp_new_i32();
11031 TCGv_i32 fp1 = tcg_temp_new_i32();
11032
7c979afd
LA
11033 gen_load_fpr32(ctx, fp0, fs);
11034 gen_load_fpr32(ctx, fp1, ft);
e7f16abb
LA
11035 gen_helper_float_rsqrt2_s(fp0, cpu_env, fp0, fp1);
11036 tcg_temp_free_i32(fp1);
7c979afd 11037 gen_store_fpr32(ctx, fp0, fd);
e7f16abb
LA
11038 tcg_temp_free_i32(fp0);
11039 }
b6d96bed 11040 }
57fa1fb3 11041 break;
bf4120ad 11042 case OPC_CVT_D_S:
5e755519 11043 check_cp1_registers(ctx, fd);
b6d96bed 11044 {
a7812ae4
PB
11045 TCGv_i32 fp32 = tcg_temp_new_i32();
11046 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 11047
7c979afd 11048 gen_load_fpr32(ctx, fp32, fs);
895c2d04 11049 gen_helper_float_cvtd_s(fp64, cpu_env, fp32);
a7812ae4 11050 tcg_temp_free_i32(fp32);
b6d96bed 11051 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 11052 tcg_temp_free_i64(fp64);
b6d96bed 11053 }
5a5012ec 11054 break;
bf4120ad 11055 case OPC_CVT_W_S:
b6d96bed 11056 {
a7812ae4 11057 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 11058
7c979afd 11059 gen_load_fpr32(ctx, fp0, fs);
87552089
AM
11060 if (ctx->nan2008) {
11061 gen_helper_float_cvt_2008_w_s(fp0, cpu_env, fp0);
11062 } else {
11063 gen_helper_float_cvt_w_s(fp0, cpu_env, fp0);
11064 }
7c979afd 11065 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 11066 tcg_temp_free_i32(fp0);
b6d96bed 11067 }
5a5012ec 11068 break;
bf4120ad 11069 case OPC_CVT_L_S:
5e755519 11070 check_cp1_64bitmode(ctx);
b6d96bed 11071 {
a7812ae4
PB
11072 TCGv_i32 fp32 = tcg_temp_new_i32();
11073 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 11074
7c979afd 11075 gen_load_fpr32(ctx, fp32, fs);
87552089
AM
11076 if (ctx->nan2008) {
11077 gen_helper_float_cvt_2008_l_s(fp64, cpu_env, fp32);
11078 } else {
11079 gen_helper_float_cvt_l_s(fp64, cpu_env, fp32);
11080 }
a7812ae4 11081 tcg_temp_free_i32(fp32);
b6d96bed 11082 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 11083 tcg_temp_free_i64(fp64);
b6d96bed 11084 }
5a5012ec 11085 break;
bf4120ad 11086 case OPC_CVT_PS_S:
e29c9628 11087 check_ps(ctx);
b6d96bed 11088 {
a7812ae4
PB
11089 TCGv_i64 fp64 = tcg_temp_new_i64();
11090 TCGv_i32 fp32_0 = tcg_temp_new_i32();
11091 TCGv_i32 fp32_1 = tcg_temp_new_i32();
b6d96bed 11092
7c979afd
LA
11093 gen_load_fpr32(ctx, fp32_0, fs);
11094 gen_load_fpr32(ctx, fp32_1, ft);
13d24f49 11095 tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0);
a7812ae4
PB
11096 tcg_temp_free_i32(fp32_1);
11097 tcg_temp_free_i32(fp32_0);
36aa55dc 11098 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 11099 tcg_temp_free_i64(fp64);
b6d96bed 11100 }
5a5012ec 11101 break;
bf4120ad
NF
11102 case OPC_CMP_F_S:
11103 case OPC_CMP_UN_S:
11104 case OPC_CMP_EQ_S:
11105 case OPC_CMP_UEQ_S:
11106 case OPC_CMP_OLT_S:
11107 case OPC_CMP_ULT_S:
11108 case OPC_CMP_OLE_S:
11109 case OPC_CMP_ULE_S:
11110 case OPC_CMP_SF_S:
11111 case OPC_CMP_NGLE_S:
11112 case OPC_CMP_SEQ_S:
11113 case OPC_CMP_NGL_S:
11114 case OPC_CMP_LT_S:
11115 case OPC_CMP_NGE_S:
11116 case OPC_CMP_LE_S:
11117 case OPC_CMP_NGT_S:
fecd2646 11118 check_insn_opc_removed(ctx, ISA_MIPS32R6);
8153667c
NF
11119 if (ctx->opcode & (1 << 6)) {
11120 gen_cmpabs_s(ctx, func-48, ft, fs, cc);
8153667c
NF
11121 } else {
11122 gen_cmp_s(ctx, func-48, ft, fs, cc);
5a1e8ffb 11123 }
5a5012ec 11124 break;
bf4120ad 11125 case OPC_ADD_D:
5e755519 11126 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 11127 {
a7812ae4
PB
11128 TCGv_i64 fp0 = tcg_temp_new_i64();
11129 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
11130
11131 gen_load_fpr64(ctx, fp0, fs);
11132 gen_load_fpr64(ctx, fp1, ft);
895c2d04 11133 gen_helper_float_add_d(fp0, cpu_env, fp0, fp1);
a7812ae4 11134 tcg_temp_free_i64(fp1);
b6d96bed 11135 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11136 tcg_temp_free_i64(fp0);
b6d96bed 11137 }
6ea83fed 11138 break;
bf4120ad 11139 case OPC_SUB_D:
5e755519 11140 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 11141 {
a7812ae4
PB
11142 TCGv_i64 fp0 = tcg_temp_new_i64();
11143 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
11144
11145 gen_load_fpr64(ctx, fp0, fs);
11146 gen_load_fpr64(ctx, fp1, ft);
895c2d04 11147 gen_helper_float_sub_d(fp0, cpu_env, fp0, fp1);
a7812ae4 11148 tcg_temp_free_i64(fp1);
b6d96bed 11149 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11150 tcg_temp_free_i64(fp0);
b6d96bed 11151 }
6ea83fed 11152 break;
bf4120ad 11153 case OPC_MUL_D:
5e755519 11154 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 11155 {
a7812ae4
PB
11156 TCGv_i64 fp0 = tcg_temp_new_i64();
11157 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
11158
11159 gen_load_fpr64(ctx, fp0, fs);
11160 gen_load_fpr64(ctx, fp1, ft);
895c2d04 11161 gen_helper_float_mul_d(fp0, cpu_env, fp0, fp1);
a7812ae4 11162 tcg_temp_free_i64(fp1);
b6d96bed 11163 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11164 tcg_temp_free_i64(fp0);
b6d96bed 11165 }
6ea83fed 11166 break;
bf4120ad 11167 case OPC_DIV_D:
5e755519 11168 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 11169 {
a7812ae4
PB
11170 TCGv_i64 fp0 = tcg_temp_new_i64();
11171 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
11172
11173 gen_load_fpr64(ctx, fp0, fs);
11174 gen_load_fpr64(ctx, fp1, ft);
895c2d04 11175 gen_helper_float_div_d(fp0, cpu_env, fp0, fp1);
a7812ae4 11176 tcg_temp_free_i64(fp1);
b6d96bed 11177 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11178 tcg_temp_free_i64(fp0);
b6d96bed 11179 }
6ea83fed 11180 break;
bf4120ad 11181 case OPC_SQRT_D:
5e755519 11182 check_cp1_registers(ctx, fs | fd);
b6d96bed 11183 {
a7812ae4 11184 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
11185
11186 gen_load_fpr64(ctx, fp0, fs);
895c2d04 11187 gen_helper_float_sqrt_d(fp0, cpu_env, fp0);
b6d96bed 11188 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11189 tcg_temp_free_i64(fp0);
b6d96bed 11190 }
6ea83fed 11191 break;
bf4120ad 11192 case OPC_ABS_D:
5e755519 11193 check_cp1_registers(ctx, fs | fd);
b6d96bed 11194 {
a7812ae4 11195 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
11196
11197 gen_load_fpr64(ctx, fp0, fs);
6be77480
AM
11198 if (ctx->abs2008) {
11199 tcg_gen_andi_i64(fp0, fp0, 0x7fffffffffffffffULL);
11200 } else {
11201 gen_helper_float_abs_d(fp0, fp0);
11202 }
b6d96bed 11203 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11204 tcg_temp_free_i64(fp0);
b6d96bed 11205 }
6ea83fed 11206 break;
bf4120ad 11207 case OPC_MOV_D:
5e755519 11208 check_cp1_registers(ctx, fs | fd);
b6d96bed 11209 {
a7812ae4 11210 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
11211
11212 gen_load_fpr64(ctx, fp0, fs);
11213 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11214 tcg_temp_free_i64(fp0);
b6d96bed 11215 }
6ea83fed 11216 break;
bf4120ad 11217 case OPC_NEG_D:
5e755519 11218 check_cp1_registers(ctx, fs | fd);
b6d96bed 11219 {
a7812ae4 11220 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
11221
11222 gen_load_fpr64(ctx, fp0, fs);
6be77480
AM
11223 if (ctx->abs2008) {
11224 tcg_gen_xori_i64(fp0, fp0, 1ULL << 63);
11225 } else {
11226 gen_helper_float_chs_d(fp0, fp0);
11227 }
b6d96bed 11228 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11229 tcg_temp_free_i64(fp0);
b6d96bed 11230 }
6ea83fed 11231 break;
bf4120ad 11232 case OPC_ROUND_L_D:
5e755519 11233 check_cp1_64bitmode(ctx);
b6d96bed 11234 {
a7812ae4 11235 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
11236
11237 gen_load_fpr64(ctx, fp0, fs);
87552089
AM
11238 if (ctx->nan2008) {
11239 gen_helper_float_round_2008_l_d(fp0, cpu_env, fp0);
11240 } else {
11241 gen_helper_float_round_l_d(fp0, cpu_env, fp0);
11242 }
b6d96bed 11243 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11244 tcg_temp_free_i64(fp0);
b6d96bed 11245 }
5a5012ec 11246 break;
bf4120ad 11247 case OPC_TRUNC_L_D:
5e755519 11248 check_cp1_64bitmode(ctx);
b6d96bed 11249 {
a7812ae4 11250 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
11251
11252 gen_load_fpr64(ctx, fp0, fs);
87552089
AM
11253 if (ctx->nan2008) {
11254 gen_helper_float_trunc_2008_l_d(fp0, cpu_env, fp0);
11255 } else {
11256 gen_helper_float_trunc_l_d(fp0, cpu_env, fp0);
11257 }
b6d96bed 11258 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11259 tcg_temp_free_i64(fp0);
b6d96bed 11260 }
5a5012ec 11261 break;
bf4120ad 11262 case OPC_CEIL_L_D:
5e755519 11263 check_cp1_64bitmode(ctx);
b6d96bed 11264 {
a7812ae4 11265 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
11266
11267 gen_load_fpr64(ctx, fp0, fs);
87552089
AM
11268 if (ctx->nan2008) {
11269 gen_helper_float_ceil_2008_l_d(fp0, cpu_env, fp0);
11270 } else {
11271 gen_helper_float_ceil_l_d(fp0, cpu_env, fp0);
11272 }
b6d96bed 11273 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11274 tcg_temp_free_i64(fp0);
b6d96bed 11275 }
5a5012ec 11276 break;
bf4120ad 11277 case OPC_FLOOR_L_D:
5e755519 11278 check_cp1_64bitmode(ctx);
b6d96bed 11279 {
a7812ae4 11280 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
11281
11282 gen_load_fpr64(ctx, fp0, fs);
87552089
AM
11283 if (ctx->nan2008) {
11284 gen_helper_float_floor_2008_l_d(fp0, cpu_env, fp0);
11285 } else {
11286 gen_helper_float_floor_l_d(fp0, cpu_env, fp0);
11287 }
b6d96bed 11288 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11289 tcg_temp_free_i64(fp0);
b6d96bed 11290 }
5a5012ec 11291 break;
bf4120ad 11292 case OPC_ROUND_W_D:
5e755519 11293 check_cp1_registers(ctx, fs);
b6d96bed 11294 {
a7812ae4
PB
11295 TCGv_i32 fp32 = tcg_temp_new_i32();
11296 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
11297
11298 gen_load_fpr64(ctx, fp64, fs);
87552089
AM
11299 if (ctx->nan2008) {
11300 gen_helper_float_round_2008_w_d(fp32, cpu_env, fp64);
11301 } else {
11302 gen_helper_float_round_w_d(fp32, cpu_env, fp64);
11303 }
a7812ae4 11304 tcg_temp_free_i64(fp64);
7c979afd 11305 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 11306 tcg_temp_free_i32(fp32);
b6d96bed 11307 }
6ea83fed 11308 break;
bf4120ad 11309 case OPC_TRUNC_W_D:
5e755519 11310 check_cp1_registers(ctx, fs);
b6d96bed 11311 {
a7812ae4
PB
11312 TCGv_i32 fp32 = tcg_temp_new_i32();
11313 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
11314
11315 gen_load_fpr64(ctx, fp64, fs);
87552089
AM
11316 if (ctx->nan2008) {
11317 gen_helper_float_trunc_2008_w_d(fp32, cpu_env, fp64);
11318 } else {
11319 gen_helper_float_trunc_w_d(fp32, cpu_env, fp64);
11320 }
a7812ae4 11321 tcg_temp_free_i64(fp64);
7c979afd 11322 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 11323 tcg_temp_free_i32(fp32);
b6d96bed 11324 }
6ea83fed 11325 break;
bf4120ad 11326 case OPC_CEIL_W_D:
5e755519 11327 check_cp1_registers(ctx, fs);
b6d96bed 11328 {
a7812ae4
PB
11329 TCGv_i32 fp32 = tcg_temp_new_i32();
11330 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
11331
11332 gen_load_fpr64(ctx, fp64, fs);
87552089
AM
11333 if (ctx->nan2008) {
11334 gen_helper_float_ceil_2008_w_d(fp32, cpu_env, fp64);
11335 } else {
11336 gen_helper_float_ceil_w_d(fp32, cpu_env, fp64);
11337 }
a7812ae4 11338 tcg_temp_free_i64(fp64);
7c979afd 11339 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 11340 tcg_temp_free_i32(fp32);
b6d96bed 11341 }
6ea83fed 11342 break;
bf4120ad 11343 case OPC_FLOOR_W_D:
5e755519 11344 check_cp1_registers(ctx, fs);
b6d96bed 11345 {
a7812ae4
PB
11346 TCGv_i32 fp32 = tcg_temp_new_i32();
11347 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
11348
11349 gen_load_fpr64(ctx, fp64, fs);
87552089
AM
11350 if (ctx->nan2008) {
11351 gen_helper_float_floor_2008_w_d(fp32, cpu_env, fp64);
11352 } else {
11353 gen_helper_float_floor_w_d(fp32, cpu_env, fp64);
11354 }
a7812ae4 11355 tcg_temp_free_i64(fp64);
7c979afd 11356 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 11357 tcg_temp_free_i32(fp32);
b6d96bed 11358 }
6ea83fed 11359 break;
e7f16abb
LA
11360 case OPC_SEL_D:
11361 check_insn(ctx, ISA_MIPS32R6);
11362 gen_sel_d(ctx, op1, fd, ft, fs);
e7f16abb
LA
11363 break;
11364 case OPC_SELEQZ_D:
11365 check_insn(ctx, ISA_MIPS32R6);
11366 gen_sel_d(ctx, op1, fd, ft, fs);
e7f16abb
LA
11367 break;
11368 case OPC_SELNEZ_D:
11369 check_insn(ctx, ISA_MIPS32R6);
11370 gen_sel_d(ctx, op1, fd, ft, fs);
e7f16abb 11371 break;
bf4120ad 11372 case OPC_MOVCF_D:
fecd2646 11373 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b6d96bed 11374 gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
dd016883 11375 break;
bf4120ad 11376 case OPC_MOVZ_D:
fecd2646 11377 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a16336e4 11378 {
42a268c2 11379 TCGLabel *l1 = gen_new_label();
c9297f4d 11380 TCGv_i64 fp0;
a16336e4 11381
c9297f4d
AJ
11382 if (ft != 0) {
11383 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
11384 }
11385 fp0 = tcg_temp_new_i64();
b6d96bed
TS
11386 gen_load_fpr64(ctx, fp0, fs);
11387 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11388 tcg_temp_free_i64(fp0);
a16336e4
TS
11389 gen_set_label(l1);
11390 }
5a5012ec 11391 break;
bf4120ad 11392 case OPC_MOVN_D:
fecd2646 11393 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a16336e4 11394 {
42a268c2 11395 TCGLabel *l1 = gen_new_label();
c9297f4d
AJ
11396 TCGv_i64 fp0;
11397
11398 if (ft != 0) {
11399 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
11400 fp0 = tcg_temp_new_i64();
11401 gen_load_fpr64(ctx, fp0, fs);
11402 gen_store_fpr64(ctx, fp0, fd);
11403 tcg_temp_free_i64(fp0);
11404 gen_set_label(l1);
11405 }
a16336e4 11406 }
6ea83fed 11407 break;
bf4120ad 11408 case OPC_RECIP_D:
ca6c7803 11409 check_cp1_registers(ctx, fs | fd);
b6d96bed 11410 {
a7812ae4 11411 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
11412
11413 gen_load_fpr64(ctx, fp0, fs);
895c2d04 11414 gen_helper_float_recip_d(fp0, cpu_env, fp0);
b6d96bed 11415 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11416 tcg_temp_free_i64(fp0);
b6d96bed 11417 }
57fa1fb3 11418 break;
bf4120ad 11419 case OPC_RSQRT_D:
ca6c7803 11420 check_cp1_registers(ctx, fs | fd);
b6d96bed 11421 {
a7812ae4 11422 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
11423
11424 gen_load_fpr64(ctx, fp0, fs);
895c2d04 11425 gen_helper_float_rsqrt_d(fp0, cpu_env, fp0);
b6d96bed 11426 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11427 tcg_temp_free_i64(fp0);
b6d96bed 11428 }
57fa1fb3 11429 break;
e7f16abb
LA
11430 case OPC_MADDF_D:
11431 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 11432 {
a7812ae4
PB
11433 TCGv_i64 fp0 = tcg_temp_new_i64();
11434 TCGv_i64 fp1 = tcg_temp_new_i64();
e7f16abb 11435 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
11436 gen_load_fpr64(ctx, fp0, fs);
11437 gen_load_fpr64(ctx, fp1, ft);
e7f16abb
LA
11438 gen_load_fpr64(ctx, fp2, fd);
11439 gen_helper_float_maddf_d(fp2, cpu_env, fp0, fp1, fp2);
11440 gen_store_fpr64(ctx, fp2, fd);
11441 tcg_temp_free_i64(fp2);
a7812ae4 11442 tcg_temp_free_i64(fp1);
a7812ae4 11443 tcg_temp_free_i64(fp0);
b6d96bed 11444 }
57fa1fb3 11445 break;
e7f16abb
LA
11446 case OPC_MSUBF_D:
11447 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 11448 {
a7812ae4 11449 TCGv_i64 fp0 = tcg_temp_new_i64();
e7f16abb
LA
11450 TCGv_i64 fp1 = tcg_temp_new_i64();
11451 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed 11452 gen_load_fpr64(ctx, fp0, fs);
e7f16abb
LA
11453 gen_load_fpr64(ctx, fp1, ft);
11454 gen_load_fpr64(ctx, fp2, fd);
11455 gen_helper_float_msubf_d(fp2, cpu_env, fp0, fp1, fp2);
11456 gen_store_fpr64(ctx, fp2, fd);
11457 tcg_temp_free_i64(fp2);
11458 tcg_temp_free_i64(fp1);
a7812ae4 11459 tcg_temp_free_i64(fp0);
b6d96bed 11460 }
57fa1fb3 11461 break;
e7f16abb
LA
11462 case OPC_RINT_D:
11463 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 11464 {
a7812ae4 11465 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 11466 gen_load_fpr64(ctx, fp0, fs);
e7f16abb 11467 gen_helper_float_rint_d(fp0, cpu_env, fp0);
b6d96bed 11468 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11469 tcg_temp_free_i64(fp0);
b6d96bed 11470 }
57fa1fb3 11471 break;
e7f16abb
LA
11472 case OPC_CLASS_D:
11473 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 11474 {
e7f16abb
LA
11475 TCGv_i64 fp0 = tcg_temp_new_i64();
11476 gen_load_fpr64(ctx, fp0, fs);
af39bc8c 11477 gen_helper_float_class_d(fp0, cpu_env, fp0);
e7f16abb
LA
11478 gen_store_fpr64(ctx, fp0, fd);
11479 tcg_temp_free_i64(fp0);
e7f16abb
LA
11480 }
11481 break;
11482 case OPC_MIN_D: /* OPC_RECIP2_D */
11483 if (ctx->insn_flags & ISA_MIPS32R6) {
11484 /* OPC_MIN_D */
a7812ae4
PB
11485 TCGv_i64 fp0 = tcg_temp_new_i64();
11486 TCGv_i64 fp1 = tcg_temp_new_i64();
e7f16abb
LA
11487 gen_load_fpr64(ctx, fp0, fs);
11488 gen_load_fpr64(ctx, fp1, ft);
11489 gen_helper_float_min_d(fp1, cpu_env, fp0, fp1);
11490 gen_store_fpr64(ctx, fp1, fd);
11491 tcg_temp_free_i64(fp1);
11492 tcg_temp_free_i64(fp0);
e7f16abb
LA
11493 } else {
11494 /* OPC_RECIP2_D */
11495 check_cp1_64bitmode(ctx);
11496 {
11497 TCGv_i64 fp0 = tcg_temp_new_i64();
11498 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed 11499
e7f16abb
LA
11500 gen_load_fpr64(ctx, fp0, fs);
11501 gen_load_fpr64(ctx, fp1, ft);
11502 gen_helper_float_recip2_d(fp0, cpu_env, fp0, fp1);
11503 tcg_temp_free_i64(fp1);
11504 gen_store_fpr64(ctx, fp0, fd);
11505 tcg_temp_free_i64(fp0);
11506 }
e7f16abb
LA
11507 }
11508 break;
11509 case OPC_MINA_D: /* OPC_RECIP1_D */
11510 if (ctx->insn_flags & ISA_MIPS32R6) {
11511 /* OPC_MINA_D */
11512 TCGv_i64 fp0 = tcg_temp_new_i64();
11513 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
11514 gen_load_fpr64(ctx, fp0, fs);
11515 gen_load_fpr64(ctx, fp1, ft);
e7f16abb
LA
11516 gen_helper_float_mina_d(fp1, cpu_env, fp0, fp1);
11517 gen_store_fpr64(ctx, fp1, fd);
11518 tcg_temp_free_i64(fp1);
11519 tcg_temp_free_i64(fp0);
e7f16abb
LA
11520 } else {
11521 /* OPC_RECIP1_D */
11522 check_cp1_64bitmode(ctx);
11523 {
11524 TCGv_i64 fp0 = tcg_temp_new_i64();
11525
11526 gen_load_fpr64(ctx, fp0, fs);
11527 gen_helper_float_recip1_d(fp0, cpu_env, fp0);
11528 gen_store_fpr64(ctx, fp0, fd);
11529 tcg_temp_free_i64(fp0);
11530 }
e7f16abb
LA
11531 }
11532 break;
11533 case OPC_MAX_D: /* OPC_RSQRT1_D */
11534 if (ctx->insn_flags & ISA_MIPS32R6) {
11535 /* OPC_MAX_D */
11536 TCGv_i64 fp0 = tcg_temp_new_i64();
11537 TCGv_i64 fp1 = tcg_temp_new_i64();
11538 gen_load_fpr64(ctx, fp0, fs);
11539 gen_load_fpr64(ctx, fp1, ft);
11540 gen_helper_float_max_d(fp1, cpu_env, fp0, fp1);
11541 gen_store_fpr64(ctx, fp1, fd);
a7812ae4 11542 tcg_temp_free_i64(fp1);
a7812ae4 11543 tcg_temp_free_i64(fp0);
e7f16abb
LA
11544 } else {
11545 /* OPC_RSQRT1_D */
11546 check_cp1_64bitmode(ctx);
11547 {
11548 TCGv_i64 fp0 = tcg_temp_new_i64();
11549
11550 gen_load_fpr64(ctx, fp0, fs);
11551 gen_helper_float_rsqrt1_d(fp0, cpu_env, fp0);
11552 gen_store_fpr64(ctx, fp0, fd);
11553 tcg_temp_free_i64(fp0);
11554 }
e7f16abb
LA
11555 }
11556 break;
11557 case OPC_MAXA_D: /* OPC_RSQRT2_D */
11558 if (ctx->insn_flags & ISA_MIPS32R6) {
11559 /* OPC_MAXA_D */
11560 TCGv_i64 fp0 = tcg_temp_new_i64();
11561 TCGv_i64 fp1 = tcg_temp_new_i64();
11562 gen_load_fpr64(ctx, fp0, fs);
11563 gen_load_fpr64(ctx, fp1, ft);
11564 gen_helper_float_maxa_d(fp1, cpu_env, fp0, fp1);
11565 gen_store_fpr64(ctx, fp1, fd);
11566 tcg_temp_free_i64(fp1);
11567 tcg_temp_free_i64(fp0);
e7f16abb
LA
11568 } else {
11569 /* OPC_RSQRT2_D */
11570 check_cp1_64bitmode(ctx);
11571 {
11572 TCGv_i64 fp0 = tcg_temp_new_i64();
11573 TCGv_i64 fp1 = tcg_temp_new_i64();
11574
11575 gen_load_fpr64(ctx, fp0, fs);
11576 gen_load_fpr64(ctx, fp1, ft);
11577 gen_helper_float_rsqrt2_d(fp0, cpu_env, fp0, fp1);
11578 tcg_temp_free_i64(fp1);
11579 gen_store_fpr64(ctx, fp0, fd);
11580 tcg_temp_free_i64(fp0);
11581 }
b6d96bed 11582 }
57fa1fb3 11583 break;
bf4120ad
NF
11584 case OPC_CMP_F_D:
11585 case OPC_CMP_UN_D:
11586 case OPC_CMP_EQ_D:
11587 case OPC_CMP_UEQ_D:
11588 case OPC_CMP_OLT_D:
11589 case OPC_CMP_ULT_D:
11590 case OPC_CMP_OLE_D:
11591 case OPC_CMP_ULE_D:
11592 case OPC_CMP_SF_D:
11593 case OPC_CMP_NGLE_D:
11594 case OPC_CMP_SEQ_D:
11595 case OPC_CMP_NGL_D:
11596 case OPC_CMP_LT_D:
11597 case OPC_CMP_NGE_D:
11598 case OPC_CMP_LE_D:
11599 case OPC_CMP_NGT_D:
fecd2646 11600 check_insn_opc_removed(ctx, ISA_MIPS32R6);
8153667c
NF
11601 if (ctx->opcode & (1 << 6)) {
11602 gen_cmpabs_d(ctx, func-48, ft, fs, cc);
8153667c
NF
11603 } else {
11604 gen_cmp_d(ctx, func-48, ft, fs, cc);
5a1e8ffb 11605 }
6ea83fed 11606 break;
bf4120ad 11607 case OPC_CVT_S_D:
5e755519 11608 check_cp1_registers(ctx, fs);
b6d96bed 11609 {
a7812ae4
PB
11610 TCGv_i32 fp32 = tcg_temp_new_i32();
11611 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
11612
11613 gen_load_fpr64(ctx, fp64, fs);
895c2d04 11614 gen_helper_float_cvts_d(fp32, cpu_env, fp64);
a7812ae4 11615 tcg_temp_free_i64(fp64);
7c979afd 11616 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 11617 tcg_temp_free_i32(fp32);
b6d96bed 11618 }
5a5012ec 11619 break;
bf4120ad 11620 case OPC_CVT_W_D:
5e755519 11621 check_cp1_registers(ctx, fs);
b6d96bed 11622 {
a7812ae4
PB
11623 TCGv_i32 fp32 = tcg_temp_new_i32();
11624 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
11625
11626 gen_load_fpr64(ctx, fp64, fs);
87552089
AM
11627 if (ctx->nan2008) {
11628 gen_helper_float_cvt_2008_w_d(fp32, cpu_env, fp64);
11629 } else {
11630 gen_helper_float_cvt_w_d(fp32, cpu_env, fp64);
11631 }
a7812ae4 11632 tcg_temp_free_i64(fp64);
7c979afd 11633 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 11634 tcg_temp_free_i32(fp32);
b6d96bed 11635 }
5a5012ec 11636 break;
bf4120ad 11637 case OPC_CVT_L_D:
5e755519 11638 check_cp1_64bitmode(ctx);
b6d96bed 11639 {
a7812ae4 11640 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
11641
11642 gen_load_fpr64(ctx, fp0, fs);
87552089
AM
11643 if (ctx->nan2008) {
11644 gen_helper_float_cvt_2008_l_d(fp0, cpu_env, fp0);
11645 } else {
11646 gen_helper_float_cvt_l_d(fp0, cpu_env, fp0);
11647 }
b6d96bed 11648 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11649 tcg_temp_free_i64(fp0);
b6d96bed 11650 }
5a5012ec 11651 break;
bf4120ad 11652 case OPC_CVT_S_W:
b6d96bed 11653 {
a7812ae4 11654 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 11655
7c979afd 11656 gen_load_fpr32(ctx, fp0, fs);
895c2d04 11657 gen_helper_float_cvts_w(fp0, cpu_env, fp0);
7c979afd 11658 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 11659 tcg_temp_free_i32(fp0);
b6d96bed 11660 }
6ea83fed 11661 break;
bf4120ad 11662 case OPC_CVT_D_W:
5e755519 11663 check_cp1_registers(ctx, fd);
b6d96bed 11664 {
a7812ae4
PB
11665 TCGv_i32 fp32 = tcg_temp_new_i32();
11666 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 11667
7c979afd 11668 gen_load_fpr32(ctx, fp32, fs);
895c2d04 11669 gen_helper_float_cvtd_w(fp64, cpu_env, fp32);
a7812ae4 11670 tcg_temp_free_i32(fp32);
b6d96bed 11671 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 11672 tcg_temp_free_i64(fp64);
b6d96bed 11673 }
5a5012ec 11674 break;
bf4120ad 11675 case OPC_CVT_S_L:
5e755519 11676 check_cp1_64bitmode(ctx);
b6d96bed 11677 {
a7812ae4
PB
11678 TCGv_i32 fp32 = tcg_temp_new_i32();
11679 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
11680
11681 gen_load_fpr64(ctx, fp64, fs);
895c2d04 11682 gen_helper_float_cvts_l(fp32, cpu_env, fp64);
a7812ae4 11683 tcg_temp_free_i64(fp64);
7c979afd 11684 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 11685 tcg_temp_free_i32(fp32);
b6d96bed 11686 }
5a5012ec 11687 break;
bf4120ad 11688 case OPC_CVT_D_L:
5e755519 11689 check_cp1_64bitmode(ctx);
b6d96bed 11690 {
a7812ae4 11691 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
11692
11693 gen_load_fpr64(ctx, fp0, fs);
895c2d04 11694 gen_helper_float_cvtd_l(fp0, cpu_env, fp0);
b6d96bed 11695 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11696 tcg_temp_free_i64(fp0);
b6d96bed 11697 }
5a5012ec 11698 break;
bf4120ad 11699 case OPC_CVT_PS_PW:
e29c9628 11700 check_ps(ctx);
b6d96bed 11701 {
a7812ae4 11702 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
11703
11704 gen_load_fpr64(ctx, fp0, fs);
895c2d04 11705 gen_helper_float_cvtps_pw(fp0, cpu_env, fp0);
b6d96bed 11706 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11707 tcg_temp_free_i64(fp0);
b6d96bed 11708 }
5a5012ec 11709 break;
bf4120ad 11710 case OPC_ADD_PS:
e29c9628 11711 check_ps(ctx);
b6d96bed 11712 {
a7812ae4
PB
11713 TCGv_i64 fp0 = tcg_temp_new_i64();
11714 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
11715
11716 gen_load_fpr64(ctx, fp0, fs);
11717 gen_load_fpr64(ctx, fp1, ft);
895c2d04 11718 gen_helper_float_add_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 11719 tcg_temp_free_i64(fp1);
b6d96bed 11720 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11721 tcg_temp_free_i64(fp0);
b6d96bed 11722 }
6ea83fed 11723 break;
bf4120ad 11724 case OPC_SUB_PS:
e29c9628 11725 check_ps(ctx);
b6d96bed 11726 {
a7812ae4
PB
11727 TCGv_i64 fp0 = tcg_temp_new_i64();
11728 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
11729
11730 gen_load_fpr64(ctx, fp0, fs);
11731 gen_load_fpr64(ctx, fp1, ft);
895c2d04 11732 gen_helper_float_sub_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 11733 tcg_temp_free_i64(fp1);
b6d96bed 11734 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11735 tcg_temp_free_i64(fp0);
b6d96bed 11736 }
6ea83fed 11737 break;
bf4120ad 11738 case OPC_MUL_PS:
e29c9628 11739 check_ps(ctx);
b6d96bed 11740 {
a7812ae4
PB
11741 TCGv_i64 fp0 = tcg_temp_new_i64();
11742 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
11743
11744 gen_load_fpr64(ctx, fp0, fs);
11745 gen_load_fpr64(ctx, fp1, ft);
895c2d04 11746 gen_helper_float_mul_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 11747 tcg_temp_free_i64(fp1);
b6d96bed 11748 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11749 tcg_temp_free_i64(fp0);
b6d96bed 11750 }
6ea83fed 11751 break;
bf4120ad 11752 case OPC_ABS_PS:
e29c9628 11753 check_ps(ctx);
b6d96bed 11754 {
a7812ae4 11755 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
11756
11757 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 11758 gen_helper_float_abs_ps(fp0, fp0);
b6d96bed 11759 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11760 tcg_temp_free_i64(fp0);
b6d96bed 11761 }
6ea83fed 11762 break;
bf4120ad 11763 case OPC_MOV_PS:
e29c9628 11764 check_ps(ctx);
b6d96bed 11765 {
a7812ae4 11766 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
11767
11768 gen_load_fpr64(ctx, fp0, fs);
11769 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11770 tcg_temp_free_i64(fp0);
b6d96bed 11771 }
6ea83fed 11772 break;
bf4120ad 11773 case OPC_NEG_PS:
e29c9628 11774 check_ps(ctx);
b6d96bed 11775 {
a7812ae4 11776 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
11777
11778 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 11779 gen_helper_float_chs_ps(fp0, fp0);
b6d96bed 11780 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11781 tcg_temp_free_i64(fp0);
b6d96bed 11782 }
6ea83fed 11783 break;
bf4120ad 11784 case OPC_MOVCF_PS:
e29c9628 11785 check_ps(ctx);
7f6613ce 11786 gen_movcf_ps(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
6ea83fed 11787 break;
bf4120ad 11788 case OPC_MOVZ_PS:
e29c9628 11789 check_ps(ctx);
a16336e4 11790 {
42a268c2 11791 TCGLabel *l1 = gen_new_label();
30a3848b 11792 TCGv_i64 fp0;
a16336e4 11793
c9297f4d
AJ
11794 if (ft != 0)
11795 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
11796 fp0 = tcg_temp_new_i64();
11797 gen_load_fpr64(ctx, fp0, fs);
11798 gen_store_fpr64(ctx, fp0, fd);
11799 tcg_temp_free_i64(fp0);
a16336e4
TS
11800 gen_set_label(l1);
11801 }
6ea83fed 11802 break;
bf4120ad 11803 case OPC_MOVN_PS:
e29c9628 11804 check_ps(ctx);
a16336e4 11805 {
42a268c2 11806 TCGLabel *l1 = gen_new_label();
30a3848b 11807 TCGv_i64 fp0;
c9297f4d
AJ
11808
11809 if (ft != 0) {
11810 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
11811 fp0 = tcg_temp_new_i64();
11812 gen_load_fpr64(ctx, fp0, fs);
11813 gen_store_fpr64(ctx, fp0, fd);
11814 tcg_temp_free_i64(fp0);
11815 gen_set_label(l1);
11816 }
a16336e4 11817 }
6ea83fed 11818 break;
bf4120ad 11819 case OPC_ADDR_PS:
e29c9628 11820 check_ps(ctx);
b6d96bed 11821 {
a7812ae4
PB
11822 TCGv_i64 fp0 = tcg_temp_new_i64();
11823 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
11824
11825 gen_load_fpr64(ctx, fp0, ft);
11826 gen_load_fpr64(ctx, fp1, fs);
895c2d04 11827 gen_helper_float_addr_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 11828 tcg_temp_free_i64(fp1);
b6d96bed 11829 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11830 tcg_temp_free_i64(fp0);
b6d96bed 11831 }
fbcc6828 11832 break;
bf4120ad 11833 case OPC_MULR_PS:
e29c9628 11834 check_ps(ctx);
b6d96bed 11835 {
a7812ae4
PB
11836 TCGv_i64 fp0 = tcg_temp_new_i64();
11837 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
11838
11839 gen_load_fpr64(ctx, fp0, ft);
11840 gen_load_fpr64(ctx, fp1, fs);
895c2d04 11841 gen_helper_float_mulr_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 11842 tcg_temp_free_i64(fp1);
b6d96bed 11843 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11844 tcg_temp_free_i64(fp0);
b6d96bed 11845 }
57fa1fb3 11846 break;
bf4120ad 11847 case OPC_RECIP2_PS:
e29c9628 11848 check_ps(ctx);
b6d96bed 11849 {
a7812ae4
PB
11850 TCGv_i64 fp0 = tcg_temp_new_i64();
11851 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
11852
11853 gen_load_fpr64(ctx, fp0, fs);
d22d7289 11854 gen_load_fpr64(ctx, fp1, ft);
895c2d04 11855 gen_helper_float_recip2_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 11856 tcg_temp_free_i64(fp1);
b6d96bed 11857 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11858 tcg_temp_free_i64(fp0);
b6d96bed 11859 }
57fa1fb3 11860 break;
bf4120ad 11861 case OPC_RECIP1_PS:
e29c9628 11862 check_ps(ctx);
b6d96bed 11863 {
a7812ae4 11864 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
11865
11866 gen_load_fpr64(ctx, fp0, fs);
895c2d04 11867 gen_helper_float_recip1_ps(fp0, cpu_env, fp0);
b6d96bed 11868 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11869 tcg_temp_free_i64(fp0);
b6d96bed 11870 }
57fa1fb3 11871 break;
bf4120ad 11872 case OPC_RSQRT1_PS:
e29c9628 11873 check_ps(ctx);
b6d96bed 11874 {
a7812ae4 11875 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
11876
11877 gen_load_fpr64(ctx, fp0, fs);
895c2d04 11878 gen_helper_float_rsqrt1_ps(fp0, cpu_env, fp0);
b6d96bed 11879 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11880 tcg_temp_free_i64(fp0);
b6d96bed 11881 }
57fa1fb3 11882 break;
bf4120ad 11883 case OPC_RSQRT2_PS:
e29c9628 11884 check_ps(ctx);
b6d96bed 11885 {
a7812ae4
PB
11886 TCGv_i64 fp0 = tcg_temp_new_i64();
11887 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
11888
11889 gen_load_fpr64(ctx, fp0, fs);
11890 gen_load_fpr64(ctx, fp1, ft);
895c2d04 11891 gen_helper_float_rsqrt2_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 11892 tcg_temp_free_i64(fp1);
b6d96bed 11893 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11894 tcg_temp_free_i64(fp0);
b6d96bed 11895 }
57fa1fb3 11896 break;
bf4120ad 11897 case OPC_CVT_S_PU:
5e755519 11898 check_cp1_64bitmode(ctx);
b6d96bed 11899 {
a7812ae4 11900 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 11901
7f6613ce 11902 gen_load_fpr32h(ctx, fp0, fs);
895c2d04 11903 gen_helper_float_cvts_pu(fp0, cpu_env, fp0);
7c979afd 11904 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 11905 tcg_temp_free_i32(fp0);
b6d96bed 11906 }
dd016883 11907 break;
bf4120ad 11908 case OPC_CVT_PW_PS:
e29c9628 11909 check_ps(ctx);
b6d96bed 11910 {
a7812ae4 11911 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
11912
11913 gen_load_fpr64(ctx, fp0, fs);
895c2d04 11914 gen_helper_float_cvtpw_ps(fp0, cpu_env, fp0);
b6d96bed 11915 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 11916 tcg_temp_free_i64(fp0);
b6d96bed 11917 }
6ea83fed 11918 break;
bf4120ad 11919 case OPC_CVT_S_PL:
5e755519 11920 check_cp1_64bitmode(ctx);
b6d96bed 11921 {
a7812ae4 11922 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 11923
7c979afd 11924 gen_load_fpr32(ctx, fp0, fs);
895c2d04 11925 gen_helper_float_cvts_pl(fp0, cpu_env, fp0);
7c979afd 11926 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 11927 tcg_temp_free_i32(fp0);
b6d96bed 11928 }
6ea83fed 11929 break;
bf4120ad 11930 case OPC_PLL_PS:
e29c9628 11931 check_ps(ctx);
b6d96bed 11932 {
a7812ae4
PB
11933 TCGv_i32 fp0 = tcg_temp_new_i32();
11934 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 11935
7c979afd
LA
11936 gen_load_fpr32(ctx, fp0, fs);
11937 gen_load_fpr32(ctx, fp1, ft);
7f6613ce 11938 gen_store_fpr32h(ctx, fp0, fd);
7c979afd 11939 gen_store_fpr32(ctx, fp1, fd);
a7812ae4
PB
11940 tcg_temp_free_i32(fp0);
11941 tcg_temp_free_i32(fp1);
b6d96bed 11942 }
6ea83fed 11943 break;
bf4120ad 11944 case OPC_PLU_PS:
e29c9628 11945 check_ps(ctx);
b6d96bed 11946 {
a7812ae4
PB
11947 TCGv_i32 fp0 = tcg_temp_new_i32();
11948 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 11949
7c979afd 11950 gen_load_fpr32(ctx, fp0, fs);
7f6613ce 11951 gen_load_fpr32h(ctx, fp1, ft);
7c979afd 11952 gen_store_fpr32(ctx, fp1, fd);
7f6613ce 11953 gen_store_fpr32h(ctx, fp0, fd);
a7812ae4
PB
11954 tcg_temp_free_i32(fp0);
11955 tcg_temp_free_i32(fp1);
b6d96bed 11956 }
5a5012ec 11957 break;
bf4120ad 11958 case OPC_PUL_PS:
e29c9628 11959 check_ps(ctx);
b6d96bed 11960 {
a7812ae4
PB
11961 TCGv_i32 fp0 = tcg_temp_new_i32();
11962 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 11963
7f6613ce 11964 gen_load_fpr32h(ctx, fp0, fs);
7c979afd
LA
11965 gen_load_fpr32(ctx, fp1, ft);
11966 gen_store_fpr32(ctx, fp1, fd);
7f6613ce 11967 gen_store_fpr32h(ctx, fp0, fd);
a7812ae4
PB
11968 tcg_temp_free_i32(fp0);
11969 tcg_temp_free_i32(fp1);
b6d96bed 11970 }
5a5012ec 11971 break;
bf4120ad 11972 case OPC_PUU_PS:
e29c9628 11973 check_ps(ctx);
b6d96bed 11974 {
a7812ae4
PB
11975 TCGv_i32 fp0 = tcg_temp_new_i32();
11976 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 11977
7f6613ce
PJ
11978 gen_load_fpr32h(ctx, fp0, fs);
11979 gen_load_fpr32h(ctx, fp1, ft);
7c979afd 11980 gen_store_fpr32(ctx, fp1, fd);
7f6613ce 11981 gen_store_fpr32h(ctx, fp0, fd);
a7812ae4
PB
11982 tcg_temp_free_i32(fp0);
11983 tcg_temp_free_i32(fp1);
b6d96bed 11984 }
5a5012ec 11985 break;
bf4120ad
NF
11986 case OPC_CMP_F_PS:
11987 case OPC_CMP_UN_PS:
11988 case OPC_CMP_EQ_PS:
11989 case OPC_CMP_UEQ_PS:
11990 case OPC_CMP_OLT_PS:
11991 case OPC_CMP_ULT_PS:
11992 case OPC_CMP_OLE_PS:
11993 case OPC_CMP_ULE_PS:
11994 case OPC_CMP_SF_PS:
11995 case OPC_CMP_NGLE_PS:
11996 case OPC_CMP_SEQ_PS:
11997 case OPC_CMP_NGL_PS:
11998 case OPC_CMP_LT_PS:
11999 case OPC_CMP_NGE_PS:
12000 case OPC_CMP_LE_PS:
12001 case OPC_CMP_NGT_PS:
8153667c
NF
12002 if (ctx->opcode & (1 << 6)) {
12003 gen_cmpabs_ps(ctx, func-48, ft, fs, cc);
8153667c
NF
12004 } else {
12005 gen_cmp_ps(ctx, func-48, ft, fs, cc);
5a1e8ffb 12006 }
6ea83fed 12007 break;
5a5012ec 12008 default:
9d68ac14 12009 MIPS_INVAL("farith");
9c708c7f 12010 generate_exception_end(ctx, EXCP_RI);
6ea83fed
FB
12011 return;
12012 }
6ea83fed 12013}
6af0bf9c 12014
5a5012ec 12015/* Coprocessor 3 (FPU) */
5e755519
TS
12016static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
12017 int fd, int fs, int base, int index)
7a387fff 12018{
4e2474d6 12019 TCGv t0 = tcg_temp_new();
7a387fff 12020
93b12ccc 12021 if (base == 0) {
6c5c1e20 12022 gen_load_gpr(t0, index);
93b12ccc 12023 } else if (index == 0) {
6c5c1e20 12024 gen_load_gpr(t0, base);
93b12ccc 12025 } else {
05168674 12026 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]);
93b12ccc 12027 }
5a5012ec 12028 /* Don't do NOP if destination is zero: we must perform the actual
ead9360e 12029 memory access. */
5a5012ec
TS
12030 switch (opc) {
12031 case OPC_LWXC1:
8c0ab41f 12032 check_cop1x(ctx);
b6d96bed 12033 {
a7812ae4 12034 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 12035
5f68f5ae 12036 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
585c88d5 12037 tcg_gen_trunc_tl_i32(fp0, t0);
7c979afd 12038 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 12039 tcg_temp_free_i32(fp0);
b6d96bed 12040 }
5a5012ec
TS
12041 break;
12042 case OPC_LDXC1:
8c0ab41f
AJ
12043 check_cop1x(ctx);
12044 check_cp1_registers(ctx, fd);
b6d96bed 12045 {
a7812ae4 12046 TCGv_i64 fp0 = tcg_temp_new_i64();
5f68f5ae 12047 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
b6d96bed 12048 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 12049 tcg_temp_free_i64(fp0);
b6d96bed 12050 }
5a5012ec
TS
12051 break;
12052 case OPC_LUXC1:
8c0ab41f 12053 check_cp1_64bitmode(ctx);
6c5c1e20 12054 tcg_gen_andi_tl(t0, t0, ~0x7);
b6d96bed 12055 {
a7812ae4 12056 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 12057
5f68f5ae 12058 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
b6d96bed 12059 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 12060 tcg_temp_free_i64(fp0);
b6d96bed 12061 }
5a5012ec
TS
12062 break;
12063 case OPC_SWXC1:
8c0ab41f 12064 check_cop1x(ctx);
b6d96bed 12065 {
a7812ae4 12066 TCGv_i32 fp0 = tcg_temp_new_i32();
7c979afd 12067 gen_load_fpr32(ctx, fp0, fs);
5f68f5ae 12068 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL);
a7812ae4 12069 tcg_temp_free_i32(fp0);
b6d96bed 12070 }
5a5012ec
TS
12071 break;
12072 case OPC_SDXC1:
8c0ab41f
AJ
12073 check_cop1x(ctx);
12074 check_cp1_registers(ctx, fs);
b6d96bed 12075 {
a7812ae4 12076 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 12077 gen_load_fpr64(ctx, fp0, fs);
5f68f5ae 12078 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
a7812ae4 12079 tcg_temp_free_i64(fp0);
b6d96bed 12080 }
5a5012ec
TS
12081 break;
12082 case OPC_SUXC1:
8c0ab41f 12083 check_cp1_64bitmode(ctx);
6c5c1e20 12084 tcg_gen_andi_tl(t0, t0, ~0x7);
b6d96bed 12085 {
a7812ae4 12086 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 12087 gen_load_fpr64(ctx, fp0, fs);
5f68f5ae 12088 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
a7812ae4 12089 tcg_temp_free_i64(fp0);
b6d96bed 12090 }
5a5012ec 12091 break;
5a5012ec 12092 }
6c5c1e20 12093 tcg_temp_free(t0);
5a5012ec
TS
12094}
12095
5e755519
TS
12096static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
12097 int fd, int fr, int fs, int ft)
5a5012ec 12098{
5a5012ec
TS
12099 switch (opc) {
12100 case OPC_ALNV_PS:
e29c9628 12101 check_ps(ctx);
a16336e4 12102 {
a7812ae4 12103 TCGv t0 = tcg_temp_local_new();
c905fdac
AJ
12104 TCGv_i32 fp = tcg_temp_new_i32();
12105 TCGv_i32 fph = tcg_temp_new_i32();
42a268c2
RH
12106 TCGLabel *l1 = gen_new_label();
12107 TCGLabel *l2 = gen_new_label();
a16336e4 12108
6c5c1e20
TS
12109 gen_load_gpr(t0, fr);
12110 tcg_gen_andi_tl(t0, t0, 0x7);
6c5c1e20
TS
12111
12112 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
7c979afd 12113 gen_load_fpr32(ctx, fp, fs);
7f6613ce 12114 gen_load_fpr32h(ctx, fph, fs);
7c979afd 12115 gen_store_fpr32(ctx, fp, fd);
7f6613ce 12116 gen_store_fpr32h(ctx, fph, fd);
a16336e4
TS
12117 tcg_gen_br(l2);
12118 gen_set_label(l1);
6c5c1e20
TS
12119 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
12120 tcg_temp_free(t0);
a16336e4 12121#ifdef TARGET_WORDS_BIGENDIAN
7c979afd 12122 gen_load_fpr32(ctx, fp, fs);
7f6613ce
PJ
12123 gen_load_fpr32h(ctx, fph, ft);
12124 gen_store_fpr32h(ctx, fp, fd);
7c979afd 12125 gen_store_fpr32(ctx, fph, fd);
a16336e4 12126#else
7f6613ce 12127 gen_load_fpr32h(ctx, fph, fs);
7c979afd
LA
12128 gen_load_fpr32(ctx, fp, ft);
12129 gen_store_fpr32(ctx, fph, fd);
7f6613ce 12130 gen_store_fpr32h(ctx, fp, fd);
a16336e4
TS
12131#endif
12132 gen_set_label(l2);
c905fdac
AJ
12133 tcg_temp_free_i32(fp);
12134 tcg_temp_free_i32(fph);
a16336e4 12135 }
5a5012ec
TS
12136 break;
12137 case OPC_MADD_S:
b8aa4598 12138 check_cop1x(ctx);
b6d96bed 12139 {
a7812ae4
PB
12140 TCGv_i32 fp0 = tcg_temp_new_i32();
12141 TCGv_i32 fp1 = tcg_temp_new_i32();
12142 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed 12143
7c979afd
LA
12144 gen_load_fpr32(ctx, fp0, fs);
12145 gen_load_fpr32(ctx, fp1, ft);
12146 gen_load_fpr32(ctx, fp2, fr);
b3d6cd44 12147 gen_helper_float_madd_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
12148 tcg_temp_free_i32(fp0);
12149 tcg_temp_free_i32(fp1);
7c979afd 12150 gen_store_fpr32(ctx, fp2, fd);
a7812ae4 12151 tcg_temp_free_i32(fp2);
b6d96bed 12152 }
5a5012ec
TS
12153 break;
12154 case OPC_MADD_D:
b8aa4598
TS
12155 check_cop1x(ctx);
12156 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 12157 {
a7812ae4
PB
12158 TCGv_i64 fp0 = tcg_temp_new_i64();
12159 TCGv_i64 fp1 = tcg_temp_new_i64();
12160 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
12161
12162 gen_load_fpr64(ctx, fp0, fs);
12163 gen_load_fpr64(ctx, fp1, ft);
12164 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 12165 gen_helper_float_madd_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
12166 tcg_temp_free_i64(fp0);
12167 tcg_temp_free_i64(fp1);
b6d96bed 12168 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 12169 tcg_temp_free_i64(fp2);
b6d96bed 12170 }
5a5012ec
TS
12171 break;
12172 case OPC_MADD_PS:
e29c9628 12173 check_ps(ctx);
b6d96bed 12174 {
a7812ae4
PB
12175 TCGv_i64 fp0 = tcg_temp_new_i64();
12176 TCGv_i64 fp1 = tcg_temp_new_i64();
12177 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
12178
12179 gen_load_fpr64(ctx, fp0, fs);
12180 gen_load_fpr64(ctx, fp1, ft);
12181 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 12182 gen_helper_float_madd_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
12183 tcg_temp_free_i64(fp0);
12184 tcg_temp_free_i64(fp1);
b6d96bed 12185 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 12186 tcg_temp_free_i64(fp2);
b6d96bed 12187 }
5a5012ec
TS
12188 break;
12189 case OPC_MSUB_S:
b8aa4598 12190 check_cop1x(ctx);
b6d96bed 12191 {
a7812ae4
PB
12192 TCGv_i32 fp0 = tcg_temp_new_i32();
12193 TCGv_i32 fp1 = tcg_temp_new_i32();
12194 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed 12195
7c979afd
LA
12196 gen_load_fpr32(ctx, fp0, fs);
12197 gen_load_fpr32(ctx, fp1, ft);
12198 gen_load_fpr32(ctx, fp2, fr);
b3d6cd44 12199 gen_helper_float_msub_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
12200 tcg_temp_free_i32(fp0);
12201 tcg_temp_free_i32(fp1);
7c979afd 12202 gen_store_fpr32(ctx, fp2, fd);
a7812ae4 12203 tcg_temp_free_i32(fp2);
b6d96bed 12204 }
5a5012ec
TS
12205 break;
12206 case OPC_MSUB_D:
b8aa4598
TS
12207 check_cop1x(ctx);
12208 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 12209 {
a7812ae4
PB
12210 TCGv_i64 fp0 = tcg_temp_new_i64();
12211 TCGv_i64 fp1 = tcg_temp_new_i64();
12212 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
12213
12214 gen_load_fpr64(ctx, fp0, fs);
12215 gen_load_fpr64(ctx, fp1, ft);
12216 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 12217 gen_helper_float_msub_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
12218 tcg_temp_free_i64(fp0);
12219 tcg_temp_free_i64(fp1);
b6d96bed 12220 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 12221 tcg_temp_free_i64(fp2);
b6d96bed 12222 }
5a5012ec
TS
12223 break;
12224 case OPC_MSUB_PS:
e29c9628 12225 check_ps(ctx);
b6d96bed 12226 {
a7812ae4
PB
12227 TCGv_i64 fp0 = tcg_temp_new_i64();
12228 TCGv_i64 fp1 = tcg_temp_new_i64();
12229 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
12230
12231 gen_load_fpr64(ctx, fp0, fs);
12232 gen_load_fpr64(ctx, fp1, ft);
12233 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 12234 gen_helper_float_msub_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
12235 tcg_temp_free_i64(fp0);
12236 tcg_temp_free_i64(fp1);
b6d96bed 12237 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 12238 tcg_temp_free_i64(fp2);
b6d96bed 12239 }
5a5012ec
TS
12240 break;
12241 case OPC_NMADD_S:
b8aa4598 12242 check_cop1x(ctx);
b6d96bed 12243 {
a7812ae4
PB
12244 TCGv_i32 fp0 = tcg_temp_new_i32();
12245 TCGv_i32 fp1 = tcg_temp_new_i32();
12246 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed 12247
7c979afd
LA
12248 gen_load_fpr32(ctx, fp0, fs);
12249 gen_load_fpr32(ctx, fp1, ft);
12250 gen_load_fpr32(ctx, fp2, fr);
b3d6cd44 12251 gen_helper_float_nmadd_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
12252 tcg_temp_free_i32(fp0);
12253 tcg_temp_free_i32(fp1);
7c979afd 12254 gen_store_fpr32(ctx, fp2, fd);
a7812ae4 12255 tcg_temp_free_i32(fp2);
b6d96bed 12256 }
5a5012ec
TS
12257 break;
12258 case OPC_NMADD_D:
b8aa4598
TS
12259 check_cop1x(ctx);
12260 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 12261 {
a7812ae4
PB
12262 TCGv_i64 fp0 = tcg_temp_new_i64();
12263 TCGv_i64 fp1 = tcg_temp_new_i64();
12264 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
12265
12266 gen_load_fpr64(ctx, fp0, fs);
12267 gen_load_fpr64(ctx, fp1, ft);
12268 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 12269 gen_helper_float_nmadd_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
12270 tcg_temp_free_i64(fp0);
12271 tcg_temp_free_i64(fp1);
b6d96bed 12272 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 12273 tcg_temp_free_i64(fp2);
b6d96bed 12274 }
5a5012ec
TS
12275 break;
12276 case OPC_NMADD_PS:
e29c9628 12277 check_ps(ctx);
b6d96bed 12278 {
a7812ae4
PB
12279 TCGv_i64 fp0 = tcg_temp_new_i64();
12280 TCGv_i64 fp1 = tcg_temp_new_i64();
12281 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
12282
12283 gen_load_fpr64(ctx, fp0, fs);
12284 gen_load_fpr64(ctx, fp1, ft);
12285 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 12286 gen_helper_float_nmadd_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
12287 tcg_temp_free_i64(fp0);
12288 tcg_temp_free_i64(fp1);
b6d96bed 12289 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 12290 tcg_temp_free_i64(fp2);
b6d96bed 12291 }
5a5012ec
TS
12292 break;
12293 case OPC_NMSUB_S:
b8aa4598 12294 check_cop1x(ctx);
b6d96bed 12295 {
a7812ae4
PB
12296 TCGv_i32 fp0 = tcg_temp_new_i32();
12297 TCGv_i32 fp1 = tcg_temp_new_i32();
12298 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed 12299
7c979afd
LA
12300 gen_load_fpr32(ctx, fp0, fs);
12301 gen_load_fpr32(ctx, fp1, ft);
12302 gen_load_fpr32(ctx, fp2, fr);
b3d6cd44 12303 gen_helper_float_nmsub_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
12304 tcg_temp_free_i32(fp0);
12305 tcg_temp_free_i32(fp1);
7c979afd 12306 gen_store_fpr32(ctx, fp2, fd);
a7812ae4 12307 tcg_temp_free_i32(fp2);
b6d96bed 12308 }
5a5012ec
TS
12309 break;
12310 case OPC_NMSUB_D:
b8aa4598
TS
12311 check_cop1x(ctx);
12312 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 12313 {
a7812ae4
PB
12314 TCGv_i64 fp0 = tcg_temp_new_i64();
12315 TCGv_i64 fp1 = tcg_temp_new_i64();
12316 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
12317
12318 gen_load_fpr64(ctx, fp0, fs);
12319 gen_load_fpr64(ctx, fp1, ft);
12320 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 12321 gen_helper_float_nmsub_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
12322 tcg_temp_free_i64(fp0);
12323 tcg_temp_free_i64(fp1);
b6d96bed 12324 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 12325 tcg_temp_free_i64(fp2);
b6d96bed 12326 }
5a5012ec
TS
12327 break;
12328 case OPC_NMSUB_PS:
e29c9628 12329 check_ps(ctx);
b6d96bed 12330 {
a7812ae4
PB
12331 TCGv_i64 fp0 = tcg_temp_new_i64();
12332 TCGv_i64 fp1 = tcg_temp_new_i64();
12333 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
12334
12335 gen_load_fpr64(ctx, fp0, fs);
12336 gen_load_fpr64(ctx, fp1, ft);
12337 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 12338 gen_helper_float_nmsub_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
12339 tcg_temp_free_i64(fp0);
12340 tcg_temp_free_i64(fp1);
b6d96bed 12341 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 12342 tcg_temp_free_i64(fp2);
b6d96bed 12343 }
5a5012ec 12344 break;
923617a3 12345 default:
9d68ac14 12346 MIPS_INVAL("flt3_arith");
9c708c7f 12347 generate_exception_end(ctx, EXCP_RI);
5a5012ec
TS
12348 return;
12349 }
7a387fff
TS
12350}
12351
b00c7218 12352static void gen_rdhwr(DisasContext *ctx, int rt, int rd, int sel)
26ebe468
NF
12353{
12354 TCGv t0;
12355
b3167288
RH
12356#if !defined(CONFIG_USER_ONLY)
12357 /* The Linux kernel will emulate rdhwr if it's not supported natively.
12358 Therefore only check the ISA in system mode. */
d75c135e 12359 check_insn(ctx, ISA_MIPS32R2);
b3167288 12360#endif
26ebe468
NF
12361 t0 = tcg_temp_new();
12362
12363 switch (rd) {
12364 case 0:
895c2d04 12365 gen_helper_rdhwr_cpunum(t0, cpu_env);
26ebe468
NF
12366 gen_store_gpr(t0, rt);
12367 break;
12368 case 1:
895c2d04 12369 gen_helper_rdhwr_synci_step(t0, cpu_env);
26ebe468
NF
12370 gen_store_gpr(t0, rt);
12371 break;
12372 case 2:
eeb3bba8 12373 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
d673a68d
JH
12374 gen_io_start();
12375 }
895c2d04 12376 gen_helper_rdhwr_cc(t0, cpu_env);
eeb3bba8 12377 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
d673a68d
JH
12378 gen_io_end();
12379 }
26ebe468 12380 gen_store_gpr(t0, rt);
d673a68d 12381 /* Break the TB to be able to take timer interrupts immediately
b28425ba 12382 after reading count. DISAS_STOP isn't sufficient, we need to ensure
d673a68d 12383 we break completely out of translated code. */
eeb3bba8
EC
12384 gen_save_pc(ctx->base.pc_next + 4);
12385 ctx->base.is_jmp = DISAS_EXIT;
26ebe468
NF
12386 break;
12387 case 3:
895c2d04 12388 gen_helper_rdhwr_ccres(t0, cpu_env);
26ebe468
NF
12389 gen_store_gpr(t0, rt);
12390 break;
b00c7218
YK
12391 case 4:
12392 check_insn(ctx, ISA_MIPS32R6);
12393 if (sel != 0) {
12394 /* Performance counter registers are not implemented other than
12395 * control register 0.
12396 */
12397 generate_exception(ctx, EXCP_RI);
12398 }
12399 gen_helper_rdhwr_performance(t0, cpu_env);
12400 gen_store_gpr(t0, rt);
12401 break;
12402 case 5:
12403 check_insn(ctx, ISA_MIPS32R6);
12404 gen_helper_rdhwr_xnp(t0, cpu_env);
12405 gen_store_gpr(t0, rt);
12406 break;
26ebe468
NF
12407 case 29:
12408#if defined(CONFIG_USER_ONLY)
d279279e
PJ
12409 tcg_gen_ld_tl(t0, cpu_env,
12410 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
26ebe468
NF
12411 gen_store_gpr(t0, rt);
12412 break;
12413#else
d279279e
PJ
12414 if ((ctx->hflags & MIPS_HFLAG_CP0) ||
12415 (ctx->hflags & MIPS_HFLAG_HWRENA_ULR)) {
12416 tcg_gen_ld_tl(t0, cpu_env,
12417 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
12418 gen_store_gpr(t0, rt);
12419 } else {
9c708c7f 12420 generate_exception_end(ctx, EXCP_RI);
d279279e
PJ
12421 }
12422 break;
26ebe468
NF
12423#endif
12424 default: /* Invalid */
12425 MIPS_INVAL("rdhwr");
9c708c7f 12426 generate_exception_end(ctx, EXCP_RI);
26ebe468
NF
12427 break;
12428 }
12429 tcg_temp_free(t0);
12430}
12431
a5f53390
LA
12432static inline void clear_branch_hflags(DisasContext *ctx)
12433{
12434 ctx->hflags &= ~MIPS_HFLAG_BMASK;
eeb3bba8 12435 if (ctx->base.is_jmp == DISAS_NEXT) {
a5f53390
LA
12436 save_cpu_state(ctx, 0);
12437 } else {
12438 /* it is not safe to save ctx->hflags as hflags may be changed
12439 in execution time by the instruction in delay / forbidden slot. */
12440 tcg_gen_andi_i32(hflags, hflags, ~MIPS_HFLAG_BMASK);
12441 }
12442}
12443
31837be3 12444static void gen_branch(DisasContext *ctx, int insn_bytes)
c9602061
NF
12445{
12446 if (ctx->hflags & MIPS_HFLAG_BMASK) {
364d4831 12447 int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
c9602061 12448 /* Branches completion */
a5f53390 12449 clear_branch_hflags(ctx);
eeb3bba8 12450 ctx->base.is_jmp = DISAS_NORETURN;
c9602061 12451 /* FIXME: Need to clear can_do_io. */
364d4831 12452 switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
339cd2a8 12453 case MIPS_HFLAG_FBNSLOT:
eeb3bba8 12454 gen_goto_tb(ctx, 0, ctx->base.pc_next + insn_bytes);
339cd2a8 12455 break;
c9602061
NF
12456 case MIPS_HFLAG_B:
12457 /* unconditional branch */
364d4831
NF
12458 if (proc_hflags & MIPS_HFLAG_BX) {
12459 tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
12460 }
c9602061
NF
12461 gen_goto_tb(ctx, 0, ctx->btarget);
12462 break;
12463 case MIPS_HFLAG_BL:
12464 /* blikely taken case */
c9602061
NF
12465 gen_goto_tb(ctx, 0, ctx->btarget);
12466 break;
12467 case MIPS_HFLAG_BC:
12468 /* Conditional branch */
c9602061 12469 {
42a268c2 12470 TCGLabel *l1 = gen_new_label();
c9602061
NF
12471
12472 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
eeb3bba8 12473 gen_goto_tb(ctx, 1, ctx->base.pc_next + insn_bytes);
c9602061
NF
12474 gen_set_label(l1);
12475 gen_goto_tb(ctx, 0, ctx->btarget);
12476 }
12477 break;
12478 case MIPS_HFLAG_BR:
12479 /* unconditional branch to register */
d75c135e 12480 if (ctx->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
364d4831
NF
12481 TCGv t0 = tcg_temp_new();
12482 TCGv_i32 t1 = tcg_temp_new_i32();
12483
12484 tcg_gen_andi_tl(t0, btarget, 0x1);
12485 tcg_gen_trunc_tl_i32(t1, t0);
12486 tcg_temp_free(t0);
12487 tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
12488 tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
12489 tcg_gen_or_i32(hflags, hflags, t1);
12490 tcg_temp_free_i32(t1);
12491
12492 tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
12493 } else {
12494 tcg_gen_mov_tl(cpu_PC, btarget);
12495 }
eeb3bba8 12496 if (ctx->base.singlestep_enabled) {
c9602061 12497 save_cpu_state(ctx, 0);
9c708c7f 12498 gen_helper_raise_exception_debug(cpu_env);
c9602061 12499 }
7f11636d 12500 tcg_gen_lookup_and_goto_ptr();
c9602061
NF
12501 break;
12502 default:
a5f53390
LA
12503 fprintf(stderr, "unknown branch 0x%x\n", proc_hflags);
12504 abort();
c9602061
NF
12505 }
12506 }
12507}
12508
6893f074
YK
12509/* Compact Branches */
12510static void gen_compute_compact_branch(DisasContext *ctx, uint32_t opc,
12511 int rs, int rt, int32_t offset)
12512{
12513 int bcond_compute = 0;
12514 TCGv t0 = tcg_temp_new();
12515 TCGv t1 = tcg_temp_new();
65935f07 12516 int m16_lowbit = (ctx->hflags & MIPS_HFLAG_M16) != 0;
6893f074
YK
12517
12518 if (ctx->hflags & MIPS_HFLAG_BMASK) {
12519#ifdef MIPS_DEBUG_DISAS
12520 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
eeb3bba8 12521 "\n", ctx->base.pc_next);
6893f074 12522#endif
9c708c7f 12523 generate_exception_end(ctx, EXCP_RI);
6893f074
YK
12524 goto out;
12525 }
12526
12527 /* Load needed operands and calculate btarget */
12528 switch (opc) {
12529 /* compact branch */
12530 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
12531 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
12532 gen_load_gpr(t0, rs);
12533 gen_load_gpr(t1, rt);
12534 bcond_compute = 1;
eeb3bba8 12535 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
6893f074
YK
12536 if (rs <= rt && rs == 0) {
12537 /* OPC_BEQZALC, OPC_BNEZALC */
eeb3bba8 12538 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
6893f074
YK
12539 }
12540 break;
12541 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
12542 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
12543 gen_load_gpr(t0, rs);
12544 gen_load_gpr(t1, rt);
12545 bcond_compute = 1;
eeb3bba8 12546 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
6893f074
YK
12547 break;
12548 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
12549 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
12550 if (rs == 0 || rs == rt) {
12551 /* OPC_BLEZALC, OPC_BGEZALC */
12552 /* OPC_BGTZALC, OPC_BLTZALC */
eeb3bba8 12553 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
6893f074
YK
12554 }
12555 gen_load_gpr(t0, rs);
12556 gen_load_gpr(t1, rt);
12557 bcond_compute = 1;
eeb3bba8 12558 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
6893f074
YK
12559 break;
12560 case OPC_BC:
12561 case OPC_BALC:
eeb3bba8 12562 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
6893f074
YK
12563 break;
12564 case OPC_BEQZC:
12565 case OPC_BNEZC:
12566 if (rs != 0) {
12567 /* OPC_BEQZC, OPC_BNEZC */
12568 gen_load_gpr(t0, rs);
12569 bcond_compute = 1;
eeb3bba8 12570 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
6893f074
YK
12571 } else {
12572 /* OPC_JIC, OPC_JIALC */
12573 TCGv tbase = tcg_temp_new();
12574 TCGv toffset = tcg_temp_new();
12575
12576 gen_load_gpr(tbase, rt);
12577 tcg_gen_movi_tl(toffset, offset);
12578 gen_op_addr_add(ctx, btarget, tbase, toffset);
12579 tcg_temp_free(tbase);
12580 tcg_temp_free(toffset);
12581 }
12582 break;
12583 default:
12584 MIPS_INVAL("Compact branch/jump");
9c708c7f 12585 generate_exception_end(ctx, EXCP_RI);
6893f074
YK
12586 goto out;
12587 }
12588
12589 if (bcond_compute == 0) {
12590 /* Uncoditional compact branch */
12591 switch (opc) {
12592 case OPC_JIALC:
eeb3bba8 12593 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
6893f074
YK
12594 /* Fallthrough */
12595 case OPC_JIC:
12596 ctx->hflags |= MIPS_HFLAG_BR;
12597 break;
12598 case OPC_BALC:
eeb3bba8 12599 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
6893f074
YK
12600 /* Fallthrough */
12601 case OPC_BC:
12602 ctx->hflags |= MIPS_HFLAG_B;
12603 break;
12604 default:
12605 MIPS_INVAL("Compact branch/jump");
9c708c7f 12606 generate_exception_end(ctx, EXCP_RI);
6893f074
YK
12607 goto out;
12608 }
12609
12610 /* Generating branch here as compact branches don't have delay slot */
12611 gen_branch(ctx, 4);
12612 } else {
12613 /* Conditional compact branch */
12614 TCGLabel *fs = gen_new_label();
12615 save_cpu_state(ctx, 0);
12616
12617 switch (opc) {
12618 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
12619 if (rs == 0 && rt != 0) {
12620 /* OPC_BLEZALC */
12621 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
12622 } else if (rs != 0 && rt != 0 && rs == rt) {
12623 /* OPC_BGEZALC */
12624 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
12625 } else {
12626 /* OPC_BGEUC */
12627 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU), t0, t1, fs);
12628 }
12629 break;
12630 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
12631 if (rs == 0 && rt != 0) {
12632 /* OPC_BGTZALC */
12633 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
12634 } else if (rs != 0 && rt != 0 && rs == rt) {
12635 /* OPC_BLTZALC */
12636 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
12637 } else {
12638 /* OPC_BLTUC */
12639 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU), t0, t1, fs);
12640 }
12641 break;
12642 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
12643 if (rs == 0 && rt != 0) {
12644 /* OPC_BLEZC */
12645 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
12646 } else if (rs != 0 && rt != 0 && rs == rt) {
12647 /* OPC_BGEZC */
12648 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
12649 } else {
12650 /* OPC_BGEC */
12651 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE), t0, t1, fs);
12652 }
12653 break;
12654 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
12655 if (rs == 0 && rt != 0) {
12656 /* OPC_BGTZC */
12657 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
12658 } else if (rs != 0 && rt != 0 && rs == rt) {
12659 /* OPC_BLTZC */
12660 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
12661 } else {
12662 /* OPC_BLTC */
12663 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT), t0, t1, fs);
12664 }
12665 break;
12666 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
12667 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
12668 if (rs >= rt) {
12669 /* OPC_BOVC, OPC_BNVC */
12670 TCGv t2 = tcg_temp_new();
12671 TCGv t3 = tcg_temp_new();
12672 TCGv t4 = tcg_temp_new();
12673 TCGv input_overflow = tcg_temp_new();
12674
12675 gen_load_gpr(t0, rs);
12676 gen_load_gpr(t1, rt);
12677 tcg_gen_ext32s_tl(t2, t0);
12678 tcg_gen_setcond_tl(TCG_COND_NE, input_overflow, t2, t0);
12679 tcg_gen_ext32s_tl(t3, t1);
12680 tcg_gen_setcond_tl(TCG_COND_NE, t4, t3, t1);
12681 tcg_gen_or_tl(input_overflow, input_overflow, t4);
12682
12683 tcg_gen_add_tl(t4, t2, t3);
12684 tcg_gen_ext32s_tl(t4, t4);
12685 tcg_gen_xor_tl(t2, t2, t3);
12686 tcg_gen_xor_tl(t3, t4, t3);
12687 tcg_gen_andc_tl(t2, t3, t2);
12688 tcg_gen_setcondi_tl(TCG_COND_LT, t4, t2, 0);
12689 tcg_gen_or_tl(t4, t4, input_overflow);
12690 if (opc == OPC_BOVC) {
12691 /* OPC_BOVC */
12692 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t4, 0, fs);
12693 } else {
12694 /* OPC_BNVC */
12695 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t4, 0, fs);
12696 }
12697 tcg_temp_free(input_overflow);
12698 tcg_temp_free(t4);
12699 tcg_temp_free(t3);
12700 tcg_temp_free(t2);
12701 } else if (rs < rt && rs == 0) {
12702 /* OPC_BEQZALC, OPC_BNEZALC */
12703 if (opc == OPC_BEQZALC) {
12704 /* OPC_BEQZALC */
12705 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t1, 0, fs);
12706 } else {
12707 /* OPC_BNEZALC */
12708 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t1, 0, fs);
12709 }
12710 } else {
12711 /* OPC_BEQC, OPC_BNEC */
12712 if (opc == OPC_BEQC) {
12713 /* OPC_BEQC */
12714 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_EQ), t0, t1, fs);
12715 } else {
12716 /* OPC_BNEC */
12717 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_NE), t0, t1, fs);
12718 }
12719 }
12720 break;
12721 case OPC_BEQZC:
12722 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t0, 0, fs);
12723 break;
12724 case OPC_BNEZC:
12725 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t0, 0, fs);
12726 break;
12727 default:
12728 MIPS_INVAL("Compact conditional branch/jump");
9c708c7f 12729 generate_exception_end(ctx, EXCP_RI);
6893f074
YK
12730 goto out;
12731 }
12732
12733 /* Generating branch here as compact branches don't have delay slot */
12734 gen_goto_tb(ctx, 1, ctx->btarget);
12735 gen_set_label(fs);
12736
12737 ctx->hflags |= MIPS_HFLAG_FBNSLOT;
6893f074
YK
12738 }
12739
12740out:
12741 tcg_temp_free(t0);
12742 tcg_temp_free(t1);
12743}
12744
7a387fff 12745/* ISA extensions (ASEs) */
6af0bf9c 12746/* MIPS16 extension to MIPS32 */
6ea219d0
NF
12747
12748/* MIPS16 major opcodes */
12749enum {
12750 M16_OPC_ADDIUSP = 0x00,
12751 M16_OPC_ADDIUPC = 0x01,
12752 M16_OPC_B = 0x02,
12753 M16_OPC_JAL = 0x03,
12754 M16_OPC_BEQZ = 0x04,
12755 M16_OPC_BNEQZ = 0x05,
12756 M16_OPC_SHIFT = 0x06,
12757 M16_OPC_LD = 0x07,
12758 M16_OPC_RRIA = 0x08,
12759 M16_OPC_ADDIU8 = 0x09,
12760 M16_OPC_SLTI = 0x0a,
12761 M16_OPC_SLTIU = 0x0b,
12762 M16_OPC_I8 = 0x0c,
12763 M16_OPC_LI = 0x0d,
12764 M16_OPC_CMPI = 0x0e,
12765 M16_OPC_SD = 0x0f,
12766 M16_OPC_LB = 0x10,
12767 M16_OPC_LH = 0x11,
12768 M16_OPC_LWSP = 0x12,
12769 M16_OPC_LW = 0x13,
12770 M16_OPC_LBU = 0x14,
12771 M16_OPC_LHU = 0x15,
12772 M16_OPC_LWPC = 0x16,
12773 M16_OPC_LWU = 0x17,
12774 M16_OPC_SB = 0x18,
12775 M16_OPC_SH = 0x19,
12776 M16_OPC_SWSP = 0x1a,
12777 M16_OPC_SW = 0x1b,
12778 M16_OPC_RRR = 0x1c,
12779 M16_OPC_RR = 0x1d,
12780 M16_OPC_EXTEND = 0x1e,
12781 M16_OPC_I64 = 0x1f
12782};
12783
12784/* I8 funct field */
12785enum {
12786 I8_BTEQZ = 0x0,
12787 I8_BTNEZ = 0x1,
12788 I8_SWRASP = 0x2,
12789 I8_ADJSP = 0x3,
12790 I8_SVRS = 0x4,
12791 I8_MOV32R = 0x5,
12792 I8_MOVR32 = 0x7
12793};
12794
12795/* RRR f field */
12796enum {
12797 RRR_DADDU = 0x0,
12798 RRR_ADDU = 0x1,
12799 RRR_DSUBU = 0x2,
12800 RRR_SUBU = 0x3
12801};
12802
12803/* RR funct field */
12804enum {
12805 RR_JR = 0x00,
12806 RR_SDBBP = 0x01,
12807 RR_SLT = 0x02,
12808 RR_SLTU = 0x03,
12809 RR_SLLV = 0x04,
12810 RR_BREAK = 0x05,
12811 RR_SRLV = 0x06,
12812 RR_SRAV = 0x07,
12813 RR_DSRL = 0x08,
12814 RR_CMP = 0x0a,
12815 RR_NEG = 0x0b,
12816 RR_AND = 0x0c,
12817 RR_OR = 0x0d,
12818 RR_XOR = 0x0e,
12819 RR_NOT = 0x0f,
12820 RR_MFHI = 0x10,
12821 RR_CNVT = 0x11,
12822 RR_MFLO = 0x12,
12823 RR_DSRA = 0x13,
12824 RR_DSLLV = 0x14,
12825 RR_DSRLV = 0x16,
12826 RR_DSRAV = 0x17,
12827 RR_MULT = 0x18,
12828 RR_MULTU = 0x19,
12829 RR_DIV = 0x1a,
12830 RR_DIVU = 0x1b,
12831 RR_DMULT = 0x1c,
12832 RR_DMULTU = 0x1d,
12833 RR_DDIV = 0x1e,
12834 RR_DDIVU = 0x1f
12835};
12836
12837/* I64 funct field */
12838enum {
12839 I64_LDSP = 0x0,
12840 I64_SDSP = 0x1,
12841 I64_SDRASP = 0x2,
12842 I64_DADJSP = 0x3,
12843 I64_LDPC = 0x4,
364d4831 12844 I64_DADDIU5 = 0x5,
6ea219d0
NF
12845 I64_DADDIUPC = 0x6,
12846 I64_DADDIUSP = 0x7
12847};
12848
12849/* RR ry field for CNVT */
12850enum {
12851 RR_RY_CNVT_ZEB = 0x0,
12852 RR_RY_CNVT_ZEH = 0x1,
12853 RR_RY_CNVT_ZEW = 0x2,
12854 RR_RY_CNVT_SEB = 0x4,
12855 RR_RY_CNVT_SEH = 0x5,
12856 RR_RY_CNVT_SEW = 0x6,
12857};
12858
364d4831
NF
12859static int xlat (int r)
12860{
12861 static int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
12862
12863 return map[r];
12864}
12865
12866static void gen_mips16_save (DisasContext *ctx,
12867 int xsregs, int aregs,
12868 int do_ra, int do_s0, int do_s1,
12869 int framesize)
12870{
12871 TCGv t0 = tcg_temp_new();
12872 TCGv t1 = tcg_temp_new();
c48245f0 12873 TCGv t2 = tcg_temp_new();
364d4831
NF
12874 int args, astatic;
12875
12876 switch (aregs) {
12877 case 0:
12878 case 1:
12879 case 2:
12880 case 3:
12881 case 11:
12882 args = 0;
12883 break;
12884 case 4:
12885 case 5:
12886 case 6:
12887 case 7:
12888 args = 1;
12889 break;
12890 case 8:
12891 case 9:
12892 case 10:
12893 args = 2;
12894 break;
12895 case 12:
12896 case 13:
12897 args = 3;
12898 break;
12899 case 14:
12900 args = 4;
12901 break;
12902 default:
9c708c7f 12903 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
12904 return;
12905 }
12906
12907 switch (args) {
12908 case 4:
12909 gen_base_offset_addr(ctx, t0, 29, 12);
12910 gen_load_gpr(t1, 7);
5f68f5ae 12911 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
364d4831
NF
12912 /* Fall through */
12913 case 3:
12914 gen_base_offset_addr(ctx, t0, 29, 8);
12915 gen_load_gpr(t1, 6);
5f68f5ae 12916 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
364d4831
NF
12917 /* Fall through */
12918 case 2:
12919 gen_base_offset_addr(ctx, t0, 29, 4);
12920 gen_load_gpr(t1, 5);
5f68f5ae 12921 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
364d4831
NF
12922 /* Fall through */
12923 case 1:
12924 gen_base_offset_addr(ctx, t0, 29, 0);
12925 gen_load_gpr(t1, 4);
5f68f5ae 12926 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
364d4831
NF
12927 }
12928
12929 gen_load_gpr(t0, 29);
12930
5f68f5ae 12931#define DECR_AND_STORE(reg) do { \
c48245f0
MR
12932 tcg_gen_movi_tl(t2, -4); \
12933 gen_op_addr_add(ctx, t0, t0, t2); \
5f68f5ae
AJ
12934 gen_load_gpr(t1, reg); \
12935 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); \
364d4831
NF
12936 } while (0)
12937
12938 if (do_ra) {
12939 DECR_AND_STORE(31);
12940 }
12941
12942 switch (xsregs) {
12943 case 7:
12944 DECR_AND_STORE(30);
12945 /* Fall through */
12946 case 6:
12947 DECR_AND_STORE(23);
12948 /* Fall through */
12949 case 5:
12950 DECR_AND_STORE(22);
12951 /* Fall through */
12952 case 4:
12953 DECR_AND_STORE(21);
12954 /* Fall through */
12955 case 3:
12956 DECR_AND_STORE(20);
12957 /* Fall through */
12958 case 2:
12959 DECR_AND_STORE(19);
12960 /* Fall through */
12961 case 1:
12962 DECR_AND_STORE(18);
12963 }
12964
12965 if (do_s1) {
12966 DECR_AND_STORE(17);
12967 }
12968 if (do_s0) {
12969 DECR_AND_STORE(16);
12970 }
12971
12972 switch (aregs) {
12973 case 0:
12974 case 4:
12975 case 8:
12976 case 12:
12977 case 14:
12978 astatic = 0;
12979 break;
12980 case 1:
12981 case 5:
12982 case 9:
12983 case 13:
12984 astatic = 1;
12985 break;
12986 case 2:
12987 case 6:
12988 case 10:
12989 astatic = 2;
12990 break;
12991 case 3:
12992 case 7:
12993 astatic = 3;
12994 break;
12995 case 11:
12996 astatic = 4;
12997 break;
12998 default:
9c708c7f 12999 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
13000 return;
13001 }
13002
13003 if (astatic > 0) {
13004 DECR_AND_STORE(7);
13005 if (astatic > 1) {
13006 DECR_AND_STORE(6);
13007 if (astatic > 2) {
13008 DECR_AND_STORE(5);
13009 if (astatic > 3) {
13010 DECR_AND_STORE(4);
13011 }
13012 }
13013 }
13014 }
13015#undef DECR_AND_STORE
13016
c48245f0
MR
13017 tcg_gen_movi_tl(t2, -framesize);
13018 gen_op_addr_add(ctx, cpu_gpr[29], cpu_gpr[29], t2);
364d4831
NF
13019 tcg_temp_free(t0);
13020 tcg_temp_free(t1);
c48245f0 13021 tcg_temp_free(t2);
364d4831
NF
13022}
13023
13024static void gen_mips16_restore (DisasContext *ctx,
13025 int xsregs, int aregs,
13026 int do_ra, int do_s0, int do_s1,
13027 int framesize)
13028{
13029 int astatic;
13030 TCGv t0 = tcg_temp_new();
13031 TCGv t1 = tcg_temp_new();
c48245f0 13032 TCGv t2 = tcg_temp_new();
364d4831 13033
c48245f0
MR
13034 tcg_gen_movi_tl(t2, framesize);
13035 gen_op_addr_add(ctx, t0, cpu_gpr[29], t2);
364d4831 13036
5f68f5ae 13037#define DECR_AND_LOAD(reg) do { \
c48245f0
MR
13038 tcg_gen_movi_tl(t2, -4); \
13039 gen_op_addr_add(ctx, t0, t0, t2); \
5f68f5ae
AJ
13040 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL); \
13041 gen_store_gpr(t1, reg); \
364d4831
NF
13042 } while (0)
13043
13044 if (do_ra) {
13045 DECR_AND_LOAD(31);
13046 }
13047
13048 switch (xsregs) {
13049 case 7:
13050 DECR_AND_LOAD(30);
13051 /* Fall through */
13052 case 6:
13053 DECR_AND_LOAD(23);
13054 /* Fall through */
13055 case 5:
13056 DECR_AND_LOAD(22);
13057 /* Fall through */
13058 case 4:
13059 DECR_AND_LOAD(21);
13060 /* Fall through */
13061 case 3:
13062 DECR_AND_LOAD(20);
13063 /* Fall through */
13064 case 2:
13065 DECR_AND_LOAD(19);
13066 /* Fall through */
13067 case 1:
13068 DECR_AND_LOAD(18);
13069 }
13070
13071 if (do_s1) {
13072 DECR_AND_LOAD(17);
13073 }
13074 if (do_s0) {
13075 DECR_AND_LOAD(16);
13076 }
13077
13078 switch (aregs) {
13079 case 0:
13080 case 4:
13081 case 8:
13082 case 12:
13083 case 14:
13084 astatic = 0;
13085 break;
13086 case 1:
13087 case 5:
13088 case 9:
13089 case 13:
13090 astatic = 1;
13091 break;
13092 case 2:
13093 case 6:
13094 case 10:
13095 astatic = 2;
13096 break;
13097 case 3:
13098 case 7:
13099 astatic = 3;
13100 break;
13101 case 11:
13102 astatic = 4;
13103 break;
13104 default:
9c708c7f 13105 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
13106 return;
13107 }
13108
13109 if (astatic > 0) {
13110 DECR_AND_LOAD(7);
13111 if (astatic > 1) {
13112 DECR_AND_LOAD(6);
13113 if (astatic > 2) {
13114 DECR_AND_LOAD(5);
13115 if (astatic > 3) {
13116 DECR_AND_LOAD(4);
13117 }
13118 }
13119 }
13120 }
13121#undef DECR_AND_LOAD
13122
c48245f0
MR
13123 tcg_gen_movi_tl(t2, framesize);
13124 gen_op_addr_add(ctx, cpu_gpr[29], cpu_gpr[29], t2);
364d4831
NF
13125 tcg_temp_free(t0);
13126 tcg_temp_free(t1);
c48245f0 13127 tcg_temp_free(t2);
364d4831
NF
13128}
13129
13130static void gen_addiupc (DisasContext *ctx, int rx, int imm,
13131 int is_64_bit, int extended)
13132{
13133 TCGv t0;
13134
13135 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9c708c7f 13136 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
13137 return;
13138 }
13139
13140 t0 = tcg_temp_new();
13141
13142 tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
13143 tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
13144 if (!is_64_bit) {
13145 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
13146 }
13147
13148 tcg_temp_free(t0);
13149}
13150
0d74a222
LA
13151static void gen_cache_operation(DisasContext *ctx, uint32_t op, int base,
13152 int16_t offset)
13153{
13154 TCGv_i32 t0 = tcg_const_i32(op);
13155 TCGv t1 = tcg_temp_new();
13156 gen_base_offset_addr(ctx, t1, base, offset);
13157 gen_helper_cache(cpu_env, t1, t0);
13158}
13159
364d4831 13160#if defined(TARGET_MIPS64)
d75c135e 13161static void decode_i64_mips16 (DisasContext *ctx,
364d4831
NF
13162 int ry, int funct, int16_t offset,
13163 int extended)
13164{
13165 switch (funct) {
13166 case I64_LDSP:
d9224450 13167 check_insn(ctx, ISA_MIPS3);
364d4831
NF
13168 check_mips_64(ctx);
13169 offset = extended ? offset : offset << 3;
d75c135e 13170 gen_ld(ctx, OPC_LD, ry, 29, offset);
364d4831
NF
13171 break;
13172 case I64_SDSP:
d9224450 13173 check_insn(ctx, ISA_MIPS3);
364d4831
NF
13174 check_mips_64(ctx);
13175 offset = extended ? offset : offset << 3;
5c13fdfd 13176 gen_st(ctx, OPC_SD, ry, 29, offset);
364d4831
NF
13177 break;
13178 case I64_SDRASP:
d9224450 13179 check_insn(ctx, ISA_MIPS3);
364d4831
NF
13180 check_mips_64(ctx);
13181 offset = extended ? offset : (ctx->opcode & 0xff) << 3;
5c13fdfd 13182 gen_st(ctx, OPC_SD, 31, 29, offset);
364d4831
NF
13183 break;
13184 case I64_DADJSP:
d9224450 13185 check_insn(ctx, ISA_MIPS3);
364d4831
NF
13186 check_mips_64(ctx);
13187 offset = extended ? offset : ((int8_t)ctx->opcode) << 3;
d75c135e 13188 gen_arith_imm(ctx, OPC_DADDIU, 29, 29, offset);
364d4831
NF
13189 break;
13190 case I64_LDPC:
d9224450
MR
13191 check_insn(ctx, ISA_MIPS3);
13192 check_mips_64(ctx);
364d4831 13193 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9c708c7f 13194 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
13195 } else {
13196 offset = extended ? offset : offset << 3;
d75c135e 13197 gen_ld(ctx, OPC_LDPC, ry, 0, offset);
364d4831
NF
13198 }
13199 break;
13200 case I64_DADDIU5:
d9224450 13201 check_insn(ctx, ISA_MIPS3);
364d4831
NF
13202 check_mips_64(ctx);
13203 offset = extended ? offset : ((int8_t)(offset << 3)) >> 3;
d75c135e 13204 gen_arith_imm(ctx, OPC_DADDIU, ry, ry, offset);
364d4831
NF
13205 break;
13206 case I64_DADDIUPC:
d9224450 13207 check_insn(ctx, ISA_MIPS3);
364d4831
NF
13208 check_mips_64(ctx);
13209 offset = extended ? offset : offset << 2;
13210 gen_addiupc(ctx, ry, offset, 1, extended);
13211 break;
13212 case I64_DADDIUSP:
d9224450 13213 check_insn(ctx, ISA_MIPS3);
364d4831
NF
13214 check_mips_64(ctx);
13215 offset = extended ? offset : offset << 2;
d75c135e 13216 gen_arith_imm(ctx, OPC_DADDIU, ry, 29, offset);
364d4831
NF
13217 break;
13218 }
13219}
13220#endif
13221
240ce26a 13222static int decode_extended_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
364d4831 13223{
eeb3bba8 13224 int extend = cpu_lduw_code(env, ctx->base.pc_next + 2);
364d4831
NF
13225 int op, rx, ry, funct, sa;
13226 int16_t imm, offset;
13227
13228 ctx->opcode = (ctx->opcode << 16) | extend;
13229 op = (ctx->opcode >> 11) & 0x1f;
13230 sa = (ctx->opcode >> 22) & 0x1f;
13231 funct = (ctx->opcode >> 8) & 0x7;
13232 rx = xlat((ctx->opcode >> 8) & 0x7);
13233 ry = xlat((ctx->opcode >> 5) & 0x7);
13234 offset = imm = (int16_t) (((ctx->opcode >> 16) & 0x1f) << 11
13235 | ((ctx->opcode >> 21) & 0x3f) << 5
13236 | (ctx->opcode & 0x1f));
13237
13238 /* The extended opcodes cleverly reuse the opcodes from their 16-bit
13239 counterparts. */
13240 switch (op) {
13241 case M16_OPC_ADDIUSP:
d75c135e 13242 gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
364d4831
NF
13243 break;
13244 case M16_OPC_ADDIUPC:
13245 gen_addiupc(ctx, rx, imm, 0, 1);
13246 break;
13247 case M16_OPC_B:
b231c103 13248 gen_compute_branch(ctx, OPC_BEQ, 4, 0, 0, offset << 1, 0);
364d4831
NF
13249 /* No delay slot, so just process as a normal instruction */
13250 break;
13251 case M16_OPC_BEQZ:
b231c103 13252 gen_compute_branch(ctx, OPC_BEQ, 4, rx, 0, offset << 1, 0);
364d4831
NF
13253 /* No delay slot, so just process as a normal instruction */
13254 break;
13255 case M16_OPC_BNEQZ:
b231c103 13256 gen_compute_branch(ctx, OPC_BNE, 4, rx, 0, offset << 1, 0);
364d4831
NF
13257 /* No delay slot, so just process as a normal instruction */
13258 break;
13259 case M16_OPC_SHIFT:
13260 switch (ctx->opcode & 0x3) {
13261 case 0x0:
d75c135e 13262 gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
364d4831
NF
13263 break;
13264 case 0x1:
13265#if defined(TARGET_MIPS64)
13266 check_mips_64(ctx);
d75c135e 13267 gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
364d4831 13268#else
9c708c7f 13269 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
13270#endif
13271 break;
13272 case 0x2:
d75c135e 13273 gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
364d4831
NF
13274 break;
13275 case 0x3:
d75c135e 13276 gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
364d4831
NF
13277 break;
13278 }
13279 break;
13280#if defined(TARGET_MIPS64)
13281 case M16_OPC_LD:
d9224450 13282 check_insn(ctx, ISA_MIPS3);
d75de749 13283 check_mips_64(ctx);
d75c135e 13284 gen_ld(ctx, OPC_LD, ry, rx, offset);
364d4831
NF
13285 break;
13286#endif
13287 case M16_OPC_RRIA:
13288 imm = ctx->opcode & 0xf;
13289 imm = imm | ((ctx->opcode >> 20) & 0x7f) << 4;
13290 imm = imm | ((ctx->opcode >> 16) & 0xf) << 11;
13291 imm = (int16_t) (imm << 1) >> 1;
13292 if ((ctx->opcode >> 4) & 0x1) {
13293#if defined(TARGET_MIPS64)
13294 check_mips_64(ctx);
d75c135e 13295 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
364d4831 13296#else
9c708c7f 13297 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
13298#endif
13299 } else {
d75c135e 13300 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
364d4831
NF
13301 }
13302 break;
13303 case M16_OPC_ADDIU8:
d75c135e 13304 gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
364d4831
NF
13305 break;
13306 case M16_OPC_SLTI:
d75c135e 13307 gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
364d4831
NF
13308 break;
13309 case M16_OPC_SLTIU:
d75c135e 13310 gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
364d4831
NF
13311 break;
13312 case M16_OPC_I8:
13313 switch (funct) {
13314 case I8_BTEQZ:
b231c103 13315 gen_compute_branch(ctx, OPC_BEQ, 4, 24, 0, offset << 1, 0);
364d4831
NF
13316 break;
13317 case I8_BTNEZ:
b231c103 13318 gen_compute_branch(ctx, OPC_BNE, 4, 24, 0, offset << 1, 0);
364d4831
NF
13319 break;
13320 case I8_SWRASP:
5c13fdfd 13321 gen_st(ctx, OPC_SW, 31, 29, imm);
364d4831
NF
13322 break;
13323 case I8_ADJSP:
d75c135e 13324 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm);
364d4831
NF
13325 break;
13326 case I8_SVRS:
d9224450 13327 check_insn(ctx, ISA_MIPS32);
364d4831
NF
13328 {
13329 int xsregs = (ctx->opcode >> 24) & 0x7;
13330 int aregs = (ctx->opcode >> 16) & 0xf;
13331 int do_ra = (ctx->opcode >> 6) & 0x1;
13332 int do_s0 = (ctx->opcode >> 5) & 0x1;
13333 int do_s1 = (ctx->opcode >> 4) & 0x1;
13334 int framesize = (((ctx->opcode >> 20) & 0xf) << 4
13335 | (ctx->opcode & 0xf)) << 3;
13336
13337 if (ctx->opcode & (1 << 7)) {
13338 gen_mips16_save(ctx, xsregs, aregs,
13339 do_ra, do_s0, do_s1,
13340 framesize);
13341 } else {
13342 gen_mips16_restore(ctx, xsregs, aregs,
13343 do_ra, do_s0, do_s1,
13344 framesize);
13345 }
13346 }
13347 break;
13348 default:
9c708c7f 13349 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
13350 break;
13351 }
13352 break;
13353 case M16_OPC_LI:
13354 tcg_gen_movi_tl(cpu_gpr[rx], (uint16_t) imm);
13355 break;
13356 case M16_OPC_CMPI:
13357 tcg_gen_xori_tl(cpu_gpr[24], cpu_gpr[rx], (uint16_t) imm);
13358 break;
13359#if defined(TARGET_MIPS64)
13360 case M16_OPC_SD:
d9224450
MR
13361 check_insn(ctx, ISA_MIPS3);
13362 check_mips_64(ctx);
5c13fdfd 13363 gen_st(ctx, OPC_SD, ry, rx, offset);
364d4831
NF
13364 break;
13365#endif
13366 case M16_OPC_LB:
d75c135e 13367 gen_ld(ctx, OPC_LB, ry, rx, offset);
364d4831
NF
13368 break;
13369 case M16_OPC_LH:
d75c135e 13370 gen_ld(ctx, OPC_LH, ry, rx, offset);
364d4831
NF
13371 break;
13372 case M16_OPC_LWSP:
d75c135e 13373 gen_ld(ctx, OPC_LW, rx, 29, offset);
364d4831
NF
13374 break;
13375 case M16_OPC_LW:
d75c135e 13376 gen_ld(ctx, OPC_LW, ry, rx, offset);
364d4831
NF
13377 break;
13378 case M16_OPC_LBU:
d75c135e 13379 gen_ld(ctx, OPC_LBU, ry, rx, offset);
364d4831
NF
13380 break;
13381 case M16_OPC_LHU:
d75c135e 13382 gen_ld(ctx, OPC_LHU, ry, rx, offset);
364d4831
NF
13383 break;
13384 case M16_OPC_LWPC:
d75c135e 13385 gen_ld(ctx, OPC_LWPC, rx, 0, offset);
364d4831
NF
13386 break;
13387#if defined(TARGET_MIPS64)
13388 case M16_OPC_LWU:
d9224450
MR
13389 check_insn(ctx, ISA_MIPS3);
13390 check_mips_64(ctx);
d75c135e 13391 gen_ld(ctx, OPC_LWU, ry, rx, offset);
364d4831
NF
13392 break;
13393#endif
13394 case M16_OPC_SB:
5c13fdfd 13395 gen_st(ctx, OPC_SB, ry, rx, offset);
364d4831
NF
13396 break;
13397 case M16_OPC_SH:
5c13fdfd 13398 gen_st(ctx, OPC_SH, ry, rx, offset);
364d4831
NF
13399 break;
13400 case M16_OPC_SWSP:
5c13fdfd 13401 gen_st(ctx, OPC_SW, rx, 29, offset);
364d4831
NF
13402 break;
13403 case M16_OPC_SW:
5c13fdfd 13404 gen_st(ctx, OPC_SW, ry, rx, offset);
364d4831
NF
13405 break;
13406#if defined(TARGET_MIPS64)
13407 case M16_OPC_I64:
d75c135e 13408 decode_i64_mips16(ctx, ry, funct, offset, 1);
364d4831
NF
13409 break;
13410#endif
13411 default:
9c708c7f 13412 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
13413 break;
13414 }
13415
13416 return 4;
13417}
13418
3b3c1694
LA
13419static inline bool is_uhi(int sdbbp_code)
13420{
13421#ifdef CONFIG_USER_ONLY
13422 return false;
13423#else
13424 return semihosting_enabled() && sdbbp_code == 1;
13425#endif
13426}
13427
240ce26a 13428static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
364d4831
NF
13429{
13430 int rx, ry;
13431 int sa;
13432 int op, cnvt_op, op1, offset;
13433 int funct;
13434 int n_bytes;
13435
13436 op = (ctx->opcode >> 11) & 0x1f;
13437 sa = (ctx->opcode >> 2) & 0x7;
13438 sa = sa == 0 ? 8 : sa;
13439 rx = xlat((ctx->opcode >> 8) & 0x7);
13440 cnvt_op = (ctx->opcode >> 5) & 0x7;
13441 ry = xlat((ctx->opcode >> 5) & 0x7);
13442 op1 = offset = ctx->opcode & 0x1f;
13443
13444 n_bytes = 2;
13445
13446 switch (op) {
13447 case M16_OPC_ADDIUSP:
13448 {
13449 int16_t imm = ((uint8_t) ctx->opcode) << 2;
13450
d75c135e 13451 gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
364d4831
NF
13452 }
13453 break;
13454 case M16_OPC_ADDIUPC:
13455 gen_addiupc(ctx, rx, ((uint8_t) ctx->opcode) << 2, 0, 0);
13456 break;
13457 case M16_OPC_B:
13458 offset = (ctx->opcode & 0x7ff) << 1;
13459 offset = (int16_t)(offset << 4) >> 4;
b231c103 13460 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, offset, 0);
364d4831
NF
13461 /* No delay slot, so just process as a normal instruction */
13462 break;
13463 case M16_OPC_JAL:
eeb3bba8 13464 offset = cpu_lduw_code(env, ctx->base.pc_next + 2);
364d4831
NF
13465 offset = (((ctx->opcode & 0x1f) << 21)
13466 | ((ctx->opcode >> 5) & 0x1f) << 16
13467 | offset) << 2;
b231c103
YK
13468 op = ((ctx->opcode >> 10) & 0x1) ? OPC_JALX : OPC_JAL;
13469 gen_compute_branch(ctx, op, 4, rx, ry, offset, 2);
364d4831 13470 n_bytes = 4;
364d4831
NF
13471 break;
13472 case M16_OPC_BEQZ:
b231c103
YK
13473 gen_compute_branch(ctx, OPC_BEQ, 2, rx, 0,
13474 ((int8_t)ctx->opcode) << 1, 0);
364d4831
NF
13475 /* No delay slot, so just process as a normal instruction */
13476 break;
13477 case M16_OPC_BNEQZ:
b231c103
YK
13478 gen_compute_branch(ctx, OPC_BNE, 2, rx, 0,
13479 ((int8_t)ctx->opcode) << 1, 0);
364d4831
NF
13480 /* No delay slot, so just process as a normal instruction */
13481 break;
13482 case M16_OPC_SHIFT:
13483 switch (ctx->opcode & 0x3) {
13484 case 0x0:
d75c135e 13485 gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
364d4831
NF
13486 break;
13487 case 0x1:
13488#if defined(TARGET_MIPS64)
d9224450 13489 check_insn(ctx, ISA_MIPS3);
364d4831 13490 check_mips_64(ctx);
d75c135e 13491 gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
364d4831 13492#else
9c708c7f 13493 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
13494#endif
13495 break;
13496 case 0x2:
d75c135e 13497 gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
364d4831
NF
13498 break;
13499 case 0x3:
d75c135e 13500 gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
364d4831
NF
13501 break;
13502 }
13503 break;
13504#if defined(TARGET_MIPS64)
13505 case M16_OPC_LD:
d9224450 13506 check_insn(ctx, ISA_MIPS3);
364d4831 13507 check_mips_64(ctx);
d75c135e 13508 gen_ld(ctx, OPC_LD, ry, rx, offset << 3);
364d4831
NF
13509 break;
13510#endif
13511 case M16_OPC_RRIA:
13512 {
13513 int16_t imm = (int8_t)((ctx->opcode & 0xf) << 4) >> 4;
13514
13515 if ((ctx->opcode >> 4) & 1) {
13516#if defined(TARGET_MIPS64)
d9224450 13517 check_insn(ctx, ISA_MIPS3);
364d4831 13518 check_mips_64(ctx);
d75c135e 13519 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
364d4831 13520#else
9c708c7f 13521 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
13522#endif
13523 } else {
d75c135e 13524 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
364d4831
NF
13525 }
13526 }
13527 break;
13528 case M16_OPC_ADDIU8:
13529 {
13530 int16_t imm = (int8_t) ctx->opcode;
13531
d75c135e 13532 gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
364d4831
NF
13533 }
13534 break;
13535 case M16_OPC_SLTI:
13536 {
13537 int16_t imm = (uint8_t) ctx->opcode;
d75c135e 13538 gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
364d4831
NF
13539 }
13540 break;
13541 case M16_OPC_SLTIU:
13542 {
13543 int16_t imm = (uint8_t) ctx->opcode;
d75c135e 13544 gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
364d4831
NF
13545 }
13546 break;
13547 case M16_OPC_I8:
13548 {
13549 int reg32;
13550
13551 funct = (ctx->opcode >> 8) & 0x7;
13552 switch (funct) {
13553 case I8_BTEQZ:
13554 gen_compute_branch(ctx, OPC_BEQ, 2, 24, 0,
b231c103 13555 ((int8_t)ctx->opcode) << 1, 0);
364d4831
NF
13556 break;
13557 case I8_BTNEZ:
13558 gen_compute_branch(ctx, OPC_BNE, 2, 24, 0,
b231c103 13559 ((int8_t)ctx->opcode) << 1, 0);
364d4831
NF
13560 break;
13561 case I8_SWRASP:
5c13fdfd 13562 gen_st(ctx, OPC_SW, 31, 29, (ctx->opcode & 0xff) << 2);
364d4831
NF
13563 break;
13564 case I8_ADJSP:
d75c135e 13565 gen_arith_imm(ctx, OPC_ADDIU, 29, 29,
364d4831
NF
13566 ((int8_t)ctx->opcode) << 3);
13567 break;
13568 case I8_SVRS:
d9224450 13569 check_insn(ctx, ISA_MIPS32);
364d4831
NF
13570 {
13571 int do_ra = ctx->opcode & (1 << 6);
13572 int do_s0 = ctx->opcode & (1 << 5);
13573 int do_s1 = ctx->opcode & (1 << 4);
13574 int framesize = ctx->opcode & 0xf;
13575
13576 if (framesize == 0) {
13577 framesize = 128;
13578 } else {
13579 framesize = framesize << 3;
13580 }
13581
13582 if (ctx->opcode & (1 << 7)) {
13583 gen_mips16_save(ctx, 0, 0,
13584 do_ra, do_s0, do_s1, framesize);
13585 } else {
13586 gen_mips16_restore(ctx, 0, 0,
13587 do_ra, do_s0, do_s1, framesize);
13588 }
13589 }
13590 break;
13591 case I8_MOV32R:
13592 {
13593 int rz = xlat(ctx->opcode & 0x7);
13594
13595 reg32 = (((ctx->opcode >> 3) & 0x3) << 3) |
13596 ((ctx->opcode >> 5) & 0x7);
d75c135e 13597 gen_arith(ctx, OPC_ADDU, reg32, rz, 0);
364d4831
NF
13598 }
13599 break;
13600 case I8_MOVR32:
13601 reg32 = ctx->opcode & 0x1f;
d75c135e 13602 gen_arith(ctx, OPC_ADDU, ry, reg32, 0);
364d4831
NF
13603 break;
13604 default:
9c708c7f 13605 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
13606 break;
13607 }
13608 }
13609 break;
13610 case M16_OPC_LI:
13611 {
13612 int16_t imm = (uint8_t) ctx->opcode;
13613
d75c135e 13614 gen_arith_imm(ctx, OPC_ADDIU, rx, 0, imm);
364d4831
NF
13615 }
13616 break;
13617 case M16_OPC_CMPI:
13618 {
13619 int16_t imm = (uint8_t) ctx->opcode;
d75c135e 13620 gen_logic_imm(ctx, OPC_XORI, 24, rx, imm);
364d4831
NF
13621 }
13622 break;
13623#if defined(TARGET_MIPS64)
13624 case M16_OPC_SD:
d9224450 13625 check_insn(ctx, ISA_MIPS3);
364d4831 13626 check_mips_64(ctx);
5c13fdfd 13627 gen_st(ctx, OPC_SD, ry, rx, offset << 3);
364d4831
NF
13628 break;
13629#endif
13630 case M16_OPC_LB:
d75c135e 13631 gen_ld(ctx, OPC_LB, ry, rx, offset);
364d4831
NF
13632 break;
13633 case M16_OPC_LH:
d75c135e 13634 gen_ld(ctx, OPC_LH, ry, rx, offset << 1);
364d4831
NF
13635 break;
13636 case M16_OPC_LWSP:
d75c135e 13637 gen_ld(ctx, OPC_LW, rx, 29, ((uint8_t)ctx->opcode) << 2);
364d4831
NF
13638 break;
13639 case M16_OPC_LW:
d75c135e 13640 gen_ld(ctx, OPC_LW, ry, rx, offset << 2);
364d4831
NF
13641 break;
13642 case M16_OPC_LBU:
d75c135e 13643 gen_ld(ctx, OPC_LBU, ry, rx, offset);
364d4831
NF
13644 break;
13645 case M16_OPC_LHU:
d75c135e 13646 gen_ld(ctx, OPC_LHU, ry, rx, offset << 1);
364d4831
NF
13647 break;
13648 case M16_OPC_LWPC:
d75c135e 13649 gen_ld(ctx, OPC_LWPC, rx, 0, ((uint8_t)ctx->opcode) << 2);
364d4831
NF
13650 break;
13651#if defined (TARGET_MIPS64)
13652 case M16_OPC_LWU:
d9224450 13653 check_insn(ctx, ISA_MIPS3);
364d4831 13654 check_mips_64(ctx);
d75c135e 13655 gen_ld(ctx, OPC_LWU, ry, rx, offset << 2);
364d4831
NF
13656 break;
13657#endif
13658 case M16_OPC_SB:
5c13fdfd 13659 gen_st(ctx, OPC_SB, ry, rx, offset);
364d4831
NF
13660 break;
13661 case M16_OPC_SH:
5c13fdfd 13662 gen_st(ctx, OPC_SH, ry, rx, offset << 1);
364d4831
NF
13663 break;
13664 case M16_OPC_SWSP:
5c13fdfd 13665 gen_st(ctx, OPC_SW, rx, 29, ((uint8_t)ctx->opcode) << 2);
364d4831
NF
13666 break;
13667 case M16_OPC_SW:
5c13fdfd 13668 gen_st(ctx, OPC_SW, ry, rx, offset << 2);
364d4831
NF
13669 break;
13670 case M16_OPC_RRR:
13671 {
13672 int rz = xlat((ctx->opcode >> 2) & 0x7);
13673 int mips32_op;
13674
13675 switch (ctx->opcode & 0x3) {
13676 case RRR_ADDU:
13677 mips32_op = OPC_ADDU;
13678 break;
13679 case RRR_SUBU:
13680 mips32_op = OPC_SUBU;
13681 break;
13682#if defined(TARGET_MIPS64)
13683 case RRR_DADDU:
13684 mips32_op = OPC_DADDU;
d9224450 13685 check_insn(ctx, ISA_MIPS3);
364d4831
NF
13686 check_mips_64(ctx);
13687 break;
13688 case RRR_DSUBU:
13689 mips32_op = OPC_DSUBU;
d9224450 13690 check_insn(ctx, ISA_MIPS3);
364d4831
NF
13691 check_mips_64(ctx);
13692 break;
13693#endif
13694 default:
9c708c7f 13695 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
13696 goto done;
13697 }
13698
d75c135e 13699 gen_arith(ctx, mips32_op, rz, rx, ry);
364d4831
NF
13700 done:
13701 ;
13702 }
13703 break;
13704 case M16_OPC_RR:
13705 switch (op1) {
13706 case RR_JR:
13707 {
13708 int nd = (ctx->opcode >> 7) & 0x1;
13709 int link = (ctx->opcode >> 6) & 0x1;
13710 int ra = (ctx->opcode >> 5) & 0x1;
13711
d9224450
MR
13712 if (nd) {
13713 check_insn(ctx, ISA_MIPS32);
13714 }
13715
364d4831 13716 if (link) {
b231c103 13717 op = OPC_JALR;
364d4831
NF
13718 } else {
13719 op = OPC_JR;
13720 }
13721
b231c103
YK
13722 gen_compute_branch(ctx, op, 2, ra ? 31 : rx, 31, 0,
13723 (nd ? 0 : 2));
364d4831
NF
13724 }
13725 break;
13726 case RR_SDBBP:
3b3c1694
LA
13727 if (is_uhi(extract32(ctx->opcode, 5, 6))) {
13728 gen_helper_do_semihosting(cpu_env);
13729 } else {
13730 /* XXX: not clear which exception should be raised
13731 * when in debug mode...
13732 */
13733 check_insn(ctx, ISA_MIPS32);
9c708c7f 13734 generate_exception_end(ctx, EXCP_DBp);
3b3c1694 13735 }
364d4831
NF
13736 break;
13737 case RR_SLT:
d75c135e 13738 gen_slt(ctx, OPC_SLT, 24, rx, ry);
364d4831
NF
13739 break;
13740 case RR_SLTU:
d75c135e 13741 gen_slt(ctx, OPC_SLTU, 24, rx, ry);
364d4831
NF
13742 break;
13743 case RR_BREAK:
9c708c7f 13744 generate_exception_end(ctx, EXCP_BREAK);
364d4831
NF
13745 break;
13746 case RR_SLLV:
d75c135e 13747 gen_shift(ctx, OPC_SLLV, ry, rx, ry);
364d4831
NF
13748 break;
13749 case RR_SRLV:
d75c135e 13750 gen_shift(ctx, OPC_SRLV, ry, rx, ry);
364d4831
NF
13751 break;
13752 case RR_SRAV:
d75c135e 13753 gen_shift(ctx, OPC_SRAV, ry, rx, ry);
364d4831
NF
13754 break;
13755#if defined (TARGET_MIPS64)
13756 case RR_DSRL:
d9224450 13757 check_insn(ctx, ISA_MIPS3);
364d4831 13758 check_mips_64(ctx);
d75c135e 13759 gen_shift_imm(ctx, OPC_DSRL, ry, ry, sa);
364d4831
NF
13760 break;
13761#endif
13762 case RR_CMP:
d75c135e 13763 gen_logic(ctx, OPC_XOR, 24, rx, ry);
364d4831
NF
13764 break;
13765 case RR_NEG:
d75c135e 13766 gen_arith(ctx, OPC_SUBU, rx, 0, ry);
364d4831
NF
13767 break;
13768 case RR_AND:
d75c135e 13769 gen_logic(ctx, OPC_AND, rx, rx, ry);
364d4831
NF
13770 break;
13771 case RR_OR:
d75c135e 13772 gen_logic(ctx, OPC_OR, rx, rx, ry);
364d4831
NF
13773 break;
13774 case RR_XOR:
d75c135e 13775 gen_logic(ctx, OPC_XOR, rx, rx, ry);
364d4831
NF
13776 break;
13777 case RR_NOT:
d75c135e 13778 gen_logic(ctx, OPC_NOR, rx, ry, 0);
364d4831
NF
13779 break;
13780 case RR_MFHI:
26135ead 13781 gen_HILO(ctx, OPC_MFHI, 0, rx);
364d4831
NF
13782 break;
13783 case RR_CNVT:
d9224450 13784 check_insn(ctx, ISA_MIPS32);
364d4831
NF
13785 switch (cnvt_op) {
13786 case RR_RY_CNVT_ZEB:
13787 tcg_gen_ext8u_tl(cpu_gpr[rx], cpu_gpr[rx]);
13788 break;
13789 case RR_RY_CNVT_ZEH:
13790 tcg_gen_ext16u_tl(cpu_gpr[rx], cpu_gpr[rx]);
13791 break;
13792 case RR_RY_CNVT_SEB:
13793 tcg_gen_ext8s_tl(cpu_gpr[rx], cpu_gpr[rx]);
13794 break;
13795 case RR_RY_CNVT_SEH:
13796 tcg_gen_ext16s_tl(cpu_gpr[rx], cpu_gpr[rx]);
13797 break;
13798#if defined (TARGET_MIPS64)
13799 case RR_RY_CNVT_ZEW:
d9224450 13800 check_insn(ctx, ISA_MIPS64);
364d4831
NF
13801 check_mips_64(ctx);
13802 tcg_gen_ext32u_tl(cpu_gpr[rx], cpu_gpr[rx]);
13803 break;
13804 case RR_RY_CNVT_SEW:
d9224450 13805 check_insn(ctx, ISA_MIPS64);
364d4831
NF
13806 check_mips_64(ctx);
13807 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
13808 break;
13809#endif
13810 default:
9c708c7f 13811 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
13812 break;
13813 }
13814 break;
13815 case RR_MFLO:
26135ead 13816 gen_HILO(ctx, OPC_MFLO, 0, rx);
364d4831
NF
13817 break;
13818#if defined (TARGET_MIPS64)
13819 case RR_DSRA:
d9224450 13820 check_insn(ctx, ISA_MIPS3);
364d4831 13821 check_mips_64(ctx);
d75c135e 13822 gen_shift_imm(ctx, OPC_DSRA, ry, ry, sa);
364d4831
NF
13823 break;
13824 case RR_DSLLV:
d9224450 13825 check_insn(ctx, ISA_MIPS3);
364d4831 13826 check_mips_64(ctx);
d75c135e 13827 gen_shift(ctx, OPC_DSLLV, ry, rx, ry);
364d4831
NF
13828 break;
13829 case RR_DSRLV:
d9224450 13830 check_insn(ctx, ISA_MIPS3);
364d4831 13831 check_mips_64(ctx);
d75c135e 13832 gen_shift(ctx, OPC_DSRLV, ry, rx, ry);
364d4831
NF
13833 break;
13834 case RR_DSRAV:
d9224450 13835 check_insn(ctx, ISA_MIPS3);
364d4831 13836 check_mips_64(ctx);
d75c135e 13837 gen_shift(ctx, OPC_DSRAV, ry, rx, ry);
364d4831
NF
13838 break;
13839#endif
13840 case RR_MULT:
26135ead 13841 gen_muldiv(ctx, OPC_MULT, 0, rx, ry);
364d4831
NF
13842 break;
13843 case RR_MULTU:
26135ead 13844 gen_muldiv(ctx, OPC_MULTU, 0, rx, ry);
364d4831
NF
13845 break;
13846 case RR_DIV:
26135ead 13847 gen_muldiv(ctx, OPC_DIV, 0, rx, ry);
364d4831
NF
13848 break;
13849 case RR_DIVU:
26135ead 13850 gen_muldiv(ctx, OPC_DIVU, 0, rx, ry);
364d4831
NF
13851 break;
13852#if defined (TARGET_MIPS64)
13853 case RR_DMULT:
d9224450 13854 check_insn(ctx, ISA_MIPS3);
364d4831 13855 check_mips_64(ctx);
26135ead 13856 gen_muldiv(ctx, OPC_DMULT, 0, rx, ry);
364d4831
NF
13857 break;
13858 case RR_DMULTU:
d9224450 13859 check_insn(ctx, ISA_MIPS3);
364d4831 13860 check_mips_64(ctx);
26135ead 13861 gen_muldiv(ctx, OPC_DMULTU, 0, rx, ry);
364d4831
NF
13862 break;
13863 case RR_DDIV:
d9224450 13864 check_insn(ctx, ISA_MIPS3);
364d4831 13865 check_mips_64(ctx);
26135ead 13866 gen_muldiv(ctx, OPC_DDIV, 0, rx, ry);
364d4831
NF
13867 break;
13868 case RR_DDIVU:
d9224450 13869 check_insn(ctx, ISA_MIPS3);
364d4831 13870 check_mips_64(ctx);
26135ead 13871 gen_muldiv(ctx, OPC_DDIVU, 0, rx, ry);
364d4831
NF
13872 break;
13873#endif
13874 default:
9c708c7f 13875 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
13876 break;
13877 }
13878 break;
13879 case M16_OPC_EXTEND:
240ce26a 13880 decode_extended_mips16_opc(env, ctx);
364d4831
NF
13881 n_bytes = 4;
13882 break;
13883#if defined(TARGET_MIPS64)
13884 case M16_OPC_I64:
13885 funct = (ctx->opcode >> 8) & 0x7;
d75c135e 13886 decode_i64_mips16(ctx, ry, funct, offset, 0);
364d4831
NF
13887 break;
13888#endif
13889 default:
9c708c7f 13890 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
13891 break;
13892 }
13893
13894 return n_bytes;
13895}
13896
211da992 13897/* microMIPS extension to MIPS32/MIPS64 */
6af0bf9c 13898
211da992
CWR
13899/*
13900 * microMIPS32/microMIPS64 major opcodes
13901 *
13902 * 1. MIPS Architecture for Programmers Volume II-B:
13903 * The microMIPS32 Instruction Set (Revision 3.05)
13904 *
13905 * Table 6.2 microMIPS32 Encoding of Major Opcode Field
13906 *
13907 * 2. MIPS Architecture For Programmers Volume II-A:
13908 * The MIPS64 Instruction Set (Revision 3.51)
13909 */
6af0bf9c 13910
3c824109
NF
13911enum {
13912 POOL32A = 0x00,
13913 POOL16A = 0x01,
13914 LBU16 = 0x02,
13915 MOVE16 = 0x03,
13916 ADDI32 = 0x04,
3a1f4268
YK
13917 R6_LUI = 0x04,
13918 AUI = 0x04,
3c824109
NF
13919 LBU32 = 0x05,
13920 SB32 = 0x06,
13921 LB32 = 0x07,
13922
13923 POOL32B = 0x08,
13924 POOL16B = 0x09,
13925 LHU16 = 0x0a,
13926 ANDI16 = 0x0b,
13927 ADDIU32 = 0x0c,
13928 LHU32 = 0x0d,
13929 SH32 = 0x0e,
13930 LH32 = 0x0f,
13931
13932 POOL32I = 0x10,
13933 POOL16C = 0x11,
13934 LWSP16 = 0x12,
13935 POOL16D = 0x13,
13936 ORI32 = 0x14,
13937 POOL32F = 0x15,
211da992
CWR
13938 POOL32S = 0x16, /* MIPS64 */
13939 DADDIU32 = 0x17, /* MIPS64 */
3c824109
NF
13940
13941 POOL32C = 0x18,
13942 LWGP16 = 0x19,
13943 LW16 = 0x1a,
13944 POOL16E = 0x1b,
13945 XORI32 = 0x1c,
13946 JALS32 = 0x1d,
3a1f4268
YK
13947 BOVC = 0x1d,
13948 BEQC = 0x1d,
13949 BEQZALC = 0x1d,
3c824109 13950 ADDIUPC = 0x1e,
3a1f4268
YK
13951 PCREL = 0x1e,
13952 BNVC = 0x1f,
13953 BNEC = 0x1f,
13954 BNEZALC = 0x1f,
3c824109 13955
3a1f4268
YK
13956 R6_BEQZC = 0x20,
13957 JIC = 0x20,
3c824109
NF
13958 POOL16F = 0x21,
13959 SB16 = 0x22,
13960 BEQZ16 = 0x23,
3a1f4268 13961 BEQZC16 = 0x23,
3c824109
NF
13962 SLTI32 = 0x24,
13963 BEQ32 = 0x25,
3a1f4268 13964 BC = 0x25,
3c824109
NF
13965 SWC132 = 0x26,
13966 LWC132 = 0x27,
13967
3a1f4268 13968 /* 0x29 is reserved */
3c824109 13969 RES_29 = 0x29,
3a1f4268
YK
13970 R6_BNEZC = 0x28,
13971 JIALC = 0x28,
3c824109
NF
13972 SH16 = 0x2a,
13973 BNEZ16 = 0x2b,
3a1f4268 13974 BNEZC16 = 0x2b,
3c824109
NF
13975 SLTIU32 = 0x2c,
13976 BNE32 = 0x2d,
3a1f4268 13977 BALC = 0x2d,
3c824109
NF
13978 SDC132 = 0x2e,
13979 LDC132 = 0x2f,
13980
3a1f4268 13981 /* 0x31 is reserved */
3c824109 13982 RES_31 = 0x31,
3a1f4268
YK
13983 BLEZALC = 0x30,
13984 BGEZALC = 0x30,
13985 BGEUC = 0x30,
3c824109
NF
13986 SWSP16 = 0x32,
13987 B16 = 0x33,
3a1f4268 13988 BC16 = 0x33,
3c824109
NF
13989 ANDI32 = 0x34,
13990 J32 = 0x35,
3a1f4268
YK
13991 BGTZC = 0x35,
13992 BLTZC = 0x35,
13993 BLTC = 0x35,
211da992
CWR
13994 SD32 = 0x36, /* MIPS64 */
13995 LD32 = 0x37, /* MIPS64 */
3c824109 13996
3a1f4268 13997 /* 0x39 is reserved */
3c824109 13998 RES_39 = 0x39,
3a1f4268
YK
13999 BGTZALC = 0x38,
14000 BLTZALC = 0x38,
14001 BLTUC = 0x38,
3c824109
NF
14002 SW16 = 0x3a,
14003 LI16 = 0x3b,
14004 JALX32 = 0x3c,
14005 JAL32 = 0x3d,
3a1f4268
YK
14006 BLEZC = 0x3d,
14007 BGEZC = 0x3d,
14008 BGEC = 0x3d,
3c824109
NF
14009 SW32 = 0x3e,
14010 LW32 = 0x3f
14011};
14012
3a1f4268
YK
14013/* PCREL Instructions perform PC-Relative address calculation. bits 20..16 */
14014enum {
14015 ADDIUPC_00 = 0x00,
c38a1d52
AR
14016 ADDIUPC_01 = 0x01,
14017 ADDIUPC_02 = 0x02,
14018 ADDIUPC_03 = 0x03,
14019 ADDIUPC_04 = 0x04,
14020 ADDIUPC_05 = 0x05,
14021 ADDIUPC_06 = 0x06,
3a1f4268
YK
14022 ADDIUPC_07 = 0x07,
14023 AUIPC = 0x1e,
14024 ALUIPC = 0x1f,
14025 LWPC_08 = 0x08,
c38a1d52
AR
14026 LWPC_09 = 0x09,
14027 LWPC_0A = 0x0A,
14028 LWPC_0B = 0x0B,
14029 LWPC_0C = 0x0C,
14030 LWPC_0D = 0x0D,
14031 LWPC_0E = 0x0E,
3a1f4268
YK
14032 LWPC_0F = 0x0F,
14033};
14034
3c824109
NF
14035/* POOL32A encoding of minor opcode field */
14036
14037enum {
14038 /* These opcodes are distinguished only by bits 9..6; those bits are
14039 * what are recorded below. */
14040 SLL32 = 0x0,
14041 SRL32 = 0x1,
14042 SRA = 0x2,
14043 ROTR = 0x3,
3a1f4268
YK
14044 SELEQZ = 0x5,
14045 SELNEZ = 0x6,
b00c7218 14046 R6_RDHWR = 0x7,
3c824109
NF
14047
14048 SLLV = 0x0,
14049 SRLV = 0x1,
14050 SRAV = 0x2,
14051 ROTRV = 0x3,
14052 ADD = 0x4,
14053 ADDU32 = 0x5,
14054 SUB = 0x6,
14055 SUBU32 = 0x7,
14056 MUL = 0x8,
14057 AND = 0x9,
14058 OR32 = 0xa,
14059 NOR = 0xb,
14060 XOR32 = 0xc,
14061 SLT = 0xd,
14062 SLTU = 0xe,
14063
14064 MOVN = 0x0,
3a1f4268 14065 R6_MUL = 0x0,
3c824109 14066 MOVZ = 0x1,
3a1f4268
YK
14067 MUH = 0x1,
14068 MULU = 0x2,
14069 MUHU = 0x3,
3c824109 14070 LWXS = 0x4,
3a1f4268
YK
14071 R6_DIV = 0x4,
14072 MOD = 0x5,
14073 R6_DIVU = 0x6,
14074 MODU = 0x7,
3c824109
NF
14075
14076 /* The following can be distinguished by their lower 6 bits. */
dbd8af98 14077 BREAK32 = 0x07,
3c824109 14078 INS = 0x0c,
3a1f4268
YK
14079 LSA = 0x0f,
14080 ALIGN = 0x1f,
3c824109 14081 EXT = 0x2c,
bb238210
YK
14082 POOL32AXF = 0x3c,
14083 SIGRIE = 0x3f
3c824109
NF
14084};
14085
14086/* POOL32AXF encoding of minor opcode field extension */
14087
d132c79f
CWR
14088/*
14089 * 1. MIPS Architecture for Programmers Volume II-B:
14090 * The microMIPS32 Instruction Set (Revision 3.05)
14091 *
14092 * Table 6.5 POOL32Axf Encoding of Minor Opcode Extension Field
14093 *
14094 * 2. MIPS Architecture for Programmers VolumeIV-e:
14095 * The MIPS DSP Application-Specific Extension
14096 * to the microMIPS32 Architecture (Revision 2.34)
14097 *
14098 * Table 5.5 POOL32Axf Encoding of Minor Opcode Extension Field
14099 */
14100
3c824109
NF
14101enum {
14102 /* bits 11..6 */
14103 TEQ = 0x00,
14104 TGE = 0x08,
14105 TGEU = 0x10,
14106 TLT = 0x20,
14107 TLTU = 0x28,
14108 TNE = 0x30,
14109
14110 MFC0 = 0x03,
14111 MTC0 = 0x0b,
14112
d132c79f
CWR
14113 /* begin of microMIPS32 DSP */
14114
3c824109
NF
14115 /* bits 13..12 for 0x01 */
14116 MFHI_ACC = 0x0,
14117 MFLO_ACC = 0x1,
14118 MTHI_ACC = 0x2,
14119 MTLO_ACC = 0x3,
14120
14121 /* bits 13..12 for 0x2a */
14122 MADD_ACC = 0x0,
14123 MADDU_ACC = 0x1,
14124 MSUB_ACC = 0x2,
14125 MSUBU_ACC = 0x3,
14126
14127 /* bits 13..12 for 0x32 */
14128 MULT_ACC = 0x0,
6801038b 14129 MULTU_ACC = 0x1,
3c824109 14130
d132c79f
CWR
14131 /* end of microMIPS32 DSP */
14132
3c824109 14133 /* bits 15..12 for 0x2c */
3a1f4268 14134 BITSWAP = 0x0,
3c824109
NF
14135 SEB = 0x2,
14136 SEH = 0x3,
14137 CLO = 0x4,
14138 CLZ = 0x5,
14139 RDHWR = 0x6,
14140 WSBH = 0x7,
14141 MULT = 0x8,
14142 MULTU = 0x9,
14143 DIV = 0xa,
14144 DIVU = 0xb,
14145 MADD = 0xc,
14146 MADDU = 0xd,
14147 MSUB = 0xe,
14148 MSUBU = 0xf,
14149
14150 /* bits 15..12 for 0x34 */
14151 MFC2 = 0x4,
14152 MTC2 = 0x5,
14153 MFHC2 = 0x8,
14154 MTHC2 = 0x9,
14155 CFC2 = 0xc,
14156 CTC2 = 0xd,
14157
14158 /* bits 15..12 for 0x3c */
14159 JALR = 0x0,
14160 JR = 0x0, /* alias */
3a1f4268
YK
14161 JALRC = 0x0,
14162 JRC = 0x0,
3c824109 14163 JALR_HB = 0x1,
3a1f4268 14164 JALRC_HB = 0x1,
3c824109
NF
14165 JALRS = 0x4,
14166 JALRS_HB = 0x5,
14167
14168 /* bits 15..12 for 0x05 */
14169 RDPGPR = 0xe,
14170 WRPGPR = 0xf,
14171
14172 /* bits 15..12 for 0x0d */
14173 TLBP = 0x0,
14174 TLBR = 0x1,
14175 TLBWI = 0x2,
14176 TLBWR = 0x3,
e60ec063
YK
14177 TLBINV = 0x4,
14178 TLBINVF = 0x5,
3c824109
NF
14179 WAIT = 0x9,
14180 IRET = 0xd,
14181 DERET = 0xe,
14182 ERET = 0xf,
14183
14184 /* bits 15..12 for 0x15 */
14185 DMT = 0x0,
14186 DVPE = 0x1,
14187 EMT = 0x2,
14188 EVPE = 0x3,
14189
14190 /* bits 15..12 for 0x1d */
14191 DI = 0x4,
14192 EI = 0x5,
14193
14194 /* bits 15..12 for 0x2d */
14195 SYNC = 0x6,
14196 SYSCALL = 0x8,
14197 SDBBP = 0xd,
14198
14199 /* bits 15..12 for 0x35 */
14200 MFHI32 = 0x0,
14201 MFLO32 = 0x1,
14202 MTHI32 = 0x2,
14203 MTLO32 = 0x3,
14204};
14205
14206/* POOL32B encoding of minor opcode field (bits 15..12) */
14207
14208enum {
14209 LWC2 = 0x0,
14210 LWP = 0x1,
14211 LDP = 0x4,
14212 LWM32 = 0x5,
14213 CACHE = 0x6,
14214 LDM = 0x7,
14215 SWC2 = 0x8,
14216 SWP = 0x9,
14217 SDP = 0xc,
14218 SWM32 = 0xd,
14219 SDM = 0xf
14220};
14221
14222/* POOL32C encoding of minor opcode field (bits 15..12) */
14223
14224enum {
14225 LWL = 0x0,
14226 SWL = 0x8,
14227 LWR = 0x1,
14228 SWR = 0x9,
14229 PREF = 0x2,
8fffc646 14230 ST_EVA = 0xa,
3c824109
NF
14231 LL = 0x3,
14232 SC = 0xb,
14233 LDL = 0x4,
14234 SDL = 0xc,
14235 LDR = 0x5,
14236 SDR = 0xd,
8fffc646 14237 LD_EVA = 0x6,
3c824109
NF
14238 LWU = 0xe,
14239 LLD = 0x7,
14240 SCD = 0xf
14241};
14242
8fffc646
JH
14243/* POOL32C LD-EVA encoding of minor opcode field (bits 11..9) */
14244
14245enum {
14246 LBUE = 0x0,
14247 LHUE = 0x1,
14248 LWLE = 0x2,
14249 LWRE = 0x3,
14250 LBE = 0x4,
14251 LHE = 0x5,
14252 LLE = 0x6,
14253 LWE = 0x7,
14254};
14255
14256/* POOL32C ST-EVA encoding of minor opcode field (bits 11..9) */
14257
14258enum {
14259 SWLE = 0x0,
14260 SWRE = 0x1,
14261 PREFE = 0x2,
14262 CACHEE = 0x3,
14263 SBE = 0x4,
14264 SHE = 0x5,
14265 SCE = 0x6,
14266 SWE = 0x7,
14267};
14268
3c824109
NF
14269/* POOL32F encoding of minor opcode field (bits 5..0) */
14270
14271enum {
14272 /* These are the bit 7..6 values */
14273 ADD_FMT = 0x0,
3c824109
NF
14274
14275 SUB_FMT = 0x1,
3c824109
NF
14276
14277 MUL_FMT = 0x2,
14278
14279 DIV_FMT = 0x3,
14280
14281 /* These are the bit 8..6 values */
3a1f4268 14282 MOVN_FMT = 0x0,
3c824109
NF
14283 RSQRT2_FMT = 0x0,
14284 MOVF_FMT = 0x0,
3a1f4268
YK
14285 RINT_FMT = 0x0,
14286 SELNEZ_FMT = 0x0,
3c824109 14287
3a1f4268 14288 MOVZ_FMT = 0x1,
3c824109
NF
14289 LWXC1 = 0x1,
14290 MOVT_FMT = 0x1,
3a1f4268
YK
14291 CLASS_FMT = 0x1,
14292 SELEQZ_FMT = 0x1,
3c824109
NF
14293
14294 PLL_PS = 0x2,
14295 SWXC1 = 0x2,
3a1f4268 14296 SEL_FMT = 0x2,
3c824109
NF
14297
14298 PLU_PS = 0x3,
14299 LDXC1 = 0x3,
14300
3a1f4268 14301 MOVN_FMT_04 = 0x4,
3c824109
NF
14302 PUL_PS = 0x4,
14303 SDXC1 = 0x4,
14304 RECIP2_FMT = 0x4,
14305
3a1f4268 14306 MOVZ_FMT_05 = 0x05,
3c824109
NF
14307 PUU_PS = 0x5,
14308 LUXC1 = 0x5,
14309
14310 CVT_PS_S = 0x6,
14311 SUXC1 = 0x6,
14312 ADDR_PS = 0x6,
14313 PREFX = 0x6,
3a1f4268 14314 MADDF_FMT = 0x6,
3c824109
NF
14315
14316 MULR_PS = 0x7,
3a1f4268 14317 MSUBF_FMT = 0x7,
3c824109
NF
14318
14319 MADD_S = 0x01,
14320 MADD_D = 0x09,
14321 MADD_PS = 0x11,
14322 ALNV_PS = 0x19,
14323 MSUB_S = 0x21,
14324 MSUB_D = 0x29,
14325 MSUB_PS = 0x31,
14326
14327 NMADD_S = 0x02,
14328 NMADD_D = 0x0a,
14329 NMADD_PS = 0x12,
14330 NMSUB_S = 0x22,
14331 NMSUB_D = 0x2a,
14332 NMSUB_PS = 0x32,
14333
3a1f4268
YK
14334 MIN_FMT = 0x3,
14335 MAX_FMT = 0xb,
14336 MINA_FMT = 0x23,
14337 MAXA_FMT = 0x2b,
3c824109
NF
14338 POOL32FXF = 0x3b,
14339
14340 CABS_COND_FMT = 0x1c, /* MIPS3D */
3a1f4268
YK
14341 C_COND_FMT = 0x3c,
14342
14343 CMP_CONDN_S = 0x5,
14344 CMP_CONDN_D = 0x15
3c824109
NF
14345};
14346
14347/* POOL32Fxf encoding of minor opcode extension field */
14348
14349enum {
14350 CVT_L = 0x04,
14351 RSQRT_FMT = 0x08,
14352 FLOOR_L = 0x0c,
14353 CVT_PW_PS = 0x1c,
14354 CVT_W = 0x24,
14355 SQRT_FMT = 0x28,
14356 FLOOR_W = 0x2c,
14357 CVT_PS_PW = 0x3c,
14358 CFC1 = 0x40,
14359 RECIP_FMT = 0x48,
14360 CEIL_L = 0x4c,
14361 CTC1 = 0x60,
14362 CEIL_W = 0x6c,
14363 MFC1 = 0x80,
14364 CVT_S_PL = 0x84,
14365 TRUNC_L = 0x8c,
14366 MTC1 = 0xa0,
14367 CVT_S_PU = 0xa4,
14368 TRUNC_W = 0xac,
14369 MFHC1 = 0xc0,
14370 ROUND_L = 0xcc,
14371 MTHC1 = 0xe0,
14372 ROUND_W = 0xec,
14373
14374 MOV_FMT = 0x01,
14375 MOVF = 0x05,
14376 ABS_FMT = 0x0d,
14377 RSQRT1_FMT = 0x1d,
14378 MOVT = 0x25,
14379 NEG_FMT = 0x2d,
14380 CVT_D = 0x4d,
14381 RECIP1_FMT = 0x5d,
14382 CVT_S = 0x6d
14383};
14384
14385/* POOL32I encoding of minor opcode field (bits 25..21) */
14386
14387enum {
14388 BLTZ = 0x00,
14389 BLTZAL = 0x01,
14390 BGEZ = 0x02,
14391 BGEZAL = 0x03,
14392 BLEZ = 0x04,
14393 BNEZC = 0x05,
14394 BGTZ = 0x06,
14395 BEQZC = 0x07,
14396 TLTI = 0x08,
3a1f4268 14397 BC1EQZC = 0x08,
3c824109 14398 TGEI = 0x09,
3a1f4268 14399 BC1NEZC = 0x09,
3c824109 14400 TLTIU = 0x0a,
3a1f4268 14401 BC2EQZC = 0x0a,
3c824109 14402 TGEIU = 0x0b,
3a1f4268 14403 BC2NEZC = 0x0a,
3c824109 14404 TNEI = 0x0c,
3a1f4268 14405 R6_SYNCI = 0x0c,
3c824109
NF
14406 LUI = 0x0d,
14407 TEQI = 0x0e,
14408 SYNCI = 0x10,
14409 BLTZALS = 0x11,
14410 BGEZALS = 0x13,
14411 BC2F = 0x14,
14412 BC2T = 0x15,
14413 BPOSGE64 = 0x1a,
14414 BPOSGE32 = 0x1b,
14415 /* These overlap and are distinguished by bit16 of the instruction */
14416 BC1F = 0x1c,
14417 BC1T = 0x1d,
14418 BC1ANY2F = 0x1c,
14419 BC1ANY2T = 0x1d,
14420 BC1ANY4F = 0x1e,
14421 BC1ANY4T = 0x1f
14422};
14423
14424/* POOL16A encoding of minor opcode field */
14425
14426enum {
14427 ADDU16 = 0x0,
14428 SUBU16 = 0x1
14429};
14430
14431/* POOL16B encoding of minor opcode field */
14432
14433enum {
14434 SLL16 = 0x0,
14435 SRL16 = 0x1
14436};
14437
14438/* POOL16C encoding of minor opcode field */
14439
14440enum {
14441 NOT16 = 0x00,
14442 XOR16 = 0x04,
14443 AND16 = 0x08,
14444 OR16 = 0x0c,
14445 LWM16 = 0x10,
14446 SWM16 = 0x14,
14447 JR16 = 0x18,
14448 JRC16 = 0x1a,
14449 JALR16 = 0x1c,
14450 JALR16S = 0x1e,
14451 MFHI16 = 0x20,
14452 MFLO16 = 0x24,
14453 BREAK16 = 0x28,
14454 SDBBP16 = 0x2c,
14455 JRADDIUSP = 0x30
14456};
14457
3a1f4268
YK
14458/* R6 POOL16C encoding of minor opcode field (bits 0..5) */
14459
14460enum {
14461 R6_NOT16 = 0x00,
14462 R6_AND16 = 0x01,
14463 R6_LWM16 = 0x02,
14464 R6_JRC16 = 0x03,
14465 MOVEP = 0x04,
c38a1d52
AR
14466 MOVEP_05 = 0x05,
14467 MOVEP_06 = 0x06,
3a1f4268
YK
14468 MOVEP_07 = 0x07,
14469 R6_XOR16 = 0x08,
14470 R6_OR16 = 0x09,
14471 R6_SWM16 = 0x0a,
14472 JALRC16 = 0x0b,
14473 MOVEP_0C = 0x0c,
c38a1d52
AR
14474 MOVEP_0D = 0x0d,
14475 MOVEP_0E = 0x0e,
3a1f4268
YK
14476 MOVEP_0F = 0x0f,
14477 JRCADDIUSP = 0x13,
14478 R6_BREAK16 = 0x1b,
14479 R6_SDBBP16 = 0x3b
14480};
14481
3c824109
NF
14482/* POOL16D encoding of minor opcode field */
14483
14484enum {
14485 ADDIUS5 = 0x0,
14486 ADDIUSP = 0x1
14487};
14488
14489/* POOL16E encoding of minor opcode field */
14490
14491enum {
14492 ADDIUR2 = 0x0,
14493 ADDIUR1SP = 0x1
14494};
14495
14496static int mmreg (int r)
14497{
14498 static const int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
14499
14500 return map[r];
14501}
14502
14503/* Used for 16-bit store instructions. */
14504static int mmreg2 (int r)
14505{
14506 static const int map[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
14507
14508 return map[r];
14509}
14510
14511#define uMIPS_RD(op) ((op >> 7) & 0x7)
14512#define uMIPS_RS(op) ((op >> 4) & 0x7)
14513#define uMIPS_RS2(op) uMIPS_RS(op)
14514#define uMIPS_RS1(op) ((op >> 1) & 0x7)
14515#define uMIPS_RD5(op) ((op >> 5) & 0x1f)
14516#define uMIPS_RS5(op) (op & 0x1f)
14517
14518/* Signed immediate */
14519#define SIMM(op, start, width) \
14520 ((int32_t)(((op >> start) & ((~0U) >> (32-width))) \
14521 << (32-width)) \
14522 >> (32-width))
14523/* Zero-extended immediate */
14524#define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
14525
d75c135e 14526static void gen_addiur1sp(DisasContext *ctx)
3c824109
NF
14527{
14528 int rd = mmreg(uMIPS_RD(ctx->opcode));
14529
d75c135e 14530 gen_arith_imm(ctx, OPC_ADDIU, rd, 29, ((ctx->opcode >> 1) & 0x3f) << 2);
3c824109
NF
14531}
14532
d75c135e 14533static void gen_addiur2(DisasContext *ctx)
3c824109
NF
14534{
14535 static const int decoded_imm[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
14536 int rd = mmreg(uMIPS_RD(ctx->opcode));
14537 int rs = mmreg(uMIPS_RS(ctx->opcode));
14538
d75c135e 14539 gen_arith_imm(ctx, OPC_ADDIU, rd, rs, decoded_imm[ZIMM(ctx->opcode, 1, 3)]);
3c824109
NF
14540}
14541
d75c135e 14542static void gen_addiusp(DisasContext *ctx)
3c824109
NF
14543{
14544 int encoded = ZIMM(ctx->opcode, 1, 9);
14545 int decoded;
14546
14547 if (encoded <= 1) {
14548 decoded = 256 + encoded;
14549 } else if (encoded <= 255) {
14550 decoded = encoded;
14551 } else if (encoded <= 509) {
14552 decoded = encoded - 512;
14553 } else {
14554 decoded = encoded - 768;
14555 }
14556
d75c135e 14557 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, decoded << 2);
3c824109
NF
14558}
14559
d75c135e 14560static void gen_addius5(DisasContext *ctx)
3c824109
NF
14561{
14562 int imm = SIMM(ctx->opcode, 1, 4);
14563 int rd = (ctx->opcode >> 5) & 0x1f;
14564
d75c135e 14565 gen_arith_imm(ctx, OPC_ADDIU, rd, rd, imm);
3c824109
NF
14566}
14567
d75c135e 14568static void gen_andi16(DisasContext *ctx)
3c824109
NF
14569{
14570 static const int decoded_imm[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
14571 31, 32, 63, 64, 255, 32768, 65535 };
14572 int rd = mmreg(uMIPS_RD(ctx->opcode));
14573 int rs = mmreg(uMIPS_RS(ctx->opcode));
14574 int encoded = ZIMM(ctx->opcode, 0, 4);
14575
d75c135e 14576 gen_logic_imm(ctx, OPC_ANDI, rd, rs, decoded_imm[encoded]);
3c824109
NF
14577}
14578
14579static void gen_ldst_multiple (DisasContext *ctx, uint32_t opc, int reglist,
14580 int base, int16_t offset)
14581{
14582 TCGv t0, t1;
14583 TCGv_i32 t2;
14584
14585 if (ctx->hflags & MIPS_HFLAG_BMASK) {
9c708c7f 14586 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
14587 return;
14588 }
14589
14590 t0 = tcg_temp_new();
14591
14592 gen_base_offset_addr(ctx, t0, base, offset);
14593
14594 t1 = tcg_const_tl(reglist);
14595 t2 = tcg_const_i32(ctx->mem_idx);
6af0bf9c 14596
3c824109
NF
14597 save_cpu_state(ctx, 1);
14598 switch (opc) {
14599 case LWM32:
895c2d04 14600 gen_helper_lwm(cpu_env, t0, t1, t2);
3c824109
NF
14601 break;
14602 case SWM32:
895c2d04 14603 gen_helper_swm(cpu_env, t0, t1, t2);
3c824109
NF
14604 break;
14605#ifdef TARGET_MIPS64
14606 case LDM:
895c2d04 14607 gen_helper_ldm(cpu_env, t0, t1, t2);
3c824109
NF
14608 break;
14609 case SDM:
895c2d04 14610 gen_helper_sdm(cpu_env, t0, t1, t2);
3c824109 14611 break;
6af0bf9c 14612#endif
3c824109 14613 }
3c824109 14614 tcg_temp_free(t0);
33087598 14615 tcg_temp_free(t1);
3c824109
NF
14616 tcg_temp_free_i32(t2);
14617}
6af0bf9c 14618
3c824109 14619
240ce26a 14620static void gen_pool16c_insn(DisasContext *ctx)
6af0bf9c 14621{
3c824109
NF
14622 int rd = mmreg((ctx->opcode >> 3) & 0x7);
14623 int rs = mmreg(ctx->opcode & 0x7);
6af0bf9c 14624
3c824109
NF
14625 switch (((ctx->opcode) >> 4) & 0x3f) {
14626 case NOT16 + 0:
14627 case NOT16 + 1:
14628 case NOT16 + 2:
14629 case NOT16 + 3:
d75c135e 14630 gen_logic(ctx, OPC_NOR, rd, rs, 0);
3c824109
NF
14631 break;
14632 case XOR16 + 0:
14633 case XOR16 + 1:
14634 case XOR16 + 2:
14635 case XOR16 + 3:
d75c135e 14636 gen_logic(ctx, OPC_XOR, rd, rd, rs);
3c824109
NF
14637 break;
14638 case AND16 + 0:
14639 case AND16 + 1:
14640 case AND16 + 2:
14641 case AND16 + 3:
d75c135e 14642 gen_logic(ctx, OPC_AND, rd, rd, rs);
3c824109
NF
14643 break;
14644 case OR16 + 0:
14645 case OR16 + 1:
14646 case OR16 + 2:
14647 case OR16 + 3:
d75c135e 14648 gen_logic(ctx, OPC_OR, rd, rd, rs);
3c824109
NF
14649 break;
14650 case LWM16 + 0:
14651 case LWM16 + 1:
14652 case LWM16 + 2:
14653 case LWM16 + 3:
14654 {
14655 static const int lwm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
14656 int offset = ZIMM(ctx->opcode, 0, 4);
14657
14658 gen_ldst_multiple(ctx, LWM32, lwm_convert[(ctx->opcode >> 4) & 0x3],
14659 29, offset << 2);
14660 }
14661 break;
14662 case SWM16 + 0:
14663 case SWM16 + 1:
14664 case SWM16 + 2:
14665 case SWM16 + 3:
14666 {
14667 static const int swm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
14668 int offset = ZIMM(ctx->opcode, 0, 4);
14669
14670 gen_ldst_multiple(ctx, SWM32, swm_convert[(ctx->opcode >> 4) & 0x3],
14671 29, offset << 2);
14672 }
14673 break;
14674 case JR16 + 0:
14675 case JR16 + 1:
14676 {
14677 int reg = ctx->opcode & 0x1f;
14678
b231c103 14679 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 4);
3c824109 14680 }
3c824109
NF
14681 break;
14682 case JRC16 + 0:
14683 case JRC16 + 1:
14684 {
14685 int reg = ctx->opcode & 0x1f;
b231c103 14686 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 0);
3c824109
NF
14687 /* Let normal delay slot handling in our caller take us
14688 to the branch target. */
14689 }
14690 break;
14691 case JALR16 + 0:
14692 case JALR16 + 1:
b231c103
YK
14693 gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 4);
14694 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14695 break;
3c824109
NF
14696 case JALR16S + 0:
14697 case JALR16S + 1:
b231c103
YK
14698 gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 2);
14699 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
3c824109
NF
14700 break;
14701 case MFHI16 + 0:
14702 case MFHI16 + 1:
26135ead 14703 gen_HILO(ctx, OPC_MFHI, 0, uMIPS_RS5(ctx->opcode));
3c824109
NF
14704 break;
14705 case MFLO16 + 0:
14706 case MFLO16 + 1:
26135ead 14707 gen_HILO(ctx, OPC_MFLO, 0, uMIPS_RS5(ctx->opcode));
3c824109
NF
14708 break;
14709 case BREAK16:
9c708c7f 14710 generate_exception_end(ctx, EXCP_BREAK);
3c824109
NF
14711 break;
14712 case SDBBP16:
3b3c1694
LA
14713 if (is_uhi(extract32(ctx->opcode, 0, 4))) {
14714 gen_helper_do_semihosting(cpu_env);
14715 } else {
14716 /* XXX: not clear which exception should be raised
14717 * when in debug mode...
14718 */
14719 check_insn(ctx, ISA_MIPS32);
9c708c7f 14720 generate_exception_end(ctx, EXCP_DBp);
3b3c1694 14721 }
3c824109
NF
14722 break;
14723 case JRADDIUSP + 0:
14724 case JRADDIUSP + 1:
14725 {
14726 int imm = ZIMM(ctx->opcode, 0, 5);
b231c103 14727 gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0, 0);
d75c135e 14728 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
3c824109
NF
14729 /* Let normal delay slot handling in our caller take us
14730 to the branch target. */
14731 }
14732 break;
14733 default:
9c708c7f 14734 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
14735 break;
14736 }
14737}
14738
ed7ce6c0
YK
14739static inline void gen_movep(DisasContext *ctx, int enc_dest, int enc_rt,
14740 int enc_rs)
14741{
14742 int rd, rs, re, rt;
14743 static const int rd_enc[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
14744 static const int re_enc[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
14745 static const int rs_rt_enc[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
14746 rd = rd_enc[enc_dest];
14747 re = re_enc[enc_dest];
14748 rs = rs_rt_enc[enc_rs];
14749 rt = rs_rt_enc[enc_rt];
14750 if (rs) {
14751 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
14752 } else {
14753 tcg_gen_movi_tl(cpu_gpr[rd], 0);
14754 }
14755 if (rt) {
14756 tcg_gen_mov_tl(cpu_gpr[re], cpu_gpr[rt]);
14757 } else {
14758 tcg_gen_movi_tl(cpu_gpr[re], 0);
14759 }
14760}
14761
14762static void gen_pool16c_r6_insn(DisasContext *ctx)
14763{
14764 int rt = mmreg((ctx->opcode >> 7) & 0x7);
14765 int rs = mmreg((ctx->opcode >> 4) & 0x7);
14766
14767 switch (ctx->opcode & 0xf) {
14768 case R6_NOT16:
14769 gen_logic(ctx, OPC_NOR, rt, rs, 0);
14770 break;
14771 case R6_AND16:
14772 gen_logic(ctx, OPC_AND, rt, rt, rs);
14773 break;
14774 case R6_LWM16:
14775 {
14776 int lwm_converted = 0x11 + extract32(ctx->opcode, 8, 2);
14777 int offset = extract32(ctx->opcode, 4, 4);
14778 gen_ldst_multiple(ctx, LWM32, lwm_converted, 29, offset << 2);
14779 }
14780 break;
14781 case R6_JRC16: /* JRCADDIUSP */
14782 if ((ctx->opcode >> 4) & 1) {
14783 /* JRCADDIUSP */
14784 int imm = extract32(ctx->opcode, 5, 5);
14785 gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0, 0);
14786 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
14787 } else {
14788 /* JRC16 */
e1555d7d 14789 rs = extract32(ctx->opcode, 5, 5);
ed7ce6c0
YK
14790 gen_compute_branch(ctx, OPC_JR, 2, rs, 0, 0, 0);
14791 }
14792 break;
c38a1d52
AR
14793 case MOVEP:
14794 case MOVEP_05:
14795 case MOVEP_06:
14796 case MOVEP_07:
14797 case MOVEP_0C:
14798 case MOVEP_0D:
14799 case MOVEP_0E:
14800 case MOVEP_0F:
ed7ce6c0
YK
14801 {
14802 int enc_dest = uMIPS_RD(ctx->opcode);
14803 int enc_rt = uMIPS_RS2(ctx->opcode);
14804 int enc_rs = (ctx->opcode & 3) | ((ctx->opcode >> 1) & 4);
14805 gen_movep(ctx, enc_dest, enc_rt, enc_rs);
14806 }
14807 break;
14808 case R6_XOR16:
14809 gen_logic(ctx, OPC_XOR, rt, rt, rs);
14810 break;
14811 case R6_OR16:
14812 gen_logic(ctx, OPC_OR, rt, rt, rs);
14813 break;
14814 case R6_SWM16:
14815 {
14816 int swm_converted = 0x11 + extract32(ctx->opcode, 8, 2);
14817 int offset = extract32(ctx->opcode, 4, 4);
14818 gen_ldst_multiple(ctx, SWM32, swm_converted, 29, offset << 2);
14819 }
14820 break;
14821 case JALRC16: /* BREAK16, SDBBP16 */
14822 switch (ctx->opcode & 0x3f) {
14823 case JALRC16:
14824 case JALRC16 + 0x20:
14825 /* JALRC16 */
14826 gen_compute_branch(ctx, OPC_JALR, 2, (ctx->opcode >> 5) & 0x1f,
14827 31, 0, 0);
14828 break;
14829 case R6_BREAK16:
14830 /* BREAK16 */
14831 generate_exception(ctx, EXCP_BREAK);
14832 break;
14833 case R6_SDBBP16:
14834 /* SDBBP16 */
060ebfef
LA
14835 if (is_uhi(extract32(ctx->opcode, 6, 4))) {
14836 gen_helper_do_semihosting(cpu_env);
ed7ce6c0 14837 } else {
060ebfef
LA
14838 if (ctx->hflags & MIPS_HFLAG_SBRI) {
14839 generate_exception(ctx, EXCP_RI);
14840 } else {
14841 generate_exception(ctx, EXCP_DBp);
14842 }
ed7ce6c0
YK
14843 }
14844 break;
14845 }
14846 break;
14847 default:
14848 generate_exception(ctx, EXCP_RI);
14849 break;
14850 }
14851}
14852
3c824109
NF
14853static void gen_ldxs (DisasContext *ctx, int base, int index, int rd)
14854{
14855 TCGv t0 = tcg_temp_new();
14856 TCGv t1 = tcg_temp_new();
14857
14858 gen_load_gpr(t0, base);
14859
14860 if (index != 0) {
14861 gen_load_gpr(t1, index);
14862 tcg_gen_shli_tl(t1, t1, 2);
14863 gen_op_addr_add(ctx, t0, t1, t0);
14864 }
14865
5f68f5ae 14866 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
3c824109
NF
14867 gen_store_gpr(t1, rd);
14868
14869 tcg_temp_free(t0);
14870 tcg_temp_free(t1);
14871}
14872
14873static void gen_ldst_pair (DisasContext *ctx, uint32_t opc, int rd,
14874 int base, int16_t offset)
14875{
3c824109
NF
14876 TCGv t0, t1;
14877
36c6711b 14878 if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31) {
9c708c7f 14879 generate_exception_end(ctx, EXCP_RI);
d796321b
FB
14880 return;
14881 }
14882
3c824109
NF
14883 t0 = tcg_temp_new();
14884 t1 = tcg_temp_new();
8e9ade68 14885
3c824109
NF
14886 gen_base_offset_addr(ctx, t0, base, offset);
14887
14888 switch (opc) {
14889 case LWP:
36c6711b 14890 if (rd == base) {
9c708c7f 14891 generate_exception_end(ctx, EXCP_RI);
36c6711b
EJ
14892 return;
14893 }
5f68f5ae 14894 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
3c824109
NF
14895 gen_store_gpr(t1, rd);
14896 tcg_gen_movi_tl(t1, 4);
14897 gen_op_addr_add(ctx, t0, t0, t1);
5f68f5ae 14898 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
3c824109 14899 gen_store_gpr(t1, rd+1);
3c824109
NF
14900 break;
14901 case SWP:
3c824109 14902 gen_load_gpr(t1, rd);
5f68f5ae 14903 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
3c824109
NF
14904 tcg_gen_movi_tl(t1, 4);
14905 gen_op_addr_add(ctx, t0, t0, t1);
14906 gen_load_gpr(t1, rd+1);
5f68f5ae 14907 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
3c824109
NF
14908 break;
14909#ifdef TARGET_MIPS64
14910 case LDP:
36c6711b 14911 if (rd == base) {
9c708c7f 14912 generate_exception_end(ctx, EXCP_RI);
36c6711b
EJ
14913 return;
14914 }
5f68f5ae 14915 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
3c824109
NF
14916 gen_store_gpr(t1, rd);
14917 tcg_gen_movi_tl(t1, 8);
14918 gen_op_addr_add(ctx, t0, t0, t1);
5f68f5ae 14919 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
3c824109 14920 gen_store_gpr(t1, rd+1);
3c824109
NF
14921 break;
14922 case SDP:
3c824109 14923 gen_load_gpr(t1, rd);
5f68f5ae 14924 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
3c824109
NF
14925 tcg_gen_movi_tl(t1, 8);
14926 gen_op_addr_add(ctx, t0, t0, t1);
14927 gen_load_gpr(t1, rd+1);
5f68f5ae 14928 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
3c824109
NF
14929 break;
14930#endif
6af0bf9c 14931 }
3c824109
NF
14932 tcg_temp_free(t0);
14933 tcg_temp_free(t1);
14934}
618b0fe9 14935
d208ac0c
LA
14936static void gen_sync(int stype)
14937{
14938 TCGBar tcg_mo = TCG_BAR_SC;
14939
14940 switch (stype) {
14941 case 0x4: /* SYNC_WMB */
14942 tcg_mo |= TCG_MO_ST_ST;
14943 break;
14944 case 0x10: /* SYNC_MB */
14945 tcg_mo |= TCG_MO_ALL;
14946 break;
14947 case 0x11: /* SYNC_ACQUIRE */
14948 tcg_mo |= TCG_MO_LD_LD | TCG_MO_LD_ST;
14949 break;
14950 case 0x12: /* SYNC_RELEASE */
14951 tcg_mo |= TCG_MO_ST_ST | TCG_MO_LD_ST;
14952 break;
14953 case 0x13: /* SYNC_RMB */
14954 tcg_mo |= TCG_MO_LD_LD;
14955 break;
14956 default:
14957 tcg_mo |= TCG_MO_ALL;
14958 break;
14959 }
14960
14961 tcg_gen_mb(tcg_mo);
14962}
14963
240ce26a 14964static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
3c824109
NF
14965{
14966 int extension = (ctx->opcode >> 6) & 0x3f;
14967 int minor = (ctx->opcode >> 12) & 0xf;
14968 uint32_t mips32_op;
14969
14970 switch (extension) {
14971 case TEQ:
14972 mips32_op = OPC_TEQ;
14973 goto do_trap;
14974 case TGE:
14975 mips32_op = OPC_TGE;
14976 goto do_trap;
14977 case TGEU:
14978 mips32_op = OPC_TGEU;
14979 goto do_trap;
14980 case TLT:
14981 mips32_op = OPC_TLT;
14982 goto do_trap;
14983 case TLTU:
14984 mips32_op = OPC_TLTU;
14985 goto do_trap;
14986 case TNE:
14987 mips32_op = OPC_TNE;
14988 do_trap:
14989 gen_trap(ctx, mips32_op, rs, rt, -1);
14990 break;
14991#ifndef CONFIG_USER_ONLY
14992 case MFC0:
14993 case MFC0 + 32:
2e15497c 14994 check_cp0_enabled(ctx);
3c824109
NF
14995 if (rt == 0) {
14996 /* Treat as NOP. */
14997 break;
14998 }
d75c135e 14999 gen_mfc0(ctx, cpu_gpr[rt], rs, (ctx->opcode >> 11) & 0x7);
3c824109
NF
15000 break;
15001 case MTC0:
15002 case MTC0 + 32:
2e15497c 15003 check_cp0_enabled(ctx);
3c824109
NF
15004 {
15005 TCGv t0 = tcg_temp_new();
618b0fe9 15006
3c824109 15007 gen_load_gpr(t0, rt);
d75c135e 15008 gen_mtc0(ctx, t0, rs, (ctx->opcode >> 11) & 0x7);
3c824109
NF
15009 tcg_temp_free(t0);
15010 }
15011 break;
15012#endif
a1fc6246
LA
15013 case 0x2a:
15014 switch (minor & 3) {
15015 case MADD_ACC:
15016 gen_muldiv(ctx, OPC_MADD, (ctx->opcode >> 14) & 3, rs, rt);
15017 break;
15018 case MADDU_ACC:
15019 gen_muldiv(ctx, OPC_MADDU, (ctx->opcode >> 14) & 3, rs, rt);
15020 break;
15021 case MSUB_ACC:
15022 gen_muldiv(ctx, OPC_MSUB, (ctx->opcode >> 14) & 3, rs, rt);
15023 break;
15024 case MSUBU_ACC:
15025 gen_muldiv(ctx, OPC_MSUBU, (ctx->opcode >> 14) & 3, rs, rt);
15026 break;
15027 default:
15028 goto pool32axf_invalid;
15029 }
15030 break;
15031 case 0x32:
15032 switch (minor & 3) {
15033 case MULT_ACC:
15034 gen_muldiv(ctx, OPC_MULT, (ctx->opcode >> 14) & 3, rs, rt);
15035 break;
15036 case MULTU_ACC:
15037 gen_muldiv(ctx, OPC_MULTU, (ctx->opcode >> 14) & 3, rs, rt);
15038 break;
15039 default:
15040 goto pool32axf_invalid;
15041 }
15042 break;
3c824109
NF
15043 case 0x2c:
15044 switch (minor) {
e0332095
YK
15045 case BITSWAP:
15046 check_insn(ctx, ISA_MIPS32R6);
15047 gen_bitswap(ctx, OPC_BITSWAP, rs, rt);
15048 break;
3c824109
NF
15049 case SEB:
15050 gen_bshfl(ctx, OPC_SEB, rs, rt);
15051 break;
15052 case SEH:
15053 gen_bshfl(ctx, OPC_SEH, rs, rt);
15054 break;
15055 case CLO:
15056 mips32_op = OPC_CLO;
15057 goto do_cl;
15058 case CLZ:
15059 mips32_op = OPC_CLZ;
15060 do_cl:
d75c135e 15061 check_insn(ctx, ISA_MIPS32);
3c824109
NF
15062 gen_cl(ctx, mips32_op, rt, rs);
15063 break;
15064 case RDHWR:
b00c7218
YK
15065 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15066 gen_rdhwr(ctx, rt, rs, 0);
3c824109
NF
15067 break;
15068 case WSBH:
15069 gen_bshfl(ctx, OPC_WSBH, rs, rt);
15070 break;
15071 case MULT:
9e8f441a 15072 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 15073 mips32_op = OPC_MULT;
26135ead 15074 goto do_mul;
3c824109 15075 case MULTU:
9e8f441a 15076 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 15077 mips32_op = OPC_MULTU;
26135ead 15078 goto do_mul;
3c824109 15079 case DIV:
9e8f441a 15080 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 15081 mips32_op = OPC_DIV;
26135ead 15082 goto do_div;
3c824109 15083 case DIVU:
9e8f441a 15084 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 15085 mips32_op = OPC_DIVU;
26135ead
RS
15086 goto do_div;
15087 do_div:
15088 check_insn(ctx, ISA_MIPS32);
15089 gen_muldiv(ctx, mips32_op, 0, rs, rt);
15090 break;
3c824109 15091 case MADD:
9e8f441a 15092 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 15093 mips32_op = OPC_MADD;
26135ead 15094 goto do_mul;
3c824109 15095 case MADDU:
9e8f441a 15096 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 15097 mips32_op = OPC_MADDU;
26135ead 15098 goto do_mul;
3c824109 15099 case MSUB:
9e8f441a 15100 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 15101 mips32_op = OPC_MSUB;
26135ead 15102 goto do_mul;
3c824109 15103 case MSUBU:
9e8f441a 15104 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 15105 mips32_op = OPC_MSUBU;
26135ead 15106 do_mul:
d75c135e 15107 check_insn(ctx, ISA_MIPS32);
a1fc6246 15108 gen_muldiv(ctx, mips32_op, 0, rs, rt);
3c824109
NF
15109 break;
15110 default:
15111 goto pool32axf_invalid;
15112 }
15113 break;
15114 case 0x34:
15115 switch (minor) {
15116 case MFC2:
15117 case MTC2:
15118 case MFHC2:
15119 case MTHC2:
15120 case CFC2:
15121 case CTC2:
15122 generate_exception_err(ctx, EXCP_CpU, 2);
15123 break;
15124 default:
15125 goto pool32axf_invalid;
15126 }
15127 break;
15128 case 0x3c:
15129 switch (minor) {
65935f07
YK
15130 case JALR: /* JALRC */
15131 case JALR_HB: /* JALRC_HB */
15132 if (ctx->insn_flags & ISA_MIPS32R6) {
15133 /* JALRC, JALRC_HB */
15134 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 0);
15135 } else {
15136 /* JALR, JALR_HB */
15137 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 4);
15138 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
15139 }
3c824109
NF
15140 break;
15141 case JALRS:
15142 case JALRS_HB:
9e8f441a 15143 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
15144 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 2);
15145 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
3c824109
NF
15146 break;
15147 default:
15148 goto pool32axf_invalid;
15149 }
15150 break;
15151 case 0x05:
15152 switch (minor) {
15153 case RDPGPR:
2e15497c 15154 check_cp0_enabled(ctx);
d75c135e 15155 check_insn(ctx, ISA_MIPS32R2);
1bf5902d 15156 gen_load_srsgpr(rs, rt);
3c824109
NF
15157 break;
15158 case WRPGPR:
2e15497c 15159 check_cp0_enabled(ctx);
d75c135e 15160 check_insn(ctx, ISA_MIPS32R2);
1bf5902d 15161 gen_store_srsgpr(rs, rt);
3c824109
NF
15162 break;
15163 default:
15164 goto pool32axf_invalid;
15165 }
15166 break;
15167#ifndef CONFIG_USER_ONLY
15168 case 0x0d:
15169 switch (minor) {
15170 case TLBP:
15171 mips32_op = OPC_TLBP;
15172 goto do_cp0;
15173 case TLBR:
15174 mips32_op = OPC_TLBR;
15175 goto do_cp0;
15176 case TLBWI:
15177 mips32_op = OPC_TLBWI;
15178 goto do_cp0;
15179 case TLBWR:
15180 mips32_op = OPC_TLBWR;
15181 goto do_cp0;
e60ec063
YK
15182 case TLBINV:
15183 mips32_op = OPC_TLBINV;
15184 goto do_cp0;
15185 case TLBINVF:
15186 mips32_op = OPC_TLBINVF;
15187 goto do_cp0;
3c824109
NF
15188 case WAIT:
15189 mips32_op = OPC_WAIT;
15190 goto do_cp0;
15191 case DERET:
15192 mips32_op = OPC_DERET;
15193 goto do_cp0;
15194 case ERET:
15195 mips32_op = OPC_ERET;
15196 do_cp0:
15197 gen_cp0(env, ctx, mips32_op, rt, rs);
15198 break;
15199 default:
15200 goto pool32axf_invalid;
15201 }
15202 break;
15203 case 0x1d:
15204 switch (minor) {
15205 case DI:
2e15497c 15206 check_cp0_enabled(ctx);
3c824109
NF
15207 {
15208 TCGv t0 = tcg_temp_new();
15209
15210 save_cpu_state(ctx, 1);
895c2d04 15211 gen_helper_di(t0, cpu_env);
3c824109
NF
15212 gen_store_gpr(t0, rs);
15213 /* Stop translation as we may have switched the execution mode */
eeb3bba8 15214 ctx->base.is_jmp = DISAS_STOP;
3c824109
NF
15215 tcg_temp_free(t0);
15216 }
15217 break;
15218 case EI:
2e15497c 15219 check_cp0_enabled(ctx);
3c824109
NF
15220 {
15221 TCGv t0 = tcg_temp_new();
15222
15223 save_cpu_state(ctx, 1);
895c2d04 15224 gen_helper_ei(t0, cpu_env);
3c824109 15225 gen_store_gpr(t0, rs);
b28425ba 15226 /* DISAS_STOP isn't sufficient, we need to ensure we break out
b74cddcb 15227 of translated code to check for pending interrupts. */
eeb3bba8
EC
15228 gen_save_pc(ctx->base.pc_next + 4);
15229 ctx->base.is_jmp = DISAS_EXIT;
3c824109
NF
15230 tcg_temp_free(t0);
15231 }
15232 break;
15233 default:
15234 goto pool32axf_invalid;
15235 }
15236 break;
15237#endif
15238 case 0x2d:
15239 switch (minor) {
15240 case SYNC:
d208ac0c 15241 gen_sync(extract32(ctx->opcode, 16, 5));
3c824109
NF
15242 break;
15243 case SYSCALL:
9c708c7f 15244 generate_exception_end(ctx, EXCP_SYSCALL);
3c824109
NF
15245 break;
15246 case SDBBP:
3b3c1694
LA
15247 if (is_uhi(extract32(ctx->opcode, 16, 10))) {
15248 gen_helper_do_semihosting(cpu_env);
15249 } else {
15250 check_insn(ctx, ISA_MIPS32);
e0332095 15251 if (ctx->hflags & MIPS_HFLAG_SBRI) {
9c708c7f 15252 generate_exception_end(ctx, EXCP_RI);
e0332095 15253 } else {
9c708c7f 15254 generate_exception_end(ctx, EXCP_DBp);
e0332095 15255 }
3b3c1694 15256 }
3c824109
NF
15257 break;
15258 default:
15259 goto pool32axf_invalid;
15260 }
15261 break;
a1fc6246 15262 case 0x01:
26135ead 15263 switch (minor & 3) {
a1fc6246 15264 case MFHI_ACC:
26135ead 15265 gen_HILO(ctx, OPC_MFHI, minor >> 2, rs);
3c824109 15266 break;
a1fc6246 15267 case MFLO_ACC:
26135ead 15268 gen_HILO(ctx, OPC_MFLO, minor >> 2, rs);
3c824109 15269 break;
a1fc6246 15270 case MTHI_ACC:
26135ead 15271 gen_HILO(ctx, OPC_MTHI, minor >> 2, rs);
3c824109 15272 break;
a1fc6246 15273 case MTLO_ACC:
26135ead 15274 gen_HILO(ctx, OPC_MTLO, minor >> 2, rs);
3c824109
NF
15275 break;
15276 default:
15277 goto pool32axf_invalid;
15278 }
15279 break;
a1fc6246 15280 case 0x35:
9e8f441a 15281 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a1fc6246
LA
15282 switch (minor) {
15283 case MFHI32:
15284 gen_HILO(ctx, OPC_MFHI, 0, rs);
15285 break;
15286 case MFLO32:
15287 gen_HILO(ctx, OPC_MFLO, 0, rs);
15288 break;
15289 case MTHI32:
15290 gen_HILO(ctx, OPC_MTHI, 0, rs);
15291 break;
15292 case MTLO32:
15293 gen_HILO(ctx, OPC_MTLO, 0, rs);
15294 break;
15295 default:
15296 goto pool32axf_invalid;
15297 }
15298 break;
3c824109
NF
15299 default:
15300 pool32axf_invalid:
15301 MIPS_INVAL("pool32axf");
9c708c7f 15302 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
15303 break;
15304 }
15305}
15306
15307/* Values for microMIPS fmt field. Variable-width, depending on which
15308 formats the instruction supports. */
15309
15310enum {
15311 FMT_SD_S = 0,
15312 FMT_SD_D = 1,
15313
15314 FMT_SDPS_S = 0,
15315 FMT_SDPS_D = 1,
15316 FMT_SDPS_PS = 2,
15317
15318 FMT_SWL_S = 0,
15319 FMT_SWL_W = 1,
15320 FMT_SWL_L = 2,
15321
15322 FMT_DWL_D = 0,
15323 FMT_DWL_W = 1,
15324 FMT_DWL_L = 2
15325};
15326
d75c135e 15327static void gen_pool32fxf(DisasContext *ctx, int rt, int rs)
3c824109
NF
15328{
15329 int extension = (ctx->opcode >> 6) & 0x3ff;
15330 uint32_t mips32_op;
15331
15332#define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
15333#define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
15334#define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
15335
15336 switch (extension) {
15337 case FLOAT_1BIT_FMT(CFC1, 0):
15338 mips32_op = OPC_CFC1;
15339 goto do_cp1;
15340 case FLOAT_1BIT_FMT(CTC1, 0):
15341 mips32_op = OPC_CTC1;
15342 goto do_cp1;
15343 case FLOAT_1BIT_FMT(MFC1, 0):
15344 mips32_op = OPC_MFC1;
15345 goto do_cp1;
15346 case FLOAT_1BIT_FMT(MTC1, 0):
15347 mips32_op = OPC_MTC1;
15348 goto do_cp1;
15349 case FLOAT_1BIT_FMT(MFHC1, 0):
15350 mips32_op = OPC_MFHC1;
15351 goto do_cp1;
15352 case FLOAT_1BIT_FMT(MTHC1, 0):
15353 mips32_op = OPC_MTHC1;
15354 do_cp1:
15355 gen_cp1(ctx, mips32_op, rt, rs);
15356 break;
15357
15358 /* Reciprocal square root */
15359 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_S):
15360 mips32_op = OPC_RSQRT_S;
15361 goto do_unaryfp;
15362 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_D):
15363 mips32_op = OPC_RSQRT_D;
15364 goto do_unaryfp;
15365
15366 /* Square root */
15367 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_S):
15368 mips32_op = OPC_SQRT_S;
15369 goto do_unaryfp;
15370 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_D):
15371 mips32_op = OPC_SQRT_D;
15372 goto do_unaryfp;
15373
15374 /* Reciprocal */
15375 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_S):
15376 mips32_op = OPC_RECIP_S;
15377 goto do_unaryfp;
15378 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_D):
15379 mips32_op = OPC_RECIP_D;
15380 goto do_unaryfp;
15381
15382 /* Floor */
15383 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_S):
15384 mips32_op = OPC_FLOOR_L_S;
15385 goto do_unaryfp;
15386 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_D):
15387 mips32_op = OPC_FLOOR_L_D;
15388 goto do_unaryfp;
15389 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_S):
15390 mips32_op = OPC_FLOOR_W_S;
15391 goto do_unaryfp;
15392 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_D):
15393 mips32_op = OPC_FLOOR_W_D;
15394 goto do_unaryfp;
15395
15396 /* Ceiling */
15397 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_S):
15398 mips32_op = OPC_CEIL_L_S;
15399 goto do_unaryfp;
15400 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_D):
15401 mips32_op = OPC_CEIL_L_D;
15402 goto do_unaryfp;
15403 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_S):
15404 mips32_op = OPC_CEIL_W_S;
15405 goto do_unaryfp;
15406 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_D):
15407 mips32_op = OPC_CEIL_W_D;
15408 goto do_unaryfp;
15409
15410 /* Truncation */
15411 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_S):
15412 mips32_op = OPC_TRUNC_L_S;
15413 goto do_unaryfp;
15414 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_D):
15415 mips32_op = OPC_TRUNC_L_D;
15416 goto do_unaryfp;
15417 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_S):
15418 mips32_op = OPC_TRUNC_W_S;
15419 goto do_unaryfp;
15420 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_D):
15421 mips32_op = OPC_TRUNC_W_D;
15422 goto do_unaryfp;
15423
15424 /* Round */
15425 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_S):
15426 mips32_op = OPC_ROUND_L_S;
15427 goto do_unaryfp;
15428 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_D):
15429 mips32_op = OPC_ROUND_L_D;
15430 goto do_unaryfp;
15431 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_S):
15432 mips32_op = OPC_ROUND_W_S;
15433 goto do_unaryfp;
15434 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_D):
15435 mips32_op = OPC_ROUND_W_D;
15436 goto do_unaryfp;
15437
15438 /* Integer to floating-point conversion */
15439 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_S):
15440 mips32_op = OPC_CVT_L_S;
15441 goto do_unaryfp;
15442 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_D):
15443 mips32_op = OPC_CVT_L_D;
15444 goto do_unaryfp;
15445 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_S):
15446 mips32_op = OPC_CVT_W_S;
15447 goto do_unaryfp;
15448 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_D):
15449 mips32_op = OPC_CVT_W_D;
15450 goto do_unaryfp;
15451
15452 /* Paired-foo conversions */
15453 case FLOAT_1BIT_FMT(CVT_S_PL, 0):
15454 mips32_op = OPC_CVT_S_PL;
15455 goto do_unaryfp;
15456 case FLOAT_1BIT_FMT(CVT_S_PU, 0):
15457 mips32_op = OPC_CVT_S_PU;
15458 goto do_unaryfp;
15459 case FLOAT_1BIT_FMT(CVT_PW_PS, 0):
15460 mips32_op = OPC_CVT_PW_PS;
15461 goto do_unaryfp;
15462 case FLOAT_1BIT_FMT(CVT_PS_PW, 0):
15463 mips32_op = OPC_CVT_PS_PW;
15464 goto do_unaryfp;
15465
15466 /* Floating-point moves */
15467 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_S):
15468 mips32_op = OPC_MOV_S;
15469 goto do_unaryfp;
15470 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_D):
15471 mips32_op = OPC_MOV_D;
15472 goto do_unaryfp;
15473 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_PS):
15474 mips32_op = OPC_MOV_PS;
15475 goto do_unaryfp;
15476
15477 /* Absolute value */
15478 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_S):
15479 mips32_op = OPC_ABS_S;
15480 goto do_unaryfp;
15481 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_D):
15482 mips32_op = OPC_ABS_D;
15483 goto do_unaryfp;
15484 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_PS):
15485 mips32_op = OPC_ABS_PS;
15486 goto do_unaryfp;
15487
15488 /* Negation */
15489 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_S):
15490 mips32_op = OPC_NEG_S;
15491 goto do_unaryfp;
15492 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_D):
15493 mips32_op = OPC_NEG_D;
15494 goto do_unaryfp;
15495 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_PS):
15496 mips32_op = OPC_NEG_PS;
15497 goto do_unaryfp;
15498
15499 /* Reciprocal square root step */
15500 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_S):
15501 mips32_op = OPC_RSQRT1_S;
15502 goto do_unaryfp;
15503 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_D):
15504 mips32_op = OPC_RSQRT1_D;
15505 goto do_unaryfp;
15506 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_PS):
15507 mips32_op = OPC_RSQRT1_PS;
15508 goto do_unaryfp;
15509
15510 /* Reciprocal step */
15511 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_S):
15512 mips32_op = OPC_RECIP1_S;
15513 goto do_unaryfp;
15514 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_D):
15515 mips32_op = OPC_RECIP1_S;
15516 goto do_unaryfp;
15517 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_PS):
15518 mips32_op = OPC_RECIP1_PS;
15519 goto do_unaryfp;
15520
15521 /* Conversions from double */
15522 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_S):
15523 mips32_op = OPC_CVT_D_S;
15524 goto do_unaryfp;
15525 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_W):
15526 mips32_op = OPC_CVT_D_W;
15527 goto do_unaryfp;
15528 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_L):
15529 mips32_op = OPC_CVT_D_L;
15530 goto do_unaryfp;
15531
15532 /* Conversions from single */
15533 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_D):
15534 mips32_op = OPC_CVT_S_D;
15535 goto do_unaryfp;
15536 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_W):
15537 mips32_op = OPC_CVT_S_W;
15538 goto do_unaryfp;
15539 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_L):
15540 mips32_op = OPC_CVT_S_L;
15541 do_unaryfp:
15542 gen_farith(ctx, mips32_op, -1, rs, rt, 0);
15543 break;
15544
15545 /* Conditional moves on floating-point codes */
15546 case COND_FLOAT_MOV(MOVT, 0):
15547 case COND_FLOAT_MOV(MOVT, 1):
15548 case COND_FLOAT_MOV(MOVT, 2):
15549 case COND_FLOAT_MOV(MOVT, 3):
15550 case COND_FLOAT_MOV(MOVT, 4):
15551 case COND_FLOAT_MOV(MOVT, 5):
15552 case COND_FLOAT_MOV(MOVT, 6):
15553 case COND_FLOAT_MOV(MOVT, 7):
9e8f441a 15554 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
15555 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 1);
15556 break;
15557 case COND_FLOAT_MOV(MOVF, 0):
15558 case COND_FLOAT_MOV(MOVF, 1):
15559 case COND_FLOAT_MOV(MOVF, 2):
15560 case COND_FLOAT_MOV(MOVF, 3):
15561 case COND_FLOAT_MOV(MOVF, 4):
15562 case COND_FLOAT_MOV(MOVF, 5):
15563 case COND_FLOAT_MOV(MOVF, 6):
15564 case COND_FLOAT_MOV(MOVF, 7):
9e8f441a 15565 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
15566 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 0);
15567 break;
15568 default:
15569 MIPS_INVAL("pool32fxf");
9c708c7f 15570 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
15571 break;
15572 }
15573}
15574
f60eeb0c 15575static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx)
3c824109
NF
15576{
15577 int32_t offset;
15578 uint16_t insn;
15579 int rt, rs, rd, rr;
15580 int16_t imm;
8fffc646 15581 uint32_t op, minor, minor2, mips32_op;
3c824109
NF
15582 uint32_t cond, fmt, cc;
15583
eeb3bba8 15584 insn = cpu_lduw_code(env, ctx->base.pc_next + 2);
3c824109
NF
15585 ctx->opcode = (ctx->opcode << 16) | insn;
15586
15587 rt = (ctx->opcode >> 21) & 0x1f;
15588 rs = (ctx->opcode >> 16) & 0x1f;
15589 rd = (ctx->opcode >> 11) & 0x1f;
15590 rr = (ctx->opcode >> 6) & 0x1f;
15591 imm = (int16_t) ctx->opcode;
15592
15593 op = (ctx->opcode >> 26) & 0x3f;
15594 switch (op) {
15595 case POOL32A:
15596 minor = ctx->opcode & 0x3f;
15597 switch (minor) {
15598 case 0x00:
15599 minor = (ctx->opcode >> 6) & 0xf;
15600 switch (minor) {
15601 case SLL32:
15602 mips32_op = OPC_SLL;
15603 goto do_shifti;
15604 case SRA:
15605 mips32_op = OPC_SRA;
15606 goto do_shifti;
15607 case SRL32:
15608 mips32_op = OPC_SRL;
15609 goto do_shifti;
15610 case ROTR:
15611 mips32_op = OPC_ROTR;
15612 do_shifti:
d75c135e 15613 gen_shift_imm(ctx, mips32_op, rt, rs, rd);
3c824109 15614 break;
e0332095
YK
15615 case SELEQZ:
15616 check_insn(ctx, ISA_MIPS32R6);
15617 gen_cond_move(ctx, OPC_SELEQZ, rd, rs, rt);
15618 break;
15619 case SELNEZ:
15620 check_insn(ctx, ISA_MIPS32R6);
15621 gen_cond_move(ctx, OPC_SELNEZ, rd, rs, rt);
15622 break;
b00c7218
YK
15623 case R6_RDHWR:
15624 check_insn(ctx, ISA_MIPS32R6);
15625 gen_rdhwr(ctx, rt, rs, extract32(ctx->opcode, 11, 3));
15626 break;
3c824109
NF
15627 default:
15628 goto pool32a_invalid;
15629 }
15630 break;
15631 case 0x10:
15632 minor = (ctx->opcode >> 6) & 0xf;
15633 switch (minor) {
15634 /* Arithmetic */
15635 case ADD:
15636 mips32_op = OPC_ADD;
15637 goto do_arith;
15638 case ADDU32:
15639 mips32_op = OPC_ADDU;
15640 goto do_arith;
15641 case SUB:
15642 mips32_op = OPC_SUB;
15643 goto do_arith;
15644 case SUBU32:
15645 mips32_op = OPC_SUBU;
15646 goto do_arith;
15647 case MUL:
9e8f441a 15648 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
15649 mips32_op = OPC_MUL;
15650 do_arith:
d75c135e 15651 gen_arith(ctx, mips32_op, rd, rs, rt);
3c824109
NF
15652 break;
15653 /* Shifts */
15654 case SLLV:
15655 mips32_op = OPC_SLLV;
15656 goto do_shift;
15657 case SRLV:
15658 mips32_op = OPC_SRLV;
15659 goto do_shift;
15660 case SRAV:
15661 mips32_op = OPC_SRAV;
15662 goto do_shift;
15663 case ROTRV:
15664 mips32_op = OPC_ROTRV;
15665 do_shift:
d75c135e 15666 gen_shift(ctx, mips32_op, rd, rs, rt);
3c824109
NF
15667 break;
15668 /* Logical operations */
15669 case AND:
15670 mips32_op = OPC_AND;
15671 goto do_logic;
15672 case OR32:
15673 mips32_op = OPC_OR;
15674 goto do_logic;
15675 case NOR:
15676 mips32_op = OPC_NOR;
15677 goto do_logic;
15678 case XOR32:
15679 mips32_op = OPC_XOR;
15680 do_logic:
d75c135e 15681 gen_logic(ctx, mips32_op, rd, rs, rt);
3c824109
NF
15682 break;
15683 /* Set less than */
15684 case SLT:
15685 mips32_op = OPC_SLT;
15686 goto do_slt;
15687 case SLTU:
15688 mips32_op = OPC_SLTU;
15689 do_slt:
d75c135e 15690 gen_slt(ctx, mips32_op, rd, rs, rt);
3c824109
NF
15691 break;
15692 default:
15693 goto pool32a_invalid;
15694 }
15695 break;
15696 case 0x18:
15697 minor = (ctx->opcode >> 6) & 0xf;
15698 switch (minor) {
15699 /* Conditional moves */
e0332095
YK
15700 case MOVN: /* MUL */
15701 if (ctx->insn_flags & ISA_MIPS32R6) {
15702 /* MUL */
15703 gen_r6_muldiv(ctx, R6_OPC_MUL, rd, rs, rt);
15704 } else {
15705 /* MOVN */
15706 gen_cond_move(ctx, OPC_MOVN, rd, rs, rt);
15707 }
15708 break;
15709 case MOVZ: /* MUH */
15710 if (ctx->insn_flags & ISA_MIPS32R6) {
15711 /* MUH */
15712 gen_r6_muldiv(ctx, R6_OPC_MUH, rd, rs, rt);
15713 } else {
15714 /* MOVZ */
15715 gen_cond_move(ctx, OPC_MOVZ, rd, rs, rt);
15716 }
15717 break;
15718 case MULU:
15719 check_insn(ctx, ISA_MIPS32R6);
15720 gen_r6_muldiv(ctx, R6_OPC_MULU, rd, rs, rt);
15721 break;
15722 case MUHU:
15723 check_insn(ctx, ISA_MIPS32R6);
15724 gen_r6_muldiv(ctx, R6_OPC_MUHU, rd, rs, rt);
15725 break;
15726 case LWXS: /* DIV */
15727 if (ctx->insn_flags & ISA_MIPS32R6) {
15728 /* DIV */
15729 gen_r6_muldiv(ctx, R6_OPC_DIV, rd, rs, rt);
15730 } else {
15731 /* LWXS */
15732 gen_ldxs(ctx, rs, rt, rd);
15733 }
15734 break;
15735 case MOD:
15736 check_insn(ctx, ISA_MIPS32R6);
15737 gen_r6_muldiv(ctx, R6_OPC_MOD, rd, rs, rt);
15738 break;
15739 case R6_DIVU:
15740 check_insn(ctx, ISA_MIPS32R6);
15741 gen_r6_muldiv(ctx, R6_OPC_DIVU, rd, rs, rt);
3c824109 15742 break;
e0332095
YK
15743 case MODU:
15744 check_insn(ctx, ISA_MIPS32R6);
15745 gen_r6_muldiv(ctx, R6_OPC_MODU, rd, rs, rt);
3c824109
NF
15746 break;
15747 default:
15748 goto pool32a_invalid;
15749 }
15750 break;
15751 case INS:
15752 gen_bitops(ctx, OPC_INS, rt, rs, rr, rd);
15753 return;
e0332095
YK
15754 case LSA:
15755 check_insn(ctx, ISA_MIPS32R6);
15756 gen_lsa(ctx, OPC_LSA, rd, rs, rt,
15757 extract32(ctx->opcode, 9, 2));
15758 break;
15759 case ALIGN:
15760 check_insn(ctx, ISA_MIPS32R6);
821f2008 15761 gen_align(ctx, 32, rd, rs, rt, extract32(ctx->opcode, 9, 2));
e0332095 15762 break;
3c824109
NF
15763 case EXT:
15764 gen_bitops(ctx, OPC_EXT, rt, rs, rr, rd);
15765 return;
15766 case POOL32AXF:
240ce26a 15767 gen_pool32axf(env, ctx, rt, rs);
3c824109 15768 break;
dbd8af98 15769 case BREAK32:
9c708c7f 15770 generate_exception_end(ctx, EXCP_BREAK);
3c824109 15771 break;
bb238210
YK
15772 case SIGRIE:
15773 check_insn(ctx, ISA_MIPS32R6);
15774 generate_exception_end(ctx, EXCP_RI);
15775 break;
3c824109
NF
15776 default:
15777 pool32a_invalid:
15778 MIPS_INVAL("pool32a");
9c708c7f 15779 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
15780 break;
15781 }
15782 break;
15783 case POOL32B:
15784 minor = (ctx->opcode >> 12) & 0xf;
15785 switch (minor) {
15786 case CACHE:
2e15497c 15787 check_cp0_enabled(ctx);
0d74a222
LA
15788 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
15789 gen_cache_operation(ctx, rt, rs, imm);
15790 }
3c824109
NF
15791 break;
15792 case LWC2:
15793 case SWC2:
15794 /* COP2: Not implemented. */
15795 generate_exception_err(ctx, EXCP_CpU, 2);
15796 break;
3c824109
NF
15797#ifdef TARGET_MIPS64
15798 case LDP:
15799 case SDP:
d9224450
MR
15800 check_insn(ctx, ISA_MIPS3);
15801 check_mips_64(ctx);
3c824109 15802#endif
146dd620 15803 /* fall through */
d9224450
MR
15804 case LWP:
15805 case SWP:
3c824109
NF
15806 gen_ldst_pair(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
15807 break;
3c824109
NF
15808#ifdef TARGET_MIPS64
15809 case LDM:
15810 case SDM:
d9224450
MR
15811 check_insn(ctx, ISA_MIPS3);
15812 check_mips_64(ctx);
3c824109 15813#endif
146dd620 15814 /* fall through */
d9224450
MR
15815 case LWM32:
15816 case SWM32:
3c824109
NF
15817 gen_ldst_multiple(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
15818 break;
15819 default:
15820 MIPS_INVAL("pool32b");
9c708c7f 15821 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
15822 break;
15823 }
15824 break;
15825 case POOL32F:
5ab5c041 15826 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
3c824109
NF
15827 minor = ctx->opcode & 0x3f;
15828 check_cp1_enabled(ctx);
15829 switch (minor) {
15830 case ALNV_PS:
9e8f441a 15831 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
15832 mips32_op = OPC_ALNV_PS;
15833 goto do_madd;
15834 case MADD_S:
9e8f441a 15835 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
15836 mips32_op = OPC_MADD_S;
15837 goto do_madd;
15838 case MADD_D:
9e8f441a 15839 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
15840 mips32_op = OPC_MADD_D;
15841 goto do_madd;
15842 case MADD_PS:
9e8f441a 15843 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
15844 mips32_op = OPC_MADD_PS;
15845 goto do_madd;
15846 case MSUB_S:
9e8f441a 15847 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
15848 mips32_op = OPC_MSUB_S;
15849 goto do_madd;
15850 case MSUB_D:
9e8f441a 15851 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
15852 mips32_op = OPC_MSUB_D;
15853 goto do_madd;
15854 case MSUB_PS:
9e8f441a 15855 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
15856 mips32_op = OPC_MSUB_PS;
15857 goto do_madd;
15858 case NMADD_S:
9e8f441a 15859 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
15860 mips32_op = OPC_NMADD_S;
15861 goto do_madd;
15862 case NMADD_D:
9e8f441a 15863 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
15864 mips32_op = OPC_NMADD_D;
15865 goto do_madd;
15866 case NMADD_PS:
9e8f441a 15867 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
15868 mips32_op = OPC_NMADD_PS;
15869 goto do_madd;
15870 case NMSUB_S:
9e8f441a 15871 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
15872 mips32_op = OPC_NMSUB_S;
15873 goto do_madd;
15874 case NMSUB_D:
9e8f441a 15875 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
15876 mips32_op = OPC_NMSUB_D;
15877 goto do_madd;
15878 case NMSUB_PS:
9e8f441a 15879 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
15880 mips32_op = OPC_NMSUB_PS;
15881 do_madd:
15882 gen_flt3_arith(ctx, mips32_op, rd, rr, rs, rt);
15883 break;
15884 case CABS_COND_FMT:
9e8f441a 15885 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
15886 cond = (ctx->opcode >> 6) & 0xf;
15887 cc = (ctx->opcode >> 13) & 0x7;
15888 fmt = (ctx->opcode >> 10) & 0x3;
15889 switch (fmt) {
15890 case 0x0:
15891 gen_cmpabs_s(ctx, cond, rt, rs, cc);
15892 break;
15893 case 0x1:
15894 gen_cmpabs_d(ctx, cond, rt, rs, cc);
15895 break;
15896 case 0x2:
15897 gen_cmpabs_ps(ctx, cond, rt, rs, cc);
15898 break;
15899 default:
15900 goto pool32f_invalid;
15901 }
15902 break;
15903 case C_COND_FMT:
9e8f441a 15904 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
15905 cond = (ctx->opcode >> 6) & 0xf;
15906 cc = (ctx->opcode >> 13) & 0x7;
15907 fmt = (ctx->opcode >> 10) & 0x3;
15908 switch (fmt) {
15909 case 0x0:
15910 gen_cmp_s(ctx, cond, rt, rs, cc);
15911 break;
15912 case 0x1:
15913 gen_cmp_d(ctx, cond, rt, rs, cc);
15914 break;
15915 case 0x2:
15916 gen_cmp_ps(ctx, cond, rt, rs, cc);
15917 break;
15918 default:
15919 goto pool32f_invalid;
15920 }
15921 break;
2a24a7ba
YK
15922 case CMP_CONDN_S:
15923 check_insn(ctx, ISA_MIPS32R6);
15924 gen_r6_cmp_s(ctx, (ctx->opcode >> 6) & 0x1f, rt, rs, rd);
15925 break;
15926 case CMP_CONDN_D:
15927 check_insn(ctx, ISA_MIPS32R6);
15928 gen_r6_cmp_d(ctx, (ctx->opcode >> 6) & 0x1f, rt, rs, rd);
15929 break;
3c824109 15930 case POOL32FXF:
d75c135e 15931 gen_pool32fxf(ctx, rt, rs);
3c824109
NF
15932 break;
15933 case 0x00:
15934 /* PLL foo */
15935 switch ((ctx->opcode >> 6) & 0x7) {
15936 case PLL_PS:
15937 mips32_op = OPC_PLL_PS;
15938 goto do_ps;
15939 case PLU_PS:
15940 mips32_op = OPC_PLU_PS;
15941 goto do_ps;
15942 case PUL_PS:
15943 mips32_op = OPC_PUL_PS;
15944 goto do_ps;
15945 case PUU_PS:
15946 mips32_op = OPC_PUU_PS;
15947 goto do_ps;
15948 case CVT_PS_S:
9e8f441a 15949 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
15950 mips32_op = OPC_CVT_PS_S;
15951 do_ps:
15952 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
15953 break;
15954 default:
15955 goto pool32f_invalid;
15956 }
15957 break;
2a24a7ba
YK
15958 case MIN_FMT:
15959 check_insn(ctx, ISA_MIPS32R6);
15960 switch ((ctx->opcode >> 9) & 0x3) {
15961 case FMT_SDPS_S:
15962 gen_farith(ctx, OPC_MIN_S, rt, rs, rd, 0);
15963 break;
15964 case FMT_SDPS_D:
15965 gen_farith(ctx, OPC_MIN_D, rt, rs, rd, 0);
15966 break;
15967 default:
15968 goto pool32f_invalid;
15969 }
15970 break;
3c824109
NF
15971 case 0x08:
15972 /* [LS][WDU]XC1 */
15973 switch ((ctx->opcode >> 6) & 0x7) {
15974 case LWXC1:
9e8f441a 15975 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
15976 mips32_op = OPC_LWXC1;
15977 goto do_ldst_cp1;
15978 case SWXC1:
9e8f441a 15979 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
15980 mips32_op = OPC_SWXC1;
15981 goto do_ldst_cp1;
15982 case LDXC1:
9e8f441a 15983 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
15984 mips32_op = OPC_LDXC1;
15985 goto do_ldst_cp1;
15986 case SDXC1:
9e8f441a 15987 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
15988 mips32_op = OPC_SDXC1;
15989 goto do_ldst_cp1;
15990 case LUXC1:
9e8f441a 15991 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
15992 mips32_op = OPC_LUXC1;
15993 goto do_ldst_cp1;
15994 case SUXC1:
9e8f441a 15995 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
15996 mips32_op = OPC_SUXC1;
15997 do_ldst_cp1:
15998 gen_flt3_ldst(ctx, mips32_op, rd, rd, rt, rs);
15999 break;
16000 default:
16001 goto pool32f_invalid;
16002 }
16003 break;
2a24a7ba
YK
16004 case MAX_FMT:
16005 check_insn(ctx, ISA_MIPS32R6);
16006 switch ((ctx->opcode >> 9) & 0x3) {
16007 case FMT_SDPS_S:
16008 gen_farith(ctx, OPC_MAX_S, rt, rs, rd, 0);
16009 break;
16010 case FMT_SDPS_D:
16011 gen_farith(ctx, OPC_MAX_D, rt, rs, rd, 0);
16012 break;
16013 default:
16014 goto pool32f_invalid;
16015 }
16016 break;
3c824109
NF
16017 case 0x18:
16018 /* 3D insns */
9e8f441a 16019 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
16020 fmt = (ctx->opcode >> 9) & 0x3;
16021 switch ((ctx->opcode >> 6) & 0x7) {
16022 case RSQRT2_FMT:
16023 switch (fmt) {
16024 case FMT_SDPS_S:
16025 mips32_op = OPC_RSQRT2_S;
16026 goto do_3d;
16027 case FMT_SDPS_D:
16028 mips32_op = OPC_RSQRT2_D;
16029 goto do_3d;
16030 case FMT_SDPS_PS:
16031 mips32_op = OPC_RSQRT2_PS;
16032 goto do_3d;
16033 default:
16034 goto pool32f_invalid;
16035 }
16036 break;
16037 case RECIP2_FMT:
16038 switch (fmt) {
16039 case FMT_SDPS_S:
16040 mips32_op = OPC_RECIP2_S;
16041 goto do_3d;
16042 case FMT_SDPS_D:
16043 mips32_op = OPC_RECIP2_D;
16044 goto do_3d;
16045 case FMT_SDPS_PS:
16046 mips32_op = OPC_RECIP2_PS;
16047 goto do_3d;
16048 default:
16049 goto pool32f_invalid;
16050 }
16051 break;
16052 case ADDR_PS:
16053 mips32_op = OPC_ADDR_PS;
16054 goto do_3d;
16055 case MULR_PS:
16056 mips32_op = OPC_MULR_PS;
16057 do_3d:
16058 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
16059 break;
16060 default:
16061 goto pool32f_invalid;
16062 }
16063 break;
16064 case 0x20:
2a24a7ba 16065 /* MOV[FT].fmt, PREFX, RINT.fmt, CLASS.fmt*/
3c824109
NF
16066 cc = (ctx->opcode >> 13) & 0x7;
16067 fmt = (ctx->opcode >> 9) & 0x3;
16068 switch ((ctx->opcode >> 6) & 0x7) {
2a24a7ba
YK
16069 case MOVF_FMT: /* RINT_FMT */
16070 if (ctx->insn_flags & ISA_MIPS32R6) {
16071 /* RINT_FMT */
16072 switch (fmt) {
16073 case FMT_SDPS_S:
16074 gen_farith(ctx, OPC_RINT_S, 0, rt, rs, 0);
16075 break;
16076 case FMT_SDPS_D:
16077 gen_farith(ctx, OPC_RINT_D, 0, rt, rs, 0);
16078 break;
16079 default:
16080 goto pool32f_invalid;
16081 }
16082 } else {
16083 /* MOVF_FMT */
16084 switch (fmt) {
16085 case FMT_SDPS_S:
16086 gen_movcf_s(ctx, rs, rt, cc, 0);
16087 break;
16088 case FMT_SDPS_D:
16089 gen_movcf_d(ctx, rs, rt, cc, 0);
16090 break;
16091 case FMT_SDPS_PS:
16092 check_ps(ctx);
16093 gen_movcf_ps(ctx, rs, rt, cc, 0);
16094 break;
16095 default:
16096 goto pool32f_invalid;
16097 }
3c824109
NF
16098 }
16099 break;
2a24a7ba
YK
16100 case MOVT_FMT: /* CLASS_FMT */
16101 if (ctx->insn_flags & ISA_MIPS32R6) {
16102 /* CLASS_FMT */
16103 switch (fmt) {
16104 case FMT_SDPS_S:
16105 gen_farith(ctx, OPC_CLASS_S, 0, rt, rs, 0);
16106 break;
16107 case FMT_SDPS_D:
16108 gen_farith(ctx, OPC_CLASS_D, 0, rt, rs, 0);
16109 break;
16110 default:
16111 goto pool32f_invalid;
16112 }
16113 } else {
16114 /* MOVT_FMT */
16115 switch (fmt) {
16116 case FMT_SDPS_S:
16117 gen_movcf_s(ctx, rs, rt, cc, 1);
16118 break;
16119 case FMT_SDPS_D:
16120 gen_movcf_d(ctx, rs, rt, cc, 1);
16121 break;
16122 case FMT_SDPS_PS:
16123 check_ps(ctx);
16124 gen_movcf_ps(ctx, rs, rt, cc, 1);
16125 break;
16126 default:
16127 goto pool32f_invalid;
16128 }
3c824109
NF
16129 }
16130 break;
16131 case PREFX:
9e8f441a 16132 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
16133 break;
16134 default:
16135 goto pool32f_invalid;
16136 }
16137 break;
16138#define FINSN_3ARG_SDPS(prfx) \
16139 switch ((ctx->opcode >> 8) & 0x3) { \
16140 case FMT_SDPS_S: \
16141 mips32_op = OPC_##prfx##_S; \
16142 goto do_fpop; \
16143 case FMT_SDPS_D: \
16144 mips32_op = OPC_##prfx##_D; \
16145 goto do_fpop; \
16146 case FMT_SDPS_PS: \
e29c9628 16147 check_ps(ctx); \
3c824109
NF
16148 mips32_op = OPC_##prfx##_PS; \
16149 goto do_fpop; \
16150 default: \
16151 goto pool32f_invalid; \
16152 }
2a24a7ba
YK
16153 case MINA_FMT:
16154 check_insn(ctx, ISA_MIPS32R6);
16155 switch ((ctx->opcode >> 9) & 0x3) {
16156 case FMT_SDPS_S:
16157 gen_farith(ctx, OPC_MINA_S, rt, rs, rd, 0);
16158 break;
16159 case FMT_SDPS_D:
16160 gen_farith(ctx, OPC_MINA_D, rt, rs, rd, 0);
16161 break;
16162 default:
16163 goto pool32f_invalid;
16164 }
16165 break;
16166 case MAXA_FMT:
16167 check_insn(ctx, ISA_MIPS32R6);
16168 switch ((ctx->opcode >> 9) & 0x3) {
16169 case FMT_SDPS_S:
16170 gen_farith(ctx, OPC_MAXA_S, rt, rs, rd, 0);
16171 break;
16172 case FMT_SDPS_D:
16173 gen_farith(ctx, OPC_MAXA_D, rt, rs, rd, 0);
16174 break;
16175 default:
16176 goto pool32f_invalid;
16177 }
16178 break;
3c824109
NF
16179 case 0x30:
16180 /* regular FP ops */
16181 switch ((ctx->opcode >> 6) & 0x3) {
16182 case ADD_FMT:
16183 FINSN_3ARG_SDPS(ADD);
16184 break;
16185 case SUB_FMT:
16186 FINSN_3ARG_SDPS(SUB);
16187 break;
16188 case MUL_FMT:
16189 FINSN_3ARG_SDPS(MUL);
16190 break;
16191 case DIV_FMT:
16192 fmt = (ctx->opcode >> 8) & 0x3;
16193 if (fmt == 1) {
16194 mips32_op = OPC_DIV_D;
16195 } else if (fmt == 0) {
16196 mips32_op = OPC_DIV_S;
16197 } else {
16198 goto pool32f_invalid;
16199 }
16200 goto do_fpop;
16201 default:
16202 goto pool32f_invalid;
16203 }
16204 break;
16205 case 0x38:
16206 /* cmovs */
2a24a7ba 16207 switch ((ctx->opcode >> 6) & 0x7) {
fdac60cd 16208 case MOVN_FMT: /* SELEQZ_FMT */
2a24a7ba 16209 if (ctx->insn_flags & ISA_MIPS32R6) {
fdac60cd 16210 /* SELEQZ_FMT */
2a24a7ba
YK
16211 switch ((ctx->opcode >> 9) & 0x3) {
16212 case FMT_SDPS_S:
fdac60cd 16213 gen_sel_s(ctx, OPC_SELEQZ_S, rd, rt, rs);
2a24a7ba
YK
16214 break;
16215 case FMT_SDPS_D:
fdac60cd 16216 gen_sel_d(ctx, OPC_SELEQZ_D, rd, rt, rs);
2a24a7ba
YK
16217 break;
16218 default:
16219 goto pool32f_invalid;
16220 }
16221 } else {
16222 /* MOVN_FMT */
16223 FINSN_3ARG_SDPS(MOVN);
16224 }
16225 break;
16226 case MOVN_FMT_04:
16227 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
16228 FINSN_3ARG_SDPS(MOVN);
16229 break;
fdac60cd 16230 case MOVZ_FMT: /* SELNEZ_FMT */
2a24a7ba 16231 if (ctx->insn_flags & ISA_MIPS32R6) {
fdac60cd 16232 /* SELNEZ_FMT */
2a24a7ba
YK
16233 switch ((ctx->opcode >> 9) & 0x3) {
16234 case FMT_SDPS_S:
fdac60cd 16235 gen_sel_s(ctx, OPC_SELNEZ_S, rd, rt, rs);
2a24a7ba
YK
16236 break;
16237 case FMT_SDPS_D:
fdac60cd 16238 gen_sel_d(ctx, OPC_SELNEZ_D, rd, rt, rs);
2a24a7ba
YK
16239 break;
16240 default:
16241 goto pool32f_invalid;
16242 }
16243 } else {
16244 /* MOVZ_FMT */
16245 FINSN_3ARG_SDPS(MOVZ);
16246 }
16247 break;
16248 case MOVZ_FMT_05:
16249 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
16250 FINSN_3ARG_SDPS(MOVZ);
16251 break;
2a24a7ba
YK
16252 case SEL_FMT:
16253 check_insn(ctx, ISA_MIPS32R6);
16254 switch ((ctx->opcode >> 9) & 0x3) {
16255 case FMT_SDPS_S:
16256 gen_sel_s(ctx, OPC_SEL_S, rd, rt, rs);
16257 break;
16258 case FMT_SDPS_D:
16259 gen_sel_d(ctx, OPC_SEL_D, rd, rt, rs);
16260 break;
16261 default:
16262 goto pool32f_invalid;
16263 }
16264 break;
16265 case MADDF_FMT:
16266 check_insn(ctx, ISA_MIPS32R6);
16267 switch ((ctx->opcode >> 9) & 0x3) {
16268 case FMT_SDPS_S:
16269 mips32_op = OPC_MADDF_S;
16270 goto do_fpop;
16271 case FMT_SDPS_D:
16272 mips32_op = OPC_MADDF_D;
16273 goto do_fpop;
16274 default:
16275 goto pool32f_invalid;
16276 }
16277 break;
16278 case MSUBF_FMT:
16279 check_insn(ctx, ISA_MIPS32R6);
16280 switch ((ctx->opcode >> 9) & 0x3) {
16281 case FMT_SDPS_S:
16282 mips32_op = OPC_MSUBF_S;
16283 goto do_fpop;
16284 case FMT_SDPS_D:
16285 mips32_op = OPC_MSUBF_D;
16286 goto do_fpop;
16287 default:
16288 goto pool32f_invalid;
16289 }
16290 break;
3c824109
NF
16291 default:
16292 goto pool32f_invalid;
16293 }
16294 break;
16295 do_fpop:
16296 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
16297 break;
16298 default:
16299 pool32f_invalid:
16300 MIPS_INVAL("pool32f");
9c708c7f 16301 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
16302 break;
16303 }
16304 } else {
16305 generate_exception_err(ctx, EXCP_CpU, 1);
16306 }
16307 break;
16308 case POOL32I:
16309 minor = (ctx->opcode >> 21) & 0x1f;
16310 switch (minor) {
16311 case BLTZ:
9e8f441a 16312 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
16313 gen_compute_branch(ctx, OPC_BLTZ, 4, rs, -1, imm << 1, 4);
16314 break;
3c824109 16315 case BLTZAL:
9e8f441a 16316 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
16317 gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 4);
16318 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16319 break;
3c824109 16320 case BLTZALS:
9e8f441a 16321 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
16322 gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 2);
16323 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16324 break;
3c824109 16325 case BGEZ:
9e8f441a 16326 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
16327 gen_compute_branch(ctx, OPC_BGEZ, 4, rs, -1, imm << 1, 4);
16328 break;
3c824109 16329 case BGEZAL:
9e8f441a 16330 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
16331 gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 4);
16332 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16333 break;
3c824109 16334 case BGEZALS:
9e8f441a 16335 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
16336 gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 2);
16337 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16338 break;
3c824109 16339 case BLEZ:
9e8f441a 16340 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
16341 gen_compute_branch(ctx, OPC_BLEZ, 4, rs, -1, imm << 1, 4);
16342 break;
3c824109 16343 case BGTZ:
9e8f441a 16344 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103 16345 gen_compute_branch(ctx, OPC_BGTZ, 4, rs, -1, imm << 1, 4);
3c824109
NF
16346 break;
16347
16348 /* Traps */
65935f07
YK
16349 case TLTI: /* BC1EQZC */
16350 if (ctx->insn_flags & ISA_MIPS32R6) {
16351 /* BC1EQZC */
16352 check_cp1_enabled(ctx);
16353 gen_compute_branch1_r6(ctx, OPC_BC1EQZ, rs, imm << 1, 0);
16354 } else {
16355 /* TLTI */
16356 mips32_op = OPC_TLTI;
16357 goto do_trapi;
16358 }
16359 break;
16360 case TGEI: /* BC1NEZC */
16361 if (ctx->insn_flags & ISA_MIPS32R6) {
16362 /* BC1NEZC */
16363 check_cp1_enabled(ctx);
16364 gen_compute_branch1_r6(ctx, OPC_BC1NEZ, rs, imm << 1, 0);
16365 } else {
16366 /* TGEI */
16367 mips32_op = OPC_TGEI;
16368 goto do_trapi;
16369 }
16370 break;
3c824109 16371 case TLTIU:
9e8f441a 16372 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
16373 mips32_op = OPC_TLTIU;
16374 goto do_trapi;
16375 case TGEIU:
9e8f441a 16376 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
16377 mips32_op = OPC_TGEIU;
16378 goto do_trapi;
3b4a5489
YK
16379 case TNEI: /* SYNCI */
16380 if (ctx->insn_flags & ISA_MIPS32R6) {
16381 /* SYNCI */
16382 /* Break the TB to be able to sync copied instructions
16383 immediately */
eeb3bba8 16384 ctx->base.is_jmp = DISAS_STOP;
3b4a5489
YK
16385 } else {
16386 /* TNEI */
16387 mips32_op = OPC_TNEI;
16388 goto do_trapi;
16389 }
16390 break;
3c824109 16391 case TEQI:
9e8f441a 16392 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
16393 mips32_op = OPC_TEQI;
16394 do_trapi:
16395 gen_trap(ctx, mips32_op, rs, -1, imm);
16396 break;
16397
16398 case BNEZC:
16399 case BEQZC:
9e8f441a 16400 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 16401 gen_compute_branch(ctx, minor == BNEZC ? OPC_BNE : OPC_BEQ,
b231c103 16402 4, rs, 0, imm << 1, 0);
3c824109
NF
16403 /* Compact branches don't have a delay slot, so just let
16404 the normal delay slot handling take us to the branch
16405 target. */
16406 break;
16407 case LUI:
9e8f441a 16408 check_insn_opc_removed(ctx, ISA_MIPS32R6);
5e88759a 16409 gen_logic_imm(ctx, OPC_LUI, rs, 0, imm);
3c824109
NF
16410 break;
16411 case SYNCI:
9e8f441a 16412 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a83bddd6
DZ
16413 /* Break the TB to be able to sync copied instructions
16414 immediately */
eeb3bba8 16415 ctx->base.is_jmp = DISAS_STOP;
3c824109
NF
16416 break;
16417 case BC2F:
16418 case BC2T:
9e8f441a 16419 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
16420 /* COP2: Not implemented. */
16421 generate_exception_err(ctx, EXCP_CpU, 2);
16422 break;
16423 case BC1F:
9e8f441a 16424 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
16425 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1FANY2 : OPC_BC1F;
16426 goto do_cp1branch;
16427 case BC1T:
9e8f441a 16428 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
16429 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1TANY2 : OPC_BC1T;
16430 goto do_cp1branch;
16431 case BC1ANY4F:
9e8f441a 16432 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
16433 mips32_op = OPC_BC1FANY4;
16434 goto do_cp1mips3d;
16435 case BC1ANY4T:
9e8f441a 16436 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
16437 mips32_op = OPC_BC1TANY4;
16438 do_cp1mips3d:
16439 check_cop1x(ctx);
d75c135e 16440 check_insn(ctx, ASE_MIPS3D);
3c824109
NF
16441 /* Fall through */
16442 do_cp1branch:
272f458d
MR
16443 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
16444 check_cp1_enabled(ctx);
16445 gen_compute_branch1(ctx, mips32_op,
16446 (ctx->opcode >> 18) & 0x7, imm << 1);
16447 } else {
16448 generate_exception_err(ctx, EXCP_CpU, 1);
16449 }
3c824109
NF
16450 break;
16451 case BPOSGE64:
16452 case BPOSGE32:
16453 /* MIPS DSP: not implemented */
16454 /* Fall through */
16455 default:
16456 MIPS_INVAL("pool32i");
9c708c7f 16457 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
16458 break;
16459 }
16460 break;
16461 case POOL32C:
16462 minor = (ctx->opcode >> 12) & 0xf;
3b4a5489
YK
16463 offset = sextract32(ctx->opcode, 0,
16464 (ctx->insn_flags & ISA_MIPS32R6) ? 9 : 12);
3c824109
NF
16465 switch (minor) {
16466 case LWL:
9e8f441a 16467 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 16468 mips32_op = OPC_LWL;
5c13fdfd 16469 goto do_ld_lr;
3c824109 16470 case SWL:
9e8f441a 16471 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 16472 mips32_op = OPC_SWL;
5c13fdfd 16473 goto do_st_lr;
3c824109 16474 case LWR:
9e8f441a 16475 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 16476 mips32_op = OPC_LWR;
5c13fdfd 16477 goto do_ld_lr;
3c824109 16478 case SWR:
9e8f441a 16479 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 16480 mips32_op = OPC_SWR;
5c13fdfd 16481 goto do_st_lr;
3c824109
NF
16482#if defined(TARGET_MIPS64)
16483 case LDL:
d9224450
MR
16484 check_insn(ctx, ISA_MIPS3);
16485 check_mips_64(ctx);
9e8f441a 16486 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 16487 mips32_op = OPC_LDL;
5c13fdfd 16488 goto do_ld_lr;
3c824109 16489 case SDL:
d9224450
MR
16490 check_insn(ctx, ISA_MIPS3);
16491 check_mips_64(ctx);
9e8f441a 16492 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 16493 mips32_op = OPC_SDL;
5c13fdfd 16494 goto do_st_lr;
3c824109 16495 case LDR:
d9224450
MR
16496 check_insn(ctx, ISA_MIPS3);
16497 check_mips_64(ctx);
9e8f441a 16498 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 16499 mips32_op = OPC_LDR;
5c13fdfd 16500 goto do_ld_lr;
3c824109 16501 case SDR:
d9224450
MR
16502 check_insn(ctx, ISA_MIPS3);
16503 check_mips_64(ctx);
9e8f441a 16504 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 16505 mips32_op = OPC_SDR;
5c13fdfd 16506 goto do_st_lr;
3c824109 16507 case LWU:
d9224450
MR
16508 check_insn(ctx, ISA_MIPS3);
16509 check_mips_64(ctx);
3c824109 16510 mips32_op = OPC_LWU;
5c13fdfd 16511 goto do_ld_lr;
3c824109 16512 case LLD:
d9224450
MR
16513 check_insn(ctx, ISA_MIPS3);
16514 check_mips_64(ctx);
3c824109 16515 mips32_op = OPC_LLD;
5c13fdfd 16516 goto do_ld_lr;
3c824109
NF
16517#endif
16518 case LL:
16519 mips32_op = OPC_LL;
5c13fdfd
AJ
16520 goto do_ld_lr;
16521 do_ld_lr:
3b4a5489 16522 gen_ld(ctx, mips32_op, rt, rs, offset);
5c13fdfd
AJ
16523 break;
16524 do_st_lr:
8fffc646 16525 gen_st(ctx, mips32_op, rt, rs, offset);
3c824109
NF
16526 break;
16527 case SC:
3b4a5489 16528 gen_st_cond(ctx, OPC_SC, rt, rs, offset);
3c824109
NF
16529 break;
16530#if defined(TARGET_MIPS64)
16531 case SCD:
d9224450
MR
16532 check_insn(ctx, ISA_MIPS3);
16533 check_mips_64(ctx);
3b4a5489 16534 gen_st_cond(ctx, OPC_SCD, rt, rs, offset);
3c824109
NF
16535 break;
16536#endif
8fffc646
JH
16537 case LD_EVA:
16538 if (!ctx->eva) {
16539 MIPS_INVAL("pool32c ld-eva");
16540 generate_exception_end(ctx, EXCP_RI);
16541 break;
16542 }
16543 check_cp0_enabled(ctx);
16544
16545 minor2 = (ctx->opcode >> 9) & 0x7;
16546 offset = sextract32(ctx->opcode, 0, 9);
16547 switch (minor2) {
16548 case LBUE:
16549 mips32_op = OPC_LBUE;
16550 goto do_ld_lr;
16551 case LHUE:
16552 mips32_op = OPC_LHUE;
16553 goto do_ld_lr;
16554 case LWLE:
16555 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16556 mips32_op = OPC_LWLE;
16557 goto do_ld_lr;
16558 case LWRE:
16559 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16560 mips32_op = OPC_LWRE;
16561 goto do_ld_lr;
16562 case LBE:
16563 mips32_op = OPC_LBE;
16564 goto do_ld_lr;
16565 case LHE:
16566 mips32_op = OPC_LHE;
16567 goto do_ld_lr;
16568 case LLE:
16569 mips32_op = OPC_LLE;
16570 goto do_ld_lr;
16571 case LWE:
16572 mips32_op = OPC_LWE;
16573 goto do_ld_lr;
16574 };
16575 break;
16576 case ST_EVA:
16577 if (!ctx->eva) {
16578 MIPS_INVAL("pool32c st-eva");
16579 generate_exception_end(ctx, EXCP_RI);
16580 break;
16581 }
16582 check_cp0_enabled(ctx);
16583
16584 minor2 = (ctx->opcode >> 9) & 0x7;
16585 offset = sextract32(ctx->opcode, 0, 9);
16586 switch (minor2) {
16587 case SWLE:
16588 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16589 mips32_op = OPC_SWLE;
16590 goto do_st_lr;
16591 case SWRE:
16592 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16593 mips32_op = OPC_SWRE;
16594 goto do_st_lr;
16595 case PREFE:
16596 /* Treat as no-op */
16597 if ((ctx->insn_flags & ISA_MIPS32R6) && (rt >= 24)) {
16598 /* hint codes 24-31 are reserved and signal RI */
16599 generate_exception(ctx, EXCP_RI);
16600 }
16601 break;
16602 case CACHEE:
16603 /* Treat as no-op */
16604 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
16605 gen_cache_operation(ctx, rt, rs, offset);
16606 }
16607 break;
16608 case SBE:
16609 mips32_op = OPC_SBE;
16610 goto do_st_lr;
16611 case SHE:
16612 mips32_op = OPC_SHE;
16613 goto do_st_lr;
16614 case SCE:
16615 gen_st_cond(ctx, OPC_SCE, rt, rs, offset);
16616 break;
16617 case SWE:
16618 mips32_op = OPC_SWE;
16619 goto do_st_lr;
16620 };
16621 break;
3c824109
NF
16622 case PREF:
16623 /* Treat as no-op */
3b4a5489
YK
16624 if ((ctx->insn_flags & ISA_MIPS32R6) && (rt >= 24)) {
16625 /* hint codes 24-31 are reserved and signal RI */
16626 generate_exception(ctx, EXCP_RI);
16627 }
3c824109
NF
16628 break;
16629 default:
16630 MIPS_INVAL("pool32c");
9c708c7f 16631 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
16632 break;
16633 }
16634 break;
ab39ee45
YK
16635 case ADDI32: /* AUI, LUI */
16636 if (ctx->insn_flags & ISA_MIPS32R6) {
16637 /* AUI, LUI */
16638 gen_logic_imm(ctx, OPC_LUI, rt, rs, imm);
16639 } else {
16640 /* ADDI32 */
16641 mips32_op = OPC_ADDI;
16642 goto do_addi;
16643 }
16644 break;
3c824109
NF
16645 case ADDIU32:
16646 mips32_op = OPC_ADDIU;
16647 do_addi:
d75c135e 16648 gen_arith_imm(ctx, mips32_op, rt, rs, imm);
3c824109
NF
16649 break;
16650
16651 /* Logical operations */
16652 case ORI32:
16653 mips32_op = OPC_ORI;
16654 goto do_logici;
16655 case XORI32:
16656 mips32_op = OPC_XORI;
16657 goto do_logici;
16658 case ANDI32:
16659 mips32_op = OPC_ANDI;
16660 do_logici:
d75c135e 16661 gen_logic_imm(ctx, mips32_op, rt, rs, imm);
3c824109
NF
16662 break;
16663
16664 /* Set less than immediate */
16665 case SLTI32:
16666 mips32_op = OPC_SLTI;
16667 goto do_slti;
16668 case SLTIU32:
16669 mips32_op = OPC_SLTIU;
16670 do_slti:
d75c135e 16671 gen_slt_imm(ctx, mips32_op, rt, rs, imm);
3c824109
NF
16672 break;
16673 case JALX32:
9e8f441a 16674 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 16675 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
b231c103
YK
16676 gen_compute_branch(ctx, OPC_JALX, 4, rt, rs, offset, 4);
16677 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
3c824109 16678 break;
65935f07
YK
16679 case JALS32: /* BOVC, BEQC, BEQZALC */
16680 if (ctx->insn_flags & ISA_MIPS32R6) {
16681 if (rs >= rt) {
16682 /* BOVC */
16683 mips32_op = OPC_BOVC;
16684 } else if (rs < rt && rs == 0) {
16685 /* BEQZALC */
16686 mips32_op = OPC_BEQZALC;
16687 } else {
16688 /* BEQC */
16689 mips32_op = OPC_BEQC;
16690 }
16691 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
16692 } else {
16693 /* JALS32 */
16694 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 1;
16695 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs, offset, 2);
16696 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16697 }
3c824109 16698 break;
65935f07
YK
16699 case BEQ32: /* BC */
16700 if (ctx->insn_flags & ISA_MIPS32R6) {
16701 /* BC */
16702 gen_compute_compact_branch(ctx, OPC_BC, 0, 0,
16703 sextract32(ctx->opcode << 1, 0, 27));
16704 } else {
16705 /* BEQ32 */
16706 gen_compute_branch(ctx, OPC_BEQ, 4, rt, rs, imm << 1, 4);
16707 }
3c824109 16708 break;
65935f07
YK
16709 case BNE32: /* BALC */
16710 if (ctx->insn_flags & ISA_MIPS32R6) {
16711 /* BALC */
16712 gen_compute_compact_branch(ctx, OPC_BALC, 0, 0,
16713 sextract32(ctx->opcode << 1, 0, 27));
16714 } else {
16715 /* BNE32 */
16716 gen_compute_branch(ctx, OPC_BNE, 4, rt, rs, imm << 1, 4);
16717 }
3c824109 16718 break;
65935f07
YK
16719 case J32: /* BGTZC, BLTZC, BLTC */
16720 if (ctx->insn_flags & ISA_MIPS32R6) {
16721 if (rs == 0 && rt != 0) {
16722 /* BGTZC */
16723 mips32_op = OPC_BGTZC;
16724 } else if (rs != 0 && rt != 0 && rs == rt) {
16725 /* BLTZC */
16726 mips32_op = OPC_BLTZC;
16727 } else {
16728 /* BLTC */
16729 mips32_op = OPC_BLTC;
16730 }
16731 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
16732 } else {
16733 /* J32 */
16734 gen_compute_branch(ctx, OPC_J, 4, rt, rs,
16735 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
16736 }
3c824109 16737 break;
65935f07
YK
16738 case JAL32: /* BLEZC, BGEZC, BGEC */
16739 if (ctx->insn_flags & ISA_MIPS32R6) {
16740 if (rs == 0 && rt != 0) {
16741 /* BLEZC */
16742 mips32_op = OPC_BLEZC;
16743 } else if (rs != 0 && rt != 0 && rs == rt) {
16744 /* BGEZC */
16745 mips32_op = OPC_BGEZC;
16746 } else {
16747 /* BGEC */
16748 mips32_op = OPC_BGEC;
16749 }
16750 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
16751 } else {
16752 /* JAL32 */
16753 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs,
16754 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
16755 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16756 }
3c824109
NF
16757 break;
16758 /* Floating point (COP1) */
16759 case LWC132:
16760 mips32_op = OPC_LWC1;
16761 goto do_cop1;
16762 case LDC132:
16763 mips32_op = OPC_LDC1;
16764 goto do_cop1;
16765 case SWC132:
16766 mips32_op = OPC_SWC1;
16767 goto do_cop1;
16768 case SDC132:
16769 mips32_op = OPC_SDC1;
16770 do_cop1:
5ab5c041 16771 gen_cop1_ldst(ctx, mips32_op, rt, rs, imm);
3c824109 16772 break;
ab39ee45
YK
16773 case ADDIUPC: /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
16774 if (ctx->insn_flags & ISA_MIPS32R6) {
16775 /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
16776 switch ((ctx->opcode >> 16) & 0x1f) {
c38a1d52
AR
16777 case ADDIUPC_00:
16778 case ADDIUPC_01:
16779 case ADDIUPC_02:
16780 case ADDIUPC_03:
16781 case ADDIUPC_04:
16782 case ADDIUPC_05:
16783 case ADDIUPC_06:
16784 case ADDIUPC_07:
eeb3bba8 16785 gen_pcrel(ctx, OPC_ADDIUPC, ctx->base.pc_next & ~0x3, rt);
ab39ee45
YK
16786 break;
16787 case AUIPC:
eeb3bba8 16788 gen_pcrel(ctx, OPC_AUIPC, ctx->base.pc_next, rt);
ab39ee45
YK
16789 break;
16790 case ALUIPC:
eeb3bba8 16791 gen_pcrel(ctx, OPC_ALUIPC, ctx->base.pc_next, rt);
ab39ee45 16792 break;
c38a1d52
AR
16793 case LWPC_08:
16794 case LWPC_09:
16795 case LWPC_0A:
16796 case LWPC_0B:
16797 case LWPC_0C:
16798 case LWPC_0D:
16799 case LWPC_0E:
16800 case LWPC_0F:
eeb3bba8 16801 gen_pcrel(ctx, R6_OPC_LWPC, ctx->base.pc_next & ~0x3, rt);
ab39ee45
YK
16802 break;
16803 default:
16804 generate_exception(ctx, EXCP_RI);
16805 break;
16806 }
16807 } else {
16808 /* ADDIUPC */
3c824109 16809 int reg = mmreg(ZIMM(ctx->opcode, 23, 3));
e1555d7d 16810 offset = SIMM(ctx->opcode, 0, 23) << 2;
3c824109
NF
16811
16812 gen_addiupc(ctx, reg, offset, 0, 0);
16813 }
16814 break;
65935f07
YK
16815 case BNVC: /* BNEC, BNEZALC */
16816 check_insn(ctx, ISA_MIPS32R6);
16817 if (rs >= rt) {
16818 /* BNVC */
16819 mips32_op = OPC_BNVC;
16820 } else if (rs < rt && rs == 0) {
16821 /* BNEZALC */
16822 mips32_op = OPC_BNEZALC;
16823 } else {
16824 /* BNEC */
16825 mips32_op = OPC_BNEC;
16826 }
16827 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
16828 break;
16829 case R6_BNEZC: /* JIALC */
16830 check_insn(ctx, ISA_MIPS32R6);
16831 if (rt != 0) {
16832 /* BNEZC */
16833 gen_compute_compact_branch(ctx, OPC_BNEZC, rt, 0,
16834 sextract32(ctx->opcode << 1, 0, 22));
16835 } else {
16836 /* JIALC */
16837 gen_compute_compact_branch(ctx, OPC_JIALC, 0, rs, imm);
16838 }
16839 break;
16840 case R6_BEQZC: /* JIC */
16841 check_insn(ctx, ISA_MIPS32R6);
16842 if (rt != 0) {
16843 /* BEQZC */
16844 gen_compute_compact_branch(ctx, OPC_BEQZC, rt, 0,
16845 sextract32(ctx->opcode << 1, 0, 22));
16846 } else {
16847 /* JIC */
16848 gen_compute_compact_branch(ctx, OPC_JIC, 0, rs, imm);
16849 }
16850 break;
16851 case BLEZALC: /* BGEZALC, BGEUC */
16852 check_insn(ctx, ISA_MIPS32R6);
16853 if (rs == 0 && rt != 0) {
16854 /* BLEZALC */
16855 mips32_op = OPC_BLEZALC;
16856 } else if (rs != 0 && rt != 0 && rs == rt) {
16857 /* BGEZALC */
16858 mips32_op = OPC_BGEZALC;
16859 } else {
16860 /* BGEUC */
16861 mips32_op = OPC_BGEUC;
16862 }
16863 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
16864 break;
16865 case BGTZALC: /* BLTZALC, BLTUC */
16866 check_insn(ctx, ISA_MIPS32R6);
16867 if (rs == 0 && rt != 0) {
16868 /* BGTZALC */
16869 mips32_op = OPC_BGTZALC;
16870 } else if (rs != 0 && rt != 0 && rs == rt) {
16871 /* BLTZALC */
16872 mips32_op = OPC_BLTZALC;
16873 } else {
16874 /* BLTUC */
16875 mips32_op = OPC_BLTUC;
16876 }
16877 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
16878 break;
3c824109
NF
16879 /* Loads and stores */
16880 case LB32:
16881 mips32_op = OPC_LB;
5c13fdfd 16882 goto do_ld;
3c824109
NF
16883 case LBU32:
16884 mips32_op = OPC_LBU;
5c13fdfd 16885 goto do_ld;
3c824109
NF
16886 case LH32:
16887 mips32_op = OPC_LH;
5c13fdfd 16888 goto do_ld;
3c824109
NF
16889 case LHU32:
16890 mips32_op = OPC_LHU;
5c13fdfd 16891 goto do_ld;
3c824109
NF
16892 case LW32:
16893 mips32_op = OPC_LW;
5c13fdfd 16894 goto do_ld;
3c824109
NF
16895#ifdef TARGET_MIPS64
16896 case LD32:
d9224450
MR
16897 check_insn(ctx, ISA_MIPS3);
16898 check_mips_64(ctx);
3c824109 16899 mips32_op = OPC_LD;
5c13fdfd 16900 goto do_ld;
3c824109 16901 case SD32:
d9224450
MR
16902 check_insn(ctx, ISA_MIPS3);
16903 check_mips_64(ctx);
3c824109 16904 mips32_op = OPC_SD;
5c13fdfd 16905 goto do_st;
3c824109
NF
16906#endif
16907 case SB32:
16908 mips32_op = OPC_SB;
5c13fdfd 16909 goto do_st;
3c824109
NF
16910 case SH32:
16911 mips32_op = OPC_SH;
5c13fdfd 16912 goto do_st;
3c824109
NF
16913 case SW32:
16914 mips32_op = OPC_SW;
5c13fdfd
AJ
16915 goto do_st;
16916 do_ld:
d75c135e 16917 gen_ld(ctx, mips32_op, rt, rs, imm);
5c13fdfd
AJ
16918 break;
16919 do_st:
16920 gen_st(ctx, mips32_op, rt, rs, imm);
3c824109
NF
16921 break;
16922 default:
9c708c7f 16923 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
16924 break;
16925 }
16926}
16927
240ce26a 16928static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx)
3c824109
NF
16929{
16930 uint32_t op;
16931
16932 /* make sure instructions are on a halfword boundary */
eeb3bba8
EC
16933 if (ctx->base.pc_next & 0x1) {
16934 env->CP0_BadVAddr = ctx->base.pc_next;
9c708c7f 16935 generate_exception_end(ctx, EXCP_AdEL);
3c824109
NF
16936 return 2;
16937 }
16938
16939 op = (ctx->opcode >> 10) & 0x3f;
16940 /* Enforce properly-sized instructions in a delay slot */
b231c103
YK
16941 if (ctx->hflags & MIPS_HFLAG_BDS_STRICT) {
16942 switch (op & 0x7) { /* MSB-3..MSB-5 */
16943 case 0:
16944 /* POOL32A, POOL32B, POOL32I, POOL32C */
16945 case 4:
16946 /* ADDI32, ADDIU32, ORI32, XORI32, SLTI32, SLTIU32, ANDI32, JALX32 */
16947 case 5:
16948 /* LBU32, LHU32, POOL32F, JALS32, BEQ32, BNE32, J32, JAL32 */
16949 case 6:
16950 /* SB32, SH32, ADDIUPC, SWC132, SDC132, SW32 */
16951 case 7:
16952 /* LB32, LH32, LWC132, LDC132, LW32 */
16953 if (ctx->hflags & MIPS_HFLAG_BDS16) {
9c708c7f 16954 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
16955 return 2;
16956 }
16957 break;
b231c103
YK
16958 case 1:
16959 /* POOL16A, POOL16B, POOL16C, LWGP16, POOL16F */
16960 case 2:
16961 /* LBU16, LHU16, LWSP16, LW16, SB16, SH16, SWSP16, SW16 */
16962 case 3:
16963 /* MOVE16, ANDI16, POOL16D, POOL16E, BEQZ16, BNEZ16, B16, LI16 */
16964 if (ctx->hflags & MIPS_HFLAG_BDS32) {
9c708c7f 16965 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
16966 return 2;
16967 }
16968 break;
3c824109
NF
16969 }
16970 }
b231c103 16971
3c824109
NF
16972 switch (op) {
16973 case POOL16A:
16974 {
16975 int rd = mmreg(uMIPS_RD(ctx->opcode));
16976 int rs1 = mmreg(uMIPS_RS1(ctx->opcode));
16977 int rs2 = mmreg(uMIPS_RS2(ctx->opcode));
16978 uint32_t opc = 0;
16979
16980 switch (ctx->opcode & 0x1) {
16981 case ADDU16:
16982 opc = OPC_ADDU;
16983 break;
16984 case SUBU16:
16985 opc = OPC_SUBU;
16986 break;
16987 }
ed7ce6c0
YK
16988 if (ctx->insn_flags & ISA_MIPS32R6) {
16989 /* In the Release 6 the register number location in
16990 * the instruction encoding has changed.
16991 */
16992 gen_arith(ctx, opc, rs1, rd, rs2);
16993 } else {
16994 gen_arith(ctx, opc, rd, rs1, rs2);
16995 }
3c824109
NF
16996 }
16997 break;
16998 case POOL16B:
16999 {
17000 int rd = mmreg(uMIPS_RD(ctx->opcode));
17001 int rs = mmreg(uMIPS_RS(ctx->opcode));
17002 int amount = (ctx->opcode >> 1) & 0x7;
17003 uint32_t opc = 0;
17004 amount = amount == 0 ? 8 : amount;
17005
17006 switch (ctx->opcode & 0x1) {
17007 case SLL16:
17008 opc = OPC_SLL;
17009 break;
17010 case SRL16:
17011 opc = OPC_SRL;
17012 break;
17013 }
17014
d75c135e 17015 gen_shift_imm(ctx, opc, rd, rs, amount);
3c824109
NF
17016 }
17017 break;
17018 case POOL16C:
ed7ce6c0
YK
17019 if (ctx->insn_flags & ISA_MIPS32R6) {
17020 gen_pool16c_r6_insn(ctx);
17021 } else {
17022 gen_pool16c_insn(ctx);
17023 }
3c824109
NF
17024 break;
17025 case LWGP16:
17026 {
17027 int rd = mmreg(uMIPS_RD(ctx->opcode));
17028 int rb = 28; /* GP */
17029 int16_t offset = SIMM(ctx->opcode, 0, 7) << 2;
17030
d75c135e 17031 gen_ld(ctx, OPC_LW, rd, rb, offset);
3c824109
NF
17032 }
17033 break;
17034 case POOL16F:
9e8f441a 17035 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 17036 if (ctx->opcode & 1) {
9c708c7f 17037 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
17038 } else {
17039 /* MOVEP */
17040 int enc_dest = uMIPS_RD(ctx->opcode);
17041 int enc_rt = uMIPS_RS2(ctx->opcode);
17042 int enc_rs = uMIPS_RS1(ctx->opcode);
ed7ce6c0 17043 gen_movep(ctx, enc_dest, enc_rt, enc_rs);
3c824109
NF
17044 }
17045 break;
17046 case LBU16:
17047 {
17048 int rd = mmreg(uMIPS_RD(ctx->opcode));
17049 int rb = mmreg(uMIPS_RS(ctx->opcode));
17050 int16_t offset = ZIMM(ctx->opcode, 0, 4);
17051 offset = (offset == 0xf ? -1 : offset);
17052
d75c135e 17053 gen_ld(ctx, OPC_LBU, rd, rb, offset);
3c824109
NF
17054 }
17055 break;
17056 case LHU16:
17057 {
17058 int rd = mmreg(uMIPS_RD(ctx->opcode));
17059 int rb = mmreg(uMIPS_RS(ctx->opcode));
17060 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
17061
d75c135e 17062 gen_ld(ctx, OPC_LHU, rd, rb, offset);
3c824109
NF
17063 }
17064 break;
17065 case LWSP16:
17066 {
17067 int rd = (ctx->opcode >> 5) & 0x1f;
17068 int rb = 29; /* SP */
17069 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
17070
d75c135e 17071 gen_ld(ctx, OPC_LW, rd, rb, offset);
3c824109
NF
17072 }
17073 break;
17074 case LW16:
17075 {
17076 int rd = mmreg(uMIPS_RD(ctx->opcode));
17077 int rb = mmreg(uMIPS_RS(ctx->opcode));
17078 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
17079
d75c135e 17080 gen_ld(ctx, OPC_LW, rd, rb, offset);
3c824109
NF
17081 }
17082 break;
17083 case SB16:
17084 {
17085 int rd = mmreg2(uMIPS_RD(ctx->opcode));
17086 int rb = mmreg(uMIPS_RS(ctx->opcode));
17087 int16_t offset = ZIMM(ctx->opcode, 0, 4);
17088
5c13fdfd 17089 gen_st(ctx, OPC_SB, rd, rb, offset);
3c824109
NF
17090 }
17091 break;
17092 case SH16:
17093 {
17094 int rd = mmreg2(uMIPS_RD(ctx->opcode));
17095 int rb = mmreg(uMIPS_RS(ctx->opcode));
17096 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
17097
5c13fdfd 17098 gen_st(ctx, OPC_SH, rd, rb, offset);
3c824109
NF
17099 }
17100 break;
17101 case SWSP16:
17102 {
17103 int rd = (ctx->opcode >> 5) & 0x1f;
17104 int rb = 29; /* SP */
17105 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
17106
5c13fdfd 17107 gen_st(ctx, OPC_SW, rd, rb, offset);
3c824109
NF
17108 }
17109 break;
17110 case SW16:
17111 {
17112 int rd = mmreg2(uMIPS_RD(ctx->opcode));
17113 int rb = mmreg(uMIPS_RS(ctx->opcode));
17114 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
17115
5c13fdfd 17116 gen_st(ctx, OPC_SW, rd, rb, offset);
3c824109
NF
17117 }
17118 break;
17119 case MOVE16:
17120 {
17121 int rd = uMIPS_RD5(ctx->opcode);
17122 int rs = uMIPS_RS5(ctx->opcode);
17123
7215d7e7 17124 gen_arith(ctx, OPC_ADDU, rd, rs, 0);
3c824109
NF
17125 }
17126 break;
17127 case ANDI16:
d75c135e 17128 gen_andi16(ctx);
3c824109
NF
17129 break;
17130 case POOL16D:
17131 switch (ctx->opcode & 0x1) {
17132 case ADDIUS5:
d75c135e 17133 gen_addius5(ctx);
3c824109
NF
17134 break;
17135 case ADDIUSP:
d75c135e 17136 gen_addiusp(ctx);
3c824109
NF
17137 break;
17138 }
17139 break;
17140 case POOL16E:
17141 switch (ctx->opcode & 0x1) {
17142 case ADDIUR2:
d75c135e 17143 gen_addiur2(ctx);
3c824109
NF
17144 break;
17145 case ADDIUR1SP:
d75c135e 17146 gen_addiur1sp(ctx);
3c824109
NF
17147 break;
17148 }
17149 break;
65935f07 17150 case B16: /* BC16 */
3c824109 17151 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0,
65935f07
YK
17152 sextract32(ctx->opcode, 0, 10) << 1,
17153 (ctx->insn_flags & ISA_MIPS32R6) ? 0 : 4);
3c824109 17154 break;
65935f07
YK
17155 case BNEZ16: /* BNEZC16 */
17156 case BEQZ16: /* BEQZC16 */
3c824109
NF
17157 gen_compute_branch(ctx, op == BNEZ16 ? OPC_BNE : OPC_BEQ, 2,
17158 mmreg(uMIPS_RD(ctx->opcode)),
65935f07
YK
17159 0, sextract32(ctx->opcode, 0, 7) << 1,
17160 (ctx->insn_flags & ISA_MIPS32R6) ? 0 : 4);
17161
3c824109
NF
17162 break;
17163 case LI16:
17164 {
17165 int reg = mmreg(uMIPS_RD(ctx->opcode));
17166 int imm = ZIMM(ctx->opcode, 0, 7);
17167
17168 imm = (imm == 0x7f ? -1 : imm);
17169 tcg_gen_movi_tl(cpu_gpr[reg], imm);
17170 }
17171 break;
3c824109 17172 case RES_29:
3c824109 17173 case RES_31:
3c824109 17174 case RES_39:
9c708c7f 17175 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
17176 break;
17177 default:
f60eeb0c 17178 decode_micromips32_opc(env, ctx);
3c824109
NF
17179 return 4;
17180 }
17181
17182 return 2;
17183}
17184
261c95a0
YK
17185/*
17186 *
17187 * nanoMIPS opcodes
17188 *
17189 */
17190
17191/* MAJOR, P16, and P32 pools opcodes */
17192enum {
17193 NM_P_ADDIU = 0x00,
17194 NM_ADDIUPC = 0x01,
17195 NM_MOVE_BALC = 0x02,
17196 NM_P16_MV = 0x04,
17197 NM_LW16 = 0x05,
17198 NM_BC16 = 0x06,
17199 NM_P16_SR = 0x07,
17200
17201 NM_POOL32A = 0x08,
17202 NM_P_BAL = 0x0a,
17203 NM_P16_SHIFT = 0x0c,
17204 NM_LWSP16 = 0x0d,
17205 NM_BALC16 = 0x0e,
17206 NM_P16_4X4 = 0x0f,
17207
17208 NM_P_GP_W = 0x10,
17209 NM_P_GP_BH = 0x11,
17210 NM_P_J = 0x12,
17211 NM_P16C = 0x14,
17212 NM_LWGP16 = 0x15,
17213 NM_P16_LB = 0x17,
17214
17215 NM_P48I = 0x18,
17216 NM_P16_A1 = 0x1c,
17217 NM_LW4X4 = 0x1d,
17218 NM_P16_LH = 0x1f,
17219
17220 NM_P_U12 = 0x20,
17221 NM_P_LS_U12 = 0x21,
17222 NM_P_BR1 = 0x22,
17223 NM_P16_A2 = 0x24,
17224 NM_SW16 = 0x25,
17225 NM_BEQZC16 = 0x26,
17226
17227 NM_POOL32F = 0x28,
17228 NM_P_LS_S9 = 0x29,
17229 NM_P_BR2 = 0x2a,
17230
17231 NM_P16_ADDU = 0x2c,
17232 NM_SWSP16 = 0x2d,
17233 NM_BNEZC16 = 0x2e,
17234 NM_MOVEP = 0x2f,
17235
17236 NM_POOL32S = 0x30,
17237 NM_P_BRI = 0x32,
17238 NM_LI16 = 0x34,
17239 NM_SWGP16 = 0x35,
17240 NM_P16_BR = 0x36,
17241
17242 NM_P_LUI = 0x38,
17243 NM_ANDI16 = 0x3c,
17244 NM_SW4X4 = 0x3d,
17245 NM_MOVEPREV = 0x3f,
17246};
17247
17248/* POOL32A instruction pool */
17249enum {
17250 NM_POOL32A0 = 0x00,
17251 NM_SPECIAL2 = 0x01,
17252 NM_COP2_1 = 0x02,
17253 NM_UDI = 0x03,
17254 NM_POOL32A5 = 0x05,
17255 NM_POOL32A7 = 0x07,
17256};
17257
17258/* P.GP.W instruction pool */
17259enum {
17260 NM_ADDIUGP_W = 0x00,
17261 NM_LWGP = 0x02,
17262 NM_SWGP = 0x03,
17263};
17264
17265/* P48I instruction pool */
17266enum {
17267 NM_LI48 = 0x00,
17268 NM_ADDIU48 = 0x01,
17269 NM_ADDIUGP48 = 0x02,
17270 NM_ADDIUPC48 = 0x03,
17271 NM_LWPC48 = 0x0b,
17272 NM_SWPC48 = 0x0f,
17273};
17274
17275/* P.U12 instruction pool */
17276enum {
17277 NM_ORI = 0x00,
17278 NM_XORI = 0x01,
17279 NM_ANDI = 0x02,
17280 NM_P_SR = 0x03,
17281 NM_SLTI = 0x04,
17282 NM_SLTIU = 0x05,
17283 NM_SEQI = 0x06,
17284 NM_ADDIUNEG = 0x08,
17285 NM_P_SHIFT = 0x0c,
17286 NM_P_ROTX = 0x0d,
17287 NM_P_INS = 0x0e,
17288 NM_P_EXT = 0x0f,
17289};
17290
17291/* POOL32F instruction pool */
17292enum {
17293 NM_POOL32F_0 = 0x00,
17294 NM_POOL32F_3 = 0x03,
17295 NM_POOL32F_5 = 0x05,
17296};
17297
17298/* POOL32S instruction pool */
17299enum {
17300 NM_POOL32S_0 = 0x00,
17301 NM_POOL32S_4 = 0x04,
17302};
17303
17304/* P.LUI instruction pool */
17305enum {
17306 NM_LUI = 0x00,
17307 NM_ALUIPC = 0x01,
17308};
17309
17310/* P.GP.BH instruction pool */
17311enum {
17312 NM_LBGP = 0x00,
17313 NM_SBGP = 0x01,
17314 NM_LBUGP = 0x02,
17315 NM_ADDIUGP_B = 0x03,
17316 NM_P_GP_LH = 0x04,
17317 NM_P_GP_SH = 0x05,
17318 NM_P_GP_CP1 = 0x06,
17319};
17320
17321/* P.LS.U12 instruction pool */
17322enum {
17323 NM_LB = 0x00,
17324 NM_SB = 0x01,
17325 NM_LBU = 0x02,
17326 NM_P_PREFU12 = 0x03,
17327 NM_LH = 0x04,
17328 NM_SH = 0x05,
17329 NM_LHU = 0x06,
17330 NM_LWU = 0x07,
17331 NM_LW = 0x08,
17332 NM_SW = 0x09,
17333 NM_LWC1 = 0x0a,
17334 NM_SWC1 = 0x0b,
17335 NM_LDC1 = 0x0e,
17336 NM_SDC1 = 0x0f,
17337};
17338
17339/* P.LS.S9 instruction pool */
17340enum {
17341 NM_P_LS_S0 = 0x00,
17342 NM_P_LS_S1 = 0x01,
17343 NM_P_LS_E0 = 0x02,
17344 NM_P_LS_WM = 0x04,
17345 NM_P_LS_UAWM = 0x05,
17346};
17347
17348/* P.BAL instruction pool */
17349enum {
17350 NM_BC = 0x00,
17351 NM_BALC = 0x01,
17352};
17353
17354/* P.J instruction pool */
17355enum {
17356 NM_JALRC = 0x00,
17357 NM_JALRC_HB = 0x01,
17358 NM_P_BALRSC = 0x08,
17359};
17360
17361/* P.BR1 instruction pool */
17362enum {
17363 NM_BEQC = 0x00,
17364 NM_P_BR3A = 0x01,
17365 NM_BGEC = 0x02,
17366 NM_BGEUC = 0x03,
17367};
17368
17369/* P.BR2 instruction pool */
17370enum {
17371 NM_BNEC = 0x00,
17372 NM_BLTC = 0x02,
17373 NM_BLTUC = 0x03,
17374};
17375
17376/* P.BRI instruction pool */
17377enum {
17378 NM_BEQIC = 0x00,
17379 NM_BBEQZC = 0x01,
17380 NM_BGEIC = 0x02,
17381 NM_BGEIUC = 0x03,
17382 NM_BNEIC = 0x04,
17383 NM_BBNEZC = 0x05,
17384 NM_BLTIC = 0x06,
17385 NM_BLTIUC = 0x07,
17386};
17387
17388/* P16.SHIFT instruction pool */
17389enum {
17390 NM_SLL16 = 0x00,
17391 NM_SRL16 = 0x01,
17392};
17393
17394/* POOL16C instruction pool */
17395enum {
17396 NM_POOL16C_0 = 0x00,
17397 NM_LWXS16 = 0x01,
17398};
17399
17400/* P16.A1 instruction pool */
17401enum {
17402 NM_ADDIUR1SP = 0x01,
17403};
17404
17405/* P16.A2 instruction pool */
17406enum {
17407 NM_ADDIUR2 = 0x00,
17408 NM_P_ADDIURS5 = 0x01,
17409};
17410
17411/* P16.ADDU instruction pool */
17412enum {
17413 NM_ADDU16 = 0x00,
17414 NM_SUBU16 = 0x01,
17415};
17416
17417/* P16.SR instruction pool */
17418enum {
17419 NM_SAVE16 = 0x00,
17420 NM_RESTORE_JRC16 = 0x01,
17421};
17422
17423/* P16.4X4 instruction pool */
17424enum {
17425 NM_ADDU4X4 = 0x00,
17426 NM_MUL4X4 = 0x01,
17427};
17428
17429/* P16.LB instruction pool */
17430enum {
17431 NM_LB16 = 0x00,
17432 NM_SB16 = 0x01,
17433 NM_LBU16 = 0x02,
17434};
17435
17436/* P16.LH instruction pool */
17437enum {
17438 NM_LH16 = 0x00,
17439 NM_SH16 = 0x01,
17440 NM_LHU16 = 0x02,
17441};
17442
17443/* P.RI instruction pool */
17444enum {
17445 NM_SIGRIE = 0x00,
17446 NM_P_SYSCALL = 0x01,
17447 NM_BREAK = 0x02,
17448 NM_SDBBP = 0x03,
17449};
17450
17451/* POOL32A0 instruction pool */
17452enum {
17453 NM_P_TRAP = 0x00,
17454 NM_SEB = 0x01,
17455 NM_SLLV = 0x02,
17456 NM_MUL = 0x03,
17457 NM_MFC0 = 0x06,
17458 NM_MFHC0 = 0x07,
17459 NM_SEH = 0x09,
17460 NM_SRLV = 0x0a,
17461 NM_MUH = 0x0b,
17462 NM_MTC0 = 0x0e,
17463 NM_MTHC0 = 0x0f,
17464 NM_SRAV = 0x12,
17465 NM_MULU = 0x13,
17466 NM_ROTRV = 0x1a,
17467 NM_MUHU = 0x1b,
17468 NM_ADD = 0x22,
17469 NM_DIV = 0x23,
17470 NM_ADDU = 0x2a,
17471 NM_MOD = 0x2b,
17472 NM_SUB = 0x32,
17473 NM_DIVU = 0x33,
17474 NM_RDHWR = 0x38,
17475 NM_SUBU = 0x3a,
17476 NM_MODU = 0x3b,
17477 NM_P_CMOVE = 0x42,
17478 NM_FORK = 0x45,
17479 NM_MFTR = 0x46,
17480 NM_MFHTR = 0x47,
17481 NM_AND = 0x4a,
17482 NM_YIELD = 0x4d,
17483 NM_MTTR = 0x4e,
17484 NM_MTHTR = 0x4f,
17485 NM_OR = 0x52,
17486 NM_D_E_MT_VPE = 0x56,
17487 NM_NOR = 0x5a,
17488 NM_XOR = 0x62,
17489 NM_SLT = 0x6a,
17490 NM_P_SLTU = 0x72,
17491 NM_SOV = 0x7a,
17492};
17493
ba1e8117
AM
17494/* CRC32 instruction pool */
17495enum {
17496 NM_CRC32B = 0x00,
17497 NM_CRC32H = 0x01,
17498 NM_CRC32W = 0x02,
17499 NM_CRC32CB = 0x04,
17500 NM_CRC32CH = 0x05,
17501 NM_CRC32CW = 0x06,
17502};
17503
b3979b6f
SM
17504/* POOL32A5 instruction pool */
17505enum {
17506 NM_CMP_EQ_PH = 0x00,
17507 NM_CMP_LT_PH = 0x08,
17508 NM_CMP_LE_PH = 0x10,
17509 NM_CMPGU_EQ_QB = 0x18,
17510 NM_CMPGU_LT_QB = 0x20,
17511 NM_CMPGU_LE_QB = 0x28,
17512 NM_CMPGDU_EQ_QB = 0x30,
17513 NM_CMPGDU_LT_QB = 0x38,
17514 NM_CMPGDU_LE_QB = 0x40,
17515 NM_CMPU_EQ_QB = 0x48,
17516 NM_CMPU_LT_QB = 0x50,
17517 NM_CMPU_LE_QB = 0x58,
17518 NM_ADDQ_S_W = 0x60,
17519 NM_SUBQ_S_W = 0x68,
17520 NM_ADDSC = 0x70,
17521 NM_ADDWC = 0x78,
17522
17523 NM_ADDQ_S_PH = 0x01,
17524 NM_ADDQH_R_PH = 0x09,
17525 NM_ADDQH_R_W = 0x11,
17526 NM_ADDU_S_QB = 0x19,
17527 NM_ADDU_S_PH = 0x21,
17528 NM_ADDUH_R_QB = 0x29,
17529 NM_SHRAV_R_PH = 0x31,
17530 NM_SHRAV_R_QB = 0x39,
17531 NM_SUBQ_S_PH = 0x41,
17532 NM_SUBQH_R_PH = 0x49,
17533 NM_SUBQH_R_W = 0x51,
17534 NM_SUBU_S_QB = 0x59,
17535 NM_SUBU_S_PH = 0x61,
17536 NM_SUBUH_R_QB = 0x69,
17537 NM_SHLLV_S_PH = 0x71,
17538 NM_PRECR_SRA_R_PH_W = 0x79,
17539
17540 NM_MULEU_S_PH_QBL = 0x12,
17541 NM_MULEU_S_PH_QBR = 0x1a,
17542 NM_MULQ_RS_PH = 0x22,
17543 NM_MULQ_S_PH = 0x2a,
17544 NM_MULQ_RS_W = 0x32,
17545 NM_MULQ_S_W = 0x3a,
17546 NM_APPEND = 0x42,
17547 NM_MODSUB = 0x52,
17548 NM_SHRAV_R_W = 0x5a,
17549 NM_SHRLV_PH = 0x62,
17550 NM_SHRLV_QB = 0x6a,
17551 NM_SHLLV_QB = 0x72,
17552 NM_SHLLV_S_W = 0x7a,
17553
17554 NM_SHILO = 0x03,
17555
17556 NM_MULEQ_S_W_PHL = 0x04,
17557 NM_MULEQ_S_W_PHR = 0x0c,
17558
17559 NM_MUL_S_PH = 0x05,
17560 NM_PRECR_QB_PH = 0x0d,
17561 NM_PRECRQ_QB_PH = 0x15,
17562 NM_PRECRQ_PH_W = 0x1d,
17563 NM_PRECRQ_RS_PH_W = 0x25,
17564 NM_PRECRQU_S_QB_PH = 0x2d,
17565 NM_PACKRL_PH = 0x35,
17566 NM_PICK_QB = 0x3d,
17567 NM_PICK_PH = 0x45,
17568
17569 NM_SHRA_R_W = 0x5e,
17570 NM_SHRA_R_PH = 0x66,
17571 NM_SHLL_S_PH = 0x76,
17572 NM_SHLL_S_W = 0x7e,
17573
17574 NM_REPL_PH = 0x07
17575};
17576
261c95a0
YK
17577/* POOL32A7 instruction pool */
17578enum {
17579 NM_P_LSX = 0x00,
17580 NM_LSA = 0x01,
17581 NM_EXTW = 0x03,
17582 NM_POOL32AXF = 0x07,
17583};
17584
17585/* P.SR instruction pool */
17586enum {
17587 NM_PP_SR = 0x00,
17588 NM_P_SR_F = 0x01,
17589};
17590
17591/* P.SHIFT instruction pool */
17592enum {
17593 NM_P_SLL = 0x00,
17594 NM_SRL = 0x02,
17595 NM_SRA = 0x04,
17596 NM_ROTR = 0x06,
17597};
17598
17599/* P.ROTX instruction pool */
17600enum {
17601 NM_ROTX = 0x00,
17602};
17603
17604/* P.INS instruction pool */
17605enum {
17606 NM_INS = 0x00,
17607};
17608
17609/* P.EXT instruction pool */
17610enum {
17611 NM_EXT = 0x00,
17612};
17613
17614/* POOL32F_0 (fmt) instruction pool */
17615enum {
17616 NM_RINT_S = 0x04,
17617 NM_RINT_D = 0x44,
17618 NM_ADD_S = 0x06,
17619 NM_SELEQZ_S = 0x07,
17620 NM_SELEQZ_D = 0x47,
17621 NM_CLASS_S = 0x0c,
17622 NM_CLASS_D = 0x4c,
17623 NM_SUB_S = 0x0e,
17624 NM_SELNEZ_S = 0x0f,
17625 NM_SELNEZ_D = 0x4f,
17626 NM_MUL_S = 0x16,
17627 NM_SEL_S = 0x17,
17628 NM_SEL_D = 0x57,
17629 NM_DIV_S = 0x1e,
17630 NM_ADD_D = 0x26,
17631 NM_SUB_D = 0x2e,
17632 NM_MUL_D = 0x36,
17633 NM_MADDF_S = 0x37,
17634 NM_MADDF_D = 0x77,
17635 NM_DIV_D = 0x3e,
17636 NM_MSUBF_S = 0x3f,
17637 NM_MSUBF_D = 0x7f,
17638};
17639
17640/* POOL32F_3 instruction pool */
17641enum {
17642 NM_MIN_FMT = 0x00,
17643 NM_MAX_FMT = 0x01,
17644 NM_MINA_FMT = 0x04,
17645 NM_MAXA_FMT = 0x05,
17646 NM_POOL32FXF = 0x07,
17647};
17648
17649/* POOL32F_5 instruction pool */
17650enum {
17651 NM_CMP_CONDN_S = 0x00,
17652 NM_CMP_CONDN_D = 0x02,
17653};
17654
17655/* P.GP.LH instruction pool */
17656enum {
17657 NM_LHGP = 0x00,
17658 NM_LHUGP = 0x01,
17659};
17660
17661/* P.GP.SH instruction pool */
17662enum {
17663 NM_SHGP = 0x00,
17664};
17665
17666/* P.GP.CP1 instruction pool */
17667enum {
17668 NM_LWC1GP = 0x00,
17669 NM_SWC1GP = 0x01,
17670 NM_LDC1GP = 0x02,
17671 NM_SDC1GP = 0x03,
17672};
17673
17674/* P.LS.S0 instruction pool */
17675enum {
17676 NM_LBS9 = 0x00,
17677 NM_LHS9 = 0x04,
17678 NM_LWS9 = 0x08,
17679 NM_LDS9 = 0x0c,
17680
17681 NM_SBS9 = 0x01,
17682 NM_SHS9 = 0x05,
17683 NM_SWS9 = 0x09,
17684 NM_SDS9 = 0x0d,
17685
17686 NM_LBUS9 = 0x02,
17687 NM_LHUS9 = 0x06,
17688 NM_LWC1S9 = 0x0a,
17689 NM_LDC1S9 = 0x0e,
17690
17691 NM_P_PREFS9 = 0x03,
17692 NM_LWUS9 = 0x07,
17693 NM_SWC1S9 = 0x0b,
17694 NM_SDC1S9 = 0x0f,
17695};
17696
17697/* P.LS.S1 instruction pool */
17698enum {
17699 NM_ASET_ACLR = 0x02,
17700 NM_UALH = 0x04,
17701 NM_UASH = 0x05,
17702 NM_CACHE = 0x07,
17703 NM_P_LL = 0x0a,
17704 NM_P_SC = 0x0b,
17705};
17706
0d30b3bb
DN
17707/* P.LS.E0 instruction pool */
17708enum {
17709 NM_LBE = 0x00,
17710 NM_SBE = 0x01,
17711 NM_LBUE = 0x02,
17712 NM_P_PREFE = 0x03,
17713 NM_LHE = 0x04,
17714 NM_SHE = 0x05,
17715 NM_LHUE = 0x06,
17716 NM_CACHEE = 0x07,
17717 NM_LWE = 0x08,
17718 NM_SWE = 0x09,
17719 NM_P_LLE = 0x0a,
17720 NM_P_SCE = 0x0b,
17721};
17722
17723/* P.PREFE instruction pool */
17724enum {
17725 NM_SYNCIE = 0x00,
17726 NM_PREFE = 0x01,
17727};
17728
17729/* P.LLE instruction pool */
17730enum {
17731 NM_LLE = 0x00,
17732 NM_LLWPE = 0x01,
17733};
17734
17735/* P.SCE instruction pool */
17736enum {
17737 NM_SCE = 0x00,
17738 NM_SCWPE = 0x01,
17739};
17740
261c95a0
YK
17741/* P.LS.WM instruction pool */
17742enum {
17743 NM_LWM = 0x00,
17744 NM_SWM = 0x01,
17745};
17746
17747/* P.LS.UAWM instruction pool */
17748enum {
17749 NM_UALWM = 0x00,
17750 NM_UASWM = 0x01,
17751};
17752
17753/* P.BR3A instruction pool */
17754enum {
17755 NM_BC1EQZC = 0x00,
17756 NM_BC1NEZC = 0x01,
17757 NM_BC2EQZC = 0x02,
17758 NM_BC2NEZC = 0x03,
17759 NM_BPOSGE32C = 0x04,
17760};
17761
17762/* P16.RI instruction pool */
17763enum {
17764 NM_P16_SYSCALL = 0x01,
17765 NM_BREAK16 = 0x02,
17766 NM_SDBBP16 = 0x03,
17767};
17768
17769/* POOL16C_0 instruction pool */
17770enum {
17771 NM_POOL16C_00 = 0x00,
17772};
17773
17774/* P16.JRC instruction pool */
17775enum {
17776 NM_JRC = 0x00,
17777 NM_JALRC16 = 0x01,
17778};
17779
17780/* P.SYSCALL instruction pool */
17781enum {
17782 NM_SYSCALL = 0x00,
17783 NM_HYPCALL = 0x01,
17784};
17785
17786/* P.TRAP instruction pool */
17787enum {
17788 NM_TEQ = 0x00,
17789 NM_TNE = 0x01,
17790};
17791
17792/* P.CMOVE instruction pool */
17793enum {
17794 NM_MOVZ = 0x00,
17795 NM_MOVN = 0x01,
17796};
17797
17798/* POOL32Axf instruction pool */
17799enum {
b3979b6f
SM
17800 NM_POOL32AXF_1 = 0x01,
17801 NM_POOL32AXF_2 = 0x02,
261c95a0
YK
17802 NM_POOL32AXF_4 = 0x04,
17803 NM_POOL32AXF_5 = 0x05,
b3979b6f
SM
17804 NM_POOL32AXF_7 = 0x07,
17805};
17806
17807/* POOL32Axf_1 instruction pool */
17808enum {
17809 NM_POOL32AXF_1_0 = 0x00,
17810 NM_POOL32AXF_1_1 = 0x01,
17811 NM_POOL32AXF_1_3 = 0x03,
17812 NM_POOL32AXF_1_4 = 0x04,
17813 NM_POOL32AXF_1_5 = 0x05,
17814 NM_POOL32AXF_1_7 = 0x07,
17815};
17816
17817/* POOL32Axf_2 instruction pool */
17818enum {
17819 NM_POOL32AXF_2_0_7 = 0x00,
17820 NM_POOL32AXF_2_8_15 = 0x01,
17821 NM_POOL32AXF_2_16_23 = 0x02,
17822 NM_POOL32AXF_2_24_31 = 0x03,
17823};
17824
17825/* POOL32Axf_7 instruction pool */
17826enum {
17827 NM_SHRA_R_QB = 0x0,
17828 NM_SHRL_PH = 0x1,
17829 NM_REPL_QB = 0x2,
17830};
17831
17832/* POOL32Axf_1_0 instruction pool */
17833enum {
17834 NM_MFHI = 0x0,
17835 NM_MFLO = 0x1,
17836 NM_MTHI = 0x2,
17837 NM_MTLO = 0x3,
17838};
17839
17840/* POOL32Axf_1_1 instruction pool */
17841enum {
17842 NM_MTHLIP = 0x0,
17843 NM_SHILOV = 0x1,
17844};
17845
17846/* POOL32Axf_1_3 instruction pool */
17847enum {
17848 NM_RDDSP = 0x0,
17849 NM_WRDSP = 0x1,
17850 NM_EXTP = 0x2,
17851 NM_EXTPDP = 0x3,
17852};
17853
17854/* POOL32Axf_1_4 instruction pool */
17855enum {
17856 NM_SHLL_QB = 0x0,
17857 NM_SHRL_QB = 0x1,
17858};
17859
17860/* POOL32Axf_1_5 instruction pool */
17861enum {
17862 NM_MAQ_S_W_PHR = 0x0,
17863 NM_MAQ_S_W_PHL = 0x1,
17864 NM_MAQ_SA_W_PHR = 0x2,
17865 NM_MAQ_SA_W_PHL = 0x3,
17866};
17867
17868/* POOL32Axf_1_7 instruction pool */
17869enum {
17870 NM_EXTR_W = 0x0,
17871 NM_EXTR_R_W = 0x1,
17872 NM_EXTR_RS_W = 0x2,
17873 NM_EXTR_S_H = 0x3,
17874};
17875
17876/* POOL32Axf_2_0_7 instruction pool */
17877enum {
17878 NM_DPA_W_PH = 0x0,
17879 NM_DPAQ_S_W_PH = 0x1,
17880 NM_DPS_W_PH = 0x2,
17881 NM_DPSQ_S_W_PH = 0x3,
17882 NM_BALIGN = 0x4,
17883 NM_MADD = 0x5,
17884 NM_MULT = 0x6,
17885 NM_EXTRV_W = 0x7,
17886};
17887
17888/* POOL32Axf_2_8_15 instruction pool */
17889enum {
17890 NM_DPAX_W_PH = 0x0,
17891 NM_DPAQ_SA_L_W = 0x1,
17892 NM_DPSX_W_PH = 0x2,
17893 NM_DPSQ_SA_L_W = 0x3,
17894 NM_MADDU = 0x5,
17895 NM_MULTU = 0x6,
17896 NM_EXTRV_R_W = 0x7,
17897};
17898
17899/* POOL32Axf_2_16_23 instruction pool */
17900enum {
17901 NM_DPAU_H_QBL = 0x0,
17902 NM_DPAQX_S_W_PH = 0x1,
17903 NM_DPSU_H_QBL = 0x2,
17904 NM_DPSQX_S_W_PH = 0x3,
17905 NM_EXTPV = 0x4,
17906 NM_MSUB = 0x5,
17907 NM_MULSA_W_PH = 0x6,
17908 NM_EXTRV_RS_W = 0x7,
17909};
17910
17911/* POOL32Axf_2_24_31 instruction pool */
17912enum {
17913 NM_DPAU_H_QBR = 0x0,
17914 NM_DPAQX_SA_W_PH = 0x1,
17915 NM_DPSU_H_QBR = 0x2,
17916 NM_DPSQX_SA_W_PH = 0x3,
17917 NM_EXTPDPV = 0x4,
17918 NM_MSUBU = 0x5,
17919 NM_MULSAQ_S_W_PH = 0x6,
17920 NM_EXTRV_S_H = 0x7,
261c95a0
YK
17921};
17922
17923/* POOL32Axf_{4, 5} instruction pool */
17924enum {
17925 NM_CLO = 0x25,
17926 NM_CLZ = 0x2d,
17927
17928 NM_TLBP = 0x01,
17929 NM_TLBR = 0x09,
17930 NM_TLBWI = 0x11,
17931 NM_TLBWR = 0x19,
17932 NM_TLBINV = 0x03,
17933 NM_TLBINVF = 0x0b,
17934 NM_DI = 0x23,
17935 NM_EI = 0x2b,
17936 NM_RDPGPR = 0x70,
17937 NM_WRPGPR = 0x78,
17938 NM_WAIT = 0x61,
17939 NM_DERET = 0x71,
17940 NM_ERETX = 0x79,
b3979b6f
SM
17941
17942 /* nanoMIPS DSP instructions */
17943 NM_ABSQ_S_QB = 0x00,
17944 NM_ABSQ_S_PH = 0x08,
17945 NM_ABSQ_S_W = 0x10,
17946 NM_PRECEQ_W_PHL = 0x28,
17947 NM_PRECEQ_W_PHR = 0x30,
17948 NM_PRECEQU_PH_QBL = 0x38,
17949 NM_PRECEQU_PH_QBR = 0x48,
17950 NM_PRECEU_PH_QBL = 0x58,
17951 NM_PRECEU_PH_QBR = 0x68,
17952 NM_PRECEQU_PH_QBLA = 0x39,
17953 NM_PRECEQU_PH_QBRA = 0x49,
17954 NM_PRECEU_PH_QBLA = 0x59,
17955 NM_PRECEU_PH_QBRA = 0x69,
17956 NM_REPLV_PH = 0x01,
17957 NM_REPLV_QB = 0x09,
17958 NM_BITREV = 0x18,
17959 NM_INSV = 0x20,
17960 NM_RADDU_W_QB = 0x78,
17961
17962 NM_BITSWAP = 0x05,
17963 NM_WSBH = 0x3d,
261c95a0
YK
17964};
17965
17966/* PP.SR instruction pool */
17967enum {
17968 NM_SAVE = 0x00,
17969 NM_RESTORE = 0x02,
17970 NM_RESTORE_JRC = 0x03,
17971};
17972
17973/* P.SR.F instruction pool */
17974enum {
17975 NM_SAVEF = 0x00,
17976 NM_RESTOREF = 0x01,
17977};
17978
17979/* P16.SYSCALL instruction pool */
17980enum {
17981 NM_SYSCALL16 = 0x00,
17982 NM_HYPCALL16 = 0x01,
17983};
17984
17985/* POOL16C_00 instruction pool */
17986enum {
17987 NM_NOT16 = 0x00,
17988 NM_XOR16 = 0x01,
17989 NM_AND16 = 0x02,
17990 NM_OR16 = 0x03,
17991};
17992
17993/* PP.LSX and PP.LSXS instruction pool */
17994enum {
17995 NM_LBX = 0x00,
17996 NM_LHX = 0x04,
17997 NM_LWX = 0x08,
17998 NM_LDX = 0x0c,
17999
18000 NM_SBX = 0x01,
18001 NM_SHX = 0x05,
18002 NM_SWX = 0x09,
18003 NM_SDX = 0x0d,
18004
18005 NM_LBUX = 0x02,
18006 NM_LHUX = 0x06,
18007 NM_LWC1X = 0x0a,
18008 NM_LDC1X = 0x0e,
18009
18010 NM_LWUX = 0x07,
18011 NM_SWC1X = 0x0b,
18012 NM_SDC1X = 0x0f,
18013
18014 NM_LHXS = 0x04,
18015 NM_LWXS = 0x08,
18016 NM_LDXS = 0x0c,
18017
18018 NM_SHXS = 0x05,
18019 NM_SWXS = 0x09,
18020 NM_SDXS = 0x0d,
18021
18022 NM_LHUXS = 0x06,
18023 NM_LWC1XS = 0x0a,
18024 NM_LDC1XS = 0x0e,
18025
18026 NM_LWUXS = 0x07,
18027 NM_SWC1XS = 0x0b,
18028 NM_SDC1XS = 0x0f,
18029};
18030
18031/* ERETx instruction pool */
18032enum {
18033 NM_ERET = 0x00,
18034 NM_ERETNC = 0x01,
18035};
18036
18037/* POOL32FxF_{0, 1} insturction pool */
18038enum {
18039 NM_CFC1 = 0x40,
18040 NM_CTC1 = 0x60,
18041 NM_MFC1 = 0x80,
18042 NM_MTC1 = 0xa0,
18043 NM_MFHC1 = 0xc0,
18044 NM_MTHC1 = 0xe0,
18045
18046 NM_CVT_S_PL = 0x84,
18047 NM_CVT_S_PU = 0xa4,
18048
18049 NM_CVT_L_S = 0x004,
18050 NM_CVT_L_D = 0x104,
18051 NM_CVT_W_S = 0x024,
18052 NM_CVT_W_D = 0x124,
18053
18054 NM_RSQRT_S = 0x008,
18055 NM_RSQRT_D = 0x108,
18056
18057 NM_SQRT_S = 0x028,
18058 NM_SQRT_D = 0x128,
18059
18060 NM_RECIP_S = 0x048,
18061 NM_RECIP_D = 0x148,
18062
18063 NM_FLOOR_L_S = 0x00c,
18064 NM_FLOOR_L_D = 0x10c,
18065
18066 NM_FLOOR_W_S = 0x02c,
18067 NM_FLOOR_W_D = 0x12c,
18068
18069 NM_CEIL_L_S = 0x04c,
18070 NM_CEIL_L_D = 0x14c,
18071 NM_CEIL_W_S = 0x06c,
18072 NM_CEIL_W_D = 0x16c,
18073 NM_TRUNC_L_S = 0x08c,
18074 NM_TRUNC_L_D = 0x18c,
18075 NM_TRUNC_W_S = 0x0ac,
18076 NM_TRUNC_W_D = 0x1ac,
18077 NM_ROUND_L_S = 0x0cc,
18078 NM_ROUND_L_D = 0x1cc,
18079 NM_ROUND_W_S = 0x0ec,
18080 NM_ROUND_W_D = 0x1ec,
18081
18082 NM_MOV_S = 0x01,
18083 NM_MOV_D = 0x81,
18084 NM_ABS_S = 0x0d,
18085 NM_ABS_D = 0x8d,
18086 NM_NEG_S = 0x2d,
18087 NM_NEG_D = 0xad,
18088 NM_CVT_D_S = 0x04d,
18089 NM_CVT_D_W = 0x0cd,
18090 NM_CVT_D_L = 0x14d,
18091 NM_CVT_S_D = 0x06d,
18092 NM_CVT_S_W = 0x0ed,
18093 NM_CVT_S_L = 0x16d,
18094};
18095
18096/* P.LL instruction pool */
18097enum {
18098 NM_LL = 0x00,
18099 NM_LLWP = 0x01,
18100};
18101
18102/* P.SC instruction pool */
18103enum {
18104 NM_SC = 0x00,
18105 NM_SCWP = 0x01,
18106};
18107
18108/* P.DVP instruction pool */
18109enum {
18110 NM_DVP = 0x00,
18111 NM_EVP = 0x01,
18112};
18113
c533c0f4
AM
18114
18115/*
18116 *
18117 * nanoMIPS decoding engine
18118 *
18119 */
18120
6bfa9f4c
AM
18121
18122/* extraction utilities */
18123
18124#define NANOMIPS_EXTRACT_RD(op) ((op >> 7) & 0x7)
18125#define NANOMIPS_EXTRACT_RS(op) ((op >> 4) & 0x7)
18126#define NANOMIPS_EXTRACT_RS2(op) uMIPS_RS(op)
18127#define NANOMIPS_EXTRACT_RS1(op) ((op >> 1) & 0x7)
18128#define NANOMIPS_EXTRACT_RD5(op) ((op >> 5) & 0x1f)
18129#define NANOMIPS_EXTRACT_RS5(op) (op & 0x1f)
18130
ea4ca3c2
YK
18131/* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr3'). */
18132static inline int decode_gpr_gpr3(int r)
18133{
18134 static const int map[] = { 16, 17, 18, 19, 4, 5, 6, 7 };
18135
18136 return map[r & 0x7];
18137}
18138
8bdb7029
YK
18139/* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr3.src.store'). */
18140static inline int decode_gpr_gpr3_src_store(int r)
18141{
18142 static const int map[] = { 0, 17, 18, 19, 4, 5, 6, 7 };
18143
18144 return map[r & 0x7];
18145}
18146
ea4ca3c2
YK
18147/* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr4'). */
18148static inline int decode_gpr_gpr4(int r)
18149{
18150 static const int map[] = { 8, 9, 10, 11, 4, 5, 6, 7,
18151 16, 17, 18, 19, 20, 21, 22, 23 };
18152
18153 return map[r & 0xf];
18154}
18155
8bdb7029
YK
18156/* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr4.zero'). */
18157static inline int decode_gpr_gpr4_zero(int r)
18158{
18159 static const int map[] = { 8, 9, 10, 0, 4, 5, 6, 7,
18160 16, 17, 18, 19, 20, 21, 22, 23 };
18161
18162 return map[r & 0xf];
18163}
18164
6bfa9f4c 18165
80845edf
YK
18166/* extraction utilities */
18167
18168#define NANOMIPS_EXTRACT_RD(op) ((op >> 7) & 0x7)
18169#define NANOMIPS_EXTRACT_RS(op) ((op >> 4) & 0x7)
18170#define NANOMIPS_EXTRACT_RS2(op) uMIPS_RS(op)
18171#define NANOMIPS_EXTRACT_RS1(op) ((op >> 1) & 0x7)
18172#define NANOMIPS_EXTRACT_RD5(op) ((op >> 5) & 0x1f)
18173#define NANOMIPS_EXTRACT_RS5(op) (op & 0x1f)
18174
18175
bf0718c5
SM
18176static void gen_adjust_sp(DisasContext *ctx, int u)
18177{
18178 gen_op_addr_addi(ctx, cpu_gpr[29], cpu_gpr[29], u);
18179}
18180
18181static void gen_save(DisasContext *ctx, uint8_t rt, uint8_t count,
18182 uint8_t gp, uint16_t u)
18183{
18184 int counter = 0;
18185 TCGv va = tcg_temp_new();
18186 TCGv t0 = tcg_temp_new();
18187
18188 while (counter != count) {
18189 bool use_gp = gp && (counter == count - 1);
18190 int this_rt = use_gp ? 28 : (rt & 0x10) | ((rt + counter) & 0x1f);
18191 int this_offset = -((counter + 1) << 2);
18192 gen_base_offset_addr(ctx, va, 29, this_offset);
18193 gen_load_gpr(t0, this_rt);
18194 tcg_gen_qemu_st_tl(t0, va, ctx->mem_idx,
18195 (MO_TEUL | ctx->default_tcg_memop_mask));
18196 counter++;
18197 }
18198
18199 /* adjust stack pointer */
18200 gen_adjust_sp(ctx, -u);
18201
18202 tcg_temp_free(t0);
18203 tcg_temp_free(va);
18204}
18205
18206static void gen_restore(DisasContext *ctx, uint8_t rt, uint8_t count,
18207 uint8_t gp, uint16_t u)
18208{
18209 int counter = 0;
18210 TCGv va = tcg_temp_new();
18211 TCGv t0 = tcg_temp_new();
18212
18213 while (counter != count) {
18214 bool use_gp = gp && (counter == count - 1);
18215 int this_rt = use_gp ? 28 : (rt & 0x10) | ((rt + counter) & 0x1f);
18216 int this_offset = u - ((counter + 1) << 2);
18217 gen_base_offset_addr(ctx, va, 29, this_offset);
18218 tcg_gen_qemu_ld_tl(t0, va, ctx->mem_idx, MO_TESL |
18219 ctx->default_tcg_memop_mask);
18220 tcg_gen_ext32s_tl(t0, t0);
18221 gen_store_gpr(t0, this_rt);
18222 counter++;
18223 }
18224
18225 /* adjust stack pointer */
18226 gen_adjust_sp(ctx, u);
18227
18228 tcg_temp_free(t0);
18229 tcg_temp_free(va);
18230}
18231
80845edf
YK
18232static void gen_pool16c_nanomips_insn(DisasContext *ctx)
18233{
18234 int rt = decode_gpr_gpr3(NANOMIPS_EXTRACT_RD(ctx->opcode));
18235 int rs = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS(ctx->opcode));
18236
18237 switch (extract32(ctx->opcode, 2, 2)) {
18238 case NM_NOT16:
18239 gen_logic(ctx, OPC_NOR, rt, rs, 0);
18240 break;
18241 case NM_AND16:
18242 gen_logic(ctx, OPC_AND, rt, rt, rs);
18243 break;
18244 case NM_XOR16:
18245 gen_logic(ctx, OPC_XOR, rt, rt, rs);
18246 break;
18247 case NM_OR16:
18248 gen_logic(ctx, OPC_OR, rt, rt, rs);
18249 break;
18250 }
18251}
18252
0a1a6ed7 18253static void gen_pool32a0_nanomips_insn(CPUMIPSState *env, DisasContext *ctx)
e0cf0e65
YK
18254{
18255 int rt = extract32(ctx->opcode, 21, 5);
18256 int rs = extract32(ctx->opcode, 16, 5);
18257 int rd = extract32(ctx->opcode, 11, 5);
18258
18259 switch (extract32(ctx->opcode, 3, 7)) {
18260 case NM_P_TRAP:
18261 switch (extract32(ctx->opcode, 10, 1)) {
18262 case NM_TEQ:
fb32f8c8 18263 check_nms(ctx);
e0cf0e65
YK
18264 gen_trap(ctx, OPC_TEQ, rs, rt, -1);
18265 break;
18266 case NM_TNE:
fb32f8c8 18267 check_nms(ctx);
e0cf0e65
YK
18268 gen_trap(ctx, OPC_TNE, rs, rt, -1);
18269 break;
18270 }
18271 break;
18272 case NM_RDHWR:
fb32f8c8 18273 check_nms(ctx);
e0cf0e65
YK
18274 gen_rdhwr(ctx, rt, rs, extract32(ctx->opcode, 11, 3));
18275 break;
18276 case NM_SEB:
fb32f8c8 18277 check_nms(ctx);
e0cf0e65
YK
18278 gen_bshfl(ctx, OPC_SEB, rs, rt);
18279 break;
18280 case NM_SEH:
18281 gen_bshfl(ctx, OPC_SEH, rs, rt);
18282 break;
18283 case NM_SLLV:
18284 gen_shift(ctx, OPC_SLLV, rd, rt, rs);
18285 break;
18286 case NM_SRLV:
18287 gen_shift(ctx, OPC_SRLV, rd, rt, rs);
18288 break;
18289 case NM_SRAV:
18290 gen_shift(ctx, OPC_SRAV, rd, rt, rs);
18291 break;
18292 case NM_ROTRV:
18293 gen_shift(ctx, OPC_ROTRV, rd, rt, rs);
18294 break;
18295 case NM_ADD:
18296 gen_arith(ctx, OPC_ADD, rd, rs, rt);
18297 break;
18298 case NM_ADDU:
18299 gen_arith(ctx, OPC_ADDU, rd, rs, rt);
18300 break;
18301 case NM_SUB:
fb32f8c8 18302 check_nms(ctx);
e0cf0e65
YK
18303 gen_arith(ctx, OPC_SUB, rd, rs, rt);
18304 break;
18305 case NM_SUBU:
18306 gen_arith(ctx, OPC_SUBU, rd, rs, rt);
18307 break;
18308 case NM_P_CMOVE:
18309 switch (extract32(ctx->opcode, 10, 1)) {
18310 case NM_MOVZ:
18311 gen_cond_move(ctx, OPC_MOVZ, rd, rs, rt);
18312 break;
18313 case NM_MOVN:
18314 gen_cond_move(ctx, OPC_MOVN, rd, rs, rt);
18315 break;
18316 }
18317 break;
18318 case NM_AND:
18319 gen_logic(ctx, OPC_AND, rd, rs, rt);
18320 break;
18321 case NM_OR:
18322 gen_logic(ctx, OPC_OR, rd, rs, rt);
18323 break;
18324 case NM_NOR:
18325 gen_logic(ctx, OPC_NOR, rd, rs, rt);
18326 break;
18327 case NM_XOR:
18328 gen_logic(ctx, OPC_XOR, rd, rs, rt);
18329 break;
18330 case NM_SLT:
18331 gen_slt(ctx, OPC_SLT, rd, rs, rt);
18332 break;
18333 case NM_P_SLTU:
18334 if (rd == 0) {
18335 /* P_DVP */
18336#ifndef CONFIG_USER_ONLY
18337 TCGv t0 = tcg_temp_new();
18338 switch (extract32(ctx->opcode, 10, 1)) {
18339 case NM_DVP:
18340 if (ctx->vp) {
18341 check_cp0_enabled(ctx);
18342 gen_helper_dvp(t0, cpu_env);
18343 gen_store_gpr(t0, rt);
18344 }
18345 break;
18346 case NM_EVP:
18347 if (ctx->vp) {
18348 check_cp0_enabled(ctx);
18349 gen_helper_evp(t0, cpu_env);
18350 gen_store_gpr(t0, rt);
18351 }
18352 break;
18353 }
18354 tcg_temp_free(t0);
18355#endif
18356 } else {
18357 gen_slt(ctx, OPC_SLTU, rd, rs, rt);
18358 }
18359 break;
18360 case NM_SOV:
18361 {
18362 TCGv t0 = tcg_temp_new();
18363 TCGv t1 = tcg_temp_new();
18364 TCGv t2 = tcg_temp_new();
18365
18366 gen_load_gpr(t1, rs);
18367 gen_load_gpr(t2, rt);
18368 tcg_gen_add_tl(t0, t1, t2);
18369 tcg_gen_ext32s_tl(t0, t0);
18370 tcg_gen_xor_tl(t1, t1, t2);
18371 tcg_gen_xor_tl(t2, t0, t2);
18372 tcg_gen_andc_tl(t1, t2, t1);
18373
18374 /* operands of same sign, result different sign */
18375 tcg_gen_setcondi_tl(TCG_COND_LT, t0, t1, 0);
18376 gen_store_gpr(t0, rd);
18377
18378 tcg_temp_free(t0);
18379 tcg_temp_free(t1);
18380 tcg_temp_free(t2);
18381 }
18382 break;
18383 case NM_MUL:
18384 gen_r6_muldiv(ctx, R6_OPC_MUL, rd, rs, rt);
18385 break;
18386 case NM_MUH:
18387 gen_r6_muldiv(ctx, R6_OPC_MUH, rd, rs, rt);
18388 break;
18389 case NM_MULU:
18390 gen_r6_muldiv(ctx, R6_OPC_MULU, rd, rs, rt);
18391 break;
18392 case NM_MUHU:
18393 gen_r6_muldiv(ctx, R6_OPC_MUHU, rd, rs, rt);
18394 break;
18395 case NM_DIV:
18396 gen_r6_muldiv(ctx, R6_OPC_DIV, rd, rs, rt);
18397 break;
18398 case NM_MOD:
18399 gen_r6_muldiv(ctx, R6_OPC_MOD, rd, rs, rt);
18400 break;
18401 case NM_DIVU:
18402 gen_r6_muldiv(ctx, R6_OPC_DIVU, rd, rs, rt);
18403 break;
18404 case NM_MODU:
18405 gen_r6_muldiv(ctx, R6_OPC_MODU, rd, rs, rt);
18406 break;
18407#ifndef CONFIG_USER_ONLY
18408 case NM_MFC0:
18409 check_cp0_enabled(ctx);
18410 if (rt == 0) {
18411 /* Treat as NOP. */
18412 break;
18413 }
18414 gen_mfc0(ctx, cpu_gpr[rt], rs, extract32(ctx->opcode, 11, 3));
18415 break;
18416 case NM_MTC0:
18417 check_cp0_enabled(ctx);
18418 {
18419 TCGv t0 = tcg_temp_new();
18420
18421 gen_load_gpr(t0, rt);
18422 gen_mtc0(ctx, t0, rs, extract32(ctx->opcode, 11, 3));
18423 tcg_temp_free(t0);
18424 }
18425 break;
0a1a6ed7
SM
18426 case NM_D_E_MT_VPE:
18427 {
18428 uint8_t sc = extract32(ctx->opcode, 10, 1);
18429 TCGv t0 = tcg_temp_new();
18430
18431 switch (sc) {
18432 case 0:
18433 if (rs == 1) {
18434 /* DMT */
18435 check_cp0_mt(ctx);
18436 gen_helper_dmt(t0);
18437 gen_store_gpr(t0, rt);
18438 } else if (rs == 0) {
18439 /* DVPE */
18440 check_cp0_mt(ctx);
18441 gen_helper_dvpe(t0, cpu_env);
18442 gen_store_gpr(t0, rt);
18443 } else {
18444 generate_exception_end(ctx, EXCP_RI);
18445 }
18446 break;
18447 case 1:
18448 if (rs == 1) {
18449 /* EMT */
18450 check_cp0_mt(ctx);
18451 gen_helper_emt(t0);
18452 gen_store_gpr(t0, rt);
18453 } else if (rs == 0) {
18454 /* EVPE */
18455 check_cp0_mt(ctx);
18456 gen_helper_evpe(t0, cpu_env);
18457 gen_store_gpr(t0, rt);
18458 } else {
18459 generate_exception_end(ctx, EXCP_RI);
18460 }
18461 break;
18462 }
18463
18464 tcg_temp_free(t0);
18465 }
18466 break;
18467 case NM_FORK:
18468 check_mt(ctx);
18469 {
18470 TCGv t0 = tcg_temp_new();
18471 TCGv t1 = tcg_temp_new();
18472
18473 gen_load_gpr(t0, rt);
18474 gen_load_gpr(t1, rs);
18475 gen_helper_fork(t0, t1);
18476 tcg_temp_free(t0);
18477 tcg_temp_free(t1);
18478 }
18479 break;
18480 case NM_MFTR:
18481 case NM_MFHTR:
18482 check_cp0_enabled(ctx);
18483 if (rd == 0) {
18484 /* Treat as NOP. */
18485 return;
18486 }
18487 gen_mftr(env, ctx, rs, rt, extract32(ctx->opcode, 10, 1),
18488 extract32(ctx->opcode, 11, 5), extract32(ctx->opcode, 3, 1));
18489 break;
18490 case NM_MTTR:
18491 case NM_MTHTR:
18492 check_cp0_enabled(ctx);
18493 gen_mttr(env, ctx, rs, rt, extract32(ctx->opcode, 10, 1),
18494 extract32(ctx->opcode, 11, 5), extract32(ctx->opcode, 3, 1));
18495 break;
18496 case NM_YIELD:
18497 check_mt(ctx);
18498 {
18499 TCGv t0 = tcg_temp_new();
18500
18501 gen_load_gpr(t0, rs);
18502 gen_helper_yield(t0, cpu_env, t0);
18503 gen_store_gpr(t0, rt);
18504 tcg_temp_free(t0);
18505 }
18506 break;
e0cf0e65
YK
18507#endif
18508 default:
18509 generate_exception_end(ctx, EXCP_RI);
18510 break;
18511 }
18512}
18513
2ed42efa
SM
18514/* dsp */
18515static void gen_pool32axf_1_5_nanomips_insn(DisasContext *ctx, uint32_t opc,
18516 int ret, int v1, int v2)
18517{
18518 TCGv_i32 t0;
18519 TCGv v0_t;
18520 TCGv v1_t;
18521
18522 t0 = tcg_temp_new_i32();
18523
18524 v0_t = tcg_temp_new();
18525 v1_t = tcg_temp_new();
18526
18527 tcg_gen_movi_i32(t0, v2 >> 3);
18528
18529 gen_load_gpr(v0_t, ret);
18530 gen_load_gpr(v1_t, v1);
18531
18532 switch (opc) {
18533 case NM_MAQ_S_W_PHR:
18534 check_dsp(ctx);
18535 gen_helper_maq_s_w_phr(t0, v1_t, v0_t, cpu_env);
18536 break;
18537 case NM_MAQ_S_W_PHL:
18538 check_dsp(ctx);
18539 gen_helper_maq_s_w_phl(t0, v1_t, v0_t, cpu_env);
18540 break;
18541 case NM_MAQ_SA_W_PHR:
18542 check_dsp(ctx);
18543 gen_helper_maq_sa_w_phr(t0, v1_t, v0_t, cpu_env);
18544 break;
18545 case NM_MAQ_SA_W_PHL:
18546 check_dsp(ctx);
18547 gen_helper_maq_sa_w_phl(t0, v1_t, v0_t, cpu_env);
18548 break;
18549 default:
18550 generate_exception_end(ctx, EXCP_RI);
18551 break;
18552 }
18553
18554 tcg_temp_free_i32(t0);
18555
18556 tcg_temp_free(v0_t);
18557 tcg_temp_free(v1_t);
18558}
18559
18560
18561static void gen_pool32axf_1_nanomips_insn(DisasContext *ctx, uint32_t opc,
18562 int ret, int v1, int v2)
18563{
18564 int16_t imm;
18565 TCGv t0 = tcg_temp_new();
18566 TCGv t1 = tcg_temp_new();
18567 TCGv v0_t = tcg_temp_new();
18568
18569 gen_load_gpr(v0_t, v1);
18570
18571 switch (opc) {
18572 case NM_POOL32AXF_1_0:
18573 check_dsp(ctx);
18574 switch (extract32(ctx->opcode, 12, 2)) {
18575 case NM_MFHI:
18576 gen_HILO(ctx, OPC_MFHI, v2 >> 3, ret);
18577 break;
18578 case NM_MFLO:
18579 gen_HILO(ctx, OPC_MFLO, v2 >> 3, ret);
18580 break;
18581 case NM_MTHI:
18582 gen_HILO(ctx, OPC_MTHI, v2 >> 3, v1);
18583 break;
18584 case NM_MTLO:
18585 gen_HILO(ctx, OPC_MTLO, v2 >> 3, v1);
18586 break;
18587 }
18588 break;
18589 case NM_POOL32AXF_1_1:
18590 check_dsp(ctx);
18591 switch (extract32(ctx->opcode, 12, 2)) {
18592 case NM_MTHLIP:
18593 tcg_gen_movi_tl(t0, v2);
18594 gen_helper_mthlip(t0, v0_t, cpu_env);
18595 break;
18596 case NM_SHILOV:
18597 tcg_gen_movi_tl(t0, v2 >> 3);
18598 gen_helper_shilo(t0, v0_t, cpu_env);
18599 break;
18600 default:
18601 generate_exception_end(ctx, EXCP_RI);
18602 break;
18603 }
18604 break;
18605 case NM_POOL32AXF_1_3:
18606 check_dsp(ctx);
18607 imm = extract32(ctx->opcode, 14, 7);
18608 switch (extract32(ctx->opcode, 12, 2)) {
18609 case NM_RDDSP:
18610 tcg_gen_movi_tl(t0, imm);
18611 gen_helper_rddsp(t0, t0, cpu_env);
18612 gen_store_gpr(t0, ret);
18613 break;
18614 case NM_WRDSP:
18615 gen_load_gpr(t0, ret);
18616 tcg_gen_movi_tl(t1, imm);
18617 gen_helper_wrdsp(t0, t1, cpu_env);
18618 break;
18619 case NM_EXTP:
18620 tcg_gen_movi_tl(t0, v2 >> 3);
18621 tcg_gen_movi_tl(t1, v1);
18622 gen_helper_extp(t0, t0, t1, cpu_env);
18623 gen_store_gpr(t0, ret);
18624 break;
18625 case NM_EXTPDP:
18626 tcg_gen_movi_tl(t0, v2 >> 3);
18627 tcg_gen_movi_tl(t1, v1);
18628 gen_helper_extpdp(t0, t0, t1, cpu_env);
18629 gen_store_gpr(t0, ret);
18630 break;
18631 }
18632 break;
18633 case NM_POOL32AXF_1_4:
18634 check_dsp(ctx);
18635 tcg_gen_movi_tl(t0, v2 >> 2);
18636 switch (extract32(ctx->opcode, 12, 1)) {
18637 case NM_SHLL_QB:
18638 gen_helper_shll_qb(t0, t0, v0_t, cpu_env);
18639 gen_store_gpr(t0, ret);
18640 break;
18641 case NM_SHRL_QB:
18642 gen_helper_shrl_qb(t0, t0, v0_t);
18643 gen_store_gpr(t0, ret);
18644 break;
18645 }
18646 break;
18647 case NM_POOL32AXF_1_5:
18648 opc = extract32(ctx->opcode, 12, 2);
18649 gen_pool32axf_1_5_nanomips_insn(ctx, opc, ret, v1, v2);
18650 break;
18651 case NM_POOL32AXF_1_7:
18652 check_dsp(ctx);
18653 tcg_gen_movi_tl(t0, v2 >> 3);
18654 tcg_gen_movi_tl(t1, v1);
18655 switch (extract32(ctx->opcode, 12, 2)) {
18656 case NM_EXTR_W:
18657 gen_helper_extr_w(t0, t0, t1, cpu_env);
18658 gen_store_gpr(t0, ret);
18659 break;
18660 case NM_EXTR_R_W:
18661 gen_helper_extr_r_w(t0, t0, t1, cpu_env);
18662 gen_store_gpr(t0, ret);
18663 break;
18664 case NM_EXTR_RS_W:
18665 gen_helper_extr_rs_w(t0, t0, t1, cpu_env);
18666 gen_store_gpr(t0, ret);
18667 break;
18668 case NM_EXTR_S_H:
18669 gen_helper_extr_s_h(t0, t0, t1, cpu_env);
18670 gen_store_gpr(t0, ret);
18671 break;
18672 }
18673 break;
18674 default:
18675 generate_exception_end(ctx, EXCP_RI);
18676 break;
18677 }
18678
18679 tcg_temp_free(t0);
18680 tcg_temp_free(t1);
18681 tcg_temp_free(v0_t);
18682}
18683
8b3698b2
SM
18684static void gen_pool32axf_2_multiply(DisasContext *ctx, uint32_t opc,
18685 TCGv v0, TCGv v1, int rd)
18686{
18687 TCGv_i32 t0;
18688
18689 t0 = tcg_temp_new_i32();
18690
18691 tcg_gen_movi_i32(t0, rd >> 3);
18692
18693 switch (opc) {
18694 case NM_POOL32AXF_2_0_7:
18695 switch (extract32(ctx->opcode, 9, 3)) {
18696 case NM_DPA_W_PH:
908f6be1 18697 check_dsp_r2(ctx);
8b3698b2
SM
18698 gen_helper_dpa_w_ph(t0, v1, v0, cpu_env);
18699 break;
18700 case NM_DPAQ_S_W_PH:
18701 check_dsp(ctx);
18702 gen_helper_dpaq_s_w_ph(t0, v1, v0, cpu_env);
18703 break;
18704 case NM_DPS_W_PH:
908f6be1 18705 check_dsp_r2(ctx);
8b3698b2
SM
18706 gen_helper_dps_w_ph(t0, v1, v0, cpu_env);
18707 break;
18708 case NM_DPSQ_S_W_PH:
18709 check_dsp(ctx);
18710 gen_helper_dpsq_s_w_ph(t0, v1, v0, cpu_env);
18711 break;
18712 default:
18713 generate_exception_end(ctx, EXCP_RI);
18714 break;
18715 }
18716 break;
18717 case NM_POOL32AXF_2_8_15:
18718 switch (extract32(ctx->opcode, 9, 3)) {
18719 case NM_DPAX_W_PH:
908f6be1 18720 check_dsp_r2(ctx);
8b3698b2
SM
18721 gen_helper_dpax_w_ph(t0, v0, v1, cpu_env);
18722 break;
18723 case NM_DPAQ_SA_L_W:
18724 check_dsp(ctx);
18725 gen_helper_dpaq_sa_l_w(t0, v0, v1, cpu_env);
18726 break;
18727 case NM_DPSX_W_PH:
908f6be1 18728 check_dsp_r2(ctx);
8b3698b2
SM
18729 gen_helper_dpsx_w_ph(t0, v0, v1, cpu_env);
18730 break;
18731 case NM_DPSQ_SA_L_W:
18732 check_dsp(ctx);
18733 gen_helper_dpsq_sa_l_w(t0, v0, v1, cpu_env);
18734 break;
18735 default:
18736 generate_exception_end(ctx, EXCP_RI);
18737 break;
18738 }
18739 break;
18740 case NM_POOL32AXF_2_16_23:
18741 switch (extract32(ctx->opcode, 9, 3)) {
18742 case NM_DPAU_H_QBL:
18743 check_dsp(ctx);
18744 gen_helper_dpau_h_qbl(t0, v0, v1, cpu_env);
18745 break;
18746 case NM_DPAQX_S_W_PH:
908f6be1 18747 check_dsp_r2(ctx);
8b3698b2
SM
18748 gen_helper_dpaqx_s_w_ph(t0, v0, v1, cpu_env);
18749 break;
18750 case NM_DPSU_H_QBL:
18751 check_dsp(ctx);
18752 gen_helper_dpsu_h_qbl(t0, v0, v1, cpu_env);
18753 break;
18754 case NM_DPSQX_S_W_PH:
908f6be1 18755 check_dsp_r2(ctx);
8b3698b2
SM
18756 gen_helper_dpsqx_s_w_ph(t0, v0, v1, cpu_env);
18757 break;
18758 case NM_MULSA_W_PH:
908f6be1 18759 check_dsp_r2(ctx);
8b3698b2
SM
18760 gen_helper_mulsa_w_ph(t0, v0, v1, cpu_env);
18761 break;
18762 default:
18763 generate_exception_end(ctx, EXCP_RI);
18764 break;
18765 }
18766 break;
18767 case NM_POOL32AXF_2_24_31:
18768 switch (extract32(ctx->opcode, 9, 3)) {
18769 case NM_DPAU_H_QBR:
18770 check_dsp(ctx);
18771 gen_helper_dpau_h_qbr(t0, v1, v0, cpu_env);
18772 break;
18773 case NM_DPAQX_SA_W_PH:
908f6be1 18774 check_dsp_r2(ctx);
8b3698b2
SM
18775 gen_helper_dpaqx_sa_w_ph(t0, v1, v0, cpu_env);
18776 break;
18777 case NM_DPSU_H_QBR:
18778 check_dsp(ctx);
18779 gen_helper_dpsu_h_qbr(t0, v1, v0, cpu_env);
18780 break;
18781 case NM_DPSQX_SA_W_PH:
908f6be1 18782 check_dsp_r2(ctx);
8b3698b2
SM
18783 gen_helper_dpsqx_sa_w_ph(t0, v1, v0, cpu_env);
18784 break;
18785 case NM_MULSAQ_S_W_PH:
18786 check_dsp(ctx);
18787 gen_helper_mulsaq_s_w_ph(t0, v1, v0, cpu_env);
18788 break;
18789 default:
18790 generate_exception_end(ctx, EXCP_RI);
18791 break;
18792 }
18793 break;
18794 default:
18795 generate_exception_end(ctx, EXCP_RI);
18796 break;
18797 }
18798
18799 tcg_temp_free_i32(t0);
18800}
18801
18802static void gen_pool32axf_2_nanomips_insn(DisasContext *ctx, uint32_t opc,
18803 int rt, int rs, int rd)
18804{
18805 int ret = rt;
18806 TCGv t0 = tcg_temp_new();
18807 TCGv t1 = tcg_temp_new();
18808 TCGv v0_t = tcg_temp_new();
18809 TCGv v1_t = tcg_temp_new();
18810
18811 gen_load_gpr(v0_t, rt);
18812 gen_load_gpr(v1_t, rs);
18813
18814 switch (opc) {
18815 case NM_POOL32AXF_2_0_7:
18816 switch (extract32(ctx->opcode, 9, 3)) {
18817 case NM_DPA_W_PH:
18818 case NM_DPAQ_S_W_PH:
18819 case NM_DPS_W_PH:
18820 case NM_DPSQ_S_W_PH:
18821 gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
18822 break;
18823 case NM_BALIGN:
908f6be1 18824 check_dsp_r2(ctx);
8b3698b2
SM
18825 if (rt != 0) {
18826 gen_load_gpr(t0, rs);
18827 rd &= 3;
18828 if (rd != 0 && rd != 2) {
18829 tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 8 * rd);
18830 tcg_gen_ext32u_tl(t0, t0);
18831 tcg_gen_shri_tl(t0, t0, 8 * (4 - rd));
18832 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
18833 }
18834 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
18835 }
18836 break;
18837 case NM_MADD:
18838 check_dsp(ctx);
18839 {
18840 int acc = extract32(ctx->opcode, 14, 2);
18841 TCGv_i64 t2 = tcg_temp_new_i64();
18842 TCGv_i64 t3 = tcg_temp_new_i64();
18843
18844 gen_load_gpr(t0, rt);
18845 gen_load_gpr(t1, rs);
18846 tcg_gen_ext_tl_i64(t2, t0);
18847 tcg_gen_ext_tl_i64(t3, t1);
18848 tcg_gen_mul_i64(t2, t2, t3);
18849 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
18850 tcg_gen_add_i64(t2, t2, t3);
18851 tcg_temp_free_i64(t3);
18852 gen_move_low32(cpu_LO[acc], t2);
18853 gen_move_high32(cpu_HI[acc], t2);
18854 tcg_temp_free_i64(t2);
18855 }
18856 break;
18857 case NM_MULT:
18858 check_dsp(ctx);
18859 {
18860 int acc = extract32(ctx->opcode, 14, 2);
18861 TCGv_i32 t2 = tcg_temp_new_i32();
18862 TCGv_i32 t3 = tcg_temp_new_i32();
18863
18864 gen_load_gpr(t0, rs);
18865 gen_load_gpr(t1, rt);
18866 tcg_gen_trunc_tl_i32(t2, t0);
18867 tcg_gen_trunc_tl_i32(t3, t1);
18868 tcg_gen_muls2_i32(t2, t3, t2, t3);
18869 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
18870 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
18871 tcg_temp_free_i32(t2);
18872 tcg_temp_free_i32(t3);
18873 }
18874 break;
18875 case NM_EXTRV_W:
18876 check_dsp(ctx);
18877 gen_load_gpr(v1_t, rs);
18878 tcg_gen_movi_tl(t0, rd >> 3);
18879 gen_helper_extr_w(t0, t0, v1_t, cpu_env);
18880 gen_store_gpr(t0, ret);
18881 break;
18882 }
18883 break;
18884 case NM_POOL32AXF_2_8_15:
18885 switch (extract32(ctx->opcode, 9, 3)) {
18886 case NM_DPAX_W_PH:
18887 case NM_DPAQ_SA_L_W:
18888 case NM_DPSX_W_PH:
18889 case NM_DPSQ_SA_L_W:
18890 gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
18891 break;
18892 case NM_MADDU:
18893 check_dsp(ctx);
18894 {
18895 int acc = extract32(ctx->opcode, 14, 2);
18896 TCGv_i64 t2 = tcg_temp_new_i64();
18897 TCGv_i64 t3 = tcg_temp_new_i64();
18898
18899 gen_load_gpr(t0, rs);
18900 gen_load_gpr(t1, rt);
18901 tcg_gen_ext32u_tl(t0, t0);
18902 tcg_gen_ext32u_tl(t1, t1);
18903 tcg_gen_extu_tl_i64(t2, t0);
18904 tcg_gen_extu_tl_i64(t3, t1);
18905 tcg_gen_mul_i64(t2, t2, t3);
18906 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
18907 tcg_gen_add_i64(t2, t2, t3);
18908 tcg_temp_free_i64(t3);
18909 gen_move_low32(cpu_LO[acc], t2);
18910 gen_move_high32(cpu_HI[acc], t2);
18911 tcg_temp_free_i64(t2);
18912 }
18913 break;
18914 case NM_MULTU:
18915 check_dsp(ctx);
18916 {
18917 int acc = extract32(ctx->opcode, 14, 2);
18918 TCGv_i32 t2 = tcg_temp_new_i32();
18919 TCGv_i32 t3 = tcg_temp_new_i32();
18920
18921 gen_load_gpr(t0, rs);
18922 gen_load_gpr(t1, rt);
18923 tcg_gen_trunc_tl_i32(t2, t0);
18924 tcg_gen_trunc_tl_i32(t3, t1);
18925 tcg_gen_mulu2_i32(t2, t3, t2, t3);
18926 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
18927 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
18928 tcg_temp_free_i32(t2);
18929 tcg_temp_free_i32(t3);
18930 }
18931 break;
18932 case NM_EXTRV_R_W:
18933 check_dsp(ctx);
18934 tcg_gen_movi_tl(t0, rd >> 3);
18935 gen_helper_extr_r_w(t0, t0, v1_t, cpu_env);
18936 gen_store_gpr(t0, ret);
18937 break;
18938 default:
18939 generate_exception_end(ctx, EXCP_RI);
18940 break;
18941 }
18942 break;
18943 case NM_POOL32AXF_2_16_23:
18944 switch (extract32(ctx->opcode, 9, 3)) {
18945 case NM_DPAU_H_QBL:
18946 case NM_DPAQX_S_W_PH:
18947 case NM_DPSU_H_QBL:
18948 case NM_DPSQX_S_W_PH:
18949 case NM_MULSA_W_PH:
18950 gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
18951 break;
18952 case NM_EXTPV:
18953 check_dsp(ctx);
18954 tcg_gen_movi_tl(t0, rd >> 3);
18955 gen_helper_extp(t0, t0, v1_t, cpu_env);
18956 gen_store_gpr(t0, ret);
18957 break;
18958 case NM_MSUB:
18959 check_dsp(ctx);
18960 {
18961 int acc = extract32(ctx->opcode, 14, 2);
18962 TCGv_i64 t2 = tcg_temp_new_i64();
18963 TCGv_i64 t3 = tcg_temp_new_i64();
18964
18965 gen_load_gpr(t0, rs);
18966 gen_load_gpr(t1, rt);
18967 tcg_gen_ext_tl_i64(t2, t0);
18968 tcg_gen_ext_tl_i64(t3, t1);
18969 tcg_gen_mul_i64(t2, t2, t3);
18970 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
18971 tcg_gen_sub_i64(t2, t3, t2);
18972 tcg_temp_free_i64(t3);
18973 gen_move_low32(cpu_LO[acc], t2);
18974 gen_move_high32(cpu_HI[acc], t2);
18975 tcg_temp_free_i64(t2);
18976 }
18977 break;
18978 case NM_EXTRV_RS_W:
18979 check_dsp(ctx);
18980 tcg_gen_movi_tl(t0, rd >> 3);
18981 gen_helper_extr_rs_w(t0, t0, v1_t, cpu_env);
18982 gen_store_gpr(t0, ret);
18983 break;
18984 }
18985 break;
18986 case NM_POOL32AXF_2_24_31:
18987 switch (extract32(ctx->opcode, 9, 3)) {
18988 case NM_DPAU_H_QBR:
18989 case NM_DPAQX_SA_W_PH:
18990 case NM_DPSU_H_QBR:
18991 case NM_DPSQX_SA_W_PH:
18992 case NM_MULSAQ_S_W_PH:
18993 gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
18994 break;
18995 case NM_EXTPDPV:
18996 check_dsp(ctx);
18997 tcg_gen_movi_tl(t0, rd >> 3);
18998 gen_helper_extpdp(t0, t0, v1_t, cpu_env);
18999 gen_store_gpr(t0, ret);
19000 break;
19001 case NM_MSUBU:
19002 check_dsp(ctx);
19003 {
19004 int acc = extract32(ctx->opcode, 14, 2);
19005 TCGv_i64 t2 = tcg_temp_new_i64();
19006 TCGv_i64 t3 = tcg_temp_new_i64();
19007
19008 gen_load_gpr(t0, rs);
19009 gen_load_gpr(t1, rt);
19010 tcg_gen_ext32u_tl(t0, t0);
19011 tcg_gen_ext32u_tl(t1, t1);
19012 tcg_gen_extu_tl_i64(t2, t0);
19013 tcg_gen_extu_tl_i64(t3, t1);
19014 tcg_gen_mul_i64(t2, t2, t3);
19015 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
19016 tcg_gen_sub_i64(t2, t3, t2);
19017 tcg_temp_free_i64(t3);
19018 gen_move_low32(cpu_LO[acc], t2);
19019 gen_move_high32(cpu_HI[acc], t2);
19020 tcg_temp_free_i64(t2);
19021 }
19022 break;
19023 case NM_EXTRV_S_H:
19024 check_dsp(ctx);
19025 tcg_gen_movi_tl(t0, rd >> 3);
19026 gen_helper_extr_s_h(t0, t0, v0_t, cpu_env);
19027 gen_store_gpr(t0, ret);
19028 break;
19029 }
19030 break;
19031 default:
19032 generate_exception_end(ctx, EXCP_RI);
19033 break;
19034 }
19035
19036 tcg_temp_free(t0);
19037 tcg_temp_free(t1);
19038
19039 tcg_temp_free(v0_t);
19040 tcg_temp_free(v1_t);
19041}
19042
4c75c985
SM
19043static void gen_pool32axf_4_nanomips_insn(DisasContext *ctx, uint32_t opc,
19044 int rt, int rs)
19045{
19046 int ret = rt;
19047 TCGv t0 = tcg_temp_new();
19048 TCGv v0_t = tcg_temp_new();
19049
19050 gen_load_gpr(v0_t, rs);
19051
19052 switch (opc) {
19053 case NM_ABSQ_S_QB:
908f6be1 19054 check_dsp_r2(ctx);
4c75c985
SM
19055 gen_helper_absq_s_qb(v0_t, v0_t, cpu_env);
19056 gen_store_gpr(v0_t, ret);
19057 break;
19058 case NM_ABSQ_S_PH:
19059 check_dsp(ctx);
19060 gen_helper_absq_s_ph(v0_t, v0_t, cpu_env);
19061 gen_store_gpr(v0_t, ret);
19062 break;
19063 case NM_ABSQ_S_W:
19064 check_dsp(ctx);
19065 gen_helper_absq_s_w(v0_t, v0_t, cpu_env);
19066 gen_store_gpr(v0_t, ret);
19067 break;
19068 case NM_PRECEQ_W_PHL:
19069 check_dsp(ctx);
19070 tcg_gen_andi_tl(v0_t, v0_t, 0xFFFF0000);
19071 tcg_gen_ext32s_tl(v0_t, v0_t);
19072 gen_store_gpr(v0_t, ret);
19073 break;
19074 case NM_PRECEQ_W_PHR:
19075 check_dsp(ctx);
19076 tcg_gen_andi_tl(v0_t, v0_t, 0x0000FFFF);
19077 tcg_gen_shli_tl(v0_t, v0_t, 16);
19078 tcg_gen_ext32s_tl(v0_t, v0_t);
19079 gen_store_gpr(v0_t, ret);
19080 break;
19081 case NM_PRECEQU_PH_QBL:
19082 check_dsp(ctx);
19083 gen_helper_precequ_ph_qbl(v0_t, v0_t);
19084 gen_store_gpr(v0_t, ret);
19085 break;
19086 case NM_PRECEQU_PH_QBR:
19087 check_dsp(ctx);
19088 gen_helper_precequ_ph_qbr(v0_t, v0_t);
19089 gen_store_gpr(v0_t, ret);
19090 break;
19091 case NM_PRECEQU_PH_QBLA:
19092 check_dsp(ctx);
19093 gen_helper_precequ_ph_qbla(v0_t, v0_t);
19094 gen_store_gpr(v0_t, ret);
19095 break;
19096 case NM_PRECEQU_PH_QBRA:
19097 check_dsp(ctx);
19098 gen_helper_precequ_ph_qbra(v0_t, v0_t);
19099 gen_store_gpr(v0_t, ret);
19100 break;
19101 case NM_PRECEU_PH_QBL:
19102 check_dsp(ctx);
19103 gen_helper_preceu_ph_qbl(v0_t, v0_t);
19104 gen_store_gpr(v0_t, ret);
19105 break;
19106 case NM_PRECEU_PH_QBR:
19107 check_dsp(ctx);
19108 gen_helper_preceu_ph_qbr(v0_t, v0_t);
19109 gen_store_gpr(v0_t, ret);
19110 break;
19111 case NM_PRECEU_PH_QBLA:
19112 check_dsp(ctx);
19113 gen_helper_preceu_ph_qbla(v0_t, v0_t);
19114 gen_store_gpr(v0_t, ret);
19115 break;
19116 case NM_PRECEU_PH_QBRA:
19117 check_dsp(ctx);
19118 gen_helper_preceu_ph_qbra(v0_t, v0_t);
19119 gen_store_gpr(v0_t, ret);
19120 break;
19121 case NM_REPLV_PH:
19122 check_dsp(ctx);
19123 tcg_gen_ext16u_tl(v0_t, v0_t);
19124 tcg_gen_shli_tl(t0, v0_t, 16);
19125 tcg_gen_or_tl(v0_t, v0_t, t0);
19126 tcg_gen_ext32s_tl(v0_t, v0_t);
19127 gen_store_gpr(v0_t, ret);
19128 break;
19129 case NM_REPLV_QB:
19130 check_dsp(ctx);
19131 tcg_gen_ext8u_tl(v0_t, v0_t);
19132 tcg_gen_shli_tl(t0, v0_t, 8);
19133 tcg_gen_or_tl(v0_t, v0_t, t0);
19134 tcg_gen_shli_tl(t0, v0_t, 16);
19135 tcg_gen_or_tl(v0_t, v0_t, t0);
19136 tcg_gen_ext32s_tl(v0_t, v0_t);
19137 gen_store_gpr(v0_t, ret);
19138 break;
19139 case NM_BITREV:
19140 check_dsp(ctx);
19141 gen_helper_bitrev(v0_t, v0_t);
19142 gen_store_gpr(v0_t, ret);
19143 break;
19144 case NM_INSV:
19145 check_dsp(ctx);
19146 {
19147 TCGv tv0 = tcg_temp_new();
19148
19149 gen_load_gpr(tv0, rt);
19150 gen_helper_insv(v0_t, cpu_env, v0_t, tv0);
19151 gen_store_gpr(v0_t, ret);
19152 tcg_temp_free(tv0);
19153 }
19154 break;
19155 case NM_RADDU_W_QB:
19156 check_dsp(ctx);
19157 gen_helper_raddu_w_qb(v0_t, v0_t);
19158 gen_store_gpr(v0_t, ret);
19159 break;
19160 case NM_BITSWAP:
19161 gen_bitswap(ctx, OPC_BITSWAP, ret, rs);
19162 break;
19163 case NM_CLO:
fb32f8c8 19164 check_nms(ctx);
4c75c985
SM
19165 gen_cl(ctx, OPC_CLO, ret, rs);
19166 break;
19167 case NM_CLZ:
fb32f8c8 19168 check_nms(ctx);
4c75c985
SM
19169 gen_cl(ctx, OPC_CLZ, ret, rs);
19170 break;
19171 case NM_WSBH:
19172 gen_bshfl(ctx, OPC_WSBH, ret, rs);
19173 break;
19174 default:
19175 generate_exception_end(ctx, EXCP_RI);
19176 break;
19177 }
19178
19179 tcg_temp_free(v0_t);
19180 tcg_temp_free(t0);
19181}
19182
0b591184
SM
19183static void gen_pool32axf_7_nanomips_insn(DisasContext *ctx, uint32_t opc,
19184 int rt, int rs, int rd)
19185{
19186 TCGv t0 = tcg_temp_new();
19187 TCGv rs_t = tcg_temp_new();
19188
19189 gen_load_gpr(rs_t, rs);
19190
19191 switch (opc) {
19192 case NM_SHRA_R_QB:
908f6be1 19193 check_dsp_r2(ctx);
0b591184
SM
19194 tcg_gen_movi_tl(t0, rd >> 2);
19195 switch (extract32(ctx->opcode, 12, 1)) {
19196 case 0:
19197 /* NM_SHRA_QB */
19198 gen_helper_shra_qb(t0, t0, rs_t);
19199 gen_store_gpr(t0, rt);
19200 break;
19201 case 1:
19202 /* NM_SHRA_R_QB */
19203 gen_helper_shra_r_qb(t0, t0, rs_t);
19204 gen_store_gpr(t0, rt);
19205 break;
19206 }
19207 break;
19208 case NM_SHRL_PH:
908f6be1 19209 check_dsp_r2(ctx);
0b591184
SM
19210 tcg_gen_movi_tl(t0, rd >> 1);
19211 gen_helper_shrl_ph(t0, t0, rs_t);
19212 gen_store_gpr(t0, rt);
19213 break;
19214 case NM_REPL_QB:
19215 check_dsp(ctx);
19216 {
19217 int16_t imm;
19218 target_long result;
19219 imm = extract32(ctx->opcode, 13, 8);
19220 result = (uint32_t)imm << 24 |
19221 (uint32_t)imm << 16 |
19222 (uint32_t)imm << 8 |
19223 (uint32_t)imm;
19224 result = (int32_t)result;
19225 tcg_gen_movi_tl(t0, result);
19226 gen_store_gpr(t0, rt);
19227 }
19228 break;
19229 default:
19230 generate_exception_end(ctx, EXCP_RI);
19231 break;
19232 }
19233 tcg_temp_free(t0);
19234 tcg_temp_free(rs_t);
19235}
19236
2ed42efa 19237
64224187
YK
19238static void gen_pool32axf_nanomips_insn(CPUMIPSState *env, DisasContext *ctx)
19239{
64224187
YK
19240 int rt = extract32(ctx->opcode, 21, 5);
19241 int rs = extract32(ctx->opcode, 16, 5);
2ed42efa 19242 int rd = extract32(ctx->opcode, 11, 5);
64224187
YK
19243
19244 switch (extract32(ctx->opcode, 6, 3)) {
2ed42efa
SM
19245 case NM_POOL32AXF_1:
19246 {
19247 int32_t op1 = extract32(ctx->opcode, 9, 3);
19248 gen_pool32axf_1_nanomips_insn(ctx, op1, rt, rs, rd);
19249 }
19250 break;
19251 case NM_POOL32AXF_2:
8b3698b2
SM
19252 {
19253 int32_t op1 = extract32(ctx->opcode, 12, 2);
19254 gen_pool32axf_2_nanomips_insn(ctx, op1, rt, rs, rd);
19255 }
2ed42efa 19256 break;
64224187 19257 case NM_POOL32AXF_4:
4c75c985
SM
19258 {
19259 int32_t op1 = extract32(ctx->opcode, 9, 7);
19260 gen_pool32axf_4_nanomips_insn(ctx, op1, rt, rs);
19261 }
2ed42efa 19262 break;
64224187
YK
19263 case NM_POOL32AXF_5:
19264 switch (extract32(ctx->opcode, 9, 7)) {
19265#ifndef CONFIG_USER_ONLY
19266 case NM_TLBP:
19267 gen_cp0(env, ctx, OPC_TLBP, 0, 0);
19268 break;
19269 case NM_TLBR:
19270 gen_cp0(env, ctx, OPC_TLBR, 0, 0);
19271 break;
19272 case NM_TLBWI:
19273 gen_cp0(env, ctx, OPC_TLBWI, 0, 0);
19274 break;
19275 case NM_TLBWR:
19276 gen_cp0(env, ctx, OPC_TLBWR, 0, 0);
19277 break;
19278 case NM_TLBINV:
19279 gen_cp0(env, ctx, OPC_TLBINV, 0, 0);
19280 break;
19281 case NM_TLBINVF:
19282 gen_cp0(env, ctx, OPC_TLBINVF, 0, 0);
19283 break;
19284 case NM_DI:
19285 check_cp0_enabled(ctx);
19286 {
19287 TCGv t0 = tcg_temp_new();
19288
19289 save_cpu_state(ctx, 1);
19290 gen_helper_di(t0, cpu_env);
19291 gen_store_gpr(t0, rt);
19292 /* Stop translation as we may have switched the execution mode */
19293 ctx->base.is_jmp = DISAS_STOP;
19294 tcg_temp_free(t0);
19295 }
19296 break;
19297 case NM_EI:
19298 check_cp0_enabled(ctx);
19299 {
19300 TCGv t0 = tcg_temp_new();
19301
19302 save_cpu_state(ctx, 1);
19303 gen_helper_ei(t0, cpu_env);
19304 gen_store_gpr(t0, rt);
19305 /* Stop translation as we may have switched the execution mode */
19306 ctx->base.is_jmp = DISAS_STOP;
19307 tcg_temp_free(t0);
19308 }
19309 break;
19310 case NM_RDPGPR:
19311 gen_load_srsgpr(rs, rt);
19312 break;
19313 case NM_WRPGPR:
19314 gen_store_srsgpr(rs, rt);
19315 break;
19316 case NM_WAIT:
19317 gen_cp0(env, ctx, OPC_WAIT, 0, 0);
19318 break;
19319 case NM_DERET:
19320 gen_cp0(env, ctx, OPC_DERET, 0, 0);
19321 break;
19322 case NM_ERETX:
19323 gen_cp0(env, ctx, OPC_ERET, 0, 0);
19324 break;
19325#endif
19326 default:
19327 generate_exception_end(ctx, EXCP_RI);
19328 break;
19329 }
19330 break;
2ed42efa 19331 case NM_POOL32AXF_7:
0b591184
SM
19332 {
19333 int32_t op1 = extract32(ctx->opcode, 9, 3);
19334 gen_pool32axf_7_nanomips_insn(ctx, op1, rt, rs, rd);
19335 }
2ed42efa 19336 break;
64224187
YK
19337 default:
19338 generate_exception_end(ctx, EXCP_RI);
19339 break;
19340 }
19341}
19342
11d0fc10
SM
19343/* Immediate Value Compact Branches */
19344static void gen_compute_imm_branch(DisasContext *ctx, uint32_t opc,
19345 int rt, int32_t imm, int32_t offset)
19346{
19347 TCGCond cond;
19348 int bcond_compute = 0;
19349 TCGv t0 = tcg_temp_new();
19350 TCGv t1 = tcg_temp_new();
19351
19352 gen_load_gpr(t0, rt);
19353 tcg_gen_movi_tl(t1, imm);
19354 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
19355
19356 /* Load needed operands and calculate btarget */
19357 switch (opc) {
19358 case NM_BEQIC:
19359 if (rt == 0 && imm == 0) {
19360 /* Unconditional branch */
19361 } else if (rt == 0 && imm != 0) {
19362 /* Treat as NOP */
19363 goto out;
19364 } else {
19365 bcond_compute = 1;
19366 cond = TCG_COND_EQ;
19367 }
19368 break;
19369 case NM_BBEQZC:
19370 case NM_BBNEZC:
fb32f8c8 19371 check_nms(ctx);
11d0fc10
SM
19372 if (imm >= 32 && !(ctx->hflags & MIPS_HFLAG_64)) {
19373 generate_exception_end(ctx, EXCP_RI);
19374 goto out;
19375 } else if (rt == 0 && opc == NM_BBEQZC) {
19376 /* Unconditional branch */
19377 } else if (rt == 0 && opc == NM_BBNEZC) {
19378 /* Treat as NOP */
19379 goto out;
19380 } else {
19381 tcg_gen_shri_tl(t0, t0, imm);
19382 tcg_gen_andi_tl(t0, t0, 1);
19383 tcg_gen_movi_tl(t1, 0);
19384 bcond_compute = 1;
19385 if (opc == NM_BBEQZC) {
19386 cond = TCG_COND_EQ;
19387 } else {
19388 cond = TCG_COND_NE;
19389 }
19390 }
19391 break;
19392 case NM_BNEIC:
19393 if (rt == 0 && imm == 0) {
19394 /* Treat as NOP */
19395 goto out;
19396 } else if (rt == 0 && imm != 0) {
19397 /* Unconditional branch */
19398 } else {
19399 bcond_compute = 1;
19400 cond = TCG_COND_NE;
19401 }
19402 break;
19403 case NM_BGEIC:
19404 if (rt == 0 && imm == 0) {
19405 /* Unconditional branch */
19406 } else {
19407 bcond_compute = 1;
19408 cond = TCG_COND_GE;
19409 }
19410 break;
19411 case NM_BLTIC:
19412 bcond_compute = 1;
19413 cond = TCG_COND_LT;
19414 break;
19415 case NM_BGEIUC:
19416 if (rt == 0 && imm == 0) {
19417 /* Unconditional branch */
19418 } else {
19419 bcond_compute = 1;
19420 cond = TCG_COND_GEU;
19421 }
19422 break;
19423 case NM_BLTIUC:
19424 bcond_compute = 1;
19425 cond = TCG_COND_LTU;
19426 break;
19427 default:
19428 MIPS_INVAL("Immediate Value Compact branch");
19429 generate_exception_end(ctx, EXCP_RI);
19430 goto out;
19431 }
19432
19433 if (bcond_compute == 0) {
19434 /* Uncoditional compact branch */
19435 gen_goto_tb(ctx, 0, ctx->btarget);
19436 } else {
19437 /* Conditional compact branch */
19438 TCGLabel *fs = gen_new_label();
19439
19440 tcg_gen_brcond_tl(tcg_invert_cond(cond), t0, t1, fs);
19441
19442 gen_goto_tb(ctx, 1, ctx->btarget);
19443 gen_set_label(fs);
19444
19445 gen_goto_tb(ctx, 0, ctx->base.pc_next + 4);
19446 }
19447
19448out:
19449 tcg_temp_free(t0);
19450 tcg_temp_free(t1);
19451}
19452
19453/* P.BALRSC type nanoMIPS R6 branches: BALRSC and BRSC */
19454static void gen_compute_nanomips_pbalrsc_branch(DisasContext *ctx, int rs,
19455 int rt)
19456{
19457 TCGv t0 = tcg_temp_new();
19458 TCGv t1 = tcg_temp_new();
19459
19460 /* load rs */
19461 gen_load_gpr(t0, rs);
19462
19463 /* link */
19464 if (rt != 0) {
19465 tcg_gen_movi_tl(cpu_gpr[rt], ctx->base.pc_next + 4);
19466 }
19467
19468 /* calculate btarget */
19469 tcg_gen_shli_tl(t0, t0, 1);
19470 tcg_gen_movi_tl(t1, ctx->base.pc_next + 4);
19471 gen_op_addr_add(ctx, btarget, t1, t0);
19472
19473 /* unconditional branch to register */
19474 tcg_gen_mov_tl(cpu_PC, btarget);
19475 tcg_gen_lookup_and_goto_ptr();
19476
19477 tcg_temp_free(t0);
19478 tcg_temp_free(t1);
19479}
19480
19481/* nanoMIPS Branches */
19482static void gen_compute_compact_branch_nm(DisasContext *ctx, uint32_t opc,
19483 int rs, int rt, int32_t offset)
19484{
19485 int bcond_compute = 0;
19486 TCGv t0 = tcg_temp_new();
19487 TCGv t1 = tcg_temp_new();
19488
19489 /* Load needed operands and calculate btarget */
19490 switch (opc) {
19491 /* compact branch */
19492 case OPC_BGEC:
19493 case OPC_BLTC:
19494 gen_load_gpr(t0, rs);
19495 gen_load_gpr(t1, rt);
19496 bcond_compute = 1;
19497 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
19498 break;
19499 case OPC_BGEUC:
19500 case OPC_BLTUC:
19501 if (rs == 0 || rs == rt) {
19502 /* OPC_BLEZALC, OPC_BGEZALC */
19503 /* OPC_BGTZALC, OPC_BLTZALC */
19504 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4);
19505 }
19506 gen_load_gpr(t0, rs);
19507 gen_load_gpr(t1, rt);
19508 bcond_compute = 1;
19509 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
19510 break;
19511 case OPC_BC:
19512 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
19513 break;
19514 case OPC_BEQZC:
19515 if (rs != 0) {
19516 /* OPC_BEQZC, OPC_BNEZC */
19517 gen_load_gpr(t0, rs);
19518 bcond_compute = 1;
19519 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
19520 } else {
19521 /* OPC_JIC, OPC_JIALC */
19522 TCGv tbase = tcg_temp_new();
19523 TCGv toffset = tcg_temp_new();
19524
19525 gen_load_gpr(tbase, rt);
19526 tcg_gen_movi_tl(toffset, offset);
19527 gen_op_addr_add(ctx, btarget, tbase, toffset);
19528 tcg_temp_free(tbase);
19529 tcg_temp_free(toffset);
19530 }
19531 break;
19532 default:
19533 MIPS_INVAL("Compact branch/jump");
19534 generate_exception_end(ctx, EXCP_RI);
19535 goto out;
19536 }
19537
19538 if (bcond_compute == 0) {
19539 /* Uncoditional compact branch */
19540 switch (opc) {
19541 case OPC_BC:
19542 gen_goto_tb(ctx, 0, ctx->btarget);
19543 break;
19544 default:
19545 MIPS_INVAL("Compact branch/jump");
19546 generate_exception_end(ctx, EXCP_RI);
19547 goto out;
19548 }
19549 } else {
19550 /* Conditional compact branch */
19551 TCGLabel *fs = gen_new_label();
19552
19553 switch (opc) {
19554 case OPC_BGEUC:
19555 if (rs == 0 && rt != 0) {
19556 /* OPC_BLEZALC */
19557 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
19558 } else if (rs != 0 && rt != 0 && rs == rt) {
19559 /* OPC_BGEZALC */
19560 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
19561 } else {
19562 /* OPC_BGEUC */
19563 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU), t0, t1, fs);
19564 }
19565 break;
19566 case OPC_BLTUC:
19567 if (rs == 0 && rt != 0) {
19568 /* OPC_BGTZALC */
19569 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
19570 } else if (rs != 0 && rt != 0 && rs == rt) {
19571 /* OPC_BLTZALC */
19572 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
19573 } else {
19574 /* OPC_BLTUC */
19575 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU), t0, t1, fs);
19576 }
19577 break;
19578 case OPC_BGEC:
19579 if (rs == 0 && rt != 0) {
19580 /* OPC_BLEZC */
19581 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
19582 } else if (rs != 0 && rt != 0 && rs == rt) {
19583 /* OPC_BGEZC */
19584 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
19585 } else {
19586 /* OPC_BGEC */
19587 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE), t0, t1, fs);
19588 }
19589 break;
19590 case OPC_BLTC:
19591 if (rs == 0 && rt != 0) {
19592 /* OPC_BGTZC */
19593 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
19594 } else if (rs != 0 && rt != 0 && rs == rt) {
19595 /* OPC_BLTZC */
19596 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
19597 } else {
19598 /* OPC_BLTC */
19599 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT), t0, t1, fs);
19600 }
19601 break;
19602 case OPC_BEQZC:
19603 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t0, 0, fs);
19604 break;
19605 default:
19606 MIPS_INVAL("Compact conditional branch/jump");
19607 generate_exception_end(ctx, EXCP_RI);
19608 goto out;
19609 }
19610
19611 /* Generating branch here as compact branches don't have delay slot */
19612 gen_goto_tb(ctx, 1, ctx->btarget);
19613 gen_set_label(fs);
19614
19615 gen_goto_tb(ctx, 0, ctx->base.pc_next + 4);
19616 }
19617
19618out:
19619 tcg_temp_free(t0);
19620 tcg_temp_free(t1);
19621}
19622
19623
19624/* nanoMIPS CP1 Branches */
19625static void gen_compute_branch_cp1_nm(DisasContext *ctx, uint32_t op,
19626 int32_t ft, int32_t offset)
19627{
19628 target_ulong btarget;
19629 TCGv_i64 t0 = tcg_temp_new_i64();
19630
19631 gen_load_fpr64(ctx, t0, ft);
19632 tcg_gen_andi_i64(t0, t0, 1);
19633
19634 btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
19635
19636 switch (op) {
19637 case NM_BC1EQZC:
19638 tcg_gen_xori_i64(t0, t0, 1);
19639 ctx->hflags |= MIPS_HFLAG_BC;
19640 break;
19641 case NM_BC1NEZC:
19642 /* t0 already set */
19643 ctx->hflags |= MIPS_HFLAG_BC;
19644 break;
19645 default:
19646 MIPS_INVAL("cp1 cond branch");
19647 generate_exception_end(ctx, EXCP_RI);
19648 goto out;
19649 }
19650
19651 tcg_gen_trunc_i64_tl(bcond, t0);
19652
19653 ctx->btarget = btarget;
19654
19655out:
19656 tcg_temp_free_i64(t0);
19657}
19658
eac52664
YK
19659
19660static void gen_p_lsx(DisasContext *ctx, int rd, int rs, int rt)
19661{
19662 TCGv t0, t1;
19663 t0 = tcg_temp_new();
19664 t1 = tcg_temp_new();
19665
19666 gen_load_gpr(t0, rs);
19667 gen_load_gpr(t1, rt);
19668
19669 if ((extract32(ctx->opcode, 6, 1)) == 1) {
19670 /* PP.LSXS instructions require shifting */
19671 switch (extract32(ctx->opcode, 7, 4)) {
eac52664 19672 case NM_SHXS:
fb32f8c8
DN
19673 check_nms(ctx);
19674 case NM_LHXS:
eac52664
YK
19675 case NM_LHUXS:
19676 tcg_gen_shli_tl(t0, t0, 1);
19677 break;
eac52664 19678 case NM_SWXS:
fb32f8c8
DN
19679 check_nms(ctx);
19680 case NM_LWXS:
eac52664
YK
19681 case NM_LWC1XS:
19682 case NM_SWC1XS:
19683 tcg_gen_shli_tl(t0, t0, 2);
19684 break;
19685 case NM_LDC1XS:
19686 case NM_SDC1XS:
19687 tcg_gen_shli_tl(t0, t0, 3);
19688 break;
19689 }
19690 }
19691 gen_op_addr_add(ctx, t0, t0, t1);
19692
19693 switch (extract32(ctx->opcode, 7, 4)) {
19694 case NM_LBX:
19695 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
19696 MO_SB);
19697 gen_store_gpr(t0, rd);
19698 break;
19699 case NM_LHX:
19700 /*case NM_LHXS:*/
19701 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
19702 MO_TESW);
19703 gen_store_gpr(t0, rd);
19704 break;
19705 case NM_LWX:
19706 /*case NM_LWXS:*/
19707 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
19708 MO_TESL);
19709 gen_store_gpr(t0, rd);
19710 break;
19711 case NM_LBUX:
19712 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
19713 MO_UB);
19714 gen_store_gpr(t0, rd);
19715 break;
19716 case NM_LHUX:
19717 /*case NM_LHUXS:*/
19718 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
19719 MO_TEUW);
19720 gen_store_gpr(t0, rd);
19721 break;
19722 case NM_SBX:
fb32f8c8 19723 check_nms(ctx);
eac52664
YK
19724 gen_load_gpr(t1, rd);
19725 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx,
19726 MO_8);
19727 break;
19728 case NM_SHX:
19729 /*case NM_SHXS:*/
fb32f8c8 19730 check_nms(ctx);
eac52664
YK
19731 gen_load_gpr(t1, rd);
19732 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx,
19733 MO_TEUW);
19734 break;
19735 case NM_SWX:
19736 /*case NM_SWXS:*/
fb32f8c8 19737 check_nms(ctx);
eac52664
YK
19738 gen_load_gpr(t1, rd);
19739 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx,
19740 MO_TEUL);
19741 break;
19742 case NM_LWC1X:
19743 /*case NM_LWC1XS:*/
19744 case NM_LDC1X:
19745 /*case NM_LDC1XS:*/
19746 case NM_SWC1X:
19747 /*case NM_SWC1XS:*/
19748 case NM_SDC1X:
19749 /*case NM_SDC1XS:*/
19750 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
19751 check_cp1_enabled(ctx);
19752 switch (extract32(ctx->opcode, 7, 4)) {
19753 case NM_LWC1X:
19754 /*case NM_LWC1XS:*/
19755 gen_flt_ldst(ctx, OPC_LWC1, rd, t0);
19756 break;
19757 case NM_LDC1X:
19758 /*case NM_LDC1XS:*/
19759 gen_flt_ldst(ctx, OPC_LDC1, rd, t0);
19760 break;
19761 case NM_SWC1X:
19762 /*case NM_SWC1XS:*/
19763 gen_flt_ldst(ctx, OPC_SWC1, rd, t0);
19764 break;
19765 case NM_SDC1X:
19766 /*case NM_SDC1XS:*/
19767 gen_flt_ldst(ctx, OPC_SDC1, rd, t0);
19768 break;
19769 }
19770 } else {
19771 generate_exception_err(ctx, EXCP_CpU, 1);
19772 }
19773 break;
19774 default:
19775 generate_exception_end(ctx, EXCP_RI);
19776 break;
19777 }
19778
19779 tcg_temp_free(t0);
19780 tcg_temp_free(t1);
19781}
19782
579b8ea9
YK
19783static void gen_pool32f_nanomips_insn(DisasContext *ctx)
19784{
19785 int rt, rs, rd;
19786
19787 rt = extract32(ctx->opcode, 21, 5);
19788 rs = extract32(ctx->opcode, 16, 5);
19789 rd = extract32(ctx->opcode, 11, 5);
19790
19791 if (!(ctx->CP0_Config1 & (1 << CP0C1_FP))) {
19792 generate_exception_end(ctx, EXCP_RI);
19793 return;
19794 }
19795 check_cp1_enabled(ctx);
19796 switch (extract32(ctx->opcode, 0, 3)) {
19797 case NM_POOL32F_0:
19798 switch (extract32(ctx->opcode, 3, 7)) {
19799 case NM_RINT_S:
19800 gen_farith(ctx, OPC_RINT_S, 0, rt, rs, 0);
19801 break;
19802 case NM_RINT_D:
19803 gen_farith(ctx, OPC_RINT_D, 0, rt, rs, 0);
19804 break;
19805 case NM_CLASS_S:
19806 gen_farith(ctx, OPC_CLASS_S, 0, rt, rs, 0);
19807 break;
19808 case NM_CLASS_D:
19809 gen_farith(ctx, OPC_CLASS_D, 0, rt, rs, 0);
19810 break;
19811 case NM_ADD_S:
19812 gen_farith(ctx, OPC_ADD_S, rt, rs, rd, 0);
19813 break;
19814 case NM_ADD_D:
19815 gen_farith(ctx, OPC_ADD_D, rt, rs, rd, 0);
19816 break;
19817 case NM_SUB_S:
19818 gen_farith(ctx, OPC_SUB_S, rt, rs, rd, 0);
19819 break;
19820 case NM_SUB_D:
19821 gen_farith(ctx, OPC_SUB_D, rt, rs, rd, 0);
19822 break;
19823 case NM_MUL_S:
19824 gen_farith(ctx, OPC_MUL_S, rt, rs, rd, 0);
19825 break;
19826 case NM_MUL_D:
19827 gen_farith(ctx, OPC_MUL_D, rt, rs, rd, 0);
19828 break;
19829 case NM_DIV_S:
19830 gen_farith(ctx, OPC_DIV_S, rt, rs, rd, 0);
19831 break;
19832 case NM_DIV_D:
19833 gen_farith(ctx, OPC_DIV_D, rt, rs, rd, 0);
19834 break;
19835 case NM_SELEQZ_S:
19836 gen_sel_s(ctx, OPC_SELEQZ_S, rd, rt, rs);
19837 break;
19838 case NM_SELEQZ_D:
19839 gen_sel_d(ctx, OPC_SELEQZ_D, rd, rt, rs);
19840 break;
19841 case NM_SELNEZ_S:
19842 gen_sel_s(ctx, OPC_SELNEZ_S, rd, rt, rs);
19843 break;
19844 case NM_SELNEZ_D:
19845 gen_sel_d(ctx, OPC_SELNEZ_D, rd, rt, rs);
19846 break;
19847 case NM_SEL_S:
19848 gen_sel_s(ctx, OPC_SEL_S, rd, rt, rs);
19849 break;
19850 case NM_SEL_D:
19851 gen_sel_d(ctx, OPC_SEL_D, rd, rt, rs);
19852 break;
19853 case NM_MADDF_S:
19854 gen_farith(ctx, OPC_MADDF_S, rt, rs, rd, 0);
19855 break;
19856 case NM_MADDF_D:
19857 gen_farith(ctx, OPC_MADDF_D, rt, rs, rd, 0);
19858 break;
19859 case NM_MSUBF_S:
19860 gen_farith(ctx, OPC_MSUBF_S, rt, rs, rd, 0);
19861 break;
19862 case NM_MSUBF_D:
19863 gen_farith(ctx, OPC_MSUBF_D, rt, rs, rd, 0);
19864 break;
19865 default:
19866 generate_exception_end(ctx, EXCP_RI);
19867 break;
19868 }
19869 break;
19870 case NM_POOL32F_3:
19871 switch (extract32(ctx->opcode, 3, 3)) {
19872 case NM_MIN_FMT:
19873 switch (extract32(ctx->opcode, 9, 1)) {
19874 case FMT_SDPS_S:
19875 gen_farith(ctx, OPC_MIN_S, rt, rs, rd, 0);
19876 break;
19877 case FMT_SDPS_D:
19878 gen_farith(ctx, OPC_MIN_D, rt, rs, rd, 0);
19879 break;
19880 }
19881 break;
19882 case NM_MAX_FMT:
19883 switch (extract32(ctx->opcode, 9, 1)) {
19884 case FMT_SDPS_S:
19885 gen_farith(ctx, OPC_MAX_S, rt, rs, rd, 0);
19886 break;
19887 case FMT_SDPS_D:
19888 gen_farith(ctx, OPC_MAX_D, rt, rs, rd, 0);
19889 break;
19890 }
19891 break;
19892 case NM_MINA_FMT:
19893 switch (extract32(ctx->opcode, 9, 1)) {
19894 case FMT_SDPS_S:
19895 gen_farith(ctx, OPC_MINA_S, rt, rs, rd, 0);
19896 break;
19897 case FMT_SDPS_D:
19898 gen_farith(ctx, OPC_MINA_D, rt, rs, rd, 0);
19899 break;
19900 }
19901 break;
19902 case NM_MAXA_FMT:
19903 switch (extract32(ctx->opcode, 9, 1)) {
19904 case FMT_SDPS_S:
19905 gen_farith(ctx, OPC_MAXA_S, rt, rs, rd, 0);
19906 break;
19907 case FMT_SDPS_D:
19908 gen_farith(ctx, OPC_MAXA_D, rt, rs, rd, 0);
19909 break;
19910 }
19911 break;
19912 case NM_POOL32FXF:
19913 switch (extract32(ctx->opcode, 6, 8)) {
19914 case NM_CFC1:
19915 gen_cp1(ctx, OPC_CFC1, rt, rs);
19916 break;
19917 case NM_CTC1:
19918 gen_cp1(ctx, OPC_CTC1, rt, rs);
19919 break;
19920 case NM_MFC1:
19921 gen_cp1(ctx, OPC_MFC1, rt, rs);
19922 break;
19923 case NM_MTC1:
19924 gen_cp1(ctx, OPC_MTC1, rt, rs);
19925 break;
19926 case NM_MFHC1:
19927 gen_cp1(ctx, OPC_MFHC1, rt, rs);
19928 break;
19929 case NM_MTHC1:
19930 gen_cp1(ctx, OPC_MTHC1, rt, rs);
19931 break;
19932 case NM_CVT_S_PL:
19933 gen_farith(ctx, OPC_CVT_S_PL, -1, rs, rt, 0);
19934 break;
19935 case NM_CVT_S_PU:
19936 gen_farith(ctx, OPC_CVT_S_PU, -1, rs, rt, 0);
19937 break;
19938 default:
19939 switch (extract32(ctx->opcode, 6, 9)) {
19940 case NM_CVT_L_S:
19941 gen_farith(ctx, OPC_CVT_L_S, -1, rs, rt, 0);
19942 break;
19943 case NM_CVT_L_D:
19944 gen_farith(ctx, OPC_CVT_L_D, -1, rs, rt, 0);
19945 break;
19946 case NM_CVT_W_S:
19947 gen_farith(ctx, OPC_CVT_W_S, -1, rs, rt, 0);
19948 break;
19949 case NM_CVT_W_D:
19950 gen_farith(ctx, OPC_CVT_W_D, -1, rs, rt, 0);
19951 break;
19952 case NM_RSQRT_S:
19953 gen_farith(ctx, OPC_RSQRT_S, -1, rs, rt, 0);
19954 break;
19955 case NM_RSQRT_D:
19956 gen_farith(ctx, OPC_RSQRT_D, -1, rs, rt, 0);
19957 break;
19958 case NM_SQRT_S:
19959 gen_farith(ctx, OPC_SQRT_S, -1, rs, rt, 0);
19960 break;
19961 case NM_SQRT_D:
19962 gen_farith(ctx, OPC_SQRT_D, -1, rs, rt, 0);
19963 break;
19964 case NM_RECIP_S:
19965 gen_farith(ctx, OPC_RECIP_S, -1, rs, rt, 0);
19966 break;
19967 case NM_RECIP_D:
19968 gen_farith(ctx, OPC_RECIP_D, -1, rs, rt, 0);
19969 break;
19970 case NM_FLOOR_L_S:
19971 gen_farith(ctx, OPC_FLOOR_L_S, -1, rs, rt, 0);
19972 break;
19973 case NM_FLOOR_L_D:
19974 gen_farith(ctx, OPC_FLOOR_L_D, -1, rs, rt, 0);
19975 break;
19976 case NM_FLOOR_W_S:
19977 gen_farith(ctx, OPC_FLOOR_W_S, -1, rs, rt, 0);
19978 break;
19979 case NM_FLOOR_W_D:
19980 gen_farith(ctx, OPC_FLOOR_W_D, -1, rs, rt, 0);
19981 break;
19982 case NM_CEIL_L_S:
19983 gen_farith(ctx, OPC_CEIL_L_S, -1, rs, rt, 0);
19984 break;
19985 case NM_CEIL_L_D:
19986 gen_farith(ctx, OPC_CEIL_L_D, -1, rs, rt, 0);
19987 break;
19988 case NM_CEIL_W_S:
19989 gen_farith(ctx, OPC_CEIL_W_S, -1, rs, rt, 0);
19990 break;
19991 case NM_CEIL_W_D:
19992 gen_farith(ctx, OPC_CEIL_W_D, -1, rs, rt, 0);
19993 break;
19994 case NM_TRUNC_L_S:
19995 gen_farith(ctx, OPC_TRUNC_L_S, -1, rs, rt, 0);
19996 break;
19997 case NM_TRUNC_L_D:
19998 gen_farith(ctx, OPC_TRUNC_L_D, -1, rs, rt, 0);
19999 break;
20000 case NM_TRUNC_W_S:
20001 gen_farith(ctx, OPC_TRUNC_W_S, -1, rs, rt, 0);
20002 break;
20003 case NM_TRUNC_W_D:
20004 gen_farith(ctx, OPC_TRUNC_W_D, -1, rs, rt, 0);
20005 break;
20006 case NM_ROUND_L_S:
20007 gen_farith(ctx, OPC_ROUND_L_S, -1, rs, rt, 0);
20008 break;
20009 case NM_ROUND_L_D:
20010 gen_farith(ctx, OPC_ROUND_L_D, -1, rs, rt, 0);
20011 break;
20012 case NM_ROUND_W_S:
20013 gen_farith(ctx, OPC_ROUND_W_S, -1, rs, rt, 0);
20014 break;
20015 case NM_ROUND_W_D:
20016 gen_farith(ctx, OPC_ROUND_W_D, -1, rs, rt, 0);
20017 break;
20018 case NM_MOV_S:
20019 gen_farith(ctx, OPC_MOV_S, -1, rs, rt, 0);
20020 break;
20021 case NM_MOV_D:
20022 gen_farith(ctx, OPC_MOV_D, -1, rs, rt, 0);
20023 break;
20024 case NM_ABS_S:
20025 gen_farith(ctx, OPC_ABS_S, -1, rs, rt, 0);
20026 break;
20027 case NM_ABS_D:
20028 gen_farith(ctx, OPC_ABS_D, -1, rs, rt, 0);
20029 break;
20030 case NM_NEG_S:
20031 gen_farith(ctx, OPC_NEG_S, -1, rs, rt, 0);
20032 break;
20033 case NM_NEG_D:
20034 gen_farith(ctx, OPC_NEG_D, -1, rs, rt, 0);
20035 break;
20036 case NM_CVT_D_S:
20037 gen_farith(ctx, OPC_CVT_D_S, -1, rs, rt, 0);
20038 break;
20039 case NM_CVT_D_W:
20040 gen_farith(ctx, OPC_CVT_D_W, -1, rs, rt, 0);
20041 break;
20042 case NM_CVT_D_L:
20043 gen_farith(ctx, OPC_CVT_D_L, -1, rs, rt, 0);
20044 break;
20045 case NM_CVT_S_D:
20046 gen_farith(ctx, OPC_CVT_S_D, -1, rs, rt, 0);
20047 break;
20048 case NM_CVT_S_W:
20049 gen_farith(ctx, OPC_CVT_S_W, -1, rs, rt, 0);
20050 break;
20051 case NM_CVT_S_L:
20052 gen_farith(ctx, OPC_CVT_S_L, -1, rs, rt, 0);
20053 break;
20054 default:
20055 generate_exception_end(ctx, EXCP_RI);
20056 break;
20057 }
20058 break;
20059 }
20060 break;
20061 }
20062 break;
20063 case NM_POOL32F_5:
20064 switch (extract32(ctx->opcode, 3, 3)) {
20065 case NM_CMP_CONDN_S:
20066 gen_r6_cmp_s(ctx, extract32(ctx->opcode, 6, 5), rt, rs, rd);
20067 break;
20068 case NM_CMP_CONDN_D:
20069 gen_r6_cmp_d(ctx, extract32(ctx->opcode, 6, 5), rt, rs, rd);
20070 break;
20071 default:
20072 generate_exception_end(ctx, EXCP_RI);
20073 break;
20074 }
20075 break;
20076 default:
20077 generate_exception_end(ctx, EXCP_RI);
20078 break;
20079 }
20080}
20081
3285a3e4
SM
20082static void gen_pool32a5_nanomips_insn(DisasContext *ctx, int opc,
20083 int rd, int rs, int rt)
20084{
20085 int ret = rd;
20086 TCGv t0 = tcg_temp_new();
20087 TCGv v1_t = tcg_temp_new();
20088 TCGv v2_t = tcg_temp_new();
20089
20090 gen_load_gpr(v1_t, rs);
20091 gen_load_gpr(v2_t, rt);
20092
20093 switch (opc) {
20094 case NM_CMP_EQ_PH:
20095 check_dsp(ctx);
20096 gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
20097 break;
20098 case NM_CMP_LT_PH:
20099 check_dsp(ctx);
20100 gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
20101 break;
20102 case NM_CMP_LE_PH:
20103 check_dsp(ctx);
20104 gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
20105 break;
20106 case NM_CMPU_EQ_QB:
20107 check_dsp(ctx);
20108 gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
20109 break;
20110 case NM_CMPU_LT_QB:
20111 check_dsp(ctx);
20112 gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
20113 break;
20114 case NM_CMPU_LE_QB:
20115 check_dsp(ctx);
20116 gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
20117 break;
20118 case NM_CMPGU_EQ_QB:
20119 check_dsp(ctx);
20120 gen_helper_cmpgu_eq_qb(v1_t, v1_t, v2_t);
20121 gen_store_gpr(v1_t, ret);
20122 break;
20123 case NM_CMPGU_LT_QB:
20124 check_dsp(ctx);
20125 gen_helper_cmpgu_lt_qb(v1_t, v1_t, v2_t);
20126 gen_store_gpr(v1_t, ret);
20127 break;
20128 case NM_CMPGU_LE_QB:
20129 check_dsp(ctx);
20130 gen_helper_cmpgu_le_qb(v1_t, v1_t, v2_t);
20131 gen_store_gpr(v1_t, ret);
20132 break;
20133 case NM_CMPGDU_EQ_QB:
908f6be1 20134 check_dsp_r2(ctx);
3285a3e4
SM
20135 gen_helper_cmpgu_eq_qb(v1_t, v1_t, v2_t);
20136 tcg_gen_deposit_tl(cpu_dspctrl, cpu_dspctrl, v1_t, 24, 4);
20137 gen_store_gpr(v1_t, ret);
20138 break;
20139 case NM_CMPGDU_LT_QB:
908f6be1 20140 check_dsp_r2(ctx);
3285a3e4
SM
20141 gen_helper_cmpgu_lt_qb(v1_t, v1_t, v2_t);
20142 tcg_gen_deposit_tl(cpu_dspctrl, cpu_dspctrl, v1_t, 24, 4);
20143 gen_store_gpr(v1_t, ret);
20144 break;
20145 case NM_CMPGDU_LE_QB:
908f6be1 20146 check_dsp_r2(ctx);
3285a3e4
SM
20147 gen_helper_cmpgu_le_qb(v1_t, v1_t, v2_t);
20148 tcg_gen_deposit_tl(cpu_dspctrl, cpu_dspctrl, v1_t, 24, 4);
20149 gen_store_gpr(v1_t, ret);
20150 break;
20151 case NM_PACKRL_PH:
20152 check_dsp(ctx);
20153 gen_helper_packrl_ph(v1_t, v1_t, v2_t);
20154 gen_store_gpr(v1_t, ret);
20155 break;
20156 case NM_PICK_QB:
20157 check_dsp(ctx);
20158 gen_helper_pick_qb(v1_t, v1_t, v2_t, cpu_env);
20159 gen_store_gpr(v1_t, ret);
20160 break;
20161 case NM_PICK_PH:
20162 check_dsp(ctx);
20163 gen_helper_pick_ph(v1_t, v1_t, v2_t, cpu_env);
20164 gen_store_gpr(v1_t, ret);
20165 break;
20166 case NM_ADDQ_S_W:
20167 check_dsp(ctx);
20168 gen_helper_addq_s_w(v1_t, v1_t, v2_t, cpu_env);
20169 gen_store_gpr(v1_t, ret);
20170 break;
20171 case NM_SUBQ_S_W:
20172 check_dsp(ctx);
20173 gen_helper_subq_s_w(v1_t, v1_t, v2_t, cpu_env);
20174 gen_store_gpr(v1_t, ret);
20175 break;
20176 case NM_ADDSC:
20177 check_dsp(ctx);
20178 gen_helper_addsc(v1_t, v1_t, v2_t, cpu_env);
20179 gen_store_gpr(v1_t, ret);
20180 break;
20181 case NM_ADDWC:
20182 check_dsp(ctx);
20183 gen_helper_addwc(v1_t, v1_t, v2_t, cpu_env);
20184 gen_store_gpr(v1_t, ret);
20185 break;
20186 case NM_ADDQ_S_PH:
20187 check_dsp(ctx);
20188 switch (extract32(ctx->opcode, 10, 1)) {
20189 case 0:
20190 /* ADDQ_PH */
20191 gen_helper_addq_ph(v1_t, v1_t, v2_t, cpu_env);
20192 gen_store_gpr(v1_t, ret);
20193 break;
20194 case 1:
20195 /* ADDQ_S_PH */
20196 gen_helper_addq_s_ph(v1_t, v1_t, v2_t, cpu_env);
20197 gen_store_gpr(v1_t, ret);
20198 break;
20199 }
20200 break;
20201 case NM_ADDQH_R_PH:
908f6be1 20202 check_dsp_r2(ctx);
3285a3e4
SM
20203 switch (extract32(ctx->opcode, 10, 1)) {
20204 case 0:
20205 /* ADDQH_PH */
20206 gen_helper_addqh_ph(v1_t, v1_t, v2_t);
20207 gen_store_gpr(v1_t, ret);
20208 break;
20209 case 1:
20210 /* ADDQH_R_PH */
20211 gen_helper_addqh_r_ph(v1_t, v1_t, v2_t);
20212 gen_store_gpr(v1_t, ret);
20213 break;
20214 }
20215 break;
20216 case NM_ADDQH_R_W:
908f6be1 20217 check_dsp_r2(ctx);
3285a3e4
SM
20218 switch (extract32(ctx->opcode, 10, 1)) {
20219 case 0:
20220 /* ADDQH_W */
20221 gen_helper_addqh_w(v1_t, v1_t, v2_t);
20222 gen_store_gpr(v1_t, ret);
20223 break;
20224 case 1:
20225 /* ADDQH_R_W */
20226 gen_helper_addqh_r_w(v1_t, v1_t, v2_t);
20227 gen_store_gpr(v1_t, ret);
20228 break;
20229 }
20230 break;
20231 case NM_ADDU_S_QB:
20232 check_dsp(ctx);
20233 switch (extract32(ctx->opcode, 10, 1)) {
20234 case 0:
20235 /* ADDU_QB */
20236 gen_helper_addu_qb(v1_t, v1_t, v2_t, cpu_env);
20237 gen_store_gpr(v1_t, ret);
20238 break;
20239 case 1:
20240 /* ADDU_S_QB */
20241 gen_helper_addu_s_qb(v1_t, v1_t, v2_t, cpu_env);
20242 gen_store_gpr(v1_t, ret);
20243 break;
20244 }
20245 break;
20246 case NM_ADDU_S_PH:
908f6be1 20247 check_dsp_r2(ctx);
3285a3e4
SM
20248 switch (extract32(ctx->opcode, 10, 1)) {
20249 case 0:
20250 /* ADDU_PH */
20251 gen_helper_addu_ph(v1_t, v1_t, v2_t, cpu_env);
20252 gen_store_gpr(v1_t, ret);
20253 break;
20254 case 1:
20255 /* ADDU_S_PH */
20256 gen_helper_addu_s_ph(v1_t, v1_t, v2_t, cpu_env);
20257 gen_store_gpr(v1_t, ret);
20258 break;
20259 }
20260 break;
20261 case NM_ADDUH_R_QB:
908f6be1 20262 check_dsp_r2(ctx);
3285a3e4
SM
20263 switch (extract32(ctx->opcode, 10, 1)) {
20264 case 0:
20265 /* ADDUH_QB */
20266 gen_helper_adduh_qb(v1_t, v1_t, v2_t);
20267 gen_store_gpr(v1_t, ret);
20268 break;
20269 case 1:
20270 /* ADDUH_R_QB */
20271 gen_helper_adduh_r_qb(v1_t, v1_t, v2_t);
20272 gen_store_gpr(v1_t, ret);
20273 break;
20274 }
20275 break;
20276 case NM_SHRAV_R_PH:
20277 check_dsp(ctx);
20278 switch (extract32(ctx->opcode, 10, 1)) {
20279 case 0:
20280 /* SHRAV_PH */
20281 gen_helper_shra_ph(v1_t, v1_t, v2_t);
20282 gen_store_gpr(v1_t, ret);
20283 break;
20284 case 1:
20285 /* SHRAV_R_PH */
20286 gen_helper_shra_r_ph(v1_t, v1_t, v2_t);
20287 gen_store_gpr(v1_t, ret);
20288 break;
20289 }
20290 break;
20291 case NM_SHRAV_R_QB:
908f6be1 20292 check_dsp_r2(ctx);
3285a3e4
SM
20293 switch (extract32(ctx->opcode, 10, 1)) {
20294 case 0:
20295 /* SHRAV_QB */
20296 gen_helper_shra_qb(v1_t, v1_t, v2_t);
20297 gen_store_gpr(v1_t, ret);
20298 break;
20299 case 1:
20300 /* SHRAV_R_QB */
20301 gen_helper_shra_r_qb(v1_t, v1_t, v2_t);
20302 gen_store_gpr(v1_t, ret);
20303 break;
20304 }
20305 break;
20306 case NM_SUBQ_S_PH:
20307 check_dsp(ctx);
20308 switch (extract32(ctx->opcode, 10, 1)) {
20309 case 0:
20310 /* SUBQ_PH */
20311 gen_helper_subq_ph(v1_t, v1_t, v2_t, cpu_env);
20312 gen_store_gpr(v1_t, ret);
20313 break;
20314 case 1:
20315 /* SUBQ_S_PH */
20316 gen_helper_subq_s_ph(v1_t, v1_t, v2_t, cpu_env);
20317 gen_store_gpr(v1_t, ret);
20318 break;
20319 }
20320 break;
20321 case NM_SUBQH_R_PH:
908f6be1 20322 check_dsp_r2(ctx);
3285a3e4
SM
20323 switch (extract32(ctx->opcode, 10, 1)) {
20324 case 0:
20325 /* SUBQH_PH */
20326 gen_helper_subqh_ph(v1_t, v1_t, v2_t);
20327 gen_store_gpr(v1_t, ret);
20328 break;
20329 case 1:
20330 /* SUBQH_R_PH */
20331 gen_helper_subqh_r_ph(v1_t, v1_t, v2_t);
20332 gen_store_gpr(v1_t, ret);
20333 break;
20334 }
20335 break;
20336 case NM_SUBQH_R_W:
908f6be1 20337 check_dsp_r2(ctx);
3285a3e4
SM
20338 switch (extract32(ctx->opcode, 10, 1)) {
20339 case 0:
20340 /* SUBQH_W */
20341 gen_helper_subqh_w(v1_t, v1_t, v2_t);
20342 gen_store_gpr(v1_t, ret);
20343 break;
20344 case 1:
20345 /* SUBQH_R_W */
20346 gen_helper_subqh_r_w(v1_t, v1_t, v2_t);
20347 gen_store_gpr(v1_t, ret);
20348 break;
20349 }
20350 break;
20351 case NM_SUBU_S_QB:
20352 check_dsp(ctx);
20353 switch (extract32(ctx->opcode, 10, 1)) {
20354 case 0:
20355 /* SUBU_QB */
20356 gen_helper_subu_qb(v1_t, v1_t, v2_t, cpu_env);
20357 gen_store_gpr(v1_t, ret);
20358 break;
20359 case 1:
20360 /* SUBU_S_QB */
20361 gen_helper_subu_s_qb(v1_t, v1_t, v2_t, cpu_env);
20362 gen_store_gpr(v1_t, ret);
20363 break;
20364 }
20365 break;
20366 case NM_SUBU_S_PH:
908f6be1 20367 check_dsp_r2(ctx);
3285a3e4
SM
20368 switch (extract32(ctx->opcode, 10, 1)) {
20369 case 0:
20370 /* SUBU_PH */
20371 gen_helper_subu_ph(v1_t, v1_t, v2_t, cpu_env);
20372 gen_store_gpr(v1_t, ret);
20373 break;
20374 case 1:
20375 /* SUBU_S_PH */
20376 gen_helper_subu_s_ph(v1_t, v1_t, v2_t, cpu_env);
20377 gen_store_gpr(v1_t, ret);
20378 break;
20379 }
20380 break;
20381 case NM_SUBUH_R_QB:
908f6be1 20382 check_dsp_r2(ctx);
3285a3e4
SM
20383 switch (extract32(ctx->opcode, 10, 1)) {
20384 case 0:
20385 /* SUBUH_QB */
20386 gen_helper_subuh_qb(v1_t, v1_t, v2_t);
20387 gen_store_gpr(v1_t, ret);
20388 break;
20389 case 1:
20390 /* SUBUH_R_QB */
20391 gen_helper_subuh_r_qb(v1_t, v1_t, v2_t);
20392 gen_store_gpr(v1_t, ret);
20393 break;
20394 }
20395 break;
20396 case NM_SHLLV_S_PH:
20397 check_dsp(ctx);
20398 switch (extract32(ctx->opcode, 10, 1)) {
20399 case 0:
20400 /* SHLLV_PH */
20401 gen_helper_shll_ph(v1_t, v1_t, v2_t, cpu_env);
20402 gen_store_gpr(v1_t, ret);
20403 break;
20404 case 1:
20405 /* SHLLV_S_PH */
20406 gen_helper_shll_s_ph(v1_t, v1_t, v2_t, cpu_env);
20407 gen_store_gpr(v1_t, ret);
20408 break;
20409 }
20410 break;
20411 case NM_PRECR_SRA_R_PH_W:
908f6be1 20412 check_dsp_r2(ctx);
3285a3e4
SM
20413 switch (extract32(ctx->opcode, 10, 1)) {
20414 case 0:
20415 /* PRECR_SRA_PH_W */
20416 {
20417 TCGv_i32 sa_t = tcg_const_i32(rd);
20418 gen_helper_precr_sra_ph_w(v1_t, sa_t, v1_t,
20419 cpu_gpr[rt]);
20420 gen_store_gpr(v1_t, rt);
20421 tcg_temp_free_i32(sa_t);
20422 }
20423 break;
20424 case 1:
20425 /* PRECR_SRA_R_PH_W */
20426 {
20427 TCGv_i32 sa_t = tcg_const_i32(rd);
20428 gen_helper_precr_sra_r_ph_w(v1_t, sa_t, v1_t,
20429 cpu_gpr[rt]);
20430 gen_store_gpr(v1_t, rt);
20431 tcg_temp_free_i32(sa_t);
20432 }
20433 break;
20434 }
20435 break;
20436 case NM_MULEU_S_PH_QBL:
20437 check_dsp(ctx);
20438 gen_helper_muleu_s_ph_qbl(v1_t, v1_t, v2_t, cpu_env);
20439 gen_store_gpr(v1_t, ret);
20440 break;
20441 case NM_MULEU_S_PH_QBR:
20442 check_dsp(ctx);
20443 gen_helper_muleu_s_ph_qbr(v1_t, v1_t, v2_t, cpu_env);
20444 gen_store_gpr(v1_t, ret);
20445 break;
20446 case NM_MULQ_RS_PH:
20447 check_dsp(ctx);
20448 gen_helper_mulq_rs_ph(v1_t, v1_t, v2_t, cpu_env);
20449 gen_store_gpr(v1_t, ret);
20450 break;
20451 case NM_MULQ_S_PH:
908f6be1 20452 check_dsp_r2(ctx);
3285a3e4
SM
20453 gen_helper_mulq_s_ph(v1_t, v1_t, v2_t, cpu_env);
20454 gen_store_gpr(v1_t, ret);
20455 break;
20456 case NM_MULQ_RS_W:
908f6be1 20457 check_dsp_r2(ctx);
3285a3e4
SM
20458 gen_helper_mulq_rs_w(v1_t, v1_t, v2_t, cpu_env);
20459 gen_store_gpr(v1_t, ret);
20460 break;
20461 case NM_MULQ_S_W:
908f6be1 20462 check_dsp_r2(ctx);
3285a3e4
SM
20463 gen_helper_mulq_s_w(v1_t, v1_t, v2_t, cpu_env);
20464 gen_store_gpr(v1_t, ret);
20465 break;
20466 case NM_APPEND:
908f6be1 20467 check_dsp_r2(ctx);
3285a3e4
SM
20468 gen_load_gpr(t0, rs);
20469 if (rd != 0) {
20470 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], rd, 32 - rd);
20471 }
20472 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
20473 break;
20474 case NM_MODSUB:
20475 check_dsp(ctx);
20476 gen_helper_modsub(v1_t, v1_t, v2_t);
20477 gen_store_gpr(v1_t, ret);
20478 break;
20479 case NM_SHRAV_R_W:
20480 check_dsp(ctx);
20481 gen_helper_shra_r_w(v1_t, v1_t, v2_t);
20482 gen_store_gpr(v1_t, ret);
20483 break;
20484 case NM_SHRLV_PH:
908f6be1 20485 check_dsp_r2(ctx);
3285a3e4
SM
20486 gen_helper_shrl_ph(v1_t, v1_t, v2_t);
20487 gen_store_gpr(v1_t, ret);
20488 break;
20489 case NM_SHRLV_QB:
20490 check_dsp(ctx);
20491 gen_helper_shrl_qb(v1_t, v1_t, v2_t);
20492 gen_store_gpr(v1_t, ret);
20493 break;
20494 case NM_SHLLV_QB:
20495 check_dsp(ctx);
20496 gen_helper_shll_qb(v1_t, v1_t, v2_t, cpu_env);
20497 gen_store_gpr(v1_t, ret);
20498 break;
20499 case NM_SHLLV_S_W:
20500 check_dsp(ctx);
20501 gen_helper_shll_s_w(v1_t, v1_t, v2_t, cpu_env);
20502 gen_store_gpr(v1_t, ret);
20503 break;
20504 case NM_SHILO:
20505 check_dsp(ctx);
20506 {
20507 TCGv tv0 = tcg_temp_new();
20508 TCGv tv1 = tcg_temp_new();
20509 int16_t imm = extract32(ctx->opcode, 16, 7);
20510
20511 tcg_gen_movi_tl(tv0, rd >> 3);
20512 tcg_gen_movi_tl(tv1, imm);
20513 gen_helper_shilo(tv0, tv1, cpu_env);
20514 }
20515 break;
20516 case NM_MULEQ_S_W_PHL:
20517 check_dsp(ctx);
20518 gen_helper_muleq_s_w_phl(v1_t, v1_t, v2_t, cpu_env);
20519 gen_store_gpr(v1_t, ret);
20520 break;
20521 case NM_MULEQ_S_W_PHR:
20522 check_dsp(ctx);
20523 gen_helper_muleq_s_w_phr(v1_t, v1_t, v2_t, cpu_env);
20524 gen_store_gpr(v1_t, ret);
20525 break;
20526 case NM_MUL_S_PH:
908f6be1 20527 check_dsp_r2(ctx);
3285a3e4
SM
20528 switch (extract32(ctx->opcode, 10, 1)) {
20529 case 0:
20530 /* MUL_PH */
20531 gen_helper_mul_ph(v1_t, v1_t, v2_t, cpu_env);
20532 gen_store_gpr(v1_t, ret);
20533 break;
20534 case 1:
20535 /* MUL_S_PH */
20536 gen_helper_mul_s_ph(v1_t, v1_t, v2_t, cpu_env);
20537 gen_store_gpr(v1_t, ret);
20538 break;
20539 }
20540 break;
20541 case NM_PRECR_QB_PH:
908f6be1 20542 check_dsp_r2(ctx);
3285a3e4
SM
20543 gen_helper_precr_qb_ph(v1_t, v1_t, v2_t);
20544 gen_store_gpr(v1_t, ret);
20545 break;
20546 case NM_PRECRQ_QB_PH:
20547 check_dsp(ctx);
20548 gen_helper_precrq_qb_ph(v1_t, v1_t, v2_t);
20549 gen_store_gpr(v1_t, ret);
20550 break;
20551 case NM_PRECRQ_PH_W:
20552 check_dsp(ctx);
20553 gen_helper_precrq_ph_w(v1_t, v1_t, v2_t);
20554 gen_store_gpr(v1_t, ret);
20555 break;
20556 case NM_PRECRQ_RS_PH_W:
20557 check_dsp(ctx);
20558 gen_helper_precrq_rs_ph_w(v1_t, v1_t, v2_t, cpu_env);
20559 gen_store_gpr(v1_t, ret);
20560 break;
20561 case NM_PRECRQU_S_QB_PH:
20562 check_dsp(ctx);
20563 gen_helper_precrqu_s_qb_ph(v1_t, v1_t, v2_t, cpu_env);
20564 gen_store_gpr(v1_t, ret);
20565 break;
20566 case NM_SHRA_R_W:
20567 check_dsp(ctx);
20568 tcg_gen_movi_tl(t0, rd);
20569 gen_helper_shra_r_w(v1_t, t0, v1_t);
20570 gen_store_gpr(v1_t, rt);
20571 break;
20572 case NM_SHRA_R_PH:
20573 check_dsp(ctx);
20574 tcg_gen_movi_tl(t0, rd >> 1);
20575 switch (extract32(ctx->opcode, 10, 1)) {
20576 case 0:
20577 /* SHRA_PH */
20578 gen_helper_shra_ph(v1_t, t0, v1_t);
3285a3e4 20579 gen_store_gpr(v1_t, rt);
d5ebcbaf 20580 break;
3285a3e4
SM
20581 case 1:
20582 /* SHRA_R_PH */
20583 gen_helper_shra_r_ph(v1_t, t0, v1_t);
20584 gen_store_gpr(v1_t, rt);
20585 break;
20586 }
20587 break;
20588 case NM_SHLL_S_PH:
20589 check_dsp(ctx);
20590 tcg_gen_movi_tl(t0, rd >> 1);
20591 switch (extract32(ctx->opcode, 10, 2)) {
20592 case 0:
20593 /* SHLL_PH */
20594 gen_helper_shll_ph(v1_t, t0, v1_t, cpu_env);
20595 gen_store_gpr(v1_t, rt);
20596 break;
20597 case 2:
20598 /* SHLL_S_PH */
20599 gen_helper_shll_s_ph(v1_t, t0, v1_t, cpu_env);
20600 gen_store_gpr(v1_t, rt);
20601 break;
20602 default:
20603 generate_exception_end(ctx, EXCP_RI);
20604 break;
20605 }
20606 break;
20607 case NM_SHLL_S_W:
20608 check_dsp(ctx);
20609 tcg_gen_movi_tl(t0, rd);
20610 gen_helper_shll_s_w(v1_t, t0, v1_t, cpu_env);
20611 gen_store_gpr(v1_t, rt);
20612 break;
20613 case NM_REPL_PH:
20614 check_dsp(ctx);
20615 {
20616 int16_t imm;
20617 imm = sextract32(ctx->opcode, 11, 11);
20618 imm = (int16_t)(imm << 6) >> 6;
20619 if (rt != 0) {
20620 tcg_gen_movi_tl(cpu_gpr[rt], dup_const(MO_16, imm));
20621 }
20622 }
20623 break;
20624 default:
20625 generate_exception_end(ctx, EXCP_RI);
20626 break;
20627 }
20628}
20629
c0280983
YK
20630static int decode_nanomips_32_48_opc(CPUMIPSState *env, DisasContext *ctx)
20631{
20632 uint16_t insn;
20633 uint32_t op;
eac52664 20634 int rt, rs, rd;
c0280983
YK
20635 int offset;
20636 int imm;
20637
20638 insn = cpu_lduw_code(env, ctx->base.pc_next + 2);
20639 ctx->opcode = (ctx->opcode << 16) | insn;
20640
20641 rt = extract32(ctx->opcode, 21, 5);
20642 rs = extract32(ctx->opcode, 16, 5);
eac52664 20643 rd = extract32(ctx->opcode, 11, 5);
c0280983
YK
20644
20645 op = extract32(ctx->opcode, 26, 6);
20646 switch (op) {
20647 case NM_P_ADDIU:
20648 if (rt == 0) {
20649 /* P.RI */
20650 switch (extract32(ctx->opcode, 19, 2)) {
20651 case NM_SIGRIE:
20652 default:
20653 generate_exception_end(ctx, EXCP_RI);
20654 break;
20655 case NM_P_SYSCALL:
20656 if ((extract32(ctx->opcode, 18, 1)) == NM_SYSCALL) {
20657 generate_exception_end(ctx, EXCP_SYSCALL);
20658 } else {
20659 generate_exception_end(ctx, EXCP_RI);
20660 }
20661 break;
20662 case NM_BREAK:
20663 generate_exception_end(ctx, EXCP_BREAK);
20664 break;
20665 case NM_SDBBP:
20666 if (is_uhi(extract32(ctx->opcode, 0, 19))) {
20667 gen_helper_do_semihosting(cpu_env);
20668 } else {
20669 if (ctx->hflags & MIPS_HFLAG_SBRI) {
20670 generate_exception_end(ctx, EXCP_RI);
20671 } else {
20672 generate_exception_end(ctx, EXCP_DBp);
20673 }
20674 }
20675 break;
20676 }
20677 } else {
20678 /* NM_ADDIU */
20679 imm = extract32(ctx->opcode, 0, 16);
20680 if (rs != 0) {
20681 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm);
20682 } else {
20683 tcg_gen_movi_tl(cpu_gpr[rt], imm);
20684 }
20685 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
20686 }
20687 break;
20688 case NM_ADDIUPC:
20689 if (rt != 0) {
20690 offset = sextract32(ctx->opcode, 0, 1) << 21 |
20691 extract32(ctx->opcode, 1, 20) << 1;
20692 target_long addr = addr_add(ctx, ctx->base.pc_next + 4, offset);
20693 tcg_gen_movi_tl(cpu_gpr[rt], addr);
20694 }
20695 break;
20696 case NM_POOL32A:
e0cf0e65
YK
20697 switch (ctx->opcode & 0x07) {
20698 case NM_POOL32A0:
0a1a6ed7 20699 gen_pool32a0_nanomips_insn(env, ctx);
e0cf0e65 20700 break;
3285a3e4
SM
20701 case NM_POOL32A5:
20702 {
20703 int32_t op1 = extract32(ctx->opcode, 3, 7);
20704 gen_pool32a5_nanomips_insn(ctx, op1, rd, rs, rt);
20705 }
20706 break;
e0cf0e65 20707 case NM_POOL32A7:
64224187 20708 switch (extract32(ctx->opcode, 3, 3)) {
eac52664
YK
20709 case NM_P_LSX:
20710 gen_p_lsx(ctx, rd, rs, rt);
20711 break;
20712 case NM_LSA:
20713 /* In nanoMIPS, the shift field directly encodes the shift
20714 * amount, meaning that the supported shift values are in
20715 * the range 0 to 3 (instead of 1 to 4 in MIPSR6). */
20716 gen_lsa(ctx, OPC_LSA, rd, rs, rt,
20717 extract32(ctx->opcode, 9, 2) - 1);
20718 break;
821f2008
JH
20719 case NM_EXTW:
20720 gen_ext(ctx, 32, rd, rs, rt, extract32(ctx->opcode, 6, 5));
20721 break;
64224187
YK
20722 case NM_POOL32AXF:
20723 gen_pool32axf_nanomips_insn(env, ctx);
20724 break;
20725 default:
20726 generate_exception_end(ctx, EXCP_RI);
20727 break;
20728 }
e0cf0e65
YK
20729 break;
20730 default:
20731 generate_exception_end(ctx, EXCP_RI);
20732 break;
20733 }
c0280983
YK
20734 break;
20735 case NM_P_GP_W:
20736 switch (ctx->opcode & 0x03) {
20737 case NM_ADDIUGP_W:
20738 if (rt != 0) {
20739 offset = extract32(ctx->opcode, 0, 21);
20740 gen_op_addr_addi(ctx, cpu_gpr[rt], cpu_gpr[28], offset);
20741 }
20742 break;
20743 case NM_LWGP:
20744 gen_ld(ctx, OPC_LW, rt, 28, extract32(ctx->opcode, 2, 19) << 2);
20745 break;
20746 case NM_SWGP:
20747 gen_st(ctx, OPC_SW, rt, 28, extract32(ctx->opcode, 2, 19) << 2);
20748 break;
20749 default:
20750 generate_exception_end(ctx, EXCP_RI);
20751 break;
20752 }
20753 break;
20754 case NM_P48I:
7ef009b2
YK
20755 {
20756 insn = cpu_lduw_code(env, ctx->base.pc_next + 4);
20757 target_long addr_off = extract32(ctx->opcode, 0, 16) | insn << 16;
20758 switch (extract32(ctx->opcode, 16, 5)) {
20759 case NM_LI48:
fb32f8c8 20760 check_nms(ctx);
7ef009b2
YK
20761 if (rt != 0) {
20762 tcg_gen_movi_tl(cpu_gpr[rt], addr_off);
20763 }
20764 break;
20765 case NM_ADDIU48:
fb32f8c8 20766 check_nms(ctx);
7ef009b2
YK
20767 if (rt != 0) {
20768 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rt], addr_off);
20769 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
20770 }
20771 break;
20772 case NM_ADDIUGP48:
fb32f8c8 20773 check_nms(ctx);
7ef009b2
YK
20774 if (rt != 0) {
20775 gen_op_addr_addi(ctx, cpu_gpr[rt], cpu_gpr[28], addr_off);
20776 }
20777 break;
20778 case NM_ADDIUPC48:
fb32f8c8 20779 check_nms(ctx);
7ef009b2
YK
20780 if (rt != 0) {
20781 target_long addr = addr_add(ctx, ctx->base.pc_next + 6,
20782 addr_off);
20783
20784 tcg_gen_movi_tl(cpu_gpr[rt], addr);
20785 }
20786 break;
20787 case NM_LWPC48:
fb32f8c8 20788 check_nms(ctx);
7ef009b2
YK
20789 if (rt != 0) {
20790 TCGv t0;
20791 t0 = tcg_temp_new();
20792
20793 target_long addr = addr_add(ctx, ctx->base.pc_next + 6,
20794 addr_off);
20795
20796 tcg_gen_movi_tl(t0, addr);
20797 tcg_gen_qemu_ld_tl(cpu_gpr[rt], t0, ctx->mem_idx, MO_TESL);
20798 tcg_temp_free(t0);
20799 }
20800 break;
20801 case NM_SWPC48:
fb32f8c8 20802 check_nms(ctx);
7ef009b2
YK
20803 {
20804 TCGv t0, t1;
20805 t0 = tcg_temp_new();
20806 t1 = tcg_temp_new();
20807
20808 target_long addr = addr_add(ctx, ctx->base.pc_next + 6,
20809 addr_off);
20810
20811 tcg_gen_movi_tl(t0, addr);
20812 gen_load_gpr(t1, rt);
20813
20814 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
20815
20816 tcg_temp_free(t0);
20817 tcg_temp_free(t1);
20818 }
20819 break;
20820 default:
20821 generate_exception_end(ctx, EXCP_RI);
20822 break;
20823 }
20824 return 6;
20825 }
c0280983
YK
20826 case NM_P_U12:
20827 switch (extract32(ctx->opcode, 12, 4)) {
20828 case NM_ORI:
20829 gen_logic_imm(ctx, OPC_ORI, rt, rs, extract32(ctx->opcode, 0, 12));
20830 break;
20831 case NM_XORI:
20832 gen_logic_imm(ctx, OPC_XORI, rt, rs, extract32(ctx->opcode, 0, 12));
20833 break;
20834 case NM_ANDI:
20835 gen_logic_imm(ctx, OPC_ANDI, rt, rs, extract32(ctx->opcode, 0, 12));
20836 break;
20837 case NM_P_SR:
20838 switch (extract32(ctx->opcode, 20, 1)) {
20839 case NM_PP_SR:
20840 switch (ctx->opcode & 3) {
20841 case NM_SAVE:
20842 gen_save(ctx, rt, extract32(ctx->opcode, 16, 4),
20843 extract32(ctx->opcode, 2, 1),
20844 extract32(ctx->opcode, 3, 9) << 3);
20845 break;
20846 case NM_RESTORE:
20847 case NM_RESTORE_JRC:
20848 gen_restore(ctx, rt, extract32(ctx->opcode, 16, 4),
20849 extract32(ctx->opcode, 2, 1),
20850 extract32(ctx->opcode, 3, 9) << 3);
20851 if ((ctx->opcode & 3) == NM_RESTORE_JRC) {
20852 gen_compute_branch_nm(ctx, OPC_JR, 2, 31, 0, 0);
20853 }
20854 break;
20855 default:
20856 generate_exception_end(ctx, EXCP_RI);
20857 break;
20858 }
20859 break;
20860 case NM_P_SR_F:
20861 generate_exception_end(ctx, EXCP_RI);
20862 break;
20863 }
20864 break;
20865 case NM_SLTI:
20866 gen_slt_imm(ctx, OPC_SLTI, rt, rs, extract32(ctx->opcode, 0, 12));
20867 break;
20868 case NM_SLTIU:
20869 gen_slt_imm(ctx, OPC_SLTIU, rt, rs, extract32(ctx->opcode, 0, 12));
20870 break;
20871 case NM_SEQI:
20872 {
20873 TCGv t0 = tcg_temp_new();
20874
20875 imm = extract32(ctx->opcode, 0, 12);
20876 gen_load_gpr(t0, rs);
20877 tcg_gen_setcondi_tl(TCG_COND_EQ, t0, t0, imm);
20878 gen_store_gpr(t0, rt);
20879
20880 tcg_temp_free(t0);
20881 }
20882 break;
20883 case NM_ADDIUNEG:
20884 imm = (int16_t) extract32(ctx->opcode, 0, 12);
20885 gen_arith_imm(ctx, OPC_ADDIU, rt, rs, -imm);
20886 break;
20887 case NM_P_SHIFT:
20888 {
20889 int shift = extract32(ctx->opcode, 0, 5);
20890 switch (extract32(ctx->opcode, 5, 4)) {
20891 case NM_P_SLL:
20892 if (rt == 0 && shift == 0) {
20893 /* NOP */
20894 } else if (rt == 0 && shift == 3) {
20895 /* EHB - treat as NOP */
20896 } else if (rt == 0 && shift == 5) {
20897 /* PAUSE - treat as NOP */
20898 } else if (rt == 0 && shift == 6) {
20899 /* SYNC */
20900 gen_sync(extract32(ctx->opcode, 16, 5));
20901 } else {
20902 /* SLL */
20903 gen_shift_imm(ctx, OPC_SLL, rt, rs,
20904 extract32(ctx->opcode, 0, 5));
20905 }
20906 break;
20907 case NM_SRL:
20908 gen_shift_imm(ctx, OPC_SRL, rt, rs,
20909 extract32(ctx->opcode, 0, 5));
20910 break;
20911 case NM_SRA:
20912 gen_shift_imm(ctx, OPC_SRA, rt, rs,
20913 extract32(ctx->opcode, 0, 5));
20914 break;
20915 case NM_ROTR:
20916 gen_shift_imm(ctx, OPC_ROTR, rt, rs,
20917 extract32(ctx->opcode, 0, 5));
20918 break;
20919 }
20920 }
20921 break;
20922 case NM_P_ROTX:
fb32f8c8 20923 check_nms(ctx);
e222f506
MF
20924 if (rt != 0) {
20925 TCGv t0 = tcg_temp_new();
20926 TCGv_i32 shift = tcg_const_i32(extract32(ctx->opcode, 0, 5));
20927 TCGv_i32 shiftx = tcg_const_i32(extract32(ctx->opcode, 7, 4)
20928 << 1);
20929 TCGv_i32 stripe = tcg_const_i32(extract32(ctx->opcode, 6, 1));
20930
20931 gen_load_gpr(t0, rs);
20932 gen_helper_rotx(cpu_gpr[rt], t0, shift, shiftx, stripe);
20933 tcg_temp_free(t0);
20934
20935 tcg_temp_free_i32(shift);
20936 tcg_temp_free_i32(shiftx);
20937 tcg_temp_free_i32(stripe);
20938 }
c0280983
YK
20939 break;
20940 case NM_P_INS:
20941 switch (((ctx->opcode >> 10) & 2) |
20942 (extract32(ctx->opcode, 5, 1))) {
20943 case NM_INS:
fb32f8c8 20944 check_nms(ctx);
c0280983
YK
20945 gen_bitops(ctx, OPC_INS, rt, rs, extract32(ctx->opcode, 0, 5),
20946 extract32(ctx->opcode, 6, 5));
20947 break;
20948 default:
20949 generate_exception_end(ctx, EXCP_RI);
20950 break;
20951 }
20952 break;
20953 case NM_P_EXT:
20954 switch (((ctx->opcode >> 10) & 2) |
20955 (extract32(ctx->opcode, 5, 1))) {
20956 case NM_EXT:
fb32f8c8 20957 check_nms(ctx);
c0280983
YK
20958 gen_bitops(ctx, OPC_EXT, rt, rs, extract32(ctx->opcode, 0, 5),
20959 extract32(ctx->opcode, 6, 5));
20960 break;
20961 default:
20962 generate_exception_end(ctx, EXCP_RI);
20963 break;
20964 }
20965 break;
20966 default:
20967 generate_exception_end(ctx, EXCP_RI);
20968 break;
20969 }
20970 break;
20971 case NM_POOL32F:
579b8ea9 20972 gen_pool32f_nanomips_insn(ctx);
c0280983
YK
20973 break;
20974 case NM_POOL32S:
20975 break;
20976 case NM_P_LUI:
20977 switch (extract32(ctx->opcode, 1, 1)) {
20978 case NM_LUI:
20979 if (rt != 0) {
20980 tcg_gen_movi_tl(cpu_gpr[rt],
20981 sextract32(ctx->opcode, 0, 1) << 31 |
20982 extract32(ctx->opcode, 2, 10) << 21 |
20983 extract32(ctx->opcode, 12, 9) << 12);
20984 }
20985 break;
20986 case NM_ALUIPC:
20987 if (rt != 0) {
20988 offset = sextract32(ctx->opcode, 0, 1) << 31 |
20989 extract32(ctx->opcode, 2, 10) << 21 |
20990 extract32(ctx->opcode, 12, 9) << 12;
20991 target_long addr;
20992 addr = ~0xFFF & addr_add(ctx, ctx->base.pc_next + 4, offset);
20993 tcg_gen_movi_tl(cpu_gpr[rt], addr);
20994 }
20995 break;
20996 }
20997 break;
20998 case NM_P_GP_BH:
8f1d9b6d
YK
20999 {
21000 uint32_t u = extract32(ctx->opcode, 0, 18);
21001
21002 switch (extract32(ctx->opcode, 18, 3)) {
21003 case NM_LBGP:
21004 gen_ld(ctx, OPC_LB, rt, 28, u);
21005 break;
21006 case NM_SBGP:
21007 gen_st(ctx, OPC_SB, rt, 28, u);
21008 break;
21009 case NM_LBUGP:
21010 gen_ld(ctx, OPC_LBU, rt, 28, u);
21011 break;
21012 case NM_ADDIUGP_B:
21013 if (rt != 0) {
21014 gen_op_addr_addi(ctx, cpu_gpr[rt], cpu_gpr[28], u);
21015 }
21016 break;
21017 case NM_P_GP_LH:
21018 u &= ~1;
21019 switch (ctx->opcode & 1) {
21020 case NM_LHGP:
21021 gen_ld(ctx, OPC_LH, rt, 28, u);
21022 break;
21023 case NM_LHUGP:
21024 gen_ld(ctx, OPC_LHU, rt, 28, u);
21025 break;
21026 }
21027 break;
21028 case NM_P_GP_SH:
21029 u &= ~1;
21030 switch (ctx->opcode & 1) {
21031 case NM_SHGP:
21032 gen_st(ctx, OPC_SH, rt, 28, u);
21033 break;
21034 default:
21035 generate_exception_end(ctx, EXCP_RI);
21036 break;
21037 }
21038 break;
21039 case NM_P_GP_CP1:
21040 u &= ~0x3;
21041 switch (ctx->opcode & 0x3) {
21042 case NM_LWC1GP:
21043 gen_cop1_ldst(ctx, OPC_LWC1, rt, 28, u);
21044 break;
21045 case NM_LDC1GP:
21046 gen_cop1_ldst(ctx, OPC_LDC1, rt, 28, u);
21047 break;
21048 case NM_SWC1GP:
21049 gen_cop1_ldst(ctx, OPC_SWC1, rt, 28, u);
21050 break;
21051 case NM_SDC1GP:
21052 gen_cop1_ldst(ctx, OPC_SDC1, rt, 28, u);
21053 break;
21054 }
21055 break;
21056 default:
21057 generate_exception_end(ctx, EXCP_RI);
21058 break;
21059 }
21060 }
c0280983
YK
21061 break;
21062 case NM_P_LS_U12:
8f1d9b6d
YK
21063 {
21064 uint32_t u = extract32(ctx->opcode, 0, 12);
21065
21066 switch (extract32(ctx->opcode, 12, 4)) {
21067 case NM_P_PREFU12:
21068 if (rt == 31) {
21069 /* SYNCI */
21070 /* Break the TB to be able to sync copied instructions
21071 immediately */
21072 ctx->base.is_jmp = DISAS_STOP;
21073 } else {
21074 /* PREF */
21075 /* Treat as NOP. */
21076 }
21077 break;
21078 case NM_LB:
21079 gen_ld(ctx, OPC_LB, rt, rs, u);
21080 break;
21081 case NM_LH:
21082 gen_ld(ctx, OPC_LH, rt, rs, u);
21083 break;
21084 case NM_LW:
21085 gen_ld(ctx, OPC_LW, rt, rs, u);
21086 break;
21087 case NM_LBU:
21088 gen_ld(ctx, OPC_LBU, rt, rs, u);
21089 break;
21090 case NM_LHU:
21091 gen_ld(ctx, OPC_LHU, rt, rs, u);
21092 break;
21093 case NM_SB:
21094 gen_st(ctx, OPC_SB, rt, rs, u);
21095 break;
21096 case NM_SH:
21097 gen_st(ctx, OPC_SH, rt, rs, u);
21098 break;
21099 case NM_SW:
21100 gen_st(ctx, OPC_SW, rt, rs, u);
21101 break;
21102 case NM_LWC1:
21103 gen_cop1_ldst(ctx, OPC_LWC1, rt, rs, u);
21104 break;
21105 case NM_LDC1:
21106 gen_cop1_ldst(ctx, OPC_LDC1, rt, rs, u);
21107 break;
21108 case NM_SWC1:
21109 gen_cop1_ldst(ctx, OPC_SWC1, rt, rs, u);
21110 break;
21111 case NM_SDC1:
21112 gen_cop1_ldst(ctx, OPC_SDC1, rt, rs, u);
21113 break;
21114 default:
21115 generate_exception_end(ctx, EXCP_RI);
21116 break;
21117 }
21118 }
c0280983
YK
21119 break;
21120 case NM_P_LS_S9:
8f1d9b6d
YK
21121 {
21122 int32_t s = (sextract32(ctx->opcode, 15, 1) << 8) |
21123 extract32(ctx->opcode, 0, 8);
21124
21125 switch (extract32(ctx->opcode, 8, 3)) {
21126 case NM_P_LS_S0:
21127 switch (extract32(ctx->opcode, 11, 4)) {
21128 case NM_LBS9:
21129 gen_ld(ctx, OPC_LB, rt, rs, s);
21130 break;
21131 case NM_LHS9:
21132 gen_ld(ctx, OPC_LH, rt, rs, s);
21133 break;
21134 case NM_LWS9:
21135 gen_ld(ctx, OPC_LW, rt, rs, s);
21136 break;
21137 case NM_LBUS9:
21138 gen_ld(ctx, OPC_LBU, rt, rs, s);
21139 break;
21140 case NM_LHUS9:
21141 gen_ld(ctx, OPC_LHU, rt, rs, s);
21142 break;
21143 case NM_SBS9:
21144 gen_st(ctx, OPC_SB, rt, rs, s);
21145 break;
21146 case NM_SHS9:
21147 gen_st(ctx, OPC_SH, rt, rs, s);
21148 break;
21149 case NM_SWS9:
21150 gen_st(ctx, OPC_SW, rt, rs, s);
21151 break;
21152 case NM_LWC1S9:
21153 gen_cop1_ldst(ctx, OPC_LWC1, rt, rs, s);
21154 break;
21155 case NM_LDC1S9:
21156 gen_cop1_ldst(ctx, OPC_LDC1, rt, rs, s);
21157 break;
21158 case NM_SWC1S9:
21159 gen_cop1_ldst(ctx, OPC_SWC1, rt, rs, s);
21160 break;
21161 case NM_SDC1S9:
21162 gen_cop1_ldst(ctx, OPC_SDC1, rt, rs, s);
21163 break;
21164 case NM_P_PREFS9:
21165 if (rt == 31) {
21166 /* SYNCI */
21167 /* Break the TB to be able to sync copied instructions
21168 immediately */
21169 ctx->base.is_jmp = DISAS_STOP;
21170 } else {
21171 /* PREF */
21172 /* Treat as NOP. */
21173 }
21174 break;
21175 default:
21176 generate_exception_end(ctx, EXCP_RI);
21177 break;
21178 }
21179 break;
21180 case NM_P_LS_S1:
21181 switch (extract32(ctx->opcode, 11, 4)) {
21182 case NM_UALH:
21183 case NM_UASH:
fb32f8c8 21184 check_nms(ctx);
8f1d9b6d
YK
21185 {
21186 TCGv t0 = tcg_temp_new();
21187 TCGv t1 = tcg_temp_new();
21188
21189 gen_base_offset_addr(ctx, t0, rs, s);
21190
21191 switch (extract32(ctx->opcode, 11, 4)) {
21192 case NM_UALH:
21193 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW |
21194 MO_UNALN);
21195 gen_store_gpr(t0, rt);
21196 break;
21197 case NM_UASH:
21198 gen_load_gpr(t1, rt);
21199 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUW |
21200 MO_UNALN);
21201 break;
21202 }
21203 tcg_temp_free(t0);
21204 tcg_temp_free(t1);
21205 }
21206 break;
21207 case NM_P_LL:
21208 switch (ctx->opcode & 0x03) {
21209 case NM_LL:
21210 gen_ld(ctx, OPC_LL, rt, rs, s);
21211 break;
21212 case NM_LLWP:
0b16dcd1
AR
21213 check_xnp(ctx);
21214 gen_llwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5));
8f1d9b6d
YK
21215 break;
21216 }
21217 break;
21218 case NM_P_SC:
21219 switch (ctx->opcode & 0x03) {
21220 case NM_SC:
21221 gen_st_cond(ctx, OPC_SC, rt, rs, s);
21222 break;
21223 case NM_SCWP:
0b16dcd1
AR
21224 check_xnp(ctx);
21225 gen_scwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5));
8f1d9b6d
YK
21226 break;
21227 }
21228 break;
21229 case NM_CACHE:
21230 check_cp0_enabled(ctx);
21231 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
21232 gen_cache_operation(ctx, rt, rs, s);
21233 }
21234 break;
21235 }
21236 break;
d046a9ea
DN
21237 case NM_P_LS_E0:
21238 switch (extract32(ctx->opcode, 11, 4)) {
21239 case NM_LBE:
21240 check_eva(ctx);
21241 check_cp0_enabled(ctx);
21242 gen_ld(ctx, OPC_LBE, rt, rs, s);
21243 break;
21244 case NM_SBE:
21245 check_eva(ctx);
21246 check_cp0_enabled(ctx);
21247 gen_st(ctx, OPC_SBE, rt, rs, s);
21248 break;
21249 case NM_LBUE:
21250 check_eva(ctx);
21251 check_cp0_enabled(ctx);
21252 gen_ld(ctx, OPC_LBUE, rt, rs, s);
21253 break;
21254 case NM_P_PREFE:
21255 if (rt == 31) {
21256 /* case NM_SYNCIE */
21257 check_eva(ctx);
21258 check_cp0_enabled(ctx);
21259 /* Break the TB to be able to sync copied instructions
21260 immediately */
21261 ctx->base.is_jmp = DISAS_STOP;
21262 } else {
21263 /* case NM_PREFE */
21264 check_eva(ctx);
21265 check_cp0_enabled(ctx);
21266 /* Treat as NOP. */
21267 }
21268 break;
21269 case NM_LHE:
21270 check_eva(ctx);
21271 check_cp0_enabled(ctx);
21272 gen_ld(ctx, OPC_LHE, rt, rs, s);
21273 break;
21274 case NM_SHE:
21275 check_eva(ctx);
21276 check_cp0_enabled(ctx);
21277 gen_st(ctx, OPC_SHE, rt, rs, s);
21278 break;
21279 case NM_LHUE:
21280 check_eva(ctx);
21281 check_cp0_enabled(ctx);
21282 gen_ld(ctx, OPC_LHUE, rt, rs, s);
21283 break;
21284 case NM_CACHEE:
21285 check_nms_dl_il_sl_tl_l2c(ctx);
21286 gen_cache_operation(ctx, rt, rs, s);
21287 break;
21288 case NM_LWE:
21289 check_eva(ctx);
21290 check_cp0_enabled(ctx);
21291 gen_ld(ctx, OPC_LWE, rt, rs, s);
21292 break;
21293 case NM_SWE:
21294 check_eva(ctx);
21295 check_cp0_enabled(ctx);
21296 gen_st(ctx, OPC_SWE, rt, rs, s);
21297 break;
21298 case NM_P_LLE:
21299 switch (extract32(ctx->opcode, 2, 2)) {
21300 case NM_LLE:
21301 check_xnp(ctx);
21302 check_eva(ctx);
21303 check_cp0_enabled(ctx);
21304 gen_ld(ctx, OPC_LLE, rt, rs, s);
21305 break;
21306 case NM_LLWPE:
21307 check_xnp(ctx);
21308 check_eva(ctx);
21309 check_cp0_enabled(ctx);
21310 gen_llwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5));
2431a422 21311 break;
d046a9ea
DN
21312 default:
21313 generate_exception_end(ctx, EXCP_RI);
21314 break;
21315 }
21316 break;
21317 case NM_P_SCE:
21318 switch (extract32(ctx->opcode, 2, 2)) {
21319 case NM_SCE:
21320 check_xnp(ctx);
21321 check_eva(ctx);
21322 check_cp0_enabled(ctx);
21323 gen_st_cond(ctx, OPC_SCE, rt, rs, s);
21324 break;
21325 case NM_SCWPE:
21326 check_xnp(ctx);
21327 check_eva(ctx);
21328 check_cp0_enabled(ctx);
21329 gen_scwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5));
2431a422 21330 break;
d046a9ea
DN
21331 default:
21332 generate_exception_end(ctx, EXCP_RI);
21333 break;
21334 }
21335 break;
21336 }
21337 break;
8f1d9b6d
YK
21338 case NM_P_LS_WM:
21339 case NM_P_LS_UAWM:
fb32f8c8 21340 check_nms(ctx);
8f1d9b6d
YK
21341 {
21342 int count = extract32(ctx->opcode, 12, 3);
21343 int counter = 0;
21344
21345 offset = sextract32(ctx->opcode, 15, 1) << 8 |
21346 extract32(ctx->opcode, 0, 8);
21347 TCGv va = tcg_temp_new();
21348 TCGv t1 = tcg_temp_new();
21349 TCGMemOp memop = (extract32(ctx->opcode, 8, 3)) ==
21350 NM_P_LS_UAWM ? MO_UNALN : 0;
21351
21352 count = (count == 0) ? 8 : count;
21353 while (counter != count) {
21354 int this_rt = ((rt + counter) & 0x1f) | (rt & 0x10);
21355 int this_offset = offset + (counter << 2);
21356
21357 gen_base_offset_addr(ctx, va, rs, this_offset);
21358
21359 switch (extract32(ctx->opcode, 11, 1)) {
21360 case NM_LWM:
21361 tcg_gen_qemu_ld_tl(t1, va, ctx->mem_idx,
21362 memop | MO_TESL);
21363 gen_store_gpr(t1, this_rt);
21364 if ((this_rt == rs) &&
21365 (counter != (count - 1))) {
21366 /* UNPREDICTABLE */
21367 }
21368 break;
21369 case NM_SWM:
21370 this_rt = (rt == 0) ? 0 : this_rt;
21371 gen_load_gpr(t1, this_rt);
21372 tcg_gen_qemu_st_tl(t1, va, ctx->mem_idx,
21373 memop | MO_TEUL);
21374 break;
21375 }
21376 counter++;
21377 }
21378 tcg_temp_free(va);
21379 tcg_temp_free(t1);
21380 }
21381 break;
21382 default:
21383 generate_exception_end(ctx, EXCP_RI);
21384 break;
21385 }
21386 }
c0280983
YK
21387 break;
21388 case NM_MOVE_BALC:
fb32f8c8 21389 check_nms(ctx);
11d0fc10
SM
21390 {
21391 TCGv t0 = tcg_temp_new();
21392 int32_t s = sextract32(ctx->opcode, 0, 1) << 21 |
21393 extract32(ctx->opcode, 1, 20) << 1;
21394 rd = (extract32(ctx->opcode, 24, 1)) == 0 ? 4 : 5;
21395 rt = decode_gpr_gpr4_zero(extract32(ctx->opcode, 25, 1) << 3 |
21396 extract32(ctx->opcode, 21, 3));
21397 gen_load_gpr(t0, rt);
21398 tcg_gen_mov_tl(cpu_gpr[rd], t0);
21399 gen_compute_branch_nm(ctx, OPC_BGEZAL, 4, 0, 0, s);
21400 tcg_temp_free(t0);
21401 }
c0280983
YK
21402 break;
21403 case NM_P_BAL:
11d0fc10
SM
21404 {
21405 int32_t s = sextract32(ctx->opcode, 0, 1) << 25 |
21406 extract32(ctx->opcode, 1, 24) << 1;
21407
21408 if ((extract32(ctx->opcode, 25, 1)) == 0) {
21409 /* BC */
21410 gen_compute_branch_nm(ctx, OPC_BEQ, 4, 0, 0, s);
21411 } else {
21412 /* BALC */
21413 gen_compute_branch_nm(ctx, OPC_BGEZAL, 4, 0, 0, s);
21414 }
21415 }
c0280983
YK
21416 break;
21417 case NM_P_J:
11d0fc10
SM
21418 switch (extract32(ctx->opcode, 12, 4)) {
21419 case NM_JALRC:
21420 case NM_JALRC_HB:
21421 gen_compute_branch_nm(ctx, OPC_JALR, 4, rs, rt, 0);
21422 break;
21423 case NM_P_BALRSC:
21424 gen_compute_nanomips_pbalrsc_branch(ctx, rs, rt);
21425 break;
21426 default:
21427 generate_exception_end(ctx, EXCP_RI);
21428 break;
21429 }
c0280983
YK
21430 break;
21431 case NM_P_BR1:
11d0fc10
SM
21432 {
21433 int32_t s = sextract32(ctx->opcode, 0, 1) << 14 |
21434 extract32(ctx->opcode, 1, 13) << 1;
21435 switch (extract32(ctx->opcode, 14, 2)) {
21436 case NM_BEQC:
fb32f8c8 21437 check_nms(ctx);
11d0fc10
SM
21438 gen_compute_branch_nm(ctx, OPC_BEQ, 4, rs, rt, s);
21439 break;
21440 case NM_P_BR3A:
21441 s = sextract32(ctx->opcode, 0, 1) << 14 |
21442 extract32(ctx->opcode, 1, 13) << 1;
21443 check_cp1_enabled(ctx);
21444 switch (extract32(ctx->opcode, 16, 5)) {
21445 case NM_BC1EQZC:
21446 gen_compute_branch_cp1_nm(ctx, OPC_BC1EQZ, rt, s);
21447 break;
21448 case NM_BC1NEZC:
21449 gen_compute_branch_cp1_nm(ctx, OPC_BC1NEZ, rt, s);
21450 break;
6d033ca7 21451 case NM_BPOSGE32C:
908f6be1 21452 check_dsp_r3(ctx);
6d033ca7
SM
21453 {
21454 int32_t imm = extract32(ctx->opcode, 1, 13) |
21455 extract32(ctx->opcode, 0, 1) << 13;
21456
21457 gen_compute_branch_nm(ctx, OPC_BPOSGE32, 4, -1, -2,
21458 imm);
21459 }
21460 break;
11d0fc10
SM
21461 default:
21462 generate_exception_end(ctx, EXCP_RI);
21463 break;
21464 }
21465 break;
21466 case NM_BGEC:
21467 if (rs == rt) {
21468 gen_compute_compact_branch_nm(ctx, OPC_BC, rs, rt, s);
21469 } else {
21470 gen_compute_compact_branch_nm(ctx, OPC_BGEC, rs, rt, s);
21471 }
21472 break;
21473 case NM_BGEUC:
21474 if (rs == rt || rt == 0) {
21475 gen_compute_compact_branch_nm(ctx, OPC_BC, 0, 0, s);
21476 } else if (rs == 0) {
21477 gen_compute_compact_branch_nm(ctx, OPC_BEQZC, rt, 0, s);
21478 } else {
21479 gen_compute_compact_branch_nm(ctx, OPC_BGEUC, rs, rt, s);
21480 }
21481 break;
21482 }
21483 }
c0280983
YK
21484 break;
21485 case NM_P_BR2:
11d0fc10
SM
21486 {
21487 int32_t s = sextract32(ctx->opcode, 0, 1) << 14 |
21488 extract32(ctx->opcode, 1, 13) << 1;
21489 switch (extract32(ctx->opcode, 14, 2)) {
21490 case NM_BNEC:
fb32f8c8 21491 check_nms(ctx);
11d0fc10
SM
21492 gen_compute_branch_nm(ctx, OPC_BNE, 4, rs, rt, s);
21493 break;
21494 case NM_BLTC:
21495 if (rs != 0 && rt != 0 && rs == rt) {
21496 /* NOP */
21497 ctx->hflags |= MIPS_HFLAG_FBNSLOT;
21498 } else {
21499 gen_compute_compact_branch_nm(ctx, OPC_BLTC, rs, rt, s);
21500 }
21501 break;
21502 case NM_BLTUC:
21503 if (rs == 0 || rs == rt) {
21504 /* NOP */
21505 ctx->hflags |= MIPS_HFLAG_FBNSLOT;
21506 } else {
21507 gen_compute_compact_branch_nm(ctx, OPC_BLTUC, rs, rt, s);
21508 }
21509 break;
21510 default:
21511 generate_exception_end(ctx, EXCP_RI);
21512 break;
21513 }
21514 }
c0280983
YK
21515 break;
21516 case NM_P_BRI:
11d0fc10
SM
21517 {
21518 int32_t s = sextract32(ctx->opcode, 0, 1) << 11 |
21519 extract32(ctx->opcode, 1, 10) << 1;
21520 uint32_t u = extract32(ctx->opcode, 11, 7);
21521
21522 gen_compute_imm_branch(ctx, extract32(ctx->opcode, 18, 3),
21523 rt, u, s);
21524 }
c0280983
YK
21525 break;
21526 default:
21527 generate_exception_end(ctx, EXCP_RI);
21528 break;
21529 }
21530 return 4;
21531}
21532
c533c0f4
AM
21533static int decode_nanomips_opc(CPUMIPSState *env, DisasContext *ctx)
21534{
ea4ca3c2
YK
21535 uint32_t op;
21536 int rt = decode_gpr_gpr3(NANOMIPS_EXTRACT_RD(ctx->opcode));
21537 int rs = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS(ctx->opcode));
21538 int rd = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS1(ctx->opcode));
8bdb7029 21539 int offset;
ea4ca3c2
YK
21540 int imm;
21541
21542 /* make sure instructions are on a halfword boundary */
21543 if (ctx->base.pc_next & 0x1) {
21544 TCGv tmp = tcg_const_tl(ctx->base.pc_next);
21545 tcg_gen_st_tl(tmp, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
21546 tcg_temp_free(tmp);
21547 generate_exception_end(ctx, EXCP_AdEL);
21548 return 2;
21549 }
21550
21551 op = extract32(ctx->opcode, 10, 6);
21552 switch (op) {
21553 case NM_P16_MV:
8869ad02
YK
21554 rt = NANOMIPS_EXTRACT_RD5(ctx->opcode);
21555 if (rt != 0) {
21556 /* MOVE */
21557 rs = NANOMIPS_EXTRACT_RS5(ctx->opcode);
21558 gen_arith(ctx, OPC_ADDU, rt, rs, 0);
21559 } else {
21560 /* P16.RI */
21561 switch (extract32(ctx->opcode, 3, 2)) {
21562 case NM_P16_SYSCALL:
21563 if (extract32(ctx->opcode, 2, 1) == 0) {
21564 generate_exception_end(ctx, EXCP_SYSCALL);
21565 } else {
21566 generate_exception_end(ctx, EXCP_RI);
21567 }
21568 break;
21569 case NM_BREAK16:
21570 generate_exception_end(ctx, EXCP_BREAK);
21571 break;
21572 case NM_SDBBP16:
21573 if (is_uhi(extract32(ctx->opcode, 0, 3))) {
21574 gen_helper_do_semihosting(cpu_env);
21575 } else {
21576 if (ctx->hflags & MIPS_HFLAG_SBRI) {
21577 generate_exception_end(ctx, EXCP_RI);
21578 } else {
21579 generate_exception_end(ctx, EXCP_DBp);
21580 }
21581 }
21582 break;
21583 default:
21584 generate_exception_end(ctx, EXCP_RI);
21585 break;
21586 }
21587 }
ea4ca3c2
YK
21588 break;
21589 case NM_P16_SHIFT:
c46562fb
YK
21590 {
21591 int shift = extract32(ctx->opcode, 0, 3);
21592 uint32_t opc = 0;
21593 shift = (shift == 0) ? 8 : shift;
21594
21595 switch (extract32(ctx->opcode, 3, 1)) {
21596 case NM_SLL16:
21597 opc = OPC_SLL;
21598 break;
21599 case NM_SRL16:
21600 opc = OPC_SRL;
21601 break;
21602 }
21603 gen_shift_imm(ctx, opc, rt, rs, shift);
21604 }
ea4ca3c2
YK
21605 break;
21606 case NM_P16C:
8bdb7029
YK
21607 switch (ctx->opcode & 1) {
21608 case NM_POOL16C_0:
80845edf 21609 gen_pool16c_nanomips_insn(ctx);
8bdb7029
YK
21610 break;
21611 case NM_LWXS16:
21612 gen_ldxs(ctx, rt, rs, rd);
21613 break;
21614 }
ea4ca3c2
YK
21615 break;
21616 case NM_P16_A1:
21617 switch (extract32(ctx->opcode, 6, 1)) {
21618 case NM_ADDIUR1SP:
21619 imm = extract32(ctx->opcode, 0, 6) << 2;
21620 gen_arith_imm(ctx, OPC_ADDIU, rt, 29, imm);
21621 break;
21622 default:
21623 generate_exception_end(ctx, EXCP_RI);
21624 break;
21625 }
21626 break;
21627 case NM_P16_A2:
21628 switch (extract32(ctx->opcode, 3, 1)) {
21629 case NM_ADDIUR2:
21630 imm = extract32(ctx->opcode, 0, 3) << 2;
21631 gen_arith_imm(ctx, OPC_ADDIU, rt, rs, imm);
21632 break;
21633 case NM_P_ADDIURS5:
21634 rt = extract32(ctx->opcode, 5, 5);
21635 if (rt != 0) {
21636 /* imm = sign_extend(s[3] . s[2:0] , from_nbits = 4) */
21637 imm = (sextract32(ctx->opcode, 4, 1) << 3) |
21638 (extract32(ctx->opcode, 0, 3));
21639 gen_arith_imm(ctx, OPC_ADDIU, rt, rt, imm);
21640 }
21641 break;
21642 }
21643 break;
21644 case NM_P16_ADDU:
21645 switch (ctx->opcode & 0x1) {
21646 case NM_ADDU16:
21647 gen_arith(ctx, OPC_ADDU, rd, rs, rt);
21648 break;
21649 case NM_SUBU16:
21650 gen_arith(ctx, OPC_SUBU, rd, rs, rt);
21651 break;
21652 }
21653 break;
21654 case NM_P16_4X4:
21655 rt = (extract32(ctx->opcode, 9, 1) << 3) |
21656 extract32(ctx->opcode, 5, 3);
21657 rs = (extract32(ctx->opcode, 4, 1) << 3) |
21658 extract32(ctx->opcode, 0, 3);
21659 rt = decode_gpr_gpr4(rt);
21660 rs = decode_gpr_gpr4(rs);
21661 switch ((extract32(ctx->opcode, 7, 2) & 0x2) |
21662 (extract32(ctx->opcode, 3, 1))) {
21663 case NM_ADDU4X4:
fb32f8c8 21664 check_nms(ctx);
ea4ca3c2
YK
21665 gen_arith(ctx, OPC_ADDU, rt, rs, rt);
21666 break;
21667 case NM_MUL4X4:
fb32f8c8 21668 check_nms(ctx);
ea4ca3c2
YK
21669 gen_r6_muldiv(ctx, R6_OPC_MUL, rt, rs, rt);
21670 break;
21671 default:
21672 generate_exception_end(ctx, EXCP_RI);
21673 break;
21674 }
21675 break;
21676 case NM_LI16:
8869ad02
YK
21677 {
21678 int imm = extract32(ctx->opcode, 0, 7);
21679 imm = (imm == 0x7f ? -1 : imm);
21680 if (rt != 0) {
21681 tcg_gen_movi_tl(cpu_gpr[rt], imm);
21682 }
21683 }
ea4ca3c2
YK
21684 break;
21685 case NM_ANDI16:
80845edf
YK
21686 {
21687 uint32_t u = extract32(ctx->opcode, 0, 4);
21688 u = (u == 12) ? 0xff :
21689 (u == 13) ? 0xffff : u;
21690 gen_logic_imm(ctx, OPC_ANDI, rt, rs, u);
21691 }
ea4ca3c2
YK
21692 break;
21693 case NM_P16_LB:
8bdb7029
YK
21694 offset = extract32(ctx->opcode, 0, 2);
21695 switch (extract32(ctx->opcode, 2, 2)) {
21696 case NM_LB16:
21697 gen_ld(ctx, OPC_LB, rt, rs, offset);
21698 break;
21699 case NM_SB16:
21700 rt = decode_gpr_gpr3_src_store(
21701 NANOMIPS_EXTRACT_RD(ctx->opcode));
21702 gen_st(ctx, OPC_SB, rt, rs, offset);
21703 break;
21704 case NM_LBU16:
21705 gen_ld(ctx, OPC_LBU, rt, rs, offset);
21706 break;
21707 default:
21708 generate_exception_end(ctx, EXCP_RI);
21709 break;
21710 }
ea4ca3c2
YK
21711 break;
21712 case NM_P16_LH:
8bdb7029
YK
21713 offset = extract32(ctx->opcode, 1, 2) << 1;
21714 switch ((extract32(ctx->opcode, 3, 1) << 1) | (ctx->opcode & 1)) {
21715 case NM_LH16:
21716 gen_ld(ctx, OPC_LH, rt, rs, offset);
21717 break;
21718 case NM_SH16:
21719 rt = decode_gpr_gpr3_src_store(
21720 NANOMIPS_EXTRACT_RD(ctx->opcode));
21721 gen_st(ctx, OPC_SH, rt, rs, offset);
21722 break;
21723 case NM_LHU16:
21724 gen_ld(ctx, OPC_LHU, rt, rs, offset);
21725 break;
21726 default:
21727 generate_exception_end(ctx, EXCP_RI);
21728 break;
21729 }
ea4ca3c2
YK
21730 break;
21731 case NM_LW16:
8bdb7029
YK
21732 offset = extract32(ctx->opcode, 0, 4) << 2;
21733 gen_ld(ctx, OPC_LW, rt, rs, offset);
ea4ca3c2
YK
21734 break;
21735 case NM_LWSP16:
8bdb7029
YK
21736 rt = NANOMIPS_EXTRACT_RD5(ctx->opcode);
21737 offset = extract32(ctx->opcode, 0, 5) << 2;
21738 gen_ld(ctx, OPC_LW, rt, 29, offset);
ea4ca3c2
YK
21739 break;
21740 case NM_LW4X4:
fb32f8c8 21741 check_nms(ctx);
8bdb7029
YK
21742 rt = (extract32(ctx->opcode, 9, 1) << 3) |
21743 extract32(ctx->opcode, 5, 3);
21744 rs = (extract32(ctx->opcode, 4, 1) << 3) |
21745 extract32(ctx->opcode, 0, 3);
21746 offset = (extract32(ctx->opcode, 3, 1) << 3) |
21747 (extract32(ctx->opcode, 8, 1) << 2);
21748 rt = decode_gpr_gpr4(rt);
21749 rs = decode_gpr_gpr4(rs);
21750 gen_ld(ctx, OPC_LW, rt, rs, offset);
ea4ca3c2
YK
21751 break;
21752 case NM_SW4X4:
fb32f8c8 21753 check_nms(ctx);
8bdb7029
YK
21754 rt = (extract32(ctx->opcode, 9, 1) << 3) |
21755 extract32(ctx->opcode, 5, 3);
21756 rs = (extract32(ctx->opcode, 4, 1) << 3) |
21757 extract32(ctx->opcode, 0, 3);
21758 offset = (extract32(ctx->opcode, 3, 1) << 3) |
21759 (extract32(ctx->opcode, 8, 1) << 2);
21760 rt = decode_gpr_gpr4_zero(rt);
21761 rs = decode_gpr_gpr4(rs);
21762 gen_st(ctx, OPC_SW, rt, rs, offset);
ea4ca3c2
YK
21763 break;
21764 case NM_LWGP16:
8bdb7029
YK
21765 offset = extract32(ctx->opcode, 0, 7) << 2;
21766 gen_ld(ctx, OPC_LW, rt, 28, offset);
ea4ca3c2
YK
21767 break;
21768 case NM_SWSP16:
8bdb7029
YK
21769 rt = NANOMIPS_EXTRACT_RD5(ctx->opcode);
21770 offset = extract32(ctx->opcode, 0, 5) << 2;
21771 gen_st(ctx, OPC_SW, rt, 29, offset);
ea4ca3c2
YK
21772 break;
21773 case NM_SW16:
8bdb7029
YK
21774 rt = decode_gpr_gpr3_src_store(
21775 NANOMIPS_EXTRACT_RD(ctx->opcode));
21776 rs = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS(ctx->opcode));
21777 offset = extract32(ctx->opcode, 0, 4) << 2;
21778 gen_st(ctx, OPC_SW, rt, rs, offset);
ea4ca3c2
YK
21779 break;
21780 case NM_SWGP16:
8bdb7029
YK
21781 rt = decode_gpr_gpr3_src_store(
21782 NANOMIPS_EXTRACT_RD(ctx->opcode));
21783 offset = extract32(ctx->opcode, 0, 7) << 2;
21784 gen_st(ctx, OPC_SW, rt, 28, offset);
ea4ca3c2
YK
21785 break;
21786 case NM_BC16:
764371d2
SM
21787 gen_compute_branch_nm(ctx, OPC_BEQ, 2, 0, 0,
21788 (sextract32(ctx->opcode, 0, 1) << 10) |
21789 (extract32(ctx->opcode, 1, 9) << 1));
ea4ca3c2
YK
21790 break;
21791 case NM_BALC16:
764371d2
SM
21792 gen_compute_branch_nm(ctx, OPC_BGEZAL, 2, 0, 0,
21793 (sextract32(ctx->opcode, 0, 1) << 10) |
21794 (extract32(ctx->opcode, 1, 9) << 1));
ea4ca3c2
YK
21795 break;
21796 case NM_BEQZC16:
764371d2
SM
21797 gen_compute_branch_nm(ctx, OPC_BEQ, 2, rt, 0,
21798 (sextract32(ctx->opcode, 0, 1) << 7) |
21799 (extract32(ctx->opcode, 1, 6) << 1));
ea4ca3c2
YK
21800 break;
21801 case NM_BNEZC16:
764371d2
SM
21802 gen_compute_branch_nm(ctx, OPC_BNE, 2, rt, 0,
21803 (sextract32(ctx->opcode, 0, 1) << 7) |
21804 (extract32(ctx->opcode, 1, 6) << 1));
ea4ca3c2
YK
21805 break;
21806 case NM_P16_BR:
764371d2
SM
21807 switch (ctx->opcode & 0xf) {
21808 case 0:
21809 /* P16.JRC */
21810 switch (extract32(ctx->opcode, 4, 1)) {
21811 case NM_JRC:
21812 gen_compute_branch_nm(ctx, OPC_JR, 2,
21813 extract32(ctx->opcode, 5, 5), 0, 0);
21814 break;
21815 case NM_JALRC16:
21816 gen_compute_branch_nm(ctx, OPC_JALR, 2,
21817 extract32(ctx->opcode, 5, 5), 31, 0);
21818 break;
21819 }
21820 break;
21821 default:
21822 {
21823 /* P16.BRI */
21824 uint32_t opc = extract32(ctx->opcode, 4, 3) <
21825 extract32(ctx->opcode, 7, 3) ? OPC_BEQ : OPC_BNE;
21826 gen_compute_branch_nm(ctx, opc, 2, rs, rt,
21827 extract32(ctx->opcode, 0, 4) << 1);
21828 }
21829 break;
21830 }
ea4ca3c2
YK
21831 break;
21832 case NM_P16_SR:
bf0718c5
SM
21833 {
21834 int count = extract32(ctx->opcode, 0, 4);
21835 int u = extract32(ctx->opcode, 4, 4) << 4;
21836
21837 rt = 30 + extract32(ctx->opcode, 9, 1);
21838 switch (extract32(ctx->opcode, 8, 1)) {
21839 case NM_SAVE16:
21840 gen_save(ctx, rt, count, 0, u);
21841 break;
21842 case NM_RESTORE_JRC16:
21843 gen_restore(ctx, rt, count, 0, u);
21844 gen_compute_branch_nm(ctx, OPC_JR, 2, 31, 0, 0);
21845 break;
21846 }
21847 }
ea4ca3c2
YK
21848 break;
21849 case NM_MOVEP:
ea4ca3c2 21850 case NM_MOVEPREV:
fb32f8c8 21851 check_nms(ctx);
4d18232c
YK
21852 {
21853 static const int gpr2reg1[] = {4, 5, 6, 7};
21854 static const int gpr2reg2[] = {5, 6, 7, 8};
21855 int re;
21856 int rd2 = extract32(ctx->opcode, 3, 1) << 1 |
21857 extract32(ctx->opcode, 8, 1);
21858 int r1 = gpr2reg1[rd2];
21859 int r2 = gpr2reg2[rd2];
21860 int r3 = extract32(ctx->opcode, 4, 1) << 3 |
21861 extract32(ctx->opcode, 0, 3);
21862 int r4 = extract32(ctx->opcode, 9, 1) << 3 |
21863 extract32(ctx->opcode, 5, 3);
21864 TCGv t0 = tcg_temp_new();
21865 TCGv t1 = tcg_temp_new();
21866 if (op == NM_MOVEP) {
21867 rd = r1;
21868 re = r2;
21869 rs = decode_gpr_gpr4_zero(r3);
21870 rt = decode_gpr_gpr4_zero(r4);
21871 } else {
21872 rd = decode_gpr_gpr4(r3);
21873 re = decode_gpr_gpr4(r4);
21874 rs = r1;
21875 rt = r2;
21876 }
21877 gen_load_gpr(t0, rs);
21878 gen_load_gpr(t1, rt);
21879 tcg_gen_mov_tl(cpu_gpr[rd], t0);
21880 tcg_gen_mov_tl(cpu_gpr[re], t1);
21881 tcg_temp_free(t0);
21882 tcg_temp_free(t1);
21883 }
ea4ca3c2
YK
21884 break;
21885 default:
c0280983 21886 return decode_nanomips_32_48_opc(env, ctx);
ea4ca3c2
YK
21887 }
21888
c533c0f4
AM
21889 return 2;
21890}
21891
21892
3c824109
NF
21893/* SmartMIPS extension to MIPS32 */
21894
21895#if defined(TARGET_MIPS64)
21896
21897/* MDMX extension to MIPS64 */
21898
21899#endif
21900
9b1a1d68 21901/* MIPSDSP functions. */
d75c135e 21902static void gen_mipsdsp_ld(DisasContext *ctx, uint32_t opc,
9b1a1d68
JL
21903 int rd, int base, int offset)
21904{
9b1a1d68
JL
21905 TCGv t0;
21906
9b1a1d68
JL
21907 check_dsp(ctx);
21908 t0 = tcg_temp_new();
21909
21910 if (base == 0) {
21911 gen_load_gpr(t0, offset);
21912 } else if (offset == 0) {
21913 gen_load_gpr(t0, base);
21914 } else {
21915 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[offset]);
21916 }
21917
9b1a1d68
JL
21918 switch (opc) {
21919 case OPC_LBUX:
5f68f5ae 21920 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB);
9b1a1d68 21921 gen_store_gpr(t0, rd);
9b1a1d68
JL
21922 break;
21923 case OPC_LHX:
5f68f5ae 21924 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW);
9b1a1d68 21925 gen_store_gpr(t0, rd);
9b1a1d68
JL
21926 break;
21927 case OPC_LWX:
5f68f5ae 21928 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
9b1a1d68 21929 gen_store_gpr(t0, rd);
9b1a1d68
JL
21930 break;
21931#if defined(TARGET_MIPS64)
21932 case OPC_LDX:
5f68f5ae 21933 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
9b1a1d68 21934 gen_store_gpr(t0, rd);
9b1a1d68
JL
21935 break;
21936#endif
21937 }
9b1a1d68
JL
21938 tcg_temp_free(t0);
21939}
21940
461c08df
JL
21941static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
21942 int ret, int v1, int v2)
21943{
461c08df
JL
21944 TCGv v1_t;
21945 TCGv v2_t;
21946
21947 if (ret == 0) {
21948 /* Treat as NOP. */
461c08df
JL
21949 return;
21950 }
21951
21952 v1_t = tcg_temp_new();
21953 v2_t = tcg_temp_new();
21954
21955 gen_load_gpr(v1_t, v1);
21956 gen_load_gpr(v2_t, v2);
21957
21958 switch (op1) {
21959 /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
21960 case OPC_MULT_G_2E:
908f6be1 21961 check_dsp_r2(ctx);
461c08df
JL
21962 switch (op2) {
21963 case OPC_ADDUH_QB:
21964 gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t);
21965 break;
21966 case OPC_ADDUH_R_QB:
21967 gen_helper_adduh_r_qb(cpu_gpr[ret], v1_t, v2_t);
21968 break;
21969 case OPC_ADDQH_PH:
21970 gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t);
21971 break;
21972 case OPC_ADDQH_R_PH:
21973 gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
21974 break;
21975 case OPC_ADDQH_W:
21976 gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t);
21977 break;
21978 case OPC_ADDQH_R_W:
21979 gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t);
21980 break;
21981 case OPC_SUBUH_QB:
21982 gen_helper_subuh_qb(cpu_gpr[ret], v1_t, v2_t);
21983 break;
21984 case OPC_SUBUH_R_QB:
21985 gen_helper_subuh_r_qb(cpu_gpr[ret], v1_t, v2_t);
21986 break;
21987 case OPC_SUBQH_PH:
21988 gen_helper_subqh_ph(cpu_gpr[ret], v1_t, v2_t);
21989 break;
21990 case OPC_SUBQH_R_PH:
21991 gen_helper_subqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
21992 break;
21993 case OPC_SUBQH_W:
21994 gen_helper_subqh_w(cpu_gpr[ret], v1_t, v2_t);
21995 break;
21996 case OPC_SUBQH_R_W:
21997 gen_helper_subqh_r_w(cpu_gpr[ret], v1_t, v2_t);
21998 break;
21999 }
22000 break;
22001 case OPC_ABSQ_S_PH_DSP:
22002 switch (op2) {
22003 case OPC_ABSQ_S_QB:
908f6be1 22004 check_dsp_r2(ctx);
461c08df
JL
22005 gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, cpu_env);
22006 break;
22007 case OPC_ABSQ_S_PH:
22008 check_dsp(ctx);
22009 gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, cpu_env);
22010 break;
22011 case OPC_ABSQ_S_W:
22012 check_dsp(ctx);
22013 gen_helper_absq_s_w(cpu_gpr[ret], v2_t, cpu_env);
22014 break;
22015 case OPC_PRECEQ_W_PHL:
22016 check_dsp(ctx);
22017 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000);
22018 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
22019 break;
22020 case OPC_PRECEQ_W_PHR:
22021 check_dsp(ctx);
22022 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF);
22023 tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16);
22024 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
22025 break;
22026 case OPC_PRECEQU_PH_QBL:
22027 check_dsp(ctx);
22028 gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t);
22029 break;
22030 case OPC_PRECEQU_PH_QBR:
22031 check_dsp(ctx);
22032 gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t);
22033 break;
22034 case OPC_PRECEQU_PH_QBLA:
22035 check_dsp(ctx);
22036 gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t);
22037 break;
22038 case OPC_PRECEQU_PH_QBRA:
22039 check_dsp(ctx);
22040 gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t);
22041 break;
22042 case OPC_PRECEU_PH_QBL:
22043 check_dsp(ctx);
22044 gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t);
22045 break;
22046 case OPC_PRECEU_PH_QBR:
22047 check_dsp(ctx);
22048 gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t);
22049 break;
22050 case OPC_PRECEU_PH_QBLA:
22051 check_dsp(ctx);
22052 gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t);
22053 break;
22054 case OPC_PRECEU_PH_QBRA:
22055 check_dsp(ctx);
22056 gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t);
22057 break;
22058 }
22059 break;
22060 case OPC_ADDU_QB_DSP:
22061 switch (op2) {
22062 case OPC_ADDQ_PH:
22063 check_dsp(ctx);
22064 gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22065 break;
22066 case OPC_ADDQ_S_PH:
22067 check_dsp(ctx);
22068 gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22069 break;
22070 case OPC_ADDQ_S_W:
22071 check_dsp(ctx);
22072 gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22073 break;
22074 case OPC_ADDU_QB:
22075 check_dsp(ctx);
22076 gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22077 break;
22078 case OPC_ADDU_S_QB:
22079 check_dsp(ctx);
22080 gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22081 break;
22082 case OPC_ADDU_PH:
908f6be1 22083 check_dsp_r2(ctx);
461c08df
JL
22084 gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22085 break;
22086 case OPC_ADDU_S_PH:
908f6be1 22087 check_dsp_r2(ctx);
461c08df
JL
22088 gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22089 break;
22090 case OPC_SUBQ_PH:
22091 check_dsp(ctx);
22092 gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22093 break;
22094 case OPC_SUBQ_S_PH:
22095 check_dsp(ctx);
22096 gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22097 break;
22098 case OPC_SUBQ_S_W:
22099 check_dsp(ctx);
22100 gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22101 break;
22102 case OPC_SUBU_QB:
22103 check_dsp(ctx);
22104 gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22105 break;
22106 case OPC_SUBU_S_QB:
22107 check_dsp(ctx);
22108 gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22109 break;
22110 case OPC_SUBU_PH:
908f6be1 22111 check_dsp_r2(ctx);
461c08df
JL
22112 gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22113 break;
22114 case OPC_SUBU_S_PH:
908f6be1 22115 check_dsp_r2(ctx);
461c08df
JL
22116 gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22117 break;
22118 case OPC_ADDSC:
22119 check_dsp(ctx);
22120 gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22121 break;
22122 case OPC_ADDWC:
22123 check_dsp(ctx);
22124 gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22125 break;
22126 case OPC_MODSUB:
22127 check_dsp(ctx);
22128 gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t);
22129 break;
22130 case OPC_RADDU_W_QB:
22131 check_dsp(ctx);
22132 gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t);
22133 break;
22134 }
22135 break;
22136 case OPC_CMPU_EQ_QB_DSP:
22137 switch (op2) {
22138 case OPC_PRECR_QB_PH:
908f6be1 22139 check_dsp_r2(ctx);
461c08df
JL
22140 gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t);
22141 break;
22142 case OPC_PRECRQ_QB_PH:
22143 check_dsp(ctx);
22144 gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t);
22145 break;
22146 case OPC_PRECR_SRA_PH_W:
908f6be1 22147 check_dsp_r2(ctx);
461c08df
JL
22148 {
22149 TCGv_i32 sa_t = tcg_const_i32(v2);
22150 gen_helper_precr_sra_ph_w(cpu_gpr[ret], sa_t, v1_t,
22151 cpu_gpr[ret]);
22152 tcg_temp_free_i32(sa_t);
22153 break;
22154 }
22155 case OPC_PRECR_SRA_R_PH_W:
908f6be1 22156 check_dsp_r2(ctx);
461c08df
JL
22157 {
22158 TCGv_i32 sa_t = tcg_const_i32(v2);
22159 gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t,
22160 cpu_gpr[ret]);
22161 tcg_temp_free_i32(sa_t);
22162 break;
22163 }
22164 case OPC_PRECRQ_PH_W:
22165 check_dsp(ctx);
22166 gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t);
22167 break;
22168 case OPC_PRECRQ_RS_PH_W:
22169 check_dsp(ctx);
22170 gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22171 break;
22172 case OPC_PRECRQU_S_QB_PH:
22173 check_dsp(ctx);
22174 gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22175 break;
22176 }
22177 break;
22178#ifdef TARGET_MIPS64
22179 case OPC_ABSQ_S_QH_DSP:
22180 switch (op2) {
22181 case OPC_PRECEQ_L_PWL:
22182 check_dsp(ctx);
22183 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull);
22184 break;
22185 case OPC_PRECEQ_L_PWR:
22186 check_dsp(ctx);
22187 tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32);
22188 break;
22189 case OPC_PRECEQ_PW_QHL:
22190 check_dsp(ctx);
22191 gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t);
22192 break;
22193 case OPC_PRECEQ_PW_QHR:
22194 check_dsp(ctx);
22195 gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t);
22196 break;
22197 case OPC_PRECEQ_PW_QHLA:
22198 check_dsp(ctx);
22199 gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t);
22200 break;
22201 case OPC_PRECEQ_PW_QHRA:
22202 check_dsp(ctx);
22203 gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t);
22204 break;
22205 case OPC_PRECEQU_QH_OBL:
22206 check_dsp(ctx);
22207 gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t);
22208 break;
22209 case OPC_PRECEQU_QH_OBR:
22210 check_dsp(ctx);
22211 gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t);
22212 break;
22213 case OPC_PRECEQU_QH_OBLA:
22214 check_dsp(ctx);
22215 gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t);
22216 break;
22217 case OPC_PRECEQU_QH_OBRA:
22218 check_dsp(ctx);
22219 gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t);
22220 break;
22221 case OPC_PRECEU_QH_OBL:
22222 check_dsp(ctx);
22223 gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t);
22224 break;
22225 case OPC_PRECEU_QH_OBR:
22226 check_dsp(ctx);
22227 gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t);
22228 break;
22229 case OPC_PRECEU_QH_OBLA:
22230 check_dsp(ctx);
22231 gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t);
22232 break;
22233 case OPC_PRECEU_QH_OBRA:
22234 check_dsp(ctx);
22235 gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t);
22236 break;
22237 case OPC_ABSQ_S_OB:
908f6be1 22238 check_dsp_r2(ctx);
461c08df
JL
22239 gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, cpu_env);
22240 break;
22241 case OPC_ABSQ_S_PW:
22242 check_dsp(ctx);
22243 gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, cpu_env);
22244 break;
22245 case OPC_ABSQ_S_QH:
22246 check_dsp(ctx);
22247 gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, cpu_env);
22248 break;
22249 }
22250 break;
22251 case OPC_ADDU_OB_DSP:
22252 switch (op2) {
22253 case OPC_RADDU_L_OB:
22254 check_dsp(ctx);
22255 gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t);
22256 break;
22257 case OPC_SUBQ_PW:
22258 check_dsp(ctx);
22259 gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22260 break;
22261 case OPC_SUBQ_S_PW:
22262 check_dsp(ctx);
22263 gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22264 break;
22265 case OPC_SUBQ_QH:
22266 check_dsp(ctx);
22267 gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22268 break;
22269 case OPC_SUBQ_S_QH:
22270 check_dsp(ctx);
22271 gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22272 break;
22273 case OPC_SUBU_OB:
22274 check_dsp(ctx);
22275 gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22276 break;
22277 case OPC_SUBU_S_OB:
22278 check_dsp(ctx);
22279 gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22280 break;
22281 case OPC_SUBU_QH:
908f6be1 22282 check_dsp_r2(ctx);
461c08df
JL
22283 gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22284 break;
22285 case OPC_SUBU_S_QH:
908f6be1 22286 check_dsp_r2(ctx);
461c08df
JL
22287 gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22288 break;
22289 case OPC_SUBUH_OB:
908f6be1 22290 check_dsp_r2(ctx);
461c08df
JL
22291 gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t);
22292 break;
22293 case OPC_SUBUH_R_OB:
908f6be1 22294 check_dsp_r2(ctx);
461c08df
JL
22295 gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t);
22296 break;
22297 case OPC_ADDQ_PW:
22298 check_dsp(ctx);
22299 gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22300 break;
22301 case OPC_ADDQ_S_PW:
22302 check_dsp(ctx);
22303 gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22304 break;
22305 case OPC_ADDQ_QH:
22306 check_dsp(ctx);
22307 gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22308 break;
22309 case OPC_ADDQ_S_QH:
22310 check_dsp(ctx);
22311 gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22312 break;
22313 case OPC_ADDU_OB:
22314 check_dsp(ctx);
22315 gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22316 break;
22317 case OPC_ADDU_S_OB:
22318 check_dsp(ctx);
22319 gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22320 break;
22321 case OPC_ADDU_QH:
908f6be1 22322 check_dsp_r2(ctx);
461c08df
JL
22323 gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22324 break;
22325 case OPC_ADDU_S_QH:
908f6be1 22326 check_dsp_r2(ctx);
461c08df
JL
22327 gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22328 break;
22329 case OPC_ADDUH_OB:
908f6be1 22330 check_dsp_r2(ctx);
461c08df
JL
22331 gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t);
22332 break;
22333 case OPC_ADDUH_R_OB:
908f6be1 22334 check_dsp_r2(ctx);
461c08df
JL
22335 gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t);
22336 break;
22337 }
22338 break;
22339 case OPC_CMPU_EQ_OB_DSP:
22340 switch (op2) {
22341 case OPC_PRECR_OB_QH:
908f6be1 22342 check_dsp_r2(ctx);
461c08df
JL
22343 gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t);
22344 break;
22345 case OPC_PRECR_SRA_QH_PW:
908f6be1 22346 check_dsp_r2(ctx);
461c08df
JL
22347 {
22348 TCGv_i32 ret_t = tcg_const_i32(ret);
22349 gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t);
22350 tcg_temp_free_i32(ret_t);
22351 break;
22352 }
22353 case OPC_PRECR_SRA_R_QH_PW:
908f6be1 22354 check_dsp_r2(ctx);
461c08df
JL
22355 {
22356 TCGv_i32 sa_v = tcg_const_i32(ret);
22357 gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v);
22358 tcg_temp_free_i32(sa_v);
22359 break;
22360 }
22361 case OPC_PRECRQ_OB_QH:
22362 check_dsp(ctx);
22363 gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t);
22364 break;
22365 case OPC_PRECRQ_PW_L:
22366 check_dsp(ctx);
22367 gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t);
22368 break;
22369 case OPC_PRECRQ_QH_PW:
22370 check_dsp(ctx);
22371 gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t);
22372 break;
22373 case OPC_PRECRQ_RS_QH_PW:
22374 check_dsp(ctx);
22375 gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22376 break;
22377 case OPC_PRECRQU_S_OB_QH:
22378 check_dsp(ctx);
22379 gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22380 break;
22381 }
22382 break;
22383#endif
22384 }
22385
22386 tcg_temp_free(v1_t);
22387 tcg_temp_free(v2_t);
461c08df 22388}
9b1a1d68 22389
77c5fa8b
JL
22390static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc,
22391 int ret, int v1, int v2)
22392{
22393 uint32_t op2;
77c5fa8b
JL
22394 TCGv t0;
22395 TCGv v1_t;
22396 TCGv v2_t;
22397
22398 if (ret == 0) {
22399 /* Treat as NOP. */
77c5fa8b
JL
22400 return;
22401 }
22402
22403 t0 = tcg_temp_new();
22404 v1_t = tcg_temp_new();
22405 v2_t = tcg_temp_new();
22406
22407 tcg_gen_movi_tl(t0, v1);
22408 gen_load_gpr(v1_t, v1);
22409 gen_load_gpr(v2_t, v2);
22410
22411 switch (opc) {
22412 case OPC_SHLL_QB_DSP:
22413 {
22414 op2 = MASK_SHLL_QB(ctx->opcode);
22415 switch (op2) {
22416 case OPC_SHLL_QB:
22417 check_dsp(ctx);
22418 gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, cpu_env);
22419 break;
22420 case OPC_SHLLV_QB:
22421 check_dsp(ctx);
22422 gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22423 break;
22424 case OPC_SHLL_PH:
22425 check_dsp(ctx);
22426 gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
22427 break;
22428 case OPC_SHLLV_PH:
22429 check_dsp(ctx);
22430 gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22431 break;
22432 case OPC_SHLL_S_PH:
22433 check_dsp(ctx);
22434 gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
22435 break;
22436 case OPC_SHLLV_S_PH:
22437 check_dsp(ctx);
22438 gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22439 break;
22440 case OPC_SHLL_S_W:
22441 check_dsp(ctx);
22442 gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, cpu_env);
22443 break;
22444 case OPC_SHLLV_S_W:
22445 check_dsp(ctx);
22446 gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22447 break;
22448 case OPC_SHRL_QB:
22449 check_dsp(ctx);
22450 gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t);
22451 break;
22452 case OPC_SHRLV_QB:
22453 check_dsp(ctx);
22454 gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t);
22455 break;
22456 case OPC_SHRL_PH:
908f6be1 22457 check_dsp_r2(ctx);
77c5fa8b
JL
22458 gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t);
22459 break;
22460 case OPC_SHRLV_PH:
908f6be1 22461 check_dsp_r2(ctx);
77c5fa8b
JL
22462 gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t);
22463 break;
22464 case OPC_SHRA_QB:
908f6be1 22465 check_dsp_r2(ctx);
77c5fa8b
JL
22466 gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t);
22467 break;
22468 case OPC_SHRA_R_QB:
908f6be1 22469 check_dsp_r2(ctx);
77c5fa8b
JL
22470 gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t);
22471 break;
22472 case OPC_SHRAV_QB:
908f6be1 22473 check_dsp_r2(ctx);
77c5fa8b
JL
22474 gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t);
22475 break;
22476 case OPC_SHRAV_R_QB:
908f6be1 22477 check_dsp_r2(ctx);
77c5fa8b
JL
22478 gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t);
22479 break;
22480 case OPC_SHRA_PH:
22481 check_dsp(ctx);
22482 gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t);
22483 break;
22484 case OPC_SHRA_R_PH:
22485 check_dsp(ctx);
22486 gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t);
22487 break;
22488 case OPC_SHRAV_PH:
22489 check_dsp(ctx);
22490 gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t);
22491 break;
22492 case OPC_SHRAV_R_PH:
22493 check_dsp(ctx);
22494 gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t);
22495 break;
22496 case OPC_SHRA_R_W:
22497 check_dsp(ctx);
22498 gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t);
22499 break;
22500 case OPC_SHRAV_R_W:
22501 check_dsp(ctx);
22502 gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t);
22503 break;
22504 default: /* Invalid */
22505 MIPS_INVAL("MASK SHLL.QB");
9c708c7f 22506 generate_exception_end(ctx, EXCP_RI);
77c5fa8b
JL
22507 break;
22508 }
22509 break;
22510 }
22511#ifdef TARGET_MIPS64
22512 case OPC_SHLL_OB_DSP:
22513 op2 = MASK_SHLL_OB(ctx->opcode);
22514 switch (op2) {
22515 case OPC_SHLL_PW:
22516 check_dsp(ctx);
22517 gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
22518 break;
22519 case OPC_SHLLV_PW:
22520 check_dsp(ctx);
22521 gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
22522 break;
22523 case OPC_SHLL_S_PW:
22524 check_dsp(ctx);
22525 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
22526 break;
22527 case OPC_SHLLV_S_PW:
22528 check_dsp(ctx);
22529 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
22530 break;
22531 case OPC_SHLL_OB:
22532 check_dsp(ctx);
22533 gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, cpu_env);
22534 break;
22535 case OPC_SHLLV_OB:
22536 check_dsp(ctx);
22537 gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, cpu_env);
22538 break;
22539 case OPC_SHLL_QH:
22540 check_dsp(ctx);
22541 gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
22542 break;
22543 case OPC_SHLLV_QH:
22544 check_dsp(ctx);
22545 gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
22546 break;
22547 case OPC_SHLL_S_QH:
22548 check_dsp(ctx);
22549 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
22550 break;
22551 case OPC_SHLLV_S_QH:
22552 check_dsp(ctx);
22553 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
22554 break;
22555 case OPC_SHRA_OB:
908f6be1 22556 check_dsp_r2(ctx);
77c5fa8b
JL
22557 gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0);
22558 break;
22559 case OPC_SHRAV_OB:
908f6be1 22560 check_dsp_r2(ctx);
77c5fa8b
JL
22561 gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t);
22562 break;
22563 case OPC_SHRA_R_OB:
908f6be1 22564 check_dsp_r2(ctx);
77c5fa8b
JL
22565 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0);
22566 break;
22567 case OPC_SHRAV_R_OB:
908f6be1 22568 check_dsp_r2(ctx);
77c5fa8b
JL
22569 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t);
22570 break;
22571 case OPC_SHRA_PW:
22572 check_dsp(ctx);
22573 gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0);
22574 break;
22575 case OPC_SHRAV_PW:
22576 check_dsp(ctx);
22577 gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t);
22578 break;
22579 case OPC_SHRA_R_PW:
22580 check_dsp(ctx);
22581 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0);
22582 break;
22583 case OPC_SHRAV_R_PW:
22584 check_dsp(ctx);
22585 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t);
22586 break;
22587 case OPC_SHRA_QH:
22588 check_dsp(ctx);
22589 gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0);
22590 break;
22591 case OPC_SHRAV_QH:
22592 check_dsp(ctx);
22593 gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t);
22594 break;
22595 case OPC_SHRA_R_QH:
22596 check_dsp(ctx);
22597 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0);
22598 break;
22599 case OPC_SHRAV_R_QH:
22600 check_dsp(ctx);
22601 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t);
22602 break;
22603 case OPC_SHRL_OB:
22604 check_dsp(ctx);
22605 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0);
22606 break;
22607 case OPC_SHRLV_OB:
22608 check_dsp(ctx);
22609 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t);
22610 break;
22611 case OPC_SHRL_QH:
908f6be1 22612 check_dsp_r2(ctx);
77c5fa8b
JL
22613 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0);
22614 break;
22615 case OPC_SHRLV_QH:
908f6be1 22616 check_dsp_r2(ctx);
77c5fa8b
JL
22617 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t);
22618 break;
22619 default: /* Invalid */
22620 MIPS_INVAL("MASK SHLL.OB");
9c708c7f 22621 generate_exception_end(ctx, EXCP_RI);
77c5fa8b
JL
22622 break;
22623 }
22624 break;
22625#endif
22626 }
22627
22628 tcg_temp_free(t0);
22629 tcg_temp_free(v1_t);
22630 tcg_temp_free(v2_t);
77c5fa8b
JL
22631}
22632
a22260ae
JL
22633static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2,
22634 int ret, int v1, int v2, int check_ret)
22635{
a22260ae
JL
22636 TCGv_i32 t0;
22637 TCGv v1_t;
22638 TCGv v2_t;
22639
22640 if ((ret == 0) && (check_ret == 1)) {
22641 /* Treat as NOP. */
a22260ae
JL
22642 return;
22643 }
22644
22645 t0 = tcg_temp_new_i32();
22646 v1_t = tcg_temp_new();
22647 v2_t = tcg_temp_new();
22648
22649 tcg_gen_movi_i32(t0, ret);
22650 gen_load_gpr(v1_t, v1);
22651 gen_load_gpr(v2_t, v2);
22652
22653 switch (op1) {
22654 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
22655 * the same mask and op1. */
22656 case OPC_MULT_G_2E:
908f6be1 22657 check_dsp_r2(ctx);
a22260ae
JL
22658 switch (op2) {
22659 case OPC_MUL_PH:
22660 gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22661 break;
22662 case OPC_MUL_S_PH:
22663 gen_helper_mul_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22664 break;
22665 case OPC_MULQ_S_W:
22666 gen_helper_mulq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22667 break;
22668 case OPC_MULQ_RS_W:
22669 gen_helper_mulq_rs_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22670 break;
22671 }
22672 break;
22673 case OPC_DPA_W_PH_DSP:
22674 switch (op2) {
22675 case OPC_DPAU_H_QBL:
22676 check_dsp(ctx);
22677 gen_helper_dpau_h_qbl(t0, v1_t, v2_t, cpu_env);
22678 break;
22679 case OPC_DPAU_H_QBR:
22680 check_dsp(ctx);
22681 gen_helper_dpau_h_qbr(t0, v1_t, v2_t, cpu_env);
22682 break;
22683 case OPC_DPSU_H_QBL:
22684 check_dsp(ctx);
22685 gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, cpu_env);
22686 break;
22687 case OPC_DPSU_H_QBR:
22688 check_dsp(ctx);
22689 gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, cpu_env);
22690 break;
22691 case OPC_DPA_W_PH:
908f6be1 22692 check_dsp_r2(ctx);
a22260ae
JL
22693 gen_helper_dpa_w_ph(t0, v1_t, v2_t, cpu_env);
22694 break;
22695 case OPC_DPAX_W_PH:
908f6be1 22696 check_dsp_r2(ctx);
a22260ae
JL
22697 gen_helper_dpax_w_ph(t0, v1_t, v2_t, cpu_env);
22698 break;
22699 case OPC_DPAQ_S_W_PH:
22700 check_dsp(ctx);
22701 gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
22702 break;
22703 case OPC_DPAQX_S_W_PH:
908f6be1 22704 check_dsp_r2(ctx);
a22260ae
JL
22705 gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
22706 break;
22707 case OPC_DPAQX_SA_W_PH:
908f6be1 22708 check_dsp_r2(ctx);
a22260ae
JL
22709 gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
22710 break;
22711 case OPC_DPS_W_PH:
908f6be1 22712 check_dsp_r2(ctx);
a22260ae
JL
22713 gen_helper_dps_w_ph(t0, v1_t, v2_t, cpu_env);
22714 break;
22715 case OPC_DPSX_W_PH:
908f6be1 22716 check_dsp_r2(ctx);
a22260ae
JL
22717 gen_helper_dpsx_w_ph(t0, v1_t, v2_t, cpu_env);
22718 break;
22719 case OPC_DPSQ_S_W_PH:
22720 check_dsp(ctx);
22721 gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, cpu_env);
22722 break;
22723 case OPC_DPSQX_S_W_PH:
908f6be1 22724 check_dsp_r2(ctx);
a22260ae
JL
22725 gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
22726 break;
22727 case OPC_DPSQX_SA_W_PH:
908f6be1 22728 check_dsp_r2(ctx);
a22260ae
JL
22729 gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
22730 break;
22731 case OPC_MULSAQ_S_W_PH:
22732 check_dsp(ctx);
22733 gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
22734 break;
22735 case OPC_DPAQ_SA_L_W:
22736 check_dsp(ctx);
22737 gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, cpu_env);
22738 break;
22739 case OPC_DPSQ_SA_L_W:
22740 check_dsp(ctx);
22741 gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, cpu_env);
22742 break;
22743 case OPC_MAQ_S_W_PHL:
22744 check_dsp(ctx);
22745 gen_helper_maq_s_w_phl(t0, v1_t, v2_t, cpu_env);
22746 break;
22747 case OPC_MAQ_S_W_PHR:
22748 check_dsp(ctx);
22749 gen_helper_maq_s_w_phr(t0, v1_t, v2_t, cpu_env);
22750 break;
22751 case OPC_MAQ_SA_W_PHL:
22752 check_dsp(ctx);
22753 gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, cpu_env);
22754 break;
22755 case OPC_MAQ_SA_W_PHR:
22756 check_dsp(ctx);
22757 gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, cpu_env);
22758 break;
22759 case OPC_MULSA_W_PH:
908f6be1 22760 check_dsp_r2(ctx);
a22260ae
JL
22761 gen_helper_mulsa_w_ph(t0, v1_t, v2_t, cpu_env);
22762 break;
22763 }
22764 break;
22765#ifdef TARGET_MIPS64
22766 case OPC_DPAQ_W_QH_DSP:
22767 {
22768 int ac = ret & 0x03;
22769 tcg_gen_movi_i32(t0, ac);
22770
22771 switch (op2) {
22772 case OPC_DMADD:
22773 check_dsp(ctx);
22774 gen_helper_dmadd(v1_t, v2_t, t0, cpu_env);
22775 break;
22776 case OPC_DMADDU:
22777 check_dsp(ctx);
22778 gen_helper_dmaddu(v1_t, v2_t, t0, cpu_env);
22779 break;
22780 case OPC_DMSUB:
22781 check_dsp(ctx);
22782 gen_helper_dmsub(v1_t, v2_t, t0, cpu_env);
22783 break;
22784 case OPC_DMSUBU:
22785 check_dsp(ctx);
22786 gen_helper_dmsubu(v1_t, v2_t, t0, cpu_env);
22787 break;
22788 case OPC_DPA_W_QH:
908f6be1 22789 check_dsp_r2(ctx);
a22260ae
JL
22790 gen_helper_dpa_w_qh(v1_t, v2_t, t0, cpu_env);
22791 break;
22792 case OPC_DPAQ_S_W_QH:
22793 check_dsp(ctx);
22794 gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
22795 break;
22796 case OPC_DPAQ_SA_L_PW:
22797 check_dsp(ctx);
22798 gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
22799 break;
22800 case OPC_DPAU_H_OBL:
22801 check_dsp(ctx);
22802 gen_helper_dpau_h_obl(v1_t, v2_t, t0, cpu_env);
22803 break;
22804 case OPC_DPAU_H_OBR:
22805 check_dsp(ctx);
22806 gen_helper_dpau_h_obr(v1_t, v2_t, t0, cpu_env);
22807 break;
22808 case OPC_DPS_W_QH:
908f6be1 22809 check_dsp_r2(ctx);
a22260ae
JL
22810 gen_helper_dps_w_qh(v1_t, v2_t, t0, cpu_env);
22811 break;
22812 case OPC_DPSQ_S_W_QH:
22813 check_dsp(ctx);
22814 gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, cpu_env);
22815 break;
22816 case OPC_DPSQ_SA_L_PW:
22817 check_dsp(ctx);
22818 gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
22819 break;
22820 case OPC_DPSU_H_OBL:
22821 check_dsp(ctx);
22822 gen_helper_dpsu_h_obl(v1_t, v2_t, t0, cpu_env);
22823 break;
22824 case OPC_DPSU_H_OBR:
22825 check_dsp(ctx);
22826 gen_helper_dpsu_h_obr(v1_t, v2_t, t0, cpu_env);
22827 break;
22828 case OPC_MAQ_S_L_PWL:
22829 check_dsp(ctx);
22830 gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, cpu_env);
22831 break;
22832 case OPC_MAQ_S_L_PWR:
22833 check_dsp(ctx);
22834 gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, cpu_env);
22835 break;
22836 case OPC_MAQ_S_W_QHLL:
22837 check_dsp(ctx);
22838 gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, cpu_env);
22839 break;
22840 case OPC_MAQ_SA_W_QHLL:
22841 check_dsp(ctx);
22842 gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, cpu_env);
22843 break;
22844 case OPC_MAQ_S_W_QHLR:
22845 check_dsp(ctx);
22846 gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, cpu_env);
22847 break;
22848 case OPC_MAQ_SA_W_QHLR:
22849 check_dsp(ctx);
22850 gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, cpu_env);
22851 break;
22852 case OPC_MAQ_S_W_QHRL:
22853 check_dsp(ctx);
22854 gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, cpu_env);
22855 break;
22856 case OPC_MAQ_SA_W_QHRL:
22857 check_dsp(ctx);
22858 gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, cpu_env);
22859 break;
22860 case OPC_MAQ_S_W_QHRR:
22861 check_dsp(ctx);
22862 gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, cpu_env);
22863 break;
22864 case OPC_MAQ_SA_W_QHRR:
22865 check_dsp(ctx);
22866 gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, cpu_env);
22867 break;
22868 case OPC_MULSAQ_S_L_PW:
22869 check_dsp(ctx);
22870 gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, cpu_env);
22871 break;
22872 case OPC_MULSAQ_S_W_QH:
22873 check_dsp(ctx);
22874 gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
22875 break;
22876 }
22877 }
22878 break;
22879#endif
22880 case OPC_ADDU_QB_DSP:
22881 switch (op2) {
22882 case OPC_MULEU_S_PH_QBL:
22883 check_dsp(ctx);
22884 gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22885 break;
22886 case OPC_MULEU_S_PH_QBR:
22887 check_dsp(ctx);
22888 gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22889 break;
22890 case OPC_MULQ_RS_PH:
22891 check_dsp(ctx);
22892 gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22893 break;
22894 case OPC_MULEQ_S_W_PHL:
22895 check_dsp(ctx);
22896 gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22897 break;
22898 case OPC_MULEQ_S_W_PHR:
22899 check_dsp(ctx);
22900 gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22901 break;
22902 case OPC_MULQ_S_PH:
908f6be1 22903 check_dsp_r2(ctx);
a22260ae
JL
22904 gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22905 break;
22906 }
22907 break;
22908#ifdef TARGET_MIPS64
22909 case OPC_ADDU_OB_DSP:
22910 switch (op2) {
22911 case OPC_MULEQ_S_PW_QHL:
22912 check_dsp(ctx);
22913 gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22914 break;
22915 case OPC_MULEQ_S_PW_QHR:
22916 check_dsp(ctx);
22917 gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22918 break;
22919 case OPC_MULEU_S_QH_OBL:
22920 check_dsp(ctx);
22921 gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22922 break;
22923 case OPC_MULEU_S_QH_OBR:
22924 check_dsp(ctx);
22925 gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22926 break;
22927 case OPC_MULQ_RS_QH:
22928 check_dsp(ctx);
22929 gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22930 break;
22931 }
22932 break;
22933#endif
22934 }
22935
22936 tcg_temp_free_i32(t0);
22937 tcg_temp_free(v1_t);
22938 tcg_temp_free(v2_t);
a22260ae
JL
22939}
22940
d75c135e 22941static void gen_mipsdsp_bitinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
1cb6686c
JL
22942 int ret, int val)
22943{
1cb6686c
JL
22944 int16_t imm;
22945 TCGv t0;
22946 TCGv val_t;
22947
22948 if (ret == 0) {
22949 /* Treat as NOP. */
1cb6686c
JL
22950 return;
22951 }
22952
22953 t0 = tcg_temp_new();
22954 val_t = tcg_temp_new();
22955 gen_load_gpr(val_t, val);
22956
22957 switch (op1) {
22958 case OPC_ABSQ_S_PH_DSP:
22959 switch (op2) {
22960 case OPC_BITREV:
22961 check_dsp(ctx);
22962 gen_helper_bitrev(cpu_gpr[ret], val_t);
22963 break;
22964 case OPC_REPL_QB:
22965 check_dsp(ctx);
22966 {
22967 target_long result;
22968 imm = (ctx->opcode >> 16) & 0xFF;
22969 result = (uint32_t)imm << 24 |
22970 (uint32_t)imm << 16 |
22971 (uint32_t)imm << 8 |
22972 (uint32_t)imm;
22973 result = (int32_t)result;
22974 tcg_gen_movi_tl(cpu_gpr[ret], result);
22975 }
22976 break;
22977 case OPC_REPLV_QB:
22978 check_dsp(ctx);
22979 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
22980 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
22981 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
22982 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
22983 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
22984 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
22985 break;
22986 case OPC_REPL_PH:
22987 check_dsp(ctx);
22988 {
22989 imm = (ctx->opcode >> 16) & 0x03FF;
c4aaba92 22990 imm = (int16_t)(imm << 6) >> 6;
1cb6686c
JL
22991 tcg_gen_movi_tl(cpu_gpr[ret], \
22992 (target_long)((int32_t)imm << 16 | \
c4aaba92 22993 (uint16_t)imm));
1cb6686c
JL
22994 }
22995 break;
22996 case OPC_REPLV_PH:
22997 check_dsp(ctx);
22998 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
22999 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
23000 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23001 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
23002 break;
23003 }
23004 break;
23005#ifdef TARGET_MIPS64
23006 case OPC_ABSQ_S_QH_DSP:
23007 switch (op2) {
23008 case OPC_REPL_OB:
23009 check_dsp(ctx);
23010 {
23011 target_long temp;
23012
23013 imm = (ctx->opcode >> 16) & 0xFF;
23014 temp = ((uint64_t)imm << 8) | (uint64_t)imm;
23015 temp = (temp << 16) | temp;
23016 temp = (temp << 32) | temp;
23017 tcg_gen_movi_tl(cpu_gpr[ret], temp);
23018 break;
23019 }
23020 case OPC_REPL_PW:
23021 check_dsp(ctx);
23022 {
23023 target_long temp;
23024
23025 imm = (ctx->opcode >> 16) & 0x03FF;
23026 imm = (int16_t)(imm << 6) >> 6;
23027 temp = ((target_long)imm << 32) \
23028 | ((target_long)imm & 0xFFFFFFFF);
23029 tcg_gen_movi_tl(cpu_gpr[ret], temp);
23030 break;
23031 }
23032 case OPC_REPL_QH:
23033 check_dsp(ctx);
23034 {
23035 target_long temp;
23036
23037 imm = (ctx->opcode >> 16) & 0x03FF;
23038 imm = (int16_t)(imm << 6) >> 6;
23039
23040 temp = ((uint64_t)(uint16_t)imm << 48) |
23041 ((uint64_t)(uint16_t)imm << 32) |
23042 ((uint64_t)(uint16_t)imm << 16) |
23043 (uint64_t)(uint16_t)imm;
23044 tcg_gen_movi_tl(cpu_gpr[ret], temp);
23045 break;
23046 }
23047 case OPC_REPLV_OB:
23048 check_dsp(ctx);
23049 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
23050 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
23051 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23052 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
23053 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23054 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
23055 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23056 break;
23057 case OPC_REPLV_PW:
23058 check_dsp(ctx);
23059 tcg_gen_ext32u_i64(cpu_gpr[ret], val_t);
23060 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
23061 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23062 break;
23063 case OPC_REPLV_QH:
23064 check_dsp(ctx);
23065 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
23066 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
23067 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23068 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
23069 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23070 break;
23071 }
23072 break;
23073#endif
23074 }
23075 tcg_temp_free(t0);
23076 tcg_temp_free(val_t);
1cb6686c
JL
23077}
23078
26690560
JL
23079static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx,
23080 uint32_t op1, uint32_t op2,
23081 int ret, int v1, int v2, int check_ret)
23082{
26690560
JL
23083 TCGv t1;
23084 TCGv v1_t;
23085 TCGv v2_t;
23086
23087 if ((ret == 0) && (check_ret == 1)) {
23088 /* Treat as NOP. */
26690560
JL
23089 return;
23090 }
23091
26690560
JL
23092 t1 = tcg_temp_new();
23093 v1_t = tcg_temp_new();
23094 v2_t = tcg_temp_new();
23095
23096 gen_load_gpr(v1_t, v1);
23097 gen_load_gpr(v2_t, v2);
23098
23099 switch (op1) {
26690560
JL
23100 case OPC_CMPU_EQ_QB_DSP:
23101 switch (op2) {
23102 case OPC_CMPU_EQ_QB:
23103 check_dsp(ctx);
23104 gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
23105 break;
23106 case OPC_CMPU_LT_QB:
23107 check_dsp(ctx);
23108 gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
23109 break;
23110 case OPC_CMPU_LE_QB:
23111 check_dsp(ctx);
23112 gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
23113 break;
23114 case OPC_CMPGU_EQ_QB:
23115 check_dsp(ctx);
23116 gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t);
23117 break;
23118 case OPC_CMPGU_LT_QB:
23119 check_dsp(ctx);
23120 gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t);
23121 break;
23122 case OPC_CMPGU_LE_QB:
23123 check_dsp(ctx);
23124 gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t);
23125 break;
23126 case OPC_CMPGDU_EQ_QB:
908f6be1 23127 check_dsp_r2(ctx);
26690560
JL
23128 gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t);
23129 tcg_gen_mov_tl(cpu_gpr[ret], t1);
23130 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
23131 tcg_gen_shli_tl(t1, t1, 24);
23132 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
23133 break;
23134 case OPC_CMPGDU_LT_QB:
908f6be1 23135 check_dsp_r2(ctx);
26690560
JL
23136 gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t);
23137 tcg_gen_mov_tl(cpu_gpr[ret], t1);
23138 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
23139 tcg_gen_shli_tl(t1, t1, 24);
23140 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
23141 break;
23142 case OPC_CMPGDU_LE_QB:
908f6be1 23143 check_dsp_r2(ctx);
26690560
JL
23144 gen_helper_cmpgu_le_qb(t1, v1_t, v2_t);
23145 tcg_gen_mov_tl(cpu_gpr[ret], t1);
23146 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
23147 tcg_gen_shli_tl(t1, t1, 24);
23148 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
23149 break;
23150 case OPC_CMP_EQ_PH:
23151 check_dsp(ctx);
23152 gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
23153 break;
23154 case OPC_CMP_LT_PH:
23155 check_dsp(ctx);
23156 gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
23157 break;
23158 case OPC_CMP_LE_PH:
23159 check_dsp(ctx);
23160 gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
23161 break;
23162 case OPC_PICK_QB:
23163 check_dsp(ctx);
23164 gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23165 break;
23166 case OPC_PICK_PH:
23167 check_dsp(ctx);
23168 gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23169 break;
23170 case OPC_PACKRL_PH:
23171 check_dsp(ctx);
23172 gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t);
23173 break;
23174 }
23175 break;
23176#ifdef TARGET_MIPS64
23177 case OPC_CMPU_EQ_OB_DSP:
23178 switch (op2) {
23179 case OPC_CMP_EQ_PW:
23180 check_dsp(ctx);
23181 gen_helper_cmp_eq_pw(v1_t, v2_t, cpu_env);
23182 break;
23183 case OPC_CMP_LT_PW:
23184 check_dsp(ctx);
23185 gen_helper_cmp_lt_pw(v1_t, v2_t, cpu_env);
23186 break;
23187 case OPC_CMP_LE_PW:
23188 check_dsp(ctx);
23189 gen_helper_cmp_le_pw(v1_t, v2_t, cpu_env);
23190 break;
23191 case OPC_CMP_EQ_QH:
23192 check_dsp(ctx);
23193 gen_helper_cmp_eq_qh(v1_t, v2_t, cpu_env);
23194 break;
23195 case OPC_CMP_LT_QH:
23196 check_dsp(ctx);
23197 gen_helper_cmp_lt_qh(v1_t, v2_t, cpu_env);
23198 break;
23199 case OPC_CMP_LE_QH:
23200 check_dsp(ctx);
23201 gen_helper_cmp_le_qh(v1_t, v2_t, cpu_env);
23202 break;
23203 case OPC_CMPGDU_EQ_OB:
908f6be1 23204 check_dsp_r2(ctx);
26690560
JL
23205 gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23206 break;
23207 case OPC_CMPGDU_LT_OB:
908f6be1 23208 check_dsp_r2(ctx);
26690560
JL
23209 gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23210 break;
23211 case OPC_CMPGDU_LE_OB:
908f6be1 23212 check_dsp_r2(ctx);
26690560
JL
23213 gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23214 break;
23215 case OPC_CMPGU_EQ_OB:
23216 check_dsp(ctx);
23217 gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t);
23218 break;
23219 case OPC_CMPGU_LT_OB:
23220 check_dsp(ctx);
23221 gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t);
23222 break;
23223 case OPC_CMPGU_LE_OB:
23224 check_dsp(ctx);
23225 gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t);
23226 break;
23227 case OPC_CMPU_EQ_OB:
23228 check_dsp(ctx);
23229 gen_helper_cmpu_eq_ob(v1_t, v2_t, cpu_env);
23230 break;
23231 case OPC_CMPU_LT_OB:
23232 check_dsp(ctx);
23233 gen_helper_cmpu_lt_ob(v1_t, v2_t, cpu_env);
23234 break;
23235 case OPC_CMPU_LE_OB:
23236 check_dsp(ctx);
23237 gen_helper_cmpu_le_ob(v1_t, v2_t, cpu_env);
23238 break;
23239 case OPC_PACKRL_PW:
23240 check_dsp(ctx);
23241 gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t);
23242 break;
23243 case OPC_PICK_OB:
23244 check_dsp(ctx);
23245 gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23246 break;
23247 case OPC_PICK_PW:
23248 check_dsp(ctx);
23249 gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23250 break;
23251 case OPC_PICK_QH:
23252 check_dsp(ctx);
23253 gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23254 break;
23255 }
23256 break;
df6126a7
AJ
23257#endif
23258 }
23259
23260 tcg_temp_free(t1);
23261 tcg_temp_free(v1_t);
23262 tcg_temp_free(v2_t);
df6126a7
AJ
23263}
23264
23265static void gen_mipsdsp_append(CPUMIPSState *env, DisasContext *ctx,
23266 uint32_t op1, int rt, int rs, int sa)
23267{
df6126a7
AJ
23268 TCGv t0;
23269
908f6be1 23270 check_dsp_r2(ctx);
df6126a7
AJ
23271
23272 if (rt == 0) {
23273 /* Treat as NOP. */
df6126a7
AJ
23274 return;
23275 }
23276
23277 t0 = tcg_temp_new();
23278 gen_load_gpr(t0, rs);
23279
23280 switch (op1) {
23281 case OPC_APPEND_DSP:
23282 switch (MASK_APPEND(ctx->opcode)) {
23283 case OPC_APPEND:
23284 if (sa != 0) {
23285 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 32 - sa);
23286 }
23287 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
23288 break;
23289 case OPC_PREPEND:
23290 if (sa != 0) {
23291 tcg_gen_ext32u_tl(cpu_gpr[rt], cpu_gpr[rt]);
23292 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
23293 tcg_gen_shli_tl(t0, t0, 32 - sa);
23294 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
23295 }
23296 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
23297 break;
23298 case OPC_BALIGN:
23299 sa &= 3;
23300 if (sa != 0 && sa != 2) {
23301 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
23302 tcg_gen_ext32u_tl(t0, t0);
23303 tcg_gen_shri_tl(t0, t0, 8 * (4 - sa));
23304 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
23305 }
23306 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
23307 break;
23308 default: /* Invalid */
23309 MIPS_INVAL("MASK APPEND");
9c708c7f 23310 generate_exception_end(ctx, EXCP_RI);
df6126a7
AJ
23311 break;
23312 }
23313 break;
23314#ifdef TARGET_MIPS64
26690560 23315 case OPC_DAPPEND_DSP:
df6126a7 23316 switch (MASK_DAPPEND(ctx->opcode)) {
26690560 23317 case OPC_DAPPEND:
df6126a7
AJ
23318 if (sa != 0) {
23319 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 64 - sa);
23320 }
26690560
JL
23321 break;
23322 case OPC_PREPENDD:
df6126a7
AJ
23323 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], 0x20 | sa);
23324 tcg_gen_shli_tl(t0, t0, 64 - (0x20 | sa));
23325 tcg_gen_or_tl(cpu_gpr[rt], t0, t0);
26690560
JL
23326 break;
23327 case OPC_PREPENDW:
df6126a7
AJ
23328 if (sa != 0) {
23329 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
23330 tcg_gen_shli_tl(t0, t0, 64 - sa);
23331 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
23332 }
26690560
JL
23333 break;
23334 case OPC_DBALIGN:
df6126a7
AJ
23335 sa &= 7;
23336 if (sa != 0 && sa != 2 && sa != 4) {
23337 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
23338 tcg_gen_shri_tl(t0, t0, 8 * (8 - sa));
23339 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
23340 }
26690560
JL
23341 break;
23342 default: /* Invalid */
23343 MIPS_INVAL("MASK DAPPEND");
9c708c7f 23344 generate_exception_end(ctx, EXCP_RI);
26690560
JL
23345 break;
23346 }
23347 break;
23348#endif
23349 }
df6126a7 23350 tcg_temp_free(t0);
26690560
JL
23351}
23352
b53371ed
JL
23353static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
23354 int ret, int v1, int v2, int check_ret)
23355
23356{
b53371ed
JL
23357 TCGv t0;
23358 TCGv t1;
23359 TCGv v1_t;
23360 TCGv v2_t;
23361 int16_t imm;
23362
23363 if ((ret == 0) && (check_ret == 1)) {
23364 /* Treat as NOP. */
b53371ed
JL
23365 return;
23366 }
23367
23368 t0 = tcg_temp_new();
23369 t1 = tcg_temp_new();
23370 v1_t = tcg_temp_new();
23371 v2_t = tcg_temp_new();
23372
23373 gen_load_gpr(v1_t, v1);
23374 gen_load_gpr(v2_t, v2);
23375
23376 switch (op1) {
23377 case OPC_EXTR_W_DSP:
23378 check_dsp(ctx);
23379 switch (op2) {
23380 case OPC_EXTR_W:
23381 tcg_gen_movi_tl(t0, v2);
23382 tcg_gen_movi_tl(t1, v1);
23383 gen_helper_extr_w(cpu_gpr[ret], t0, t1, cpu_env);
23384 break;
23385 case OPC_EXTR_R_W:
23386 tcg_gen_movi_tl(t0, v2);
23387 tcg_gen_movi_tl(t1, v1);
23388 gen_helper_extr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
23389 break;
23390 case OPC_EXTR_RS_W:
23391 tcg_gen_movi_tl(t0, v2);
23392 tcg_gen_movi_tl(t1, v1);
23393 gen_helper_extr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
23394 break;
23395 case OPC_EXTR_S_H:
23396 tcg_gen_movi_tl(t0, v2);
23397 tcg_gen_movi_tl(t1, v1);
23398 gen_helper_extr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
23399 break;
23400 case OPC_EXTRV_S_H:
23401 tcg_gen_movi_tl(t0, v2);
23402 gen_helper_extr_s_h(cpu_gpr[ret], t0, v1_t, cpu_env);
23403 break;
23404 case OPC_EXTRV_W:
23405 tcg_gen_movi_tl(t0, v2);
23406 gen_helper_extr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
23407 break;
23408 case OPC_EXTRV_R_W:
23409 tcg_gen_movi_tl(t0, v2);
23410 gen_helper_extr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
23411 break;
23412 case OPC_EXTRV_RS_W:
23413 tcg_gen_movi_tl(t0, v2);
23414 gen_helper_extr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
23415 break;
23416 case OPC_EXTP:
23417 tcg_gen_movi_tl(t0, v2);
23418 tcg_gen_movi_tl(t1, v1);
23419 gen_helper_extp(cpu_gpr[ret], t0, t1, cpu_env);
23420 break;
23421 case OPC_EXTPV:
23422 tcg_gen_movi_tl(t0, v2);
23423 gen_helper_extp(cpu_gpr[ret], t0, v1_t, cpu_env);
23424 break;
23425 case OPC_EXTPDP:
23426 tcg_gen_movi_tl(t0, v2);
23427 tcg_gen_movi_tl(t1, v1);
23428 gen_helper_extpdp(cpu_gpr[ret], t0, t1, cpu_env);
23429 break;
23430 case OPC_EXTPDPV:
23431 tcg_gen_movi_tl(t0, v2);
23432 gen_helper_extpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
23433 break;
23434 case OPC_SHILO:
23435 imm = (ctx->opcode >> 20) & 0x3F;
23436 tcg_gen_movi_tl(t0, ret);
23437 tcg_gen_movi_tl(t1, imm);
23438 gen_helper_shilo(t0, t1, cpu_env);
23439 break;
23440 case OPC_SHILOV:
23441 tcg_gen_movi_tl(t0, ret);
23442 gen_helper_shilo(t0, v1_t, cpu_env);
23443 break;
23444 case OPC_MTHLIP:
23445 tcg_gen_movi_tl(t0, ret);
23446 gen_helper_mthlip(t0, v1_t, cpu_env);
23447 break;
23448 case OPC_WRDSP:
23449 imm = (ctx->opcode >> 11) & 0x3FF;
23450 tcg_gen_movi_tl(t0, imm);
23451 gen_helper_wrdsp(v1_t, t0, cpu_env);
23452 break;
23453 case OPC_RDDSP:
23454 imm = (ctx->opcode >> 16) & 0x03FF;
23455 tcg_gen_movi_tl(t0, imm);
23456 gen_helper_rddsp(cpu_gpr[ret], t0, cpu_env);
23457 break;
23458 }
23459 break;
23460#ifdef TARGET_MIPS64
23461 case OPC_DEXTR_W_DSP:
23462 check_dsp(ctx);
23463 switch (op2) {
23464 case OPC_DMTHLIP:
23465 tcg_gen_movi_tl(t0, ret);
23466 gen_helper_dmthlip(v1_t, t0, cpu_env);
23467 break;
23468 case OPC_DSHILO:
23469 {
23470 int shift = (ctx->opcode >> 19) & 0x7F;
23471 int ac = (ctx->opcode >> 11) & 0x03;
23472 tcg_gen_movi_tl(t0, shift);
23473 tcg_gen_movi_tl(t1, ac);
23474 gen_helper_dshilo(t0, t1, cpu_env);
23475 break;
23476 }
23477 case OPC_DSHILOV:
23478 {
23479 int ac = (ctx->opcode >> 11) & 0x03;
23480 tcg_gen_movi_tl(t0, ac);
23481 gen_helper_dshilo(v1_t, t0, cpu_env);
23482 break;
23483 }
23484 case OPC_DEXTP:
23485 tcg_gen_movi_tl(t0, v2);
23486 tcg_gen_movi_tl(t1, v1);
23487
23488 gen_helper_dextp(cpu_gpr[ret], t0, t1, cpu_env);
23489 break;
23490 case OPC_DEXTPV:
23491 tcg_gen_movi_tl(t0, v2);
23492 gen_helper_dextp(cpu_gpr[ret], t0, v1_t, cpu_env);
23493 break;
23494 case OPC_DEXTPDP:
23495 tcg_gen_movi_tl(t0, v2);
23496 tcg_gen_movi_tl(t1, v1);
23497 gen_helper_dextpdp(cpu_gpr[ret], t0, t1, cpu_env);
23498 break;
23499 case OPC_DEXTPDPV:
23500 tcg_gen_movi_tl(t0, v2);
23501 gen_helper_dextpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
23502 break;
23503 case OPC_DEXTR_L:
23504 tcg_gen_movi_tl(t0, v2);
23505 tcg_gen_movi_tl(t1, v1);
23506 gen_helper_dextr_l(cpu_gpr[ret], t0, t1, cpu_env);
23507 break;
23508 case OPC_DEXTR_R_L:
23509 tcg_gen_movi_tl(t0, v2);
23510 tcg_gen_movi_tl(t1, v1);
23511 gen_helper_dextr_r_l(cpu_gpr[ret], t0, t1, cpu_env);
23512 break;
23513 case OPC_DEXTR_RS_L:
23514 tcg_gen_movi_tl(t0, v2);
23515 tcg_gen_movi_tl(t1, v1);
23516 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, t1, cpu_env);
23517 break;
23518 case OPC_DEXTR_W:
23519 tcg_gen_movi_tl(t0, v2);
23520 tcg_gen_movi_tl(t1, v1);
23521 gen_helper_dextr_w(cpu_gpr[ret], t0, t1, cpu_env);
23522 break;
23523 case OPC_DEXTR_R_W:
23524 tcg_gen_movi_tl(t0, v2);
23525 tcg_gen_movi_tl(t1, v1);
23526 gen_helper_dextr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
23527 break;
23528 case OPC_DEXTR_RS_W:
23529 tcg_gen_movi_tl(t0, v2);
23530 tcg_gen_movi_tl(t1, v1);
23531 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
23532 break;
23533 case OPC_DEXTR_S_H:
23534 tcg_gen_movi_tl(t0, v2);
23535 tcg_gen_movi_tl(t1, v1);
23536 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
23537 break;
23538 case OPC_DEXTRV_S_H:
23539 tcg_gen_movi_tl(t0, v2);
23540 tcg_gen_movi_tl(t1, v1);
23541 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
23542 break;
23543 case OPC_DEXTRV_L:
23544 tcg_gen_movi_tl(t0, v2);
23545 gen_helper_dextr_l(cpu_gpr[ret], t0, v1_t, cpu_env);
23546 break;
23547 case OPC_DEXTRV_R_L:
23548 tcg_gen_movi_tl(t0, v2);
23549 gen_helper_dextr_r_l(cpu_gpr[ret], t0, v1_t, cpu_env);
23550 break;
23551 case OPC_DEXTRV_RS_L:
23552 tcg_gen_movi_tl(t0, v2);
23553 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, v1_t, cpu_env);
23554 break;
23555 case OPC_DEXTRV_W:
23556 tcg_gen_movi_tl(t0, v2);
23557 gen_helper_dextr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
23558 break;
23559 case OPC_DEXTRV_R_W:
23560 tcg_gen_movi_tl(t0, v2);
23561 gen_helper_dextr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
23562 break;
23563 case OPC_DEXTRV_RS_W:
23564 tcg_gen_movi_tl(t0, v2);
23565 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
23566 break;
23567 }
23568 break;
23569#endif
23570 }
23571
23572 tcg_temp_free(t0);
23573 tcg_temp_free(t1);
23574 tcg_temp_free(v1_t);
23575 tcg_temp_free(v2_t);
b53371ed
JL
23576}
23577
9b1a1d68
JL
23578/* End MIPSDSP functions. */
23579
10dc65db
LA
23580static void decode_opc_special_r6(CPUMIPSState *env, DisasContext *ctx)
23581{
4267d3e6 23582 int rs, rt, rd, sa;
b42ee5e1 23583 uint32_t op1, op2;
10dc65db
LA
23584
23585 rs = (ctx->opcode >> 21) & 0x1f;
23586 rt = (ctx->opcode >> 16) & 0x1f;
23587 rd = (ctx->opcode >> 11) & 0x1f;
4267d3e6 23588 sa = (ctx->opcode >> 6) & 0x1f;
10dc65db
LA
23589
23590 op1 = MASK_SPECIAL(ctx->opcode);
23591 switch (op1) {
d4ea6acd 23592 case OPC_LSA:
1f1b4c00 23593 gen_lsa(ctx, op1, rd, rs, rt, extract32(ctx->opcode, 6, 2));
d4ea6acd 23594 break;
c2e19f3c
AM
23595 case OPC_MULT:
23596 case OPC_MULTU:
23597 case OPC_DIV:
23598 case OPC_DIVU:
b42ee5e1
LA
23599 op2 = MASK_R6_MULDIV(ctx->opcode);
23600 switch (op2) {
23601 case R6_OPC_MUL:
23602 case R6_OPC_MUH:
23603 case R6_OPC_MULU:
23604 case R6_OPC_MUHU:
23605 case R6_OPC_DIV:
23606 case R6_OPC_MOD:
23607 case R6_OPC_DIVU:
23608 case R6_OPC_MODU:
23609 gen_r6_muldiv(ctx, op2, rd, rs, rt);
23610 break;
23611 default:
23612 MIPS_INVAL("special_r6 muldiv");
9c708c7f 23613 generate_exception_end(ctx, EXCP_RI);
b42ee5e1
LA
23614 break;
23615 }
23616 break;
10dc65db
LA
23617 case OPC_SELEQZ:
23618 case OPC_SELNEZ:
23619 gen_cond_move(ctx, op1, rd, rs, rt);
23620 break;
4267d3e6
LA
23621 case R6_OPC_CLO:
23622 case R6_OPC_CLZ:
23623 if (rt == 0 && sa == 1) {
23624 /* Major opcode and function field is shared with preR6 MFHI/MTHI.
23625 We need additionally to check other fields */
23626 gen_cl(ctx, op1, rd, rs);
23627 } else {
9c708c7f 23628 generate_exception_end(ctx, EXCP_RI);
4267d3e6
LA
23629 }
23630 break;
23631 case R6_OPC_SDBBP:
3b3c1694
LA
23632 if (is_uhi(extract32(ctx->opcode, 6, 20))) {
23633 gen_helper_do_semihosting(cpu_env);
faf1f68b 23634 } else {
3b3c1694 23635 if (ctx->hflags & MIPS_HFLAG_SBRI) {
9c708c7f 23636 generate_exception_end(ctx, EXCP_RI);
3b3c1694 23637 } else {
9c708c7f 23638 generate_exception_end(ctx, EXCP_DBp);
3b3c1694 23639 }
faf1f68b 23640 }
4267d3e6 23641 break;
b42ee5e1 23642#if defined(TARGET_MIPS64)
d4ea6acd
LA
23643 case OPC_DLSA:
23644 check_mips_64(ctx);
1f1b4c00 23645 gen_lsa(ctx, op1, rd, rs, rt, extract32(ctx->opcode, 6, 2));
d4ea6acd 23646 break;
4267d3e6
LA
23647 case R6_OPC_DCLO:
23648 case R6_OPC_DCLZ:
23649 if (rt == 0 && sa == 1) {
23650 /* Major opcode and function field is shared with preR6 MFHI/MTHI.
23651 We need additionally to check other fields */
23652 check_mips_64(ctx);
23653 gen_cl(ctx, op1, rd, rs);
23654 } else {
9c708c7f 23655 generate_exception_end(ctx, EXCP_RI);
4267d3e6
LA
23656 }
23657 break;
c2e19f3c
AM
23658 case OPC_DMULT:
23659 case OPC_DMULTU:
23660 case OPC_DDIV:
23661 case OPC_DDIVU:
23662
b42ee5e1
LA
23663 op2 = MASK_R6_MULDIV(ctx->opcode);
23664 switch (op2) {
23665 case R6_OPC_DMUL:
23666 case R6_OPC_DMUH:
23667 case R6_OPC_DMULU:
23668 case R6_OPC_DMUHU:
23669 case R6_OPC_DDIV:
23670 case R6_OPC_DMOD:
23671 case R6_OPC_DDIVU:
23672 case R6_OPC_DMODU:
23673 check_mips_64(ctx);
23674 gen_r6_muldiv(ctx, op2, rd, rs, rt);
23675 break;
23676 default:
23677 MIPS_INVAL("special_r6 muldiv");
9c708c7f 23678 generate_exception_end(ctx, EXCP_RI);
b42ee5e1
LA
23679 break;
23680 }
23681 break;
23682#endif
10dc65db
LA
23683 default: /* Invalid */
23684 MIPS_INVAL("special_r6");
9c708c7f 23685 generate_exception_end(ctx, EXCP_RI);
10dc65db
LA
23686 break;
23687 }
23688}
23689
23690static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx)
23691{
b42ee5e1 23692 int rs, rt, rd, sa;
10dc65db
LA
23693 uint32_t op1;
23694
23695 rs = (ctx->opcode >> 21) & 0x1f;
23696 rt = (ctx->opcode >> 16) & 0x1f;
23697 rd = (ctx->opcode >> 11) & 0x1f;
b42ee5e1 23698 sa = (ctx->opcode >> 6) & 0x1f;
10dc65db
LA
23699
23700 op1 = MASK_SPECIAL(ctx->opcode);
23701 switch (op1) {
23702 case OPC_MOVN: /* Conditional move */
23703 case OPC_MOVZ:
23704 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32 |
5601e621 23705 INSN_LOONGSON2E | INSN_LOONGSON2F | INSN_R5900);
10dc65db
LA
23706 gen_cond_move(ctx, op1, rd, rs, rt);
23707 break;
23708 case OPC_MFHI: /* Move from HI/LO */
23709 case OPC_MFLO:
23710 gen_HILO(ctx, op1, rs & 3, rd);
23711 break;
23712 case OPC_MTHI:
23713 case OPC_MTLO: /* Move to HI/LO */
23714 gen_HILO(ctx, op1, rd & 3, rs);
23715 break;
23716 case OPC_MOVCI:
23717 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
23718 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
23719 check_cp1_enabled(ctx);
23720 gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
23721 (ctx->opcode >> 16) & 1);
23722 } else {
23723 generate_exception_err(ctx, EXCP_CpU, 1);
23724 }
23725 break;
b42ee5e1
LA
23726 case OPC_MULT:
23727 case OPC_MULTU:
23728 if (sa) {
23729 check_insn(ctx, INSN_VR54XX);
23730 op1 = MASK_MUL_VR54XX(ctx->opcode);
23731 gen_mul_vr54xx(ctx, op1, rd, rs, rt);
21e8e8b2
FN
23732 } else if (ctx->insn_flags & INSN_R5900) {
23733 gen_mul_txx9(ctx, op1, rd, rs, rt);
b42ee5e1
LA
23734 } else {
23735 gen_muldiv(ctx, op1, rd & 3, rs, rt);
23736 }
23737 break;
23738 case OPC_DIV:
23739 case OPC_DIVU:
23740 gen_muldiv(ctx, op1, 0, rs, rt);
23741 break;
23742#if defined(TARGET_MIPS64)
c2e19f3c
AM
23743 case OPC_DMULT:
23744 case OPC_DMULTU:
23745 case OPC_DDIV:
23746 case OPC_DDIVU:
b42ee5e1 23747 check_insn(ctx, ISA_MIPS3);
96631327 23748 check_insn_opc_user_only(ctx, INSN_R5900);
b42ee5e1
LA
23749 check_mips_64(ctx);
23750 gen_muldiv(ctx, op1, 0, rs, rt);
23751 break;
23752#endif
0aefa333 23753 case OPC_JR:
b231c103 23754 gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
0aefa333 23755 break;
4267d3e6
LA
23756 case OPC_SPIM:
23757#ifdef MIPS_STRICT_STANDARD
23758 MIPS_INVAL("SPIM");
9c708c7f 23759 generate_exception_end(ctx, EXCP_RI);
4267d3e6
LA
23760#else
23761 /* Implemented as RI exception for now. */
23762 MIPS_INVAL("spim (unofficial)");
9c708c7f 23763 generate_exception_end(ctx, EXCP_RI);
4267d3e6
LA
23764#endif
23765 break;
10dc65db
LA
23766 default: /* Invalid */
23767 MIPS_INVAL("special_legacy");
9c708c7f 23768 generate_exception_end(ctx, EXCP_RI);
10dc65db
LA
23769 break;
23770 }
23771}
23772
099e5b4d 23773static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx)
3c824109 23774{
3c824109 23775 int rs, rt, rd, sa;
099e5b4d 23776 uint32_t op1;
3c824109 23777
3c824109
NF
23778 rs = (ctx->opcode >> 21) & 0x1f;
23779 rt = (ctx->opcode >> 16) & 0x1f;
23780 rd = (ctx->opcode >> 11) & 0x1f;
23781 sa = (ctx->opcode >> 6) & 0x1f;
099e5b4d
LA
23782
23783 op1 = MASK_SPECIAL(ctx->opcode);
23784 switch (op1) {
23785 case OPC_SLL: /* Shift with immediate */
339cd2a8
LA
23786 if (sa == 5 && rd == 0 &&
23787 rs == 0 && rt == 0) { /* PAUSE */
23788 if ((ctx->insn_flags & ISA_MIPS32R6) &&
23789 (ctx->hflags & MIPS_HFLAG_BMASK)) {
9c708c7f 23790 generate_exception_end(ctx, EXCP_RI);
339cd2a8
LA
23791 break;
23792 }
23793 }
23794 /* Fallthrough */
099e5b4d
LA
23795 case OPC_SRA:
23796 gen_shift_imm(ctx, op1, rd, rt, sa);
23797 break;
23798 case OPC_SRL:
23799 switch ((ctx->opcode >> 21) & 0x1f) {
23800 case 1:
23801 /* rotr is decoded as srl on non-R2 CPUs */
23802 if (ctx->insn_flags & ISA_MIPS32R2) {
23803 op1 = OPC_ROTR;
ea63e2c3 23804 }
099e5b4d
LA
23805 /* Fallthrough */
23806 case 0:
23807 gen_shift_imm(ctx, op1, rd, rt, sa);
ea63e2c3 23808 break;
099e5b4d 23809 default:
9c708c7f 23810 generate_exception_end(ctx, EXCP_RI);
ea63e2c3 23811 break;
099e5b4d
LA
23812 }
23813 break;
c2e19f3c
AM
23814 case OPC_ADD:
23815 case OPC_ADDU:
23816 case OPC_SUB:
23817 case OPC_SUBU:
099e5b4d
LA
23818 gen_arith(ctx, op1, rd, rs, rt);
23819 break;
23820 case OPC_SLLV: /* Shifts */
23821 case OPC_SRAV:
23822 gen_shift(ctx, op1, rd, rs, rt);
23823 break;
23824 case OPC_SRLV:
23825 switch ((ctx->opcode >> 6) & 0x1f) {
23826 case 1:
23827 /* rotrv is decoded as srlv on non-R2 CPUs */
23828 if (ctx->insn_flags & ISA_MIPS32R2) {
23829 op1 = OPC_ROTRV;
26135ead 23830 }
099e5b4d
LA
23831 /* Fallthrough */
23832 case 0:
23833 gen_shift(ctx, op1, rd, rs, rt);
26135ead 23834 break;
099e5b4d 23835 default:
9c708c7f 23836 generate_exception_end(ctx, EXCP_RI);
6af0bf9c 23837 break;
099e5b4d
LA
23838 }
23839 break;
23840 case OPC_SLT: /* Set on less than */
23841 case OPC_SLTU:
23842 gen_slt(ctx, op1, rd, rs, rt);
23843 break;
23844 case OPC_AND: /* Logic*/
23845 case OPC_OR:
23846 case OPC_NOR:
23847 case OPC_XOR:
23848 gen_logic(ctx, op1, rd, rs, rt);
23849 break;
0aefa333 23850 case OPC_JALR:
b231c103 23851 gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
099e5b4d 23852 break;
c2e19f3c
AM
23853 case OPC_TGE: /* Traps */
23854 case OPC_TGEU:
23855 case OPC_TLT:
23856 case OPC_TLTU:
23857 case OPC_TEQ:
099e5b4d 23858 case OPC_TNE:
d9224450 23859 check_insn(ctx, ISA_MIPS2);
099e5b4d
LA
23860 gen_trap(ctx, op1, rs, rt, -1);
23861 break;
d4ea6acd 23862 case OPC_LSA: /* OPC_PMON */
f7685877
YK
23863 if ((ctx->insn_flags & ISA_MIPS32R6) ||
23864 (env->CP0_Config3 & (1 << CP0C3_MSAP))) {
d4ea6acd
LA
23865 decode_opc_special_r6(env, ctx);
23866 } else {
23867 /* Pmon entry point, also R4010 selsl */
b48cfdff 23868#ifdef MIPS_STRICT_STANDARD
d4ea6acd 23869 MIPS_INVAL("PMON / selsl");
9c708c7f 23870 generate_exception_end(ctx, EXCP_RI);
b48cfdff 23871#else
d4ea6acd 23872 gen_helper_0e0i(pmon, sa);
b48cfdff 23873#endif
d4ea6acd 23874 }
099e5b4d
LA
23875 break;
23876 case OPC_SYSCALL:
9c708c7f 23877 generate_exception_end(ctx, EXCP_SYSCALL);
099e5b4d
LA
23878 break;
23879 case OPC_BREAK:
9c708c7f 23880 generate_exception_end(ctx, EXCP_BREAK);
099e5b4d 23881 break;
099e5b4d 23882 case OPC_SYNC:
d9224450 23883 check_insn(ctx, ISA_MIPS2);
d208ac0c 23884 gen_sync(extract32(ctx->opcode, 6, 5));
099e5b4d 23885 break;
4ad40f36 23886
d26bc211 23887#if defined(TARGET_MIPS64)
099e5b4d
LA
23888 /* MIPS64 specific opcodes */
23889 case OPC_DSLL:
23890 case OPC_DSRA:
23891 case OPC_DSLL32:
23892 case OPC_DSRA32:
23893 check_insn(ctx, ISA_MIPS3);
23894 check_mips_64(ctx);
23895 gen_shift_imm(ctx, op1, rd, rt, sa);
23896 break;
23897 case OPC_DSRL:
23898 switch ((ctx->opcode >> 21) & 0x1f) {
23899 case 1:
23900 /* drotr is decoded as dsrl on non-R2 CPUs */
23901 if (ctx->insn_flags & ISA_MIPS32R2) {
23902 op1 = OPC_DROTR;
ea63e2c3 23903 }
099e5b4d
LA
23904 /* Fallthrough */
23905 case 0:
d75c135e 23906 check_insn(ctx, ISA_MIPS3);
e189e748 23907 check_mips_64(ctx);
099e5b4d 23908 gen_shift_imm(ctx, op1, rd, rt, sa);
7a387fff 23909 break;
099e5b4d 23910 default:
9c708c7f 23911 generate_exception_end(ctx, EXCP_RI);
460f00c4 23912 break;
099e5b4d
LA
23913 }
23914 break;
23915 case OPC_DSRL32:
23916 switch ((ctx->opcode >> 21) & 0x1f) {
23917 case 1:
23918 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
23919 if (ctx->insn_flags & ISA_MIPS32R2) {
23920 op1 = OPC_DROTR32;
ea63e2c3 23921 }
099e5b4d
LA
23922 /* Fallthrough */
23923 case 0:
d75c135e 23924 check_insn(ctx, ISA_MIPS3);
e189e748 23925 check_mips_64(ctx);
099e5b4d 23926 gen_shift_imm(ctx, op1, rd, rt, sa);
7a387fff 23927 break;
099e5b4d 23928 default:
9c708c7f 23929 generate_exception_end(ctx, EXCP_RI);
6af0bf9c
FB
23930 break;
23931 }
23932 break;
c2e19f3c
AM
23933 case OPC_DADD:
23934 case OPC_DADDU:
23935 case OPC_DSUB:
23936 case OPC_DSUBU:
099e5b4d
LA
23937 check_insn(ctx, ISA_MIPS3);
23938 check_mips_64(ctx);
23939 gen_arith(ctx, op1, rd, rs, rt);
23940 break;
23941 case OPC_DSLLV:
23942 case OPC_DSRAV:
23943 check_insn(ctx, ISA_MIPS3);
23944 check_mips_64(ctx);
23945 gen_shift(ctx, op1, rd, rs, rt);
23946 break;
23947 case OPC_DSRLV:
23948 switch ((ctx->opcode >> 6) & 0x1f) {
23949 case 1:
23950 /* drotrv is decoded as dsrlv on non-R2 CPUs */
23951 if (ctx->insn_flags & ISA_MIPS32R2) {
23952 op1 = OPC_DROTRV;
6af0bf9c 23953 }
099e5b4d
LA
23954 /* Fallthrough */
23955 case 0:
23956 check_insn(ctx, ISA_MIPS3);
e189e748 23957 check_mips_64(ctx);
099e5b4d 23958 gen_shift(ctx, op1, rd, rs, rt);
161f85e6 23959 break;
099e5b4d 23960 default:
9c708c7f 23961 generate_exception_end(ctx, EXCP_RI);
6af0bf9c
FB
23962 break;
23963 }
23964 break;
f7685877
YK
23965 case OPC_DLSA:
23966 if ((ctx->insn_flags & ISA_MIPS32R6) ||
23967 (env->CP0_Config3 & (1 << CP0C3_MSAP))) {
23968 decode_opc_special_r6(env, ctx);
23969 }
23970 break;
099e5b4d 23971#endif
10dc65db
LA
23972 default:
23973 if (ctx->insn_flags & ISA_MIPS32R6) {
23974 decode_opc_special_r6(env, ctx);
23975 } else {
23976 decode_opc_special_legacy(env, ctx);
23977 }
23978 }
23979}
23980
d67da337
AM
23981
23982/* MXU accumulate add/subtract 1-bit pattern 'aptn1' */
23983#define MXU_APTN1_A 0
23984#define MXU_APTN1_S 1
23985
23986
03f40088
AM
23987/*
23988 *
23989 * Decode MXU pool00
23990 *
23991 * 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
23992 * +-----------+---------+-----+-------+-------+-------+-----------+
23993 * | SPECIAL2 |0 0 0 0 0|x x x| XRc | XRb | XRa |MXU__POOL00|
23994 * +-----------+---------+-----+-------+-------+-------+-----------+
23995 *
23996 */
23997static void decode_opc_mxu__pool00(CPUMIPSState *env, DisasContext *ctx)
23998{
23999 uint32_t opcode = extract32(ctx->opcode, 18, 3);
24000
24001 switch (opcode) {
24002 case OPC_MXU_S32MAX:
24003 /* TODO: Implement emulation of S32MAX instruction. */
24004 MIPS_INVAL("OPC_MXU_S32MAX");
24005 generate_exception_end(ctx, EXCP_RI);
24006 break;
24007 case OPC_MXU_S32MIN:
24008 /* TODO: Implement emulation of S32MIN instruction. */
24009 MIPS_INVAL("OPC_MXU_S32MIN");
24010 generate_exception_end(ctx, EXCP_RI);
24011 break;
24012 case OPC_MXU_D16MAX:
24013 /* TODO: Implement emulation of D16MAX instruction. */
24014 MIPS_INVAL("OPC_MXU_D16MAX");
24015 generate_exception_end(ctx, EXCP_RI);
24016 break;
24017 case OPC_MXU_D16MIN:
24018 /* TODO: Implement emulation of D16MIN instruction. */
24019 MIPS_INVAL("OPC_MXU_D16MIN");
24020 generate_exception_end(ctx, EXCP_RI);
24021 break;
24022 case OPC_MXU_Q8MAX:
24023 /* TODO: Implement emulation of Q8MAX instruction. */
24024 MIPS_INVAL("OPC_MXU_Q8MAX");
24025 generate_exception_end(ctx, EXCP_RI);
24026 break;
24027 case OPC_MXU_Q8MIN:
24028 /* TODO: Implement emulation of Q8MIN instruction. */
24029 MIPS_INVAL("OPC_MXU_Q8MIN");
24030 generate_exception_end(ctx, EXCP_RI);
24031 break;
24032 case OPC_MXU_Q8SLT:
24033 /* TODO: Implement emulation of Q8SLT instruction. */
24034 MIPS_INVAL("OPC_MXU_Q8SLT");
24035 generate_exception_end(ctx, EXCP_RI);
24036 break;
24037 case OPC_MXU_Q8SLTU:
24038 /* TODO: Implement emulation of Q8SLTU instruction. */
24039 MIPS_INVAL("OPC_MXU_Q8SLTU");
24040 generate_exception_end(ctx, EXCP_RI);
24041 break;
24042 default:
24043 MIPS_INVAL("decode_opc_mxu");
24044 generate_exception_end(ctx, EXCP_RI);
24045 break;
24046 }
24047}
24048
24049/*
24050 *
24051 * Decode MXU pool01
24052 *
24053 * S32SLT, D16SLT, D16AVG, D16AVGR, Q8AVG, Q8AVGR:
24054 * 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
24055 * +-----------+---------+-----+-------+-------+-------+-----------+
24056 * | SPECIAL2 |0 0 0 0 0|x x x| XRc | XRb | XRa |MXU__POOL01|
24057 * +-----------+---------+-----+-------+-------+-------+-----------+
24058 *
24059 * Q8ADD:
24060 * 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
24061 * +-----------+---+-----+-----+-------+-------+-------+-----------+
24062 * | SPECIAL2 |en2|0 0 0|x x x| XRc | XRb | XRa |MXU__POOL01|
24063 * +-----------+---+-----+-----+-------+-------+-------+-----------+
24064 *
24065 */
24066static void decode_opc_mxu__pool01(CPUMIPSState *env, DisasContext *ctx)
24067{
24068 uint32_t opcode = extract32(ctx->opcode, 18, 3);
24069
24070 switch (opcode) {
24071 case OPC_MXU_S32SLT:
24072 /* TODO: Implement emulation of S32SLT instruction. */
24073 MIPS_INVAL("OPC_MXU_S32SLT");
24074 generate_exception_end(ctx, EXCP_RI);
24075 break;
24076 case OPC_MXU_D16SLT:
24077 /* TODO: Implement emulation of D16SLT instruction. */
24078 MIPS_INVAL("OPC_MXU_D16SLT");
24079 generate_exception_end(ctx, EXCP_RI);
24080 break;
24081 case OPC_MXU_D16AVG:
24082 /* TODO: Implement emulation of D16AVG instruction. */
24083 MIPS_INVAL("OPC_MXU_D16AVG");
24084 generate_exception_end(ctx, EXCP_RI);
24085 break;
24086 case OPC_MXU_D16AVGR:
24087 /* TODO: Implement emulation of D16AVGR instruction. */
24088 MIPS_INVAL("OPC_MXU_D16AVGR");
24089 generate_exception_end(ctx, EXCP_RI);
24090 break;
24091 case OPC_MXU_Q8AVG:
24092 /* TODO: Implement emulation of Q8AVG instruction. */
24093 MIPS_INVAL("OPC_MXU_Q8AVG");
24094 generate_exception_end(ctx, EXCP_RI);
24095 break;
24096 case OPC_MXU_Q8AVGR:
24097 /* TODO: Implement emulation of Q8AVGR instruction. */
24098 MIPS_INVAL("OPC_MXU_Q8AVGR");
24099 generate_exception_end(ctx, EXCP_RI);
24100 break;
24101 case OPC_MXU_Q8ADD:
24102 /* TODO: Implement emulation of Q8ADD instruction. */
24103 MIPS_INVAL("OPC_MXU_Q8ADD");
24104 generate_exception_end(ctx, EXCP_RI);
24105 break;
24106 default:
24107 MIPS_INVAL("decode_opc_mxu");
24108 generate_exception_end(ctx, EXCP_RI);
24109 break;
24110 }
24111}
24112
24113/*
24114 *
24115 * Decode MXU pool02
24116 *
24117 * 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
24118 * +-----------+---------+-----+-------+-------+-------+-----------+
24119 * | SPECIAL2 |0 0 0 0 0|x x x| XRc | XRb | XRa |MXU__POOL02|
24120 * +-----------+---------+-----+-------+-------+-------+-----------+
24121 *
24122 */
24123static void decode_opc_mxu__pool02(CPUMIPSState *env, DisasContext *ctx)
24124{
24125 uint32_t opcode = extract32(ctx->opcode, 18, 3);
24126
24127 switch (opcode) {
24128 case OPC_MXU_S32CPS:
24129 /* TODO: Implement emulation of S32CPS instruction. */
24130 MIPS_INVAL("OPC_MXU_S32CPS");
24131 generate_exception_end(ctx, EXCP_RI);
24132 break;
24133 case OPC_MXU_D16CPS:
24134 /* TODO: Implement emulation of D16CPS instruction. */
24135 MIPS_INVAL("OPC_MXU_D16CPS");
24136 generate_exception_end(ctx, EXCP_RI);
24137 break;
24138 case OPC_MXU_Q8ABD:
24139 /* TODO: Implement emulation of Q8ABD instruction. */
24140 MIPS_INVAL("OPC_MXU_Q8ABD");
24141 generate_exception_end(ctx, EXCP_RI);
24142 break;
24143 case OPC_MXU_Q16SAT:
24144 /* TODO: Implement emulation of Q16SAT instruction. */
24145 MIPS_INVAL("OPC_MXU_Q16SAT");
24146 generate_exception_end(ctx, EXCP_RI);
24147 break;
24148 default:
24149 MIPS_INVAL("decode_opc_mxu");
24150 generate_exception_end(ctx, EXCP_RI);
24151 break;
24152 }
24153}
24154
24155/*
24156 *
24157 * Decode MXU pool03
24158 *
24159 * D16MULF:
24160 * 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
24161 * +-----------+---+---+-------+-------+-------+-------+-----------+
24162 * | SPECIAL2 |x x|on2|0 0 0 0| XRc | XRb | XRa |MXU__POOL03|
24163 * +-----------+---+---+-------+-------+-------+-------+-----------+
24164 *
24165 * D16MULE:
24166 * 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
24167 * +-----------+---+---+-------+-------+-------+-------+-----------+
24168 * | SPECIAL2 |x x|on2| Xd | XRc | XRb | XRa |MXU__POOL03|
24169 * +-----------+---+---+-------+-------+-------+-------+-----------+
24170 *
24171 */
24172static void decode_opc_mxu__pool03(CPUMIPSState *env, DisasContext *ctx)
24173{
24174 uint32_t opcode = extract32(ctx->opcode, 24, 2);
24175
24176 switch (opcode) {
24177 case OPC_MXU_D16MULF:
24178 /* TODO: Implement emulation of D16MULF instruction. */
24179 MIPS_INVAL("OPC_MXU_D16MULF");
24180 generate_exception_end(ctx, EXCP_RI);
24181 break;
24182 case OPC_MXU_D16MULE:
24183 /* TODO: Implement emulation of D16MULE instruction. */
24184 MIPS_INVAL("OPC_MXU_D16MULE");
24185 generate_exception_end(ctx, EXCP_RI);
24186 break;
24187 default:
24188 MIPS_INVAL("decode_opc_mxu");
24189 generate_exception_end(ctx, EXCP_RI);
24190 break;
24191 }
24192}
24193
24194/*
24195 *
24196 * Decode MXU pool04
24197 *
24198 * 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
24199 * +-----------+---------+-+-------------------+-------+-----------+
24200 * | SPECIAL2 | rb |x| s12 | XRa |MXU__POOL04|
24201 * +-----------+---------+-+-------------------+-------+-----------+
24202 *
24203 */
24204static void decode_opc_mxu__pool04(CPUMIPSState *env, DisasContext *ctx)
24205{
24206 uint32_t opcode = extract32(ctx->opcode, 20, 1);
24207
24208 switch (opcode) {
24209 case OPC_MXU_S32LDD:
24210 /* TODO: Implement emulation of S32LDD instruction. */
24211 MIPS_INVAL("OPC_MXU_S32LDD");
24212 generate_exception_end(ctx, EXCP_RI);
24213 break;
24214 case OPC_MXU_S32LDDR:
24215 /* TODO: Implement emulation of S32LDDR instruction. */
24216 MIPS_INVAL("OPC_MXU_S32LDDR");
24217 generate_exception_end(ctx, EXCP_RI);
24218 break;
24219 default:
24220 MIPS_INVAL("decode_opc_mxu");
24221 generate_exception_end(ctx, EXCP_RI);
24222 break;
24223 }
24224}
24225
24226/*
24227 *
24228 * Decode MXU pool05
24229 *
24230 * 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
24231 * +-----------+---------+-+-------------------+-------+-----------+
24232 * | SPECIAL2 | rb |x| s12 | XRa |MXU__POOL05|
24233 * +-----------+---------+-+-------------------+-------+-----------+
24234 *
24235 */
24236static void decode_opc_mxu__pool05(CPUMIPSState *env, DisasContext *ctx)
24237{
24238 uint32_t opcode = extract32(ctx->opcode, 20, 1);
24239
24240 switch (opcode) {
24241 case OPC_MXU_S32STD:
24242 /* TODO: Implement emulation of S32STD instruction. */
24243 MIPS_INVAL("OPC_MXU_S32STD");
24244 generate_exception_end(ctx, EXCP_RI);
24245 break;
24246 case OPC_MXU_S32STDR:
24247 /* TODO: Implement emulation of S32STDR instruction. */
24248 MIPS_INVAL("OPC_MXU_S32STDR");
24249 generate_exception_end(ctx, EXCP_RI);
24250 break;
24251 default:
24252 MIPS_INVAL("decode_opc_mxu");
24253 generate_exception_end(ctx, EXCP_RI);
24254 break;
24255 }
24256}
24257
24258/*
24259 *
24260 * Decode MXU pool06
24261 *
24262 * 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
24263 * +-----------+---------+---------+---+-------+-------+-----------+
24264 * | SPECIAL2 | rb | rc |st2|x x x x| XRa |MXU__POOL06|
24265 * +-----------+---------+---------+---+-------+-------+-----------+
24266 *
24267 */
24268static void decode_opc_mxu__pool06(CPUMIPSState *env, DisasContext *ctx)
24269{
24270 uint32_t opcode = extract32(ctx->opcode, 10, 4);
24271
24272 switch (opcode) {
24273 case OPC_MXU_S32LDDV:
24274 /* TODO: Implement emulation of S32LDDV instruction. */
24275 MIPS_INVAL("OPC_MXU_S32LDDV");
24276 generate_exception_end(ctx, EXCP_RI);
24277 break;
24278 case OPC_MXU_S32LDDVR:
24279 /* TODO: Implement emulation of S32LDDVR instruction. */
24280 MIPS_INVAL("OPC_MXU_S32LDDVR");
24281 generate_exception_end(ctx, EXCP_RI);
24282 break;
24283 default:
24284 MIPS_INVAL("decode_opc_mxu");
24285 generate_exception_end(ctx, EXCP_RI);
24286 break;
24287 }
24288}
24289
24290/*
24291 *
24292 * Decode MXU pool07
24293 *
24294 * 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
24295 * +-----------+---------+---------+---+-------+-------+-----------+
24296 * | SPECIAL2 | rb | rc |st2|x x x x| XRa |MXU__POOL07|
24297 * +-----------+---------+---------+---+-------+-------+-----------+
24298 *
24299 */
24300static void decode_opc_mxu__pool07(CPUMIPSState *env, DisasContext *ctx)
24301{
24302 uint32_t opcode = extract32(ctx->opcode, 10, 4);
24303
24304 switch (opcode) {
24305 case OPC_MXU_S32STDV:
24306 /* TODO: Implement emulation of S32TDV instruction. */
24307 MIPS_INVAL("OPC_MXU_S32TDV");
24308 generate_exception_end(ctx, EXCP_RI);
24309 break;
24310 case OPC_MXU_S32STDVR:
24311 /* TODO: Implement emulation of S32TDVR instruction. */
24312 MIPS_INVAL("OPC_MXU_S32TDVR");
24313 generate_exception_end(ctx, EXCP_RI);
24314 break;
24315 default:
24316 MIPS_INVAL("decode_opc_mxu");
24317 generate_exception_end(ctx, EXCP_RI);
24318 break;
24319 }
24320}
24321
24322/*
24323 *
24324 * Decode MXU pool08
24325 *
24326 * 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
24327 * +-----------+---------+-+-------------------+-------+-----------+
24328 * | SPECIAL2 | rb |x| s12 | XRa |MXU__POOL08|
24329 * +-----------+---------+-+-------------------+-------+-----------+
24330 *
24331*/
24332static void decode_opc_mxu__pool08(CPUMIPSState *env, DisasContext *ctx)
24333{
24334 uint32_t opcode = extract32(ctx->opcode, 20, 1);
24335
24336 switch (opcode) {
24337 case OPC_MXU_S32LDI:
24338 /* TODO: Implement emulation of S32LDI instruction. */
24339 MIPS_INVAL("OPC_MXU_S32LDI");
24340 generate_exception_end(ctx, EXCP_RI);
24341 break;
24342 case OPC_MXU_S32LDIR:
24343 /* TODO: Implement emulation of S32LDIR instruction. */
24344 MIPS_INVAL("OPC_MXU_S32LDIR");
24345 generate_exception_end(ctx, EXCP_RI);
24346 break;
24347 default:
24348 MIPS_INVAL("decode_opc_mxu");
24349 generate_exception_end(ctx, EXCP_RI);
24350 break;
24351 }
24352}
24353
24354/*
24355 *
24356 * Decode MXU pool09
24357 *
24358 * 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
24359 * +-----------+---------+-+-------------------+-------+-----------+
24360 * | SPECIAL2 | rb |x| s12 | XRa |MXU__POOL09|
24361 * +-----------+---------+-+-------------------+-------+-----------+
24362 *
24363 */
24364static void decode_opc_mxu__pool09(CPUMIPSState *env, DisasContext *ctx)
24365{
24366 uint32_t opcode = extract32(ctx->opcode, 5, 0);
24367
24368 switch (opcode) {
24369 case OPC_MXU_S32SDI:
24370 /* TODO: Implement emulation of S32SDI instruction. */
24371 MIPS_INVAL("OPC_MXU_S32SDI");
24372 generate_exception_end(ctx, EXCP_RI);
24373 break;
24374 case OPC_MXU_S32SDIR:
24375 /* TODO: Implement emulation of S32SDIR instruction. */
24376 MIPS_INVAL("OPC_MXU_S32SDIR");
24377 generate_exception_end(ctx, EXCP_RI);
24378 break;
24379 default:
24380 MIPS_INVAL("decode_opc_mxu");
24381 generate_exception_end(ctx, EXCP_RI);
24382 break;
24383 }
24384}
24385
24386/*
24387 *
24388 * Decode MXU pool10
24389 *
24390 * 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
24391 * +-----------+---------+---------+---+-------+-------+-----------+
24392 * | SPECIAL2 | rb | rc |st2|x x x x| XRa |MXU__POOL10|
24393 * +-----------+---------+---------+---+-------+-------+-----------+
24394 *
24395 */
24396static void decode_opc_mxu__pool10(CPUMIPSState *env, DisasContext *ctx)
24397{
24398 uint32_t opcode = extract32(ctx->opcode, 5, 0);
24399
24400 switch (opcode) {
24401 case OPC_MXU_S32LDIV:
24402 /* TODO: Implement emulation of S32LDIV instruction. */
24403 MIPS_INVAL("OPC_MXU_S32LDIV");
24404 generate_exception_end(ctx, EXCP_RI);
24405 break;
24406 case OPC_MXU_S32LDIVR:
24407 /* TODO: Implement emulation of S32LDIVR instruction. */
24408 MIPS_INVAL("OPC_MXU_S32LDIVR");
24409 generate_exception_end(ctx, EXCP_RI);
24410 break;
24411 default:
24412 MIPS_INVAL("decode_opc_mxu");
24413 generate_exception_end(ctx, EXCP_RI);
24414 break;
24415 }
24416}
24417
24418/*
24419 *
24420 * Decode MXU pool11
24421 *
24422 * 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
24423 * +-----------+---------+---------+---+-------+-------+-----------+
24424 * | SPECIAL2 | rb | rc |st2|x x x x| XRa |MXU__POOL11|
24425 * +-----------+---------+---------+---+-------+-------+-----------+
24426 *
24427 */
24428static void decode_opc_mxu__pool11(CPUMIPSState *env, DisasContext *ctx)
24429{
24430 uint32_t opcode = extract32(ctx->opcode, 10, 4);
24431
24432 switch (opcode) {
24433 case OPC_MXU_S32SDIV:
24434 /* TODO: Implement emulation of S32SDIV instruction. */
24435 MIPS_INVAL("OPC_MXU_S32SDIV");
24436 generate_exception_end(ctx, EXCP_RI);
24437 break;
24438 case OPC_MXU_S32SDIVR:
24439 /* TODO: Implement emulation of S32SDIVR instruction. */
24440 MIPS_INVAL("OPC_MXU_S32SDIVR");
24441 generate_exception_end(ctx, EXCP_RI);
24442 break;
24443 default:
24444 MIPS_INVAL("decode_opc_mxu");
24445 generate_exception_end(ctx, EXCP_RI);
24446 break;
24447 }
24448}
24449
24450/*
24451 *
24452 * Decode MXU pool12
24453 *
24454 * 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
24455 * +-----------+---+---+-------+-------+-------+-------+-----------+
24456 * | SPECIAL2 |an2|x x| Xd | XRc | XRb | XRa |MXU__POOL12|
24457 * +-----------+---+---+-------+-------+-------+-------+-----------+
24458 *
24459 */
24460static void decode_opc_mxu__pool12(CPUMIPSState *env, DisasContext *ctx)
24461{
24462 uint32_t opcode = extract32(ctx->opcode, 22, 2);
24463
24464 switch (opcode) {
24465 case OPC_MXU_D32ACC:
24466 /* TODO: Implement emulation of D32ACC instruction. */
24467 MIPS_INVAL("OPC_MXU_D32ACC");
24468 generate_exception_end(ctx, EXCP_RI);
24469 break;
24470 case OPC_MXU_D32ACCM:
24471 /* TODO: Implement emulation of D32ACCM instruction. */
24472 MIPS_INVAL("OPC_MXU_D32ACCM");
24473 generate_exception_end(ctx, EXCP_RI);
24474 break;
24475 case OPC_MXU_D32ASUM:
24476 /* TODO: Implement emulation of D32ASUM instruction. */
24477 MIPS_INVAL("OPC_MXU_D32ASUM");
24478 generate_exception_end(ctx, EXCP_RI);
24479 break;
24480 default:
24481 MIPS_INVAL("decode_opc_mxu");
24482 generate_exception_end(ctx, EXCP_RI);
24483 break;
24484 }
24485}
24486
24487/*
24488 *
24489 * Decode MXU pool13
24490 *
24491 * 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
24492 * +-----------+---+---+-------+-------+-------+-------+-----------+
24493 * | SPECIAL2 |en2|x x|0 0 0 0| XRc | XRb | XRa |MXU__POOL13|
24494 * +-----------+---+---+-------+-------+-------+-------+-----------+
24495 *
24496 */
24497static void decode_opc_mxu__pool13(CPUMIPSState *env, DisasContext *ctx)
24498{
24499 uint32_t opcode = extract32(ctx->opcode, 22, 2);
24500
24501 switch (opcode) {
24502 case OPC_MXU_Q16ACC:
24503 /* TODO: Implement emulation of Q16ACC instruction. */
24504 MIPS_INVAL("OPC_MXU_Q16ACC");
24505 generate_exception_end(ctx, EXCP_RI);
24506 break;
24507 case OPC_MXU_Q16ACCM:
24508 /* TODO: Implement emulation of Q16ACCM instruction. */
24509 MIPS_INVAL("OPC_MXU_Q16ACCM");
24510 generate_exception_end(ctx, EXCP_RI);
24511 break;
24512 case OPC_MXU_Q16ASUM:
24513 /* TODO: Implement emulation of Q16ASUM instruction. */
24514 MIPS_INVAL("OPC_MXU_Q16ASUM");
24515 generate_exception_end(ctx, EXCP_RI);
24516 break;
24517 default:
24518 MIPS_INVAL("decode_opc_mxu");
24519 generate_exception_end(ctx, EXCP_RI);
24520 break;
24521 }
24522}
24523
24524/*
24525 *
24526 * Decode MXU pool14
24527 *
24528 * Q8ADDE, Q8ACCE:
24529 * 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
24530 * +-----------+---+---+-------+-------+-------+-------+-----------+
24531 * | SPECIAL2 |0 0|x x| XRd | XRc | XRb | XRa |MXU__POOL14|
24532 * +-----------+---+---+-------+-------+-------+-------+-----------+
24533 *
24534 * D8SUM, D8SUMC:
24535 * 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
24536 * +-----------+---+---+-------+-------+-------+-------+-----------+
24537 * | SPECIAL2 |en2|x x|0 0 0 0| XRc | XRb | XRa |MXU__POOL14|
24538 * +-----------+---+---+-------+-------+-------+-------+-----------+
24539 *
24540 */
24541static void decode_opc_mxu__pool14(CPUMIPSState *env, DisasContext *ctx)
24542{
24543 uint32_t opcode = extract32(ctx->opcode, 22, 2);
24544
24545 switch (opcode) {
24546 case OPC_MXU_Q8ADDE:
24547 /* TODO: Implement emulation of Q8ADDE instruction. */
24548 MIPS_INVAL("OPC_MXU_Q8ADDE");
24549 generate_exception_end(ctx, EXCP_RI);
24550 break;
24551 case OPC_MXU_D8SUM:
24552 /* TODO: Implement emulation of D8SUM instruction. */
24553 MIPS_INVAL("OPC_MXU_D8SUM");
24554 generate_exception_end(ctx, EXCP_RI);
24555 break;
24556 case OPC_MXU_D8SUMC:
24557 /* TODO: Implement emulation of D8SUMC instruction. */
24558 MIPS_INVAL("OPC_MXU_D8SUMC");
24559 generate_exception_end(ctx, EXCP_RI);
24560 break;
24561 default:
24562 MIPS_INVAL("decode_opc_mxu");
24563 generate_exception_end(ctx, EXCP_RI);
24564 break;
24565 }
24566}
24567
24568/*
24569 *
24570 * Decode MXU pool15
24571 *
24572 * S32MUL, S32MULU, S32EXTRV:
24573 * 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
24574 * +-----------+---------+---------+---+-------+-------+-----------+
24575 * | SPECIAL2 | rs | rt |x x| XRd | XRa |MXU__POOL15|
24576 * +-----------+---------+---------+---+-------+-------+-----------+
24577 *
24578 * S32EXTR:
24579 * 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
24580 * +-----------+---------+---------+---+-------+-------+-----------+
24581 * | SPECIAL2 | rb | sft5 |x x| XRd | XRa |MXU__POOL15|
24582 * +-----------+---------+---------+---+-------+-------+-----------+
24583 *
24584 */
24585static void decode_opc_mxu__pool15(CPUMIPSState *env, DisasContext *ctx)
24586{
24587 uint32_t opcode = extract32(ctx->opcode, 14, 2);
24588
24589 switch (opcode) {
24590 case OPC_MXU_S32MUL:
24591 /* TODO: Implement emulation of S32MUL instruction. */
24592 MIPS_INVAL("OPC_MXU_S32MUL");
24593 generate_exception_end(ctx, EXCP_RI);
24594 break;
24595 case OPC_MXU_S32MULU:
24596 /* TODO: Implement emulation of S32MULU instruction. */
24597 MIPS_INVAL("OPC_MXU_S32MULU");
24598 generate_exception_end(ctx, EXCP_RI);
24599 break;
24600 case OPC_MXU_S32EXTR:
24601 /* TODO: Implement emulation of S32EXTR instruction. */
24602 MIPS_INVAL("OPC_MXU_S32EXTR");
24603 generate_exception_end(ctx, EXCP_RI);
24604 break;
24605 case OPC_MXU_S32EXTRV:
24606 /* TODO: Implement emulation of S32EXTRV instruction. */
24607 MIPS_INVAL("OPC_MXU_S32EXTRV");
24608 generate_exception_end(ctx, EXCP_RI);
24609 break;
24610 default:
24611 MIPS_INVAL("decode_opc_mxu");
24612 generate_exception_end(ctx, EXCP_RI);
24613 break;
24614 }
24615}
24616
24617/*
24618 *
24619 * Decode MXU pool16
24620 *
24621 * D32SARW:
24622 * 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
24623 * +-----------+---------+-----+-------+-------+-------+-----------+
24624 * | SPECIAL2 | rb |x x x| XRc | XRb | XRa |MXU__POOL16|
24625 * +-----------+---------+-----+-------+-------+-------+-----------+
24626 *
24627 * S32ALN:
24628 * 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
24629 * +-----------+---------+-----+-------+-------+-------+-----------+
24630 * | SPECIAL2 | rs |x x x| XRc | XRb | XRa |MXU__POOL16|
24631 * +-----------+---------+-----+-------+-------+-------+-----------+
24632 *
24633 * S32ALNI:
24634 * 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
24635 * +-----------+-----+---+-----+-------+-------+-------+-----------+
24636 * | SPECIAL2 | s3 |0 0|x x x| XRc | XRb | XRa |MXU__POOL16|
24637 * +-----------+-----+---+-----+-------+-------+-------+-----------+
24638 *
24639 * S32NOR, S32AND, S32OR, S32XOR:
24640 * 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
24641 * +-----------+---------+-----+-------+-------+-------+-----------+
24642 * | SPECIAL2 |0 0 0 0 0|x x x| XRc | XRb | XRa |MXU__POOL16|
24643 * +-----------+---------+-----+-------+-------+-------+-----------+
24644 *
24645 * S32LUI:
24646 * 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
24647 * +-----------+-----+---+-----+-------+---------------+-----------+
24648 * | SPECIAL2 |optn3|0 0|x x x| XRc | s8 |MXU__POOL16|
24649 * +-----------+-----+---+-----+-------+---------------+-----------+
24650 *
24651 */
24652static void decode_opc_mxu__pool16(CPUMIPSState *env, DisasContext *ctx)
24653{
24654 uint32_t opcode = extract32(ctx->opcode, 18, 3);
24655
24656 switch (opcode) {
24657 case OPC_MXU_D32SARW:
24658 /* TODO: Implement emulation of D32SARW instruction. */
24659 MIPS_INVAL("OPC_MXU_D32SARW");
24660 generate_exception_end(ctx, EXCP_RI);
24661 break;
24662 case OPC_MXU_S32ALN:
24663 /* TODO: Implement emulation of S32ALN instruction. */
24664 MIPS_INVAL("OPC_MXU_S32ALN");
24665 generate_exception_end(ctx, EXCP_RI);
24666 break;
24667 case OPC_MXU_S32ALNI:
24668 /* TODO: Implement emulation of S32ALNI instruction. */
24669 MIPS_INVAL("OPC_MXU_S32ALNI");
24670 generate_exception_end(ctx, EXCP_RI);
24671 break;
24672 case OPC_MXU_S32NOR:
24673 /* TODO: Implement emulation of S32NOR instruction. */
24674 MIPS_INVAL("OPC_MXU_S32NOR");
24675 generate_exception_end(ctx, EXCP_RI);
24676 break;
24677 case OPC_MXU_S32AND:
24678 /* TODO: Implement emulation of S32AND instruction. */
24679 MIPS_INVAL("OPC_MXU_S32AND");
24680 generate_exception_end(ctx, EXCP_RI);
24681 break;
24682 case OPC_MXU_S32OR:
24683 /* TODO: Implement emulation of S32OR instruction. */
24684 MIPS_INVAL("OPC_MXU_S32OR");
24685 generate_exception_end(ctx, EXCP_RI);
24686 break;
24687 case OPC_MXU_S32XOR:
24688 /* TODO: Implement emulation of S32XOR instruction. */
24689 MIPS_INVAL("OPC_MXU_S32XOR");
24690 generate_exception_end(ctx, EXCP_RI);
24691 break;
24692 case OPC_MXU_S32LUI:
24693 /* TODO: Implement emulation of S32LUI instruction. */
24694 MIPS_INVAL("OPC_MXU_S32LUI");
24695 generate_exception_end(ctx, EXCP_RI);
24696 break;
24697 default:
24698 MIPS_INVAL("decode_opc_mxu");
24699 generate_exception_end(ctx, EXCP_RI);
24700 break;
24701 }
24702}
24703
24704/*
24705 *
24706 * Decode MXU pool17
24707 *
24708 * 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
24709 * +-----------+---------+-----+-------+-------+-------+-----------+
24710 * | SPECIAL2 | rb |x x x| XRd | XRa |0 0 0 0|MXU__POOL17|
24711 * +-----------+---------+-----+-------+-------+-------+-----------+
24712 *
24713 */
24714static void decode_opc_mxu__pool17(CPUMIPSState *env, DisasContext *ctx)
24715{
24716 uint32_t opcode = extract32(ctx->opcode, 18, 3);
24717
24718 switch (opcode) {
24719 case OPC_MXU_D32SLLV:
24720 /* TODO: Implement emulation of D32SLLV instruction. */
24721 MIPS_INVAL("OPC_MXU_D32SLLV");
24722 generate_exception_end(ctx, EXCP_RI);
24723 break;
24724 case OPC_MXU_D32SLRV:
24725 /* TODO: Implement emulation of D32SLRV instruction. */
24726 MIPS_INVAL("OPC_MXU_D32SLRV");
24727 generate_exception_end(ctx, EXCP_RI);
24728 break;
24729 case OPC_MXU_D32SARV:
24730 /* TODO: Implement emulation of D32SARV instruction. */
24731 MIPS_INVAL("OPC_MXU_D32SARV");
24732 generate_exception_end(ctx, EXCP_RI);
24733 break;
24734 case OPC_MXU_Q16SLLV:
24735 /* TODO: Implement emulation of Q16SLLV instruction. */
24736 MIPS_INVAL("OPC_MXU_Q16SLLV");
24737 generate_exception_end(ctx, EXCP_RI);
24738 break;
24739 case OPC_MXU_Q16SLRV:
24740 /* TODO: Implement emulation of Q16SLRV instruction. */
24741 MIPS_INVAL("OPC_MXU_Q16SLRV");
24742 generate_exception_end(ctx, EXCP_RI);
24743 break;
24744 case OPC_MXU_Q16SARV:
24745 /* TODO: Implement emulation of Q16SARV instruction. */
24746 MIPS_INVAL("OPC_MXU_Q16SARV");
24747 generate_exception_end(ctx, EXCP_RI);
24748 break;
24749 default:
24750 MIPS_INVAL("decode_opc_mxu");
24751 generate_exception_end(ctx, EXCP_RI);
24752 break;
24753 }
24754}
24755
24756/*
24757 *
24758 * Decode MXU pool18
24759 *
24760 * 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
24761 * +-----------+---+---+-------+-------+-------+-------+-----------+
24762 * | SPECIAL2 |0 0|x x| XRd | XRc | XRb | XRa |MXU__POOL18|
24763 * +-----------+---+---+-------+-------+-------+-------+-----------+
24764 *
24765 */
24766static void decode_opc_mxu__pool18(CPUMIPSState *env, DisasContext *ctx)
24767{
24768 uint32_t opcode = extract32(ctx->opcode, 22, 2);
24769
24770 switch (opcode) {
24771 case OPC_MXU_Q8MUL:
24772 /* TODO: Implement emulation of Q8MUL instruction. */
24773 MIPS_INVAL("OPC_MXU_Q8MUL");
24774 generate_exception_end(ctx, EXCP_RI);
24775 break;
24776 case OPC_MXU_Q8MULSU:
24777 /* TODO: Implement emulation of Q8MULSU instruction. */
24778 MIPS_INVAL("OPC_MXU_Q8MULSU");
24779 generate_exception_end(ctx, EXCP_RI);
24780 break;
24781 default:
24782 MIPS_INVAL("decode_opc_mxu");
24783 generate_exception_end(ctx, EXCP_RI);
24784 break;
24785 }
24786}
24787
24788/*
24789 *
24790 * Decode MXU pool19
24791 *
24792 * 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
24793 * +-----------+---------+-----+-------+-------+-------+-----------+
24794 * | SPECIAL2 |0 0 0 0 0|x x x| XRc | XRb | XRa |MXU__POOL19|
24795 * +-----------+---------+-----+-------+-------+-------+-----------+
24796 *
24797 */
24798static void decode_opc_mxu__pool19(CPUMIPSState *env, DisasContext *ctx)
24799{
24800 uint32_t opcode = extract32(ctx->opcode, 18, 3);
24801
24802 switch (opcode) {
24803 case OPC_MXU_Q8MOVZ:
24804 /* TODO: Implement emulation of Q8MOVZ instruction. */
24805 MIPS_INVAL("OPC_MXU_Q8MOVZ");
24806 generate_exception_end(ctx, EXCP_RI);
24807 break;
24808 case OPC_MXU_Q8MOVN:
24809 /* TODO: Implement emulation of Q8MOVN instruction. */
24810 MIPS_INVAL("OPC_MXU_Q8MOVN");
24811 generate_exception_end(ctx, EXCP_RI);
24812 break;
24813 case OPC_MXU_D16MOVZ:
24814 /* TODO: Implement emulation of D16MOVZ instruction. */
24815 MIPS_INVAL("OPC_MXU_D16MOVZ");
24816 generate_exception_end(ctx, EXCP_RI);
24817 break;
24818 case OPC_MXU_D16MOVN:
24819 /* TODO: Implement emulation of D16MOVN instruction. */
24820 MIPS_INVAL("OPC_MXU_D16MOVN");
24821 generate_exception_end(ctx, EXCP_RI);
24822 break;
24823 case OPC_MXU_S32MOVZ:
24824 /* TODO: Implement emulation of S32MOVZ instruction. */
24825 MIPS_INVAL("OPC_MXU_S32MOVZ");
24826 generate_exception_end(ctx, EXCP_RI);
24827 break;
24828 case OPC_MXU_S32MOVN:
24829 /* TODO: Implement emulation of S32MOVN instruction. */
24830 MIPS_INVAL("OPC_MXU_S32MOVN");
24831 generate_exception_end(ctx, EXCP_RI);
24832 break;
24833 default:
24834 MIPS_INVAL("decode_opc_mxu");
24835 generate_exception_end(ctx, EXCP_RI);
24836 break;
24837 }
24838}
24839
24840/*
24841 *
24842 * Decode MXU pool20
24843 *
24844 * 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
24845 * +-----------+---+---+-------+-------+-------+-------+-----------+
24846 * | SPECIAL2 |an2|x x| XRd | XRc | XRb | XRa |MXU__POOL20|
24847 * +-----------+---+---+-------+-------+-------+-------+-----------+
24848 *
24849 */
24850static void decode_opc_mxu__pool20(CPUMIPSState *env, DisasContext *ctx)
24851{
24852 uint32_t opcode = extract32(ctx->opcode, 22, 2);
24853
24854 switch (opcode) {
24855 case OPC_MXU_Q8MAC:
24856 /* TODO: Implement emulation of Q8MAC instruction. */
24857 MIPS_INVAL("OPC_MXU_Q8MAC");
24858 generate_exception_end(ctx, EXCP_RI);
24859 break;
24860 case OPC_MXU_Q8MACSU:
24861 /* TODO: Implement emulation of Q8MACSU instruction. */
24862 MIPS_INVAL("OPC_MXU_Q8MACSU");
24863 generate_exception_end(ctx, EXCP_RI);
24864 break;
24865 default:
24866 MIPS_INVAL("decode_opc_mxu");
24867 generate_exception_end(ctx, EXCP_RI);
24868 break;
24869 }
24870}
24871
24872
24873/*
24874 * Main MXU decoding function
24875 *
24876 * 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
24877 * +-----------+---------------------------------------+-----------+
24878 * | SPECIAL2 | |x x x x x x|
24879 * +-----------+---------------------------------------+-----------+
24880 *
24881 */
0a348b9a
AM
24882static void decode_opc_mxu(CPUMIPSState *env, DisasContext *ctx)
24883{
03f40088
AM
24884 uint32_t opcode = extract32(ctx->opcode, 0, 6);
24885
24886 switch (opcode) {
24887 case OPC_MXU_S32MADD:
24888 /* TODO: Implement emulation of S32MADD instruction. */
24889 MIPS_INVAL("OPC_MXU_S32MADD");
24890 generate_exception_end(ctx, EXCP_RI);
24891 break;
24892 case OPC_MXU_S32MADDU:
24893 /* TODO: Implement emulation of S32MADDU instruction. */
24894 MIPS_INVAL("OPC_MXU_S32MADDU");
24895 generate_exception_end(ctx, EXCP_RI);
24896 break;
24897 case OPC_MXU__POOL00:
24898 decode_opc_mxu__pool00(env, ctx);
24899 break;
24900 case OPC_MXU_S32MSUB:
24901 /* TODO: Implement emulation of S32MSUB instruction. */
24902 MIPS_INVAL("OPC_MXU_S32MSUB");
24903 generate_exception_end(ctx, EXCP_RI);
24904 break;
24905 case OPC_MXU_S32MSUBU:
24906 /* TODO: Implement emulation of S32MSUBU instruction. */
24907 MIPS_INVAL("OPC_MXU_S32MSUBU");
24908 generate_exception_end(ctx, EXCP_RI);
24909 break;
24910 case OPC_MXU__POOL01:
24911 decode_opc_mxu__pool01(env, ctx);
24912 break;
24913 case OPC_MXU__POOL02:
24914 decode_opc_mxu__pool02(env, ctx);
24915 break;
24916 case OPC_MXU_D16MUL:
24917 /* TODO: Implement emulation of D16MUL instruction. */
24918 MIPS_INVAL("OPC_MXU_D16MUL");
24919 generate_exception_end(ctx, EXCP_RI);
24920 break;
24921 case OPC_MXU__POOL03:
24922 decode_opc_mxu__pool03(env, ctx);
24923 break;
24924 case OPC_MXU_D16MAC:
24925 /* TODO: Implement emulation of D16MAC instruction. */
24926 MIPS_INVAL("OPC_MXU_D16MAC");
24927 generate_exception_end(ctx, EXCP_RI);
24928 break;
24929 case OPC_MXU_D16MACF:
24930 /* TODO: Implement emulation of D16MACF instruction. */
24931 MIPS_INVAL("OPC_MXU_D16MACF");
24932 generate_exception_end(ctx, EXCP_RI);
24933 break;
24934 case OPC_MXU_D16MADL:
24935 /* TODO: Implement emulation of D16MADL instruction. */
24936 MIPS_INVAL("OPC_MXU_D16MADL");
24937 generate_exception_end(ctx, EXCP_RI);
24938 break;
24939 case OPC_MXU_S16MAD:
24940 /* TODO: Implement emulation of S16MAD instruction. */
24941 MIPS_INVAL("OPC_MXU_S16MAD");
24942 generate_exception_end(ctx, EXCP_RI);
24943 break;
24944 case OPC_MXU_Q16ADD:
24945 /* TODO: Implement emulation of Q16ADD instruction. */
24946 MIPS_INVAL("OPC_MXU_Q16ADD");
24947 generate_exception_end(ctx, EXCP_RI);
24948 break;
24949 case OPC_MXU_D16MACE:
24950 /* TODO: Implement emulation of D16MACE instruction. */
24951 MIPS_INVAL("OPC_MXU_D16MACE");
24952 generate_exception_end(ctx, EXCP_RI);
24953 break;
24954 case OPC_MXU__POOL04:
24955 decode_opc_mxu__pool04(env, ctx);
24956 break;
24957 case OPC_MXU__POOL05:
24958 decode_opc_mxu__pool05(env, ctx);
24959 break;
24960 case OPC_MXU__POOL06:
24961 decode_opc_mxu__pool06(env, ctx);
24962 break;
24963 case OPC_MXU__POOL07:
24964 decode_opc_mxu__pool07(env, ctx);
24965 break;
24966 case OPC_MXU__POOL08:
24967 decode_opc_mxu__pool08(env, ctx);
24968 break;
24969 case OPC_MXU__POOL09:
24970 decode_opc_mxu__pool09(env, ctx);
24971 break;
24972 case OPC_MXU__POOL10:
24973 decode_opc_mxu__pool10(env, ctx);
24974 break;
24975 case OPC_MXU__POOL11:
24976 decode_opc_mxu__pool11(env, ctx);
24977 break;
24978 case OPC_MXU_D32ADD:
24979 /* TODO: Implement emulation of D32ADD instruction. */
24980 MIPS_INVAL("OPC_MXU_D32ADD");
24981 generate_exception_end(ctx, EXCP_RI);
24982 break;
24983 case OPC_MXU__POOL12:
24984 decode_opc_mxu__pool12(env, ctx);
24985 break;
24986 case OPC_MXU__POOL13:
24987 decode_opc_mxu__pool13(env, ctx);
24988 break;
24989 case OPC_MXU__POOL14:
24990 decode_opc_mxu__pool14(env, ctx);
24991 break;
24992 case OPC_MXU_Q8ACCE:
24993 /* TODO: Implement emulation of Q8ACCE instruction. */
24994 MIPS_INVAL("OPC_MXU_Q8ACCE");
24995 generate_exception_end(ctx, EXCP_RI);
24996 break;
24997 case OPC_MXU_S8LDD:
24998 /* TODO: Implement emulation of S8LDD instruction. */
24999 MIPS_INVAL("OPC_MXU_S8LDD");
25000 generate_exception_end(ctx, EXCP_RI);
25001 break;
25002 case OPC_MXU_S8STD:
25003 /* TODO: Implement emulation of S8STD instruction. */
25004 MIPS_INVAL("OPC_MXU_S8STD");
25005 generate_exception_end(ctx, EXCP_RI);
25006 break;
25007 case OPC_MXU_S8LDI:
25008 /* TODO: Implement emulation of S8LDI instruction. */
25009 MIPS_INVAL("OPC_MXU_S8LDI");
25010 generate_exception_end(ctx, EXCP_RI);
25011 break;
25012 case OPC_MXU_S8SDI:
25013 /* TODO: Implement emulation of S8SDI instruction. */
25014 MIPS_INVAL("OPC_MXU_S8SDI");
25015 generate_exception_end(ctx, EXCP_RI);
25016 break;
25017 case OPC_MXU__POOL15:
25018 decode_opc_mxu__pool15(env, ctx);
25019 break;
25020 case OPC_MXU__POOL16:
25021 decode_opc_mxu__pool16(env, ctx);
25022 break;
25023 case OPC_MXU_LXB:
25024 /* TODO: Implement emulation of LXB instruction. */
25025 MIPS_INVAL("OPC_MXU_LXB");
25026 generate_exception_end(ctx, EXCP_RI);
25027 break;
25028 case OPC_MXU_S16LDD:
25029 /* TODO: Implement emulation of S16LDD instruction. */
25030 MIPS_INVAL("OPC_MXU_S16LDD");
25031 generate_exception_end(ctx, EXCP_RI);
25032 break;
25033 case OPC_MXU_S16STD:
25034 /* TODO: Implement emulation of S16STD instruction. */
25035 MIPS_INVAL("OPC_MXU_S16STD");
25036 generate_exception_end(ctx, EXCP_RI);
25037 break;
25038 case OPC_MXU_S16LDI:
25039 /* TODO: Implement emulation of S16LDI instruction. */
25040 MIPS_INVAL("OPC_MXU_S16LDI");
25041 generate_exception_end(ctx, EXCP_RI);
25042 break;
25043 case OPC_MXU_S16SDI:
25044 /* TODO: Implement emulation of S16SDI instruction. */
25045 MIPS_INVAL("OPC_MXU_S16SDI");
25046 generate_exception_end(ctx, EXCP_RI);
25047 break;
25048 case OPC_MXU_S32M2I:
25049 /* TODO: Implement emulation of S32M2I instruction. */
25050 MIPS_INVAL("OPC_MXU_S32M2I");
25051 generate_exception_end(ctx, EXCP_RI);
25052 break;
25053 case OPC_MXU_S32I2M:
25054 /* TODO: Implement emulation of S32I2M instruction. */
25055 MIPS_INVAL("OPC_MXU_S32I2M");
25056 generate_exception_end(ctx, EXCP_RI);
25057 break;
25058 case OPC_MXU_D32SLL:
25059 /* TODO: Implement emulation of D32SLL instruction. */
25060 MIPS_INVAL("OPC_MXU_D32SLL");
25061 generate_exception_end(ctx, EXCP_RI);
25062 break;
25063 case OPC_MXU_D32SLR:
25064 /* TODO: Implement emulation of D32SLR instruction. */
25065 MIPS_INVAL("OPC_MXU_D32SLR");
25066 generate_exception_end(ctx, EXCP_RI);
25067 break;
25068 case OPC_MXU_D32SARL:
25069 /* TODO: Implement emulation of D32SARL instruction. */
25070 MIPS_INVAL("OPC_MXU_D32SARL");
25071 generate_exception_end(ctx, EXCP_RI);
25072 break;
25073 case OPC_MXU_D32SAR:
25074 /* TODO: Implement emulation of D32SAR instruction. */
25075 MIPS_INVAL("OPC_MXU_D32SAR");
25076 generate_exception_end(ctx, EXCP_RI);
25077 break;
25078 case OPC_MXU_Q16SLL:
25079 /* TODO: Implement emulation of Q16SLL instruction. */
25080 MIPS_INVAL("OPC_MXU_Q16SLL");
25081 generate_exception_end(ctx, EXCP_RI);
25082 break;
25083 case OPC_MXU_Q16SLR:
25084 /* TODO: Implement emulation of Q16SLR instruction. */
25085 MIPS_INVAL("OPC_MXU_Q16SLR");
25086 generate_exception_end(ctx, EXCP_RI);
25087 break;
25088 case OPC_MXU__POOL17:
25089 decode_opc_mxu__pool17(env, ctx);
25090 break;
25091 case OPC_MXU_Q16SAR:
25092 /* TODO: Implement emulation of Q16SAR instruction. */
25093 MIPS_INVAL("OPC_MXU_Q16SAR");
25094 generate_exception_end(ctx, EXCP_RI);
25095 break;
25096 case OPC_MXU__POOL18:
25097 decode_opc_mxu__pool18(env, ctx);
25098 break;
25099 case OPC_MXU__POOL19:
25100 decode_opc_mxu__pool19(env, ctx);
25101 break;
25102 case OPC_MXU__POOL20:
25103 decode_opc_mxu__pool20(env, ctx);
25104 break;
25105 case OPC_MXU_Q16SCOP:
25106 /* TODO: Implement emulation of Q16SCOP instruction. */
25107 MIPS_INVAL("OPC_MXU_Q16SCOP");
25108 generate_exception_end(ctx, EXCP_RI);
25109 break;
25110 case OPC_MXU_Q8MADL:
25111 /* TODO: Implement emulation of Q8MADL instruction. */
25112 MIPS_INVAL("OPC_MXU_Q8MADL");
25113 generate_exception_end(ctx, EXCP_RI);
25114 break;
25115 case OPC_MXU_S32SFL:
25116 /* TODO: Implement emulation of S32SFL instruction. */
25117 MIPS_INVAL("OPC_MXU_S32SFL");
25118 generate_exception_end(ctx, EXCP_RI);
25119 break;
25120 case OPC_MXU_Q8SAD:
25121 /* TODO: Implement emulation of Q8SAD instruction. */
25122 MIPS_INVAL("OPC_MXU_Q8SAD");
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 }
0a348b9a
AM
25129}
25130
03f40088 25131
10dc65db 25132static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx)
099e5b4d
LA
25133{
25134 int rs, rt, rd;
25135 uint32_t op1;
6c5c1e20 25136
4267d3e6
LA
25137 check_insn_opc_removed(ctx, ISA_MIPS32R6);
25138
099e5b4d
LA
25139 rs = (ctx->opcode >> 21) & 0x1f;
25140 rt = (ctx->opcode >> 16) & 0x1f;
25141 rd = (ctx->opcode >> 11) & 0x1f;
25142
25143 op1 = MASK_SPECIAL2(ctx->opcode);
25144 switch (op1) {
c2e19f3c
AM
25145 case OPC_MADD: /* Multiply and add/sub */
25146 case OPC_MADDU:
25147 case OPC_MSUB:
25148 case OPC_MSUBU:
099e5b4d
LA
25149 check_insn(ctx, ISA_MIPS32);
25150 gen_muldiv(ctx, op1, rd & 3, rs, rt);
25151 break;
25152 case OPC_MUL:
099e5b4d
LA
25153 gen_arith(ctx, op1, rd, rs, rt);
25154 break;
fac5a073
LA
25155 case OPC_DIV_G_2F:
25156 case OPC_DIVU_G_2F:
25157 case OPC_MULT_G_2F:
25158 case OPC_MULTU_G_2F:
25159 case OPC_MOD_G_2F:
25160 case OPC_MODU_G_2F:
25161 check_insn(ctx, INSN_LOONGSON2F);
25162 gen_loongson_integer(ctx, op1, rd, rs, rt);
25163 break;
099e5b4d
LA
25164 case OPC_CLO:
25165 case OPC_CLZ:
25166 check_insn(ctx, ISA_MIPS32);
25167 gen_cl(ctx, op1, rd, rs);
25168 break;
25169 case OPC_SDBBP:
3b3c1694
LA
25170 if (is_uhi(extract32(ctx->opcode, 6, 20))) {
25171 gen_helper_do_semihosting(cpu_env);
25172 } else {
25173 /* XXX: not clear which exception should be raised
25174 * when in debug mode...
25175 */
25176 check_insn(ctx, ISA_MIPS32);
9c708c7f 25177 generate_exception_end(ctx, EXCP_DBp);
3b3c1694 25178 }
099e5b4d 25179 break;
9b1a1d68 25180#if defined(TARGET_MIPS64)
099e5b4d
LA
25181 case OPC_DCLO:
25182 case OPC_DCLZ:
25183 check_insn(ctx, ISA_MIPS64);
25184 check_mips_64(ctx);
25185 gen_cl(ctx, op1, rd, rs);
25186 break;
4267d3e6
LA
25187 case OPC_DMULT_G_2F:
25188 case OPC_DMULTU_G_2F:
25189 case OPC_DDIV_G_2F:
25190 case OPC_DDIVU_G_2F:
25191 case OPC_DMOD_G_2F:
25192 case OPC_DMODU_G_2F:
25193 check_insn(ctx, INSN_LOONGSON2F);
25194 gen_loongson_integer(ctx, op1, rd, rs, rt);
25195 break;
10dc65db 25196#endif
4267d3e6
LA
25197 default: /* Invalid */
25198 MIPS_INVAL("special2_legacy");
9c708c7f 25199 generate_exception_end(ctx, EXCP_RI);
4267d3e6 25200 break;
10dc65db
LA
25201 }
25202}
25203
25204static void decode_opc_special3_r6(CPUMIPSState *env, DisasContext *ctx)
25205{
15eacb9b
YK
25206 int rs, rt, rd, sa;
25207 uint32_t op1, op2;
10dc65db
LA
25208 int16_t imm;
25209
25210 rs = (ctx->opcode >> 21) & 0x1f;
25211 rt = (ctx->opcode >> 16) & 0x1f;
15eacb9b
YK
25212 rd = (ctx->opcode >> 11) & 0x1f;
25213 sa = (ctx->opcode >> 6) & 0x1f;
10dc65db
LA
25214 imm = (int16_t)ctx->opcode >> 7;
25215
25216 op1 = MASK_SPECIAL3(ctx->opcode);
25217 switch (op1) {
bf7910c6
LA
25218 case R6_OPC_PREF:
25219 if (rt >= 24) {
25220 /* hint codes 24-31 are reserved and signal RI */
9c708c7f 25221 generate_exception_end(ctx, EXCP_RI);
bf7910c6
LA
25222 }
25223 /* Treat as NOP. */
25224 break;
25225 case R6_OPC_CACHE:
40d48212 25226 check_cp0_enabled(ctx);
0d74a222
LA
25227 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
25228 gen_cache_operation(ctx, rt, rs, imm);
25229 }
bf7910c6 25230 break;
10dc65db
LA
25231 case R6_OPC_SC:
25232 gen_st_cond(ctx, op1, rt, rs, imm);
25233 break;
25234 case R6_OPC_LL:
25235 gen_ld(ctx, op1, rt, rs, imm);
25236 break;
15eacb9b
YK
25237 case OPC_BSHFL:
25238 {
25239 if (rd == 0) {
25240 /* Treat as NOP. */
25241 break;
25242 }
15eacb9b
YK
25243 op2 = MASK_BSHFL(ctx->opcode);
25244 switch (op2) {
c2e19f3c 25245 case OPC_ALIGN:
373ecd38
AM
25246 case OPC_ALIGN_1:
25247 case OPC_ALIGN_2:
25248 case OPC_ALIGN_3:
821f2008 25249 gen_align(ctx, 32, rd, rs, rt, sa & 3);
15eacb9b
YK
25250 break;
25251 case OPC_BITSWAP:
1f1b4c00 25252 gen_bitswap(ctx, op2, rd, rt);
15eacb9b
YK
25253 break;
25254 }
15eacb9b
YK
25255 }
25256 break;
bf7910c6
LA
25257#if defined(TARGET_MIPS64)
25258 case R6_OPC_SCD:
25259 gen_st_cond(ctx, op1, rt, rs, imm);
25260 break;
25261 case R6_OPC_LLD:
25262 gen_ld(ctx, op1, rt, rs, imm);
25263 break;
15eacb9b
YK
25264 case OPC_DBSHFL:
25265 check_mips_64(ctx);
25266 {
25267 if (rd == 0) {
25268 /* Treat as NOP. */
25269 break;
25270 }
15eacb9b
YK
25271 op2 = MASK_DBSHFL(ctx->opcode);
25272 switch (op2) {
c2e19f3c 25273 case OPC_DALIGN:
373ecd38
AM
25274 case OPC_DALIGN_1:
25275 case OPC_DALIGN_2:
25276 case OPC_DALIGN_3:
25277 case OPC_DALIGN_4:
25278 case OPC_DALIGN_5:
25279 case OPC_DALIGN_6:
25280 case OPC_DALIGN_7:
821f2008 25281 gen_align(ctx, 64, rd, rs, rt, sa & 7);
15eacb9b
YK
25282 break;
25283 case OPC_DBITSWAP:
1f1b4c00 25284 gen_bitswap(ctx, op2, rd, rt);
15eacb9b
YK
25285 break;
25286 }
1f1b4c00 25287
15eacb9b
YK
25288 }
25289 break;
bf7910c6 25290#endif
10dc65db
LA
25291 default: /* Invalid */
25292 MIPS_INVAL("special3_r6");
9c708c7f 25293 generate_exception_end(ctx, EXCP_RI);
10dc65db
LA
25294 break;
25295 }
25296}
25297
25298static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx)
25299{
fac5a073 25300 int rs, rt, rd;
099e5b4d 25301 uint32_t op1, op2;
099e5b4d
LA
25302
25303 rs = (ctx->opcode >> 21) & 0x1f;
25304 rt = (ctx->opcode >> 16) & 0x1f;
25305 rd = (ctx->opcode >> 11) & 0x1f;
099e5b4d
LA
25306
25307 op1 = MASK_SPECIAL3(ctx->opcode);
25308 switch (op1) {
c2e19f3c
AM
25309 case OPC_DIV_G_2E:
25310 case OPC_DIVU_G_2E:
25311 case OPC_MOD_G_2E:
25312 case OPC_MODU_G_2E:
25313 case OPC_MULT_G_2E:
25314 case OPC_MULTU_G_2E:
099e5b4d
LA
25315 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
25316 * the same mask and op1. */
908f6be1 25317 if ((ctx->insn_flags & ASE_DSP_R2) && (op1 == OPC_MULT_G_2E)) {
099e5b4d 25318 op2 = MASK_ADDUH_QB(ctx->opcode);
461c08df 25319 switch (op2) {
099e5b4d
LA
25320 case OPC_ADDUH_QB:
25321 case OPC_ADDUH_R_QB:
25322 case OPC_ADDQH_PH:
25323 case OPC_ADDQH_R_PH:
25324 case OPC_ADDQH_W:
25325 case OPC_ADDQH_R_W:
25326 case OPC_SUBUH_QB:
25327 case OPC_SUBUH_R_QB:
25328 case OPC_SUBQH_PH:
25329 case OPC_SUBQH_R_PH:
25330 case OPC_SUBQH_W:
25331 case OPC_SUBQH_R_W:
461c08df
JL
25332 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
25333 break;
099e5b4d
LA
25334 case OPC_MUL_PH:
25335 case OPC_MUL_S_PH:
25336 case OPC_MULQ_S_W:
25337 case OPC_MULQ_RS_W:
25338 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
1cb6686c 25339 break;
461c08df 25340 default:
099e5b4d 25341 MIPS_INVAL("MASK ADDUH.QB");
9c708c7f 25342 generate_exception_end(ctx, EXCP_RI);
461c08df
JL
25343 break;
25344 }
099e5b4d
LA
25345 } else if (ctx->insn_flags & INSN_LOONGSON2E) {
25346 gen_loongson_integer(ctx, op1, rd, rs, rt);
25347 } else {
9c708c7f 25348 generate_exception_end(ctx, EXCP_RI);
099e5b4d
LA
25349 }
25350 break;
25351 case OPC_LX_DSP:
25352 op2 = MASK_LX(ctx->opcode);
25353 switch (op2) {
25354#if defined(TARGET_MIPS64)
25355 case OPC_LDX:
25356#endif
25357 case OPC_LBUX:
25358 case OPC_LHX:
25359 case OPC_LWX:
25360 gen_mipsdsp_ld(ctx, op2, rd, rs, rt);
25361 break;
25362 default: /* Invalid */
25363 MIPS_INVAL("MASK LX");
9c708c7f 25364 generate_exception_end(ctx, EXCP_RI);
099e5b4d
LA
25365 break;
25366 }
25367 break;
25368 case OPC_ABSQ_S_PH_DSP:
25369 op2 = MASK_ABSQ_S_PH(ctx->opcode);
25370 switch (op2) {
25371 case OPC_ABSQ_S_QB:
25372 case OPC_ABSQ_S_PH:
25373 case OPC_ABSQ_S_W:
25374 case OPC_PRECEQ_W_PHL:
25375 case OPC_PRECEQ_W_PHR:
25376 case OPC_PRECEQU_PH_QBL:
25377 case OPC_PRECEQU_PH_QBR:
25378 case OPC_PRECEQU_PH_QBLA:
25379 case OPC_PRECEQU_PH_QBRA:
25380 case OPC_PRECEU_PH_QBL:
25381 case OPC_PRECEU_PH_QBR:
25382 case OPC_PRECEU_PH_QBLA:
25383 case OPC_PRECEU_PH_QBRA:
25384 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
25385 break;
25386 case OPC_BITREV:
25387 case OPC_REPL_QB:
25388 case OPC_REPLV_QB:
25389 case OPC_REPL_PH:
25390 case OPC_REPLV_PH:
25391 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
25392 break;
25393 default:
25394 MIPS_INVAL("MASK ABSQ_S.PH");
9c708c7f 25395 generate_exception_end(ctx, EXCP_RI);
099e5b4d
LA
25396 break;
25397 }
25398 break;
25399 case OPC_ADDU_QB_DSP:
25400 op2 = MASK_ADDU_QB(ctx->opcode);
25401 switch (op2) {
25402 case OPC_ADDQ_PH:
25403 case OPC_ADDQ_S_PH:
25404 case OPC_ADDQ_S_W:
25405 case OPC_ADDU_QB:
25406 case OPC_ADDU_S_QB:
25407 case OPC_ADDU_PH:
25408 case OPC_ADDU_S_PH:
25409 case OPC_SUBQ_PH:
25410 case OPC_SUBQ_S_PH:
25411 case OPC_SUBQ_S_W:
25412 case OPC_SUBU_QB:
25413 case OPC_SUBU_S_QB:
25414 case OPC_SUBU_PH:
25415 case OPC_SUBU_S_PH:
25416 case OPC_ADDSC:
25417 case OPC_ADDWC:
25418 case OPC_MODSUB:
25419 case OPC_RADDU_W_QB:
25420 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
25421 break;
25422 case OPC_MULEU_S_PH_QBL:
25423 case OPC_MULEU_S_PH_QBR:
25424 case OPC_MULQ_RS_PH:
25425 case OPC_MULEQ_S_W_PHL:
25426 case OPC_MULEQ_S_W_PHR:
25427 case OPC_MULQ_S_PH:
25428 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
25429 break;
25430 default: /* Invalid */
25431 MIPS_INVAL("MASK ADDU.QB");
9c708c7f 25432 generate_exception_end(ctx, EXCP_RI);
461c08df 25433 break;
461c08df 25434
099e5b4d
LA
25435 }
25436 break;
25437 case OPC_CMPU_EQ_QB_DSP:
25438 op2 = MASK_CMPU_EQ_QB(ctx->opcode);
25439 switch (op2) {
25440 case OPC_PRECR_SRA_PH_W:
25441 case OPC_PRECR_SRA_R_PH_W:
25442 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
461c08df 25443 break;
099e5b4d
LA
25444 case OPC_PRECR_QB_PH:
25445 case OPC_PRECRQ_QB_PH:
25446 case OPC_PRECRQ_PH_W:
25447 case OPC_PRECRQ_RS_PH_W:
25448 case OPC_PRECRQU_S_QB_PH:
25449 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
461c08df 25450 break;
099e5b4d
LA
25451 case OPC_CMPU_EQ_QB:
25452 case OPC_CMPU_LT_QB:
25453 case OPC_CMPU_LE_QB:
25454 case OPC_CMP_EQ_PH:
25455 case OPC_CMP_LT_PH:
25456 case OPC_CMP_LE_PH:
25457 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
77c5fa8b 25458 break;
099e5b4d
LA
25459 case OPC_CMPGU_EQ_QB:
25460 case OPC_CMPGU_LT_QB:
25461 case OPC_CMPGU_LE_QB:
25462 case OPC_CMPGDU_EQ_QB:
25463 case OPC_CMPGDU_LT_QB:
25464 case OPC_CMPGDU_LE_QB:
25465 case OPC_PICK_QB:
25466 case OPC_PICK_PH:
25467 case OPC_PACKRL_PH:
25468 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
25469 break;
25470 default: /* Invalid */
25471 MIPS_INVAL("MASK CMPU.EQ.QB");
9c708c7f 25472 generate_exception_end(ctx, EXCP_RI);
099e5b4d
LA
25473 break;
25474 }
25475 break;
25476 case OPC_SHLL_QB_DSP:
25477 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
25478 break;
25479 case OPC_DPA_W_PH_DSP:
25480 op2 = MASK_DPA_W_PH(ctx->opcode);
25481 switch (op2) {
25482 case OPC_DPAU_H_QBL:
25483 case OPC_DPAU_H_QBR:
25484 case OPC_DPSU_H_QBL:
25485 case OPC_DPSU_H_QBR:
25486 case OPC_DPA_W_PH:
25487 case OPC_DPAX_W_PH:
25488 case OPC_DPAQ_S_W_PH:
25489 case OPC_DPAQX_S_W_PH:
25490 case OPC_DPAQX_SA_W_PH:
25491 case OPC_DPS_W_PH:
25492 case OPC_DPSX_W_PH:
25493 case OPC_DPSQ_S_W_PH:
25494 case OPC_DPSQX_S_W_PH:
25495 case OPC_DPSQX_SA_W_PH:
25496 case OPC_MULSAQ_S_W_PH:
25497 case OPC_DPAQ_SA_L_W:
25498 case OPC_DPSQ_SA_L_W:
25499 case OPC_MAQ_S_W_PHL:
25500 case OPC_MAQ_S_W_PHR:
25501 case OPC_MAQ_SA_W_PHL:
25502 case OPC_MAQ_SA_W_PHR:
25503 case OPC_MULSA_W_PH:
25504 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
25505 break;
25506 default: /* Invalid */
25507 MIPS_INVAL("MASK DPAW.PH");
9c708c7f 25508 generate_exception_end(ctx, EXCP_RI);
099e5b4d
LA
25509 break;
25510 }
25511 break;
25512 case OPC_INSV_DSP:
25513 op2 = MASK_INSV(ctx->opcode);
25514 switch (op2) {
25515 case OPC_INSV:
25516 check_dsp(ctx);
25517 {
25518 TCGv t0, t1;
25519
25520 if (rt == 0) {
099e5b4d
LA
25521 break;
25522 }
25523
25524 t0 = tcg_temp_new();
25525 t1 = tcg_temp_new();
25526
25527 gen_load_gpr(t0, rt);
25528 gen_load_gpr(t1, rs);
25529
25530 gen_helper_insv(cpu_gpr[rt], cpu_env, t1, t0);
25531
25532 tcg_temp_free(t0);
25533 tcg_temp_free(t1);
a22260ae
JL
25534 break;
25535 }
099e5b4d
LA
25536 default: /* Invalid */
25537 MIPS_INVAL("MASK INSV");
9c708c7f 25538 generate_exception_end(ctx, EXCP_RI);
099e5b4d
LA
25539 break;
25540 }
25541 break;
25542 case OPC_APPEND_DSP:
25543 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
25544 break;
25545 case OPC_EXTR_W_DSP:
25546 op2 = MASK_EXTR_W(ctx->opcode);
25547 switch (op2) {
25548 case OPC_EXTR_W:
25549 case OPC_EXTR_R_W:
25550 case OPC_EXTR_RS_W:
25551 case OPC_EXTR_S_H:
25552 case OPC_EXTRV_S_H:
25553 case OPC_EXTRV_W:
25554 case OPC_EXTRV_R_W:
25555 case OPC_EXTRV_RS_W:
25556 case OPC_EXTP:
25557 case OPC_EXTPV:
25558 case OPC_EXTPDP:
25559 case OPC_EXTPDPV:
25560 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
25561 break;
25562 case OPC_RDDSP:
25563 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 1);
25564 break;
25565 case OPC_SHILO:
25566 case OPC_SHILOV:
25567 case OPC_MTHLIP:
25568 case OPC_WRDSP:
25569 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
25570 break;
25571 default: /* Invalid */
25572 MIPS_INVAL("MASK EXTR.W");
9c708c7f 25573 generate_exception_end(ctx, EXCP_RI);
099e5b4d
LA
25574 break;
25575 }
25576 break;
099e5b4d 25577#if defined(TARGET_MIPS64)
c2e19f3c
AM
25578 case OPC_DDIV_G_2E:
25579 case OPC_DDIVU_G_2E:
25580 case OPC_DMULT_G_2E:
25581 case OPC_DMULTU_G_2E:
25582 case OPC_DMOD_G_2E:
25583 case OPC_DMODU_G_2E:
fac5a073
LA
25584 check_insn(ctx, INSN_LOONGSON2E);
25585 gen_loongson_integer(ctx, op1, rd, rs, rt);
099e5b4d 25586 break;
099e5b4d
LA
25587 case OPC_ABSQ_S_QH_DSP:
25588 op2 = MASK_ABSQ_S_QH(ctx->opcode);
25589 switch (op2) {
25590 case OPC_PRECEQ_L_PWL:
25591 case OPC_PRECEQ_L_PWR:
25592 case OPC_PRECEQ_PW_QHL:
25593 case OPC_PRECEQ_PW_QHR:
25594 case OPC_PRECEQ_PW_QHLA:
25595 case OPC_PRECEQ_PW_QHRA:
25596 case OPC_PRECEQU_QH_OBL:
25597 case OPC_PRECEQU_QH_OBR:
25598 case OPC_PRECEQU_QH_OBLA:
25599 case OPC_PRECEQU_QH_OBRA:
25600 case OPC_PRECEU_QH_OBL:
25601 case OPC_PRECEU_QH_OBR:
25602 case OPC_PRECEU_QH_OBLA:
25603 case OPC_PRECEU_QH_OBRA:
25604 case OPC_ABSQ_S_OB:
25605 case OPC_ABSQ_S_PW:
25606 case OPC_ABSQ_S_QH:
25607 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
25608 break;
25609 case OPC_REPL_OB:
25610 case OPC_REPL_PW:
25611 case OPC_REPL_QH:
25612 case OPC_REPLV_OB:
25613 case OPC_REPLV_PW:
25614 case OPC_REPLV_QH:
25615 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
25616 break;
25617 default: /* Invalid */
25618 MIPS_INVAL("MASK ABSQ_S.QH");
9c708c7f 25619 generate_exception_end(ctx, EXCP_RI);
099e5b4d
LA
25620 break;
25621 }
25622 break;
25623 case OPC_ADDU_OB_DSP:
25624 op2 = MASK_ADDU_OB(ctx->opcode);
25625 switch (op2) {
25626 case OPC_RADDU_L_OB:
25627 case OPC_SUBQ_PW:
25628 case OPC_SUBQ_S_PW:
25629 case OPC_SUBQ_QH:
25630 case OPC_SUBQ_S_QH:
25631 case OPC_SUBU_OB:
25632 case OPC_SUBU_S_OB:
25633 case OPC_SUBU_QH:
25634 case OPC_SUBU_S_QH:
25635 case OPC_SUBUH_OB:
25636 case OPC_SUBUH_R_OB:
25637 case OPC_ADDQ_PW:
25638 case OPC_ADDQ_S_PW:
25639 case OPC_ADDQ_QH:
25640 case OPC_ADDQ_S_QH:
25641 case OPC_ADDU_OB:
25642 case OPC_ADDU_S_OB:
25643 case OPC_ADDU_QH:
25644 case OPC_ADDU_S_QH:
25645 case OPC_ADDUH_OB:
25646 case OPC_ADDUH_R_OB:
25647 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
a22260ae 25648 break;
099e5b4d
LA
25649 case OPC_MULEQ_S_PW_QHL:
25650 case OPC_MULEQ_S_PW_QHR:
25651 case OPC_MULEU_S_QH_OBL:
25652 case OPC_MULEU_S_QH_OBR:
25653 case OPC_MULQ_RS_QH:
25654 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
1cb6686c 25655 break;
099e5b4d
LA
25656 default: /* Invalid */
25657 MIPS_INVAL("MASK ADDU.OB");
9c708c7f 25658 generate_exception_end(ctx, EXCP_RI);
26690560 25659 break;
099e5b4d
LA
25660 }
25661 break;
25662 case OPC_CMPU_EQ_OB_DSP:
25663 op2 = MASK_CMPU_EQ_OB(ctx->opcode);
25664 switch (op2) {
25665 case OPC_PRECR_SRA_QH_PW:
25666 case OPC_PRECR_SRA_R_QH_PW:
25667 /* Return value is rt. */
25668 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
b53371ed 25669 break;
099e5b4d
LA
25670 case OPC_PRECR_OB_QH:
25671 case OPC_PRECRQ_OB_QH:
25672 case OPC_PRECRQ_PW_L:
25673 case OPC_PRECRQ_QH_PW:
25674 case OPC_PRECRQ_RS_QH_PW:
25675 case OPC_PRECRQU_S_OB_QH:
25676 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
4368b29a 25677 break;
099e5b4d
LA
25678 case OPC_CMPU_EQ_OB:
25679 case OPC_CMPU_LT_OB:
25680 case OPC_CMPU_LE_OB:
25681 case OPC_CMP_EQ_QH:
25682 case OPC_CMP_LT_QH:
25683 case OPC_CMP_LE_QH:
25684 case OPC_CMP_EQ_PW:
25685 case OPC_CMP_LT_PW:
25686 case OPC_CMP_LE_PW:
25687 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
7a387fff 25688 break;
099e5b4d
LA
25689 case OPC_CMPGDU_EQ_OB:
25690 case OPC_CMPGDU_LT_OB:
25691 case OPC_CMPGDU_LE_OB:
25692 case OPC_CMPGU_EQ_OB:
25693 case OPC_CMPGU_LT_OB:
25694 case OPC_CMPGU_LE_OB:
25695 case OPC_PACKRL_PW:
25696 case OPC_PICK_OB:
25697 case OPC_PICK_PW:
25698 case OPC_PICK_QH:
25699 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
c6d6dd7c 25700 break;
099e5b4d
LA
25701 default: /* Invalid */
25702 MIPS_INVAL("MASK CMPU_EQ.OB");
9c708c7f 25703 generate_exception_end(ctx, EXCP_RI);
161f85e6 25704 break;
099e5b4d
LA
25705 }
25706 break;
25707 case OPC_DAPPEND_DSP:
25708 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
25709 break;
25710 case OPC_DEXTR_W_DSP:
25711 op2 = MASK_DEXTR_W(ctx->opcode);
25712 switch (op2) {
25713 case OPC_DEXTP:
25714 case OPC_DEXTPDP:
25715 case OPC_DEXTPDPV:
25716 case OPC_DEXTPV:
25717 case OPC_DEXTR_L:
25718 case OPC_DEXTR_R_L:
25719 case OPC_DEXTR_RS_L:
25720 case OPC_DEXTR_W:
25721 case OPC_DEXTR_R_W:
25722 case OPC_DEXTR_RS_W:
25723 case OPC_DEXTR_S_H:
25724 case OPC_DEXTRV_L:
25725 case OPC_DEXTRV_R_L:
25726 case OPC_DEXTRV_RS_L:
25727 case OPC_DEXTRV_S_H:
25728 case OPC_DEXTRV_W:
25729 case OPC_DEXTRV_R_W:
25730 case OPC_DEXTRV_RS_W:
25731 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
461c08df 25732 break;
099e5b4d
LA
25733 case OPC_DMTHLIP:
25734 case OPC_DSHILO:
25735 case OPC_DSHILOV:
25736 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
461c08df 25737 break;
099e5b4d
LA
25738 default: /* Invalid */
25739 MIPS_INVAL("MASK EXTR.W");
9c708c7f 25740 generate_exception_end(ctx, EXCP_RI);
461c08df 25741 break;
099e5b4d
LA
25742 }
25743 break;
25744 case OPC_DPAQ_W_QH_DSP:
25745 op2 = MASK_DPAQ_W_QH(ctx->opcode);
25746 switch (op2) {
25747 case OPC_DPAU_H_OBL:
25748 case OPC_DPAU_H_OBR:
25749 case OPC_DPSU_H_OBL:
25750 case OPC_DPSU_H_OBR:
25751 case OPC_DPA_W_QH:
25752 case OPC_DPAQ_S_W_QH:
25753 case OPC_DPS_W_QH:
25754 case OPC_DPSQ_S_W_QH:
25755 case OPC_MULSAQ_S_W_QH:
25756 case OPC_DPAQ_SA_L_PW:
25757 case OPC_DPSQ_SA_L_PW:
25758 case OPC_MULSAQ_S_L_PW:
25759 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
25760 break;
25761 case OPC_MAQ_S_W_QHLL:
25762 case OPC_MAQ_S_W_QHLR:
25763 case OPC_MAQ_S_W_QHRL:
25764 case OPC_MAQ_S_W_QHRR:
25765 case OPC_MAQ_SA_W_QHLL:
25766 case OPC_MAQ_SA_W_QHLR:
25767 case OPC_MAQ_SA_W_QHRL:
25768 case OPC_MAQ_SA_W_QHRR:
25769 case OPC_MAQ_S_L_PWL:
25770 case OPC_MAQ_S_L_PWR:
25771 case OPC_DMADD:
25772 case OPC_DMADDU:
25773 case OPC_DMSUB:
25774 case OPC_DMSUBU:
25775 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
26690560 25776 break;
099e5b4d
LA
25777 default: /* Invalid */
25778 MIPS_INVAL("MASK DPAQ.W.QH");
9c708c7f 25779 generate_exception_end(ctx, EXCP_RI);
b53371ed 25780 break;
099e5b4d
LA
25781 }
25782 break;
25783 case OPC_DINSV_DSP:
25784 op2 = MASK_INSV(ctx->opcode);
25785 switch (op2) {
25786 case OPC_DINSV:
25787 {
25788 TCGv t0, t1;
25789
25790 if (rt == 0) {
a22260ae
JL
25791 break;
25792 }
099e5b4d 25793 check_dsp(ctx);
1cb6686c 25794
099e5b4d
LA
25795 t0 = tcg_temp_new();
25796 t1 = tcg_temp_new();
1cb6686c 25797
099e5b4d
LA
25798 gen_load_gpr(t0, rt);
25799 gen_load_gpr(t1, rs);
1cb6686c 25800
099e5b4d 25801 gen_helper_dinsv(cpu_gpr[rt], cpu_env, t1, t0);
62eb3b9a 25802
099e5b4d
LA
25803 tcg_temp_free(t0);
25804 tcg_temp_free(t1);
77c5fa8b 25805 break;
099e5b4d 25806 }
7a387fff 25807 default: /* Invalid */
099e5b4d 25808 MIPS_INVAL("MASK DINSV");
9c708c7f 25809 generate_exception_end(ctx, EXCP_RI);
7a387fff
TS
25810 break;
25811 }
25812 break;
099e5b4d
LA
25813 case OPC_SHLL_OB_DSP:
25814 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
25815 break;
25816#endif
fac5a073
LA
25817 default: /* Invalid */
25818 MIPS_INVAL("special3_legacy");
9c708c7f 25819 generate_exception_end(ctx, EXCP_RI);
fac5a073
LA
25820 break;
25821 }
25822}
25823
88eafe0b
FN
25824static void decode_tx79_mmi0(CPUMIPSState *env, DisasContext *ctx)
25825{
25826 uint32_t opc = MASK_TX79_MMI0(ctx->opcode);
25827
25828 switch (opc) {
25829 case TX79_MMI0_PADDW: /* TODO: TX79_MMI0_PADDW */
25830 case TX79_MMI0_PSUBW: /* TODO: TX79_MMI0_PSUBW */
25831 case TX79_MMI0_PCGTW: /* TODO: TX79_MMI0_PCGTW */
25832 case TX79_MMI0_PMAXW: /* TODO: TX79_MMI0_PMAXW */
25833 case TX79_MMI0_PADDH: /* TODO: TX79_MMI0_PADDH */
25834 case TX79_MMI0_PSUBH: /* TODO: TX79_MMI0_PSUBH */
25835 case TX79_MMI0_PCGTH: /* TODO: TX79_MMI0_PCGTH */
25836 case TX79_MMI0_PMAXH: /* TODO: TX79_MMI0_PMAXH */
25837 case TX79_MMI0_PADDB: /* TODO: TX79_MMI0_PADDB */
25838 case TX79_MMI0_PSUBB: /* TODO: TX79_MMI0_PSUBB */
25839 case TX79_MMI0_PCGTB: /* TODO: TX79_MMI0_PCGTB */
25840 case TX79_MMI0_PADDSW: /* TODO: TX79_MMI0_PADDSW */
25841 case TX79_MMI0_PSUBSW: /* TODO: TX79_MMI0_PSUBSW */
25842 case TX79_MMI0_PEXTLW: /* TODO: TX79_MMI0_PEXTLW */
25843 case TX79_MMI0_PPACW: /* TODO: TX79_MMI0_PPACW */
25844 case TX79_MMI0_PADDSH: /* TODO: TX79_MMI0_PADDSH */
25845 case TX79_MMI0_PSUBSH: /* TODO: TX79_MMI0_PSUBSH */
25846 case TX79_MMI0_PEXTLH: /* TODO: TX79_MMI0_PEXTLH */
25847 case TX79_MMI0_PPACH: /* TODO: TX79_MMI0_PPACH */
25848 case TX79_MMI0_PADDSB: /* TODO: TX79_MMI0_PADDSB */
25849 case TX79_MMI0_PSUBSB: /* TODO: TX79_MMI0_PSUBSB */
25850 case TX79_MMI0_PEXTLB: /* TODO: TX79_MMI0_PEXTLB */
25851 case TX79_MMI0_PPACB: /* TODO: TX79_MMI0_PPACB */
25852 case TX79_MMI0_PEXT5: /* TODO: TX79_MMI0_PEXT5 */
25853 case TX79_MMI0_PPAC5: /* TODO: TX79_MMI0_PPAC5 */
25854 generate_exception_end(ctx, EXCP_RI); /* TODO: TX79_MMI_CLASS_MMI0 */
25855 break;
25856 default:
25857 MIPS_INVAL("TX79 MMI class MMI0");
25858 generate_exception_end(ctx, EXCP_RI);
25859 break;
25860 }
25861}
25862
7a803ca2
FN
25863static void decode_tx79_mmi1(CPUMIPSState *env, DisasContext *ctx)
25864{
25865 uint32_t opc = MASK_TX79_MMI1(ctx->opcode);
25866
25867 switch (opc) {
25868 case TX79_MMI1_PABSW: /* TODO: TX79_MMI1_PABSW */
25869 case TX79_MMI1_PCEQW: /* TODO: TX79_MMI1_PCEQW */
25870 case TX79_MMI1_PMINW: /* TODO: TX79_MMI1_PMINW */
25871 case TX79_MMI1_PADSBH: /* TODO: TX79_MMI1_PADSBH */
25872 case TX79_MMI1_PABSH: /* TODO: TX79_MMI1_PABSH */
25873 case TX79_MMI1_PCEQH: /* TODO: TX79_MMI1_PCEQH */
25874 case TX79_MMI1_PMINH: /* TODO: TX79_MMI1_PMINH */
25875 case TX79_MMI1_PCEQB: /* TODO: TX79_MMI1_PCEQB */
25876 case TX79_MMI1_PADDUW: /* TODO: TX79_MMI1_PADDUW */
25877 case TX79_MMI1_PSUBUW: /* TODO: TX79_MMI1_PSUBUW */
25878 case TX79_MMI1_PEXTUW: /* TODO: TX79_MMI1_PEXTUW */
25879 case TX79_MMI1_PADDUH: /* TODO: TX79_MMI1_PADDUH */
25880 case TX79_MMI1_PSUBUH: /* TODO: TX79_MMI1_PSUBUH */
25881 case TX79_MMI1_PEXTUH: /* TODO: TX79_MMI1_PEXTUH */
25882 case TX79_MMI1_PADDUB: /* TODO: TX79_MMI1_PADDUB */
25883 case TX79_MMI1_PSUBUB: /* TODO: TX79_MMI1_PSUBUB */
25884 case TX79_MMI1_PEXTUB: /* TODO: TX79_MMI1_PEXTUB */
25885 case TX79_MMI1_QFSRV: /* TODO: TX79_MMI1_QFSRV */
25886 generate_exception_end(ctx, EXCP_RI); /* TODO: TX79_MMI_CLASS_MMI1 */
25887 break;
25888 default:
25889 MIPS_INVAL("TX79 MMI class MMI1");
25890 generate_exception_end(ctx, EXCP_RI);
25891 break;
25892 }
25893}
25894
6c1e48d3
FN
25895static void decode_tx79_mmi2(CPUMIPSState *env, DisasContext *ctx)
25896{
25897 uint32_t opc = MASK_TX79_MMI2(ctx->opcode);
25898
25899 switch (opc) {
25900 case TX79_MMI2_PMADDW: /* TODO: TX79_MMI2_PMADDW */
25901 case TX79_MMI2_PSLLVW: /* TODO: TX79_MMI2_PSLLVW */
25902 case TX79_MMI2_PSRLVW: /* TODO: TX79_MMI2_PSRLVW */
25903 case TX79_MMI2_PMSUBW: /* TODO: TX79_MMI2_PMSUBW */
25904 case TX79_MMI2_PMFHI: /* TODO: TX79_MMI2_PMFHI */
25905 case TX79_MMI2_PMFLO: /* TODO: TX79_MMI2_PMFLO */
25906 case TX79_MMI2_PINTH: /* TODO: TX79_MMI2_PINTH */
25907 case TX79_MMI2_PMULTW: /* TODO: TX79_MMI2_PMULTW */
25908 case TX79_MMI2_PDIVW: /* TODO: TX79_MMI2_PDIVW */
25909 case TX79_MMI2_PCPYLD: /* TODO: TX79_MMI2_PCPYLD */
25910 case TX79_MMI2_PMADDH: /* TODO: TX79_MMI2_PMADDH */
25911 case TX79_MMI2_PHMADH: /* TODO: TX79_MMI2_PHMADH */
25912 case TX79_MMI2_PAND: /* TODO: TX79_MMI2_PAND */
25913 case TX79_MMI2_PXOR: /* TODO: TX79_MMI2_PXOR */
25914 case TX79_MMI2_PMSUBH: /* TODO: TX79_MMI2_PMSUBH */
25915 case TX79_MMI2_PHMSBH: /* TODO: TX79_MMI2_PHMSBH */
25916 case TX79_MMI2_PEXEH: /* TODO: TX79_MMI2_PEXEH */
25917 case TX79_MMI2_PREVH: /* TODO: TX79_MMI2_PREVH */
25918 case TX79_MMI2_PMULTH: /* TODO: TX79_MMI2_PMULTH */
25919 case TX79_MMI2_PDIVBW: /* TODO: TX79_MMI2_PDIVBW */
25920 case TX79_MMI2_PEXEW: /* TODO: TX79_MMI2_PEXEW */
25921 case TX79_MMI2_PROT3W: /* TODO: TX79_MMI2_PROT3W */
25922 generate_exception_end(ctx, EXCP_RI); /* TODO: TX79_MMI_CLASS_MMI2 */
25923 break;
25924 default:
25925 MIPS_INVAL("TX79 MMI class MMI2");
25926 generate_exception_end(ctx, EXCP_RI);
25927 break;
25928 }
25929}
25930
ec1944fc
FN
25931static void decode_tx79_mmi3(CPUMIPSState *env, DisasContext *ctx)
25932{
25933 uint32_t opc = MASK_TX79_MMI3(ctx->opcode);
25934
25935 switch (opc) {
25936 case TX79_MMI3_PMADDUW: /* TODO: TX79_MMI3_PMADDUW */
25937 case TX79_MMI3_PSRAVW: /* TODO: TX79_MMI3_PSRAVW */
25938 case TX79_MMI3_PMTHI: /* TODO: TX79_MMI3_PMTHI */
25939 case TX79_MMI3_PMTLO: /* TODO: TX79_MMI3_PMTLO */
25940 case TX79_MMI3_PINTEH: /* TODO: TX79_MMI3_PINTEH */
25941 case TX79_MMI3_PMULTUW: /* TODO: TX79_MMI3_PMULTUW */
25942 case TX79_MMI3_PDIVUW: /* TODO: TX79_MMI3_PDIVUW */
25943 case TX79_MMI3_PCPYUD: /* TODO: TX79_MMI3_PCPYUD */
25944 case TX79_MMI3_POR: /* TODO: TX79_MMI3_POR */
25945 case TX79_MMI3_PNOR: /* TODO: TX79_MMI3_PNOR */
25946 case TX79_MMI3_PEXCH: /* TODO: TX79_MMI3_PEXCH */
25947 case TX79_MMI3_PCPYH: /* TODO: TX79_MMI3_PCPYH */
25948 case TX79_MMI3_PEXCW: /* TODO: TX79_MMI3_PEXCW */
25949 generate_exception_end(ctx, EXCP_RI); /* TODO: TX79_MMI_CLASS_MMI3 */
25950 break;
25951 default:
25952 MIPS_INVAL("TX79 MMI class MMI3");
25953 generate_exception_end(ctx, EXCP_RI);
25954 break;
25955 }
25956}
25957
71b8a6b3
FN
25958static void decode_tx79_mmi(CPUMIPSState *env, DisasContext *ctx)
25959{
25960 uint32_t opc = MASK_TX79_MMI(ctx->opcode);
06de726b
FN
25961 int rs = extract32(ctx->opcode, 21, 5);
25962 int rt = extract32(ctx->opcode, 16, 5);
25963 int rd = extract32(ctx->opcode, 11, 5);
71b8a6b3
FN
25964
25965 switch (opc) {
88eafe0b
FN
25966 case TX79_MMI_CLASS_MMI0:
25967 decode_tx79_mmi0(env, ctx);
25968 break;
7a803ca2
FN
25969 case TX79_MMI_CLASS_MMI1:
25970 decode_tx79_mmi1(env, ctx);
25971 break;
6c1e48d3
FN
25972 case TX79_MMI_CLASS_MMI2:
25973 decode_tx79_mmi2(env, ctx);
25974 break;
ec1944fc
FN
25975 case TX79_MMI_CLASS_MMI3:
25976 decode_tx79_mmi3(env, ctx);
25977 break;
06de726b
FN
25978 case TX79_MMI_MULT1:
25979 case TX79_MMI_MULTU1:
25980 gen_mul_txx9(ctx, opc, rd, rs, rt);
25981 break;
be9c42c9
FN
25982 case TX79_MMI_DIV1:
25983 case TX79_MMI_DIVU1:
25984 gen_muldiv(ctx, opc, 1, rs, rt);
25985 break;
8d927f7c
FN
25986 case TX79_MMI_MTLO1:
25987 case TX79_MMI_MTHI1:
25988 gen_HILO(ctx, opc, 1, rs);
25989 break;
25990 case TX79_MMI_MFLO1:
25991 case TX79_MMI_MFHI1:
25992 gen_HILO(ctx, opc, 1, rd);
25993 break;
71b8a6b3
FN
25994 case TX79_MMI_MADD: /* TODO: TX79_MMI_MADD */
25995 case TX79_MMI_MADDU: /* TODO: TX79_MMI_MADDU */
25996 case TX79_MMI_PLZCW: /* TODO: TX79_MMI_PLZCW */
71b8a6b3
FN
25997 case TX79_MMI_MADD1: /* TODO: TX79_MMI_MADD1 */
25998 case TX79_MMI_MADDU1: /* TODO: TX79_MMI_MADDU1 */
71b8a6b3
FN
25999 case TX79_MMI_PMFHL: /* TODO: TX79_MMI_PMFHL */
26000 case TX79_MMI_PMTHL: /* TODO: TX79_MMI_PMTHL */
26001 case TX79_MMI_PSLLH: /* TODO: TX79_MMI_PSLLH */
26002 case TX79_MMI_PSRLH: /* TODO: TX79_MMI_PSRLH */
26003 case TX79_MMI_PSRAH: /* TODO: TX79_MMI_PSRAH */
26004 case TX79_MMI_PSLLW: /* TODO: TX79_MMI_PSLLW */
26005 case TX79_MMI_PSRLW: /* TODO: TX79_MMI_PSRLW */
26006 case TX79_MMI_PSRAW: /* TODO: TX79_MMI_PSRAW */
26007 generate_exception_end(ctx, EXCP_RI); /* TODO: TX79_CLASS_MMI */
26008 break;
26009 default:
26010 MIPS_INVAL("TX79 MMI class");
26011 generate_exception_end(ctx, EXCP_RI);
26012 break;
26013 }
26014}
26015
f08099ad
FN
26016static void decode_tx79_lq(CPUMIPSState *env, DisasContext *ctx)
26017{
26018 generate_exception_end(ctx, EXCP_RI); /* TODO: TX79_LQ */
26019}
26020
bb41e74b
FN
26021static void gen_tx79_sq(DisasContext *ctx, int base, int rt, int offset)
26022{
26023 generate_exception_end(ctx, EXCP_RI); /* TODO: TX79_SQ */
26024}
26025
26026/*
26027 * The TX79-specific instruction Store Quadword
26028 *
26029 * +--------+-------+-------+------------------------+
26030 * | 011111 | base | rt | offset | SQ
26031 * +--------+-------+-------+------------------------+
26032 * 6 5 5 16
26033 *
26034 * has the same opcode as the Read Hardware Register instruction
26035 *
26036 * +--------+-------+-------+-------+-------+--------+
26037 * | 011111 | 00000 | rt | rd | 00000 | 111011 | RDHWR
26038 * +--------+-------+-------+-------+-------+--------+
26039 * 6 5 5 5 5 6
26040 *
26041 * that is required, trapped and emulated by the Linux kernel. However, all
26042 * RDHWR encodings yield address error exceptions on the TX79 since the SQ
26043 * offset is odd. Therefore all valid SQ instructions can execute normally.
26044 * In user mode, QEMU must verify the upper and lower 11 bits to distinguish
26045 * between SQ and RDHWR, as the Linux kernel does.
26046 */
26047static void decode_tx79_sq(CPUMIPSState *env, DisasContext *ctx)
26048{
26049 int base = extract32(ctx->opcode, 21, 5);
26050 int rt = extract32(ctx->opcode, 16, 5);
26051 int offset = extract32(ctx->opcode, 0, 16);
26052
26053#ifdef CONFIG_USER_ONLY
26054 uint32_t op1 = MASK_SPECIAL3(ctx->opcode);
26055 uint32_t op2 = extract32(ctx->opcode, 6, 5);
26056
26057 if (base == 0 && op2 == 0 && op1 == OPC_RDHWR) {
26058 int rd = extract32(ctx->opcode, 11, 5);
26059
26060 gen_rdhwr(ctx, rt, rd, 0);
26061 return;
26062 }
26063#endif
26064
26065 gen_tx79_sq(ctx, base, rt, offset);
26066}
26067
fac5a073
LA
26068static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx)
26069{
26070 int rs, rt, rd, sa;
26071 uint32_t op1, op2;
76964147 26072 int16_t imm;
fac5a073
LA
26073
26074 rs = (ctx->opcode >> 21) & 0x1f;
26075 rt = (ctx->opcode >> 16) & 0x1f;
26076 rd = (ctx->opcode >> 11) & 0x1f;
26077 sa = (ctx->opcode >> 6) & 0x1f;
76964147 26078 imm = sextract32(ctx->opcode, 7, 9);
fac5a073
LA
26079
26080 op1 = MASK_SPECIAL3(ctx->opcode);
76964147
JH
26081
26082 /*
26083 * EVA loads and stores overlap Loongson 2E instructions decoded by
26084 * decode_opc_special3_legacy(), so be careful to allow their decoding when
26085 * EVA is absent.
26086 */
26087 if (ctx->eva) {
26088 switch (op1) {
c2e19f3c
AM
26089 case OPC_LWLE:
26090 case OPC_LWRE:
76964147
JH
26091 check_insn_opc_removed(ctx, ISA_MIPS32R6);
26092 /* fall through */
c2e19f3c
AM
26093 case OPC_LBUE:
26094 case OPC_LHUE:
26095 case OPC_LBE:
26096 case OPC_LHE:
26097 case OPC_LLE:
26098 case OPC_LWE:
76964147
JH
26099 check_cp0_enabled(ctx);
26100 gen_ld(ctx, op1, rt, rs, imm);
26101 return;
c2e19f3c
AM
26102 case OPC_SWLE:
26103 case OPC_SWRE:
76964147
JH
26104 check_insn_opc_removed(ctx, ISA_MIPS32R6);
26105 /* fall through */
c2e19f3c
AM
26106 case OPC_SBE:
26107 case OPC_SHE:
76964147
JH
26108 case OPC_SWE:
26109 check_cp0_enabled(ctx);
26110 gen_st(ctx, op1, rt, rs, imm);
26111 return;
26112 case OPC_SCE:
26113 check_cp0_enabled(ctx);
26114 gen_st_cond(ctx, op1, rt, rs, imm);
26115 return;
26116 case OPC_CACHEE:
26117 check_cp0_enabled(ctx);
26118 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
26119 gen_cache_operation(ctx, rt, rs, imm);
26120 }
26121 /* Treat as NOP. */
26122 return;
26123 case OPC_PREFE:
26124 check_cp0_enabled(ctx);
26125 /* Treat as NOP. */
26126 return;
26127 }
26128 }
26129
fac5a073
LA
26130 switch (op1) {
26131 case OPC_EXT:
26132 case OPC_INS:
26133 check_insn(ctx, ISA_MIPS32R2);
26134 gen_bitops(ctx, op1, rt, rs, sa, rd);
26135 break;
26136 case OPC_BSHFL:
fac5a073 26137 op2 = MASK_BSHFL(ctx->opcode);
15eacb9b 26138 switch (op2) {
c2e19f3c 26139 case OPC_ALIGN:
373ecd38
AM
26140 case OPC_ALIGN_1:
26141 case OPC_ALIGN_2:
26142 case OPC_ALIGN_3:
15eacb9b
YK
26143 case OPC_BITSWAP:
26144 check_insn(ctx, ISA_MIPS32R6);
26145 decode_opc_special3_r6(env, ctx);
26146 break;
26147 default:
26148 check_insn(ctx, ISA_MIPS32R2);
26149 gen_bshfl(ctx, op2, rt, rd);
26150 break;
26151 }
fac5a073
LA
26152 break;
26153#if defined(TARGET_MIPS64)
c2e19f3c
AM
26154 case OPC_DEXTM:
26155 case OPC_DEXTU:
26156 case OPC_DEXT:
26157 case OPC_DINSM:
26158 case OPC_DINSU:
26159 case OPC_DINS:
fac5a073
LA
26160 check_insn(ctx, ISA_MIPS64R2);
26161 check_mips_64(ctx);
26162 gen_bitops(ctx, op1, rt, rs, sa, rd);
26163 break;
26164 case OPC_DBSHFL:
fac5a073 26165 op2 = MASK_DBSHFL(ctx->opcode);
15eacb9b 26166 switch (op2) {
c2e19f3c 26167 case OPC_DALIGN:
373ecd38
AM
26168 case OPC_DALIGN_1:
26169 case OPC_DALIGN_2:
26170 case OPC_DALIGN_3:
26171 case OPC_DALIGN_4:
26172 case OPC_DALIGN_5:
26173 case OPC_DALIGN_6:
26174 case OPC_DALIGN_7:
15eacb9b
YK
26175 case OPC_DBITSWAP:
26176 check_insn(ctx, ISA_MIPS32R6);
26177 decode_opc_special3_r6(env, ctx);
26178 break;
26179 default:
26180 check_insn(ctx, ISA_MIPS64R2);
26181 check_mips_64(ctx);
26182 op2 = MASK_DBSHFL(ctx->opcode);
26183 gen_bshfl(ctx, op2, rt, rd);
26184 break;
26185 }
fac5a073
LA
26186 break;
26187#endif
26188 case OPC_RDHWR:
b00c7218 26189 gen_rdhwr(ctx, rt, rd, extract32(ctx->opcode, 6, 3));
fac5a073
LA
26190 break;
26191 case OPC_FORK:
9affc1c5 26192 check_mt(ctx);
fac5a073
LA
26193 {
26194 TCGv t0 = tcg_temp_new();
26195 TCGv t1 = tcg_temp_new();
26196
26197 gen_load_gpr(t0, rt);
26198 gen_load_gpr(t1, rs);
26199 gen_helper_fork(t0, t1);
26200 tcg_temp_free(t0);
26201 tcg_temp_free(t1);
26202 }
26203 break;
26204 case OPC_YIELD:
9affc1c5 26205 check_mt(ctx);
fac5a073
LA
26206 {
26207 TCGv t0 = tcg_temp_new();
26208
fac5a073
LA
26209 gen_load_gpr(t0, rs);
26210 gen_helper_yield(t0, cpu_env, t0);
26211 gen_store_gpr(t0, rd);
26212 tcg_temp_free(t0);
26213 }
26214 break;
10dc65db
LA
26215 default:
26216 if (ctx->insn_flags & ISA_MIPS32R6) {
26217 decode_opc_special3_r6(env, ctx);
26218 } else {
26219 decode_opc_special3_legacy(env, ctx);
26220 }
099e5b4d
LA
26221 }
26222}
26223
863f264d
YK
26224/* MIPS SIMD Architecture (MSA) */
26225static inline int check_msa_access(DisasContext *ctx)
26226{
26227 if (unlikely((ctx->hflags & MIPS_HFLAG_FPU) &&
26228 !(ctx->hflags & MIPS_HFLAG_F64))) {
9c708c7f 26229 generate_exception_end(ctx, EXCP_RI);
863f264d
YK
26230 return 0;
26231 }
26232
26233 if (unlikely(!(ctx->hflags & MIPS_HFLAG_MSA))) {
26234 if (ctx->insn_flags & ASE_MSA) {
9c708c7f 26235 generate_exception_end(ctx, EXCP_MSADIS);
863f264d
YK
26236 return 0;
26237 } else {
9c708c7f 26238 generate_exception_end(ctx, EXCP_RI);
863f264d
YK
26239 return 0;
26240 }
26241 }
26242 return 1;
26243}
26244
5692c6e1
YK
26245static void gen_check_zero_element(TCGv tresult, uint8_t df, uint8_t wt)
26246{
26247 /* generates tcg ops to check if any element is 0 */
26248 /* Note this function only works with MSA_WRLEN = 128 */
26249 uint64_t eval_zero_or_big = 0;
26250 uint64_t eval_big = 0;
26251 TCGv_i64 t0 = tcg_temp_new_i64();
26252 TCGv_i64 t1 = tcg_temp_new_i64();
26253 switch (df) {
26254 case DF_BYTE:
26255 eval_zero_or_big = 0x0101010101010101ULL;
26256 eval_big = 0x8080808080808080ULL;
26257 break;
26258 case DF_HALF:
26259 eval_zero_or_big = 0x0001000100010001ULL;
26260 eval_big = 0x8000800080008000ULL;
26261 break;
26262 case DF_WORD:
26263 eval_zero_or_big = 0x0000000100000001ULL;
26264 eval_big = 0x8000000080000000ULL;
26265 break;
26266 case DF_DOUBLE:
26267 eval_zero_or_big = 0x0000000000000001ULL;
26268 eval_big = 0x8000000000000000ULL;
26269 break;
26270 }
26271 tcg_gen_subi_i64(t0, msa_wr_d[wt<<1], eval_zero_or_big);
26272 tcg_gen_andc_i64(t0, t0, msa_wr_d[wt<<1]);
26273 tcg_gen_andi_i64(t0, t0, eval_big);
26274 tcg_gen_subi_i64(t1, msa_wr_d[(wt<<1)+1], eval_zero_or_big);
26275 tcg_gen_andc_i64(t1, t1, msa_wr_d[(wt<<1)+1]);
26276 tcg_gen_andi_i64(t1, t1, eval_big);
26277 tcg_gen_or_i64(t0, t0, t1);
26278 /* if all bits are zero then all elements are not zero */
26279 /* if some bit is non-zero then some element is zero */
26280 tcg_gen_setcondi_i64(TCG_COND_NE, t0, t0, 0);
26281 tcg_gen_trunc_i64_tl(tresult, t0);
26282 tcg_temp_free_i64(t0);
26283 tcg_temp_free_i64(t1);
26284}
26285
26286static void gen_msa_branch(CPUMIPSState *env, DisasContext *ctx, uint32_t op1)
26287{
26288 uint8_t df = (ctx->opcode >> 21) & 0x3;
26289 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
26290 int64_t s16 = (int16_t)ctx->opcode;
26291
26292 check_msa_access(ctx);
26293
075a1fe7 26294 if (ctx->hflags & MIPS_HFLAG_BMASK) {
9c708c7f 26295 generate_exception_end(ctx, EXCP_RI);
5692c6e1
YK
26296 return;
26297 }
26298 switch (op1) {
26299 case OPC_BZ_V:
26300 case OPC_BNZ_V:
26301 {
26302 TCGv_i64 t0 = tcg_temp_new_i64();
26303 tcg_gen_or_i64(t0, msa_wr_d[wt<<1], msa_wr_d[(wt<<1)+1]);
26304 tcg_gen_setcondi_i64((op1 == OPC_BZ_V) ?
26305 TCG_COND_EQ : TCG_COND_NE, t0, t0, 0);
26306 tcg_gen_trunc_i64_tl(bcond, t0);
26307 tcg_temp_free_i64(t0);
26308 }
26309 break;
26310 case OPC_BZ_B:
26311 case OPC_BZ_H:
26312 case OPC_BZ_W:
26313 case OPC_BZ_D:
26314 gen_check_zero_element(bcond, df, wt);
26315 break;
26316 case OPC_BNZ_B:
26317 case OPC_BNZ_H:
26318 case OPC_BNZ_W:
26319 case OPC_BNZ_D:
26320 gen_check_zero_element(bcond, df, wt);
26321 tcg_gen_setcondi_tl(TCG_COND_EQ, bcond, bcond, 0);
26322 break;
26323 }
26324
eeb3bba8 26325 ctx->btarget = ctx->base.pc_next + (s16 << 2) + 4;
5692c6e1
YK
26326
26327 ctx->hflags |= MIPS_HFLAG_BC;
26328 ctx->hflags |= MIPS_HFLAG_BDS32;
26329}
26330
4c789546
YK
26331static void gen_msa_i8(CPUMIPSState *env, DisasContext *ctx)
26332{
26333#define MASK_MSA_I8(op) (MASK_MSA_MINOR(op) | (op & (0x03 << 24)))
26334 uint8_t i8 = (ctx->opcode >> 16) & 0xff;
26335 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
26336 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
26337
26338 TCGv_i32 twd = tcg_const_i32(wd);
26339 TCGv_i32 tws = tcg_const_i32(ws);
26340 TCGv_i32 ti8 = tcg_const_i32(i8);
26341
26342 switch (MASK_MSA_I8(ctx->opcode)) {
26343 case OPC_ANDI_B:
26344 gen_helper_msa_andi_b(cpu_env, twd, tws, ti8);
26345 break;
26346 case OPC_ORI_B:
26347 gen_helper_msa_ori_b(cpu_env, twd, tws, ti8);
26348 break;
26349 case OPC_NORI_B:
26350 gen_helper_msa_nori_b(cpu_env, twd, tws, ti8);
26351 break;
26352 case OPC_XORI_B:
26353 gen_helper_msa_xori_b(cpu_env, twd, tws, ti8);
26354 break;
26355 case OPC_BMNZI_B:
26356 gen_helper_msa_bmnzi_b(cpu_env, twd, tws, ti8);
26357 break;
26358 case OPC_BMZI_B:
26359 gen_helper_msa_bmzi_b(cpu_env, twd, tws, ti8);
26360 break;
26361 case OPC_BSELI_B:
26362 gen_helper_msa_bseli_b(cpu_env, twd, tws, ti8);
26363 break;
26364 case OPC_SHF_B:
26365 case OPC_SHF_H:
26366 case OPC_SHF_W:
26367 {
26368 uint8_t df = (ctx->opcode >> 24) & 0x3;
26369 if (df == DF_DOUBLE) {
9c708c7f 26370 generate_exception_end(ctx, EXCP_RI);
4c789546
YK
26371 } else {
26372 TCGv_i32 tdf = tcg_const_i32(df);
26373 gen_helper_msa_shf_df(cpu_env, tdf, twd, tws, ti8);
26374 tcg_temp_free_i32(tdf);
26375 }
26376 }
26377 break;
26378 default:
26379 MIPS_INVAL("MSA instruction");
9c708c7f 26380 generate_exception_end(ctx, EXCP_RI);
4c789546
YK
26381 break;
26382 }
26383
26384 tcg_temp_free_i32(twd);
26385 tcg_temp_free_i32(tws);
26386 tcg_temp_free_i32(ti8);
26387}
26388
80e71591
YK
26389static void gen_msa_i5(CPUMIPSState *env, DisasContext *ctx)
26390{
26391#define MASK_MSA_I5(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
26392 uint8_t df = (ctx->opcode >> 21) & 0x3;
26393 int8_t s5 = (int8_t) sextract32(ctx->opcode, 16, 5);
26394 uint8_t u5 = (ctx->opcode >> 16) & 0x1f;
26395 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
26396 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
26397
26398 TCGv_i32 tdf = tcg_const_i32(df);
26399 TCGv_i32 twd = tcg_const_i32(wd);
26400 TCGv_i32 tws = tcg_const_i32(ws);
26401 TCGv_i32 timm = tcg_temp_new_i32();
26402 tcg_gen_movi_i32(timm, u5);
26403
26404 switch (MASK_MSA_I5(ctx->opcode)) {
26405 case OPC_ADDVI_df:
26406 gen_helper_msa_addvi_df(cpu_env, tdf, twd, tws, timm);
26407 break;
26408 case OPC_SUBVI_df:
26409 gen_helper_msa_subvi_df(cpu_env, tdf, twd, tws, timm);
26410 break;
26411 case OPC_MAXI_S_df:
26412 tcg_gen_movi_i32(timm, s5);
26413 gen_helper_msa_maxi_s_df(cpu_env, tdf, twd, tws, timm);
26414 break;
26415 case OPC_MAXI_U_df:
26416 gen_helper_msa_maxi_u_df(cpu_env, tdf, twd, tws, timm);
26417 break;
26418 case OPC_MINI_S_df:
26419 tcg_gen_movi_i32(timm, s5);
26420 gen_helper_msa_mini_s_df(cpu_env, tdf, twd, tws, timm);
26421 break;
26422 case OPC_MINI_U_df:
26423 gen_helper_msa_mini_u_df(cpu_env, tdf, twd, tws, timm);
26424 break;
26425 case OPC_CEQI_df:
26426 tcg_gen_movi_i32(timm, s5);
26427 gen_helper_msa_ceqi_df(cpu_env, tdf, twd, tws, timm);
26428 break;
26429 case OPC_CLTI_S_df:
26430 tcg_gen_movi_i32(timm, s5);
26431 gen_helper_msa_clti_s_df(cpu_env, tdf, twd, tws, timm);
26432 break;
26433 case OPC_CLTI_U_df:
26434 gen_helper_msa_clti_u_df(cpu_env, tdf, twd, tws, timm);
26435 break;
26436 case OPC_CLEI_S_df:
26437 tcg_gen_movi_i32(timm, s5);
26438 gen_helper_msa_clei_s_df(cpu_env, tdf, twd, tws, timm);
26439 break;
26440 case OPC_CLEI_U_df:
26441 gen_helper_msa_clei_u_df(cpu_env, tdf, twd, tws, timm);
26442 break;
26443 case OPC_LDI_df:
26444 {
26445 int32_t s10 = sextract32(ctx->opcode, 11, 10);
26446 tcg_gen_movi_i32(timm, s10);
26447 gen_helper_msa_ldi_df(cpu_env, tdf, twd, timm);
26448 }
26449 break;
26450 default:
26451 MIPS_INVAL("MSA instruction");
9c708c7f 26452 generate_exception_end(ctx, EXCP_RI);
80e71591
YK
26453 break;
26454 }
26455
26456 tcg_temp_free_i32(tdf);
26457 tcg_temp_free_i32(twd);
26458 tcg_temp_free_i32(tws);
26459 tcg_temp_free_i32(timm);
26460}
26461
d4cf28de
YK
26462static void gen_msa_bit(CPUMIPSState *env, DisasContext *ctx)
26463{
26464#define MASK_MSA_BIT(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
26465 uint8_t dfm = (ctx->opcode >> 16) & 0x7f;
26466 uint32_t df = 0, m = 0;
26467 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
26468 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
26469
26470 TCGv_i32 tdf;
26471 TCGv_i32 tm;
26472 TCGv_i32 twd;
26473 TCGv_i32 tws;
26474
26475 if ((dfm & 0x40) == 0x00) {
26476 m = dfm & 0x3f;
26477 df = DF_DOUBLE;
26478 } else if ((dfm & 0x60) == 0x40) {
26479 m = dfm & 0x1f;
26480 df = DF_WORD;
26481 } else if ((dfm & 0x70) == 0x60) {
26482 m = dfm & 0x0f;
26483 df = DF_HALF;
26484 } else if ((dfm & 0x78) == 0x70) {
26485 m = dfm & 0x7;
26486 df = DF_BYTE;
26487 } else {
9c708c7f 26488 generate_exception_end(ctx, EXCP_RI);
d4cf28de
YK
26489 return;
26490 }
26491
26492 tdf = tcg_const_i32(df);
26493 tm = tcg_const_i32(m);
26494 twd = tcg_const_i32(wd);
26495 tws = tcg_const_i32(ws);
26496
26497 switch (MASK_MSA_BIT(ctx->opcode)) {
26498 case OPC_SLLI_df:
26499 gen_helper_msa_slli_df(cpu_env, tdf, twd, tws, tm);
26500 break;
26501 case OPC_SRAI_df:
26502 gen_helper_msa_srai_df(cpu_env, tdf, twd, tws, tm);
26503 break;
26504 case OPC_SRLI_df:
26505 gen_helper_msa_srli_df(cpu_env, tdf, twd, tws, tm);
26506 break;
26507 case OPC_BCLRI_df:
26508 gen_helper_msa_bclri_df(cpu_env, tdf, twd, tws, tm);
26509 break;
26510 case OPC_BSETI_df:
26511 gen_helper_msa_bseti_df(cpu_env, tdf, twd, tws, tm);
26512 break;
26513 case OPC_BNEGI_df:
26514 gen_helper_msa_bnegi_df(cpu_env, tdf, twd, tws, tm);
26515 break;
26516 case OPC_BINSLI_df:
26517 gen_helper_msa_binsli_df(cpu_env, tdf, twd, tws, tm);
26518 break;
26519 case OPC_BINSRI_df:
26520 gen_helper_msa_binsri_df(cpu_env, tdf, twd, tws, tm);
26521 break;
26522 case OPC_SAT_S_df:
26523 gen_helper_msa_sat_s_df(cpu_env, tdf, twd, tws, tm);
26524 break;
26525 case OPC_SAT_U_df:
26526 gen_helper_msa_sat_u_df(cpu_env, tdf, twd, tws, tm);
26527 break;
26528 case OPC_SRARI_df:
26529 gen_helper_msa_srari_df(cpu_env, tdf, twd, tws, tm);
26530 break;
26531 case OPC_SRLRI_df:
26532 gen_helper_msa_srlri_df(cpu_env, tdf, twd, tws, tm);
26533 break;
26534 default:
26535 MIPS_INVAL("MSA instruction");
9c708c7f 26536 generate_exception_end(ctx, EXCP_RI);
d4cf28de
YK
26537 break;
26538 }
26539
26540 tcg_temp_free_i32(tdf);
26541 tcg_temp_free_i32(tm);
26542 tcg_temp_free_i32(twd);
26543 tcg_temp_free_i32(tws);
26544}
26545
28f99f08
YK
26546static void gen_msa_3r(CPUMIPSState *env, DisasContext *ctx)
26547{
26548#define MASK_MSA_3R(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
26549 uint8_t df = (ctx->opcode >> 21) & 0x3;
26550 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
26551 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
26552 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
26553
26554 TCGv_i32 tdf = tcg_const_i32(df);
26555 TCGv_i32 twd = tcg_const_i32(wd);
26556 TCGv_i32 tws = tcg_const_i32(ws);
26557 TCGv_i32 twt = tcg_const_i32(wt);
26558
26559 switch (MASK_MSA_3R(ctx->opcode)) {
26560 case OPC_SLL_df:
26561 gen_helper_msa_sll_df(cpu_env, tdf, twd, tws, twt);
26562 break;
26563 case OPC_ADDV_df:
26564 gen_helper_msa_addv_df(cpu_env, tdf, twd, tws, twt);
26565 break;
26566 case OPC_CEQ_df:
26567 gen_helper_msa_ceq_df(cpu_env, tdf, twd, tws, twt);
26568 break;
26569 case OPC_ADD_A_df:
26570 gen_helper_msa_add_a_df(cpu_env, tdf, twd, tws, twt);
26571 break;
26572 case OPC_SUBS_S_df:
26573 gen_helper_msa_subs_s_df(cpu_env, tdf, twd, tws, twt);
26574 break;
26575 case OPC_MULV_df:
26576 gen_helper_msa_mulv_df(cpu_env, tdf, twd, tws, twt);
26577 break;
26578 case OPC_SLD_df:
26579 gen_helper_msa_sld_df(cpu_env, tdf, twd, tws, twt);
26580 break;
26581 case OPC_VSHF_df:
26582 gen_helper_msa_vshf_df(cpu_env, tdf, twd, tws, twt);
26583 break;
26584 case OPC_SRA_df:
26585 gen_helper_msa_sra_df(cpu_env, tdf, twd, tws, twt);
26586 break;
26587 case OPC_SUBV_df:
26588 gen_helper_msa_subv_df(cpu_env, tdf, twd, tws, twt);
26589 break;
26590 case OPC_ADDS_A_df:
26591 gen_helper_msa_adds_a_df(cpu_env, tdf, twd, tws, twt);
26592 break;
26593 case OPC_SUBS_U_df:
26594 gen_helper_msa_subs_u_df(cpu_env, tdf, twd, tws, twt);
26595 break;
26596 case OPC_MADDV_df:
26597 gen_helper_msa_maddv_df(cpu_env, tdf, twd, tws, twt);
26598 break;
26599 case OPC_SPLAT_df:
26600 gen_helper_msa_splat_df(cpu_env, tdf, twd, tws, twt);
26601 break;
26602 case OPC_SRAR_df:
26603 gen_helper_msa_srar_df(cpu_env, tdf, twd, tws, twt);
26604 break;
26605 case OPC_SRL_df:
26606 gen_helper_msa_srl_df(cpu_env, tdf, twd, tws, twt);
26607 break;
26608 case OPC_MAX_S_df:
26609 gen_helper_msa_max_s_df(cpu_env, tdf, twd, tws, twt);
26610 break;
26611 case OPC_CLT_S_df:
26612 gen_helper_msa_clt_s_df(cpu_env, tdf, twd, tws, twt);
26613 break;
26614 case OPC_ADDS_S_df:
26615 gen_helper_msa_adds_s_df(cpu_env, tdf, twd, tws, twt);
26616 break;
26617 case OPC_SUBSUS_U_df:
26618 gen_helper_msa_subsus_u_df(cpu_env, tdf, twd, tws, twt);
26619 break;
26620 case OPC_MSUBV_df:
26621 gen_helper_msa_msubv_df(cpu_env, tdf, twd, tws, twt);
26622 break;
26623 case OPC_PCKEV_df:
26624 gen_helper_msa_pckev_df(cpu_env, tdf, twd, tws, twt);
26625 break;
26626 case OPC_SRLR_df:
26627 gen_helper_msa_srlr_df(cpu_env, tdf, twd, tws, twt);
26628 break;
26629 case OPC_BCLR_df:
26630 gen_helper_msa_bclr_df(cpu_env, tdf, twd, tws, twt);
26631 break;
26632 case OPC_MAX_U_df:
26633 gen_helper_msa_max_u_df(cpu_env, tdf, twd, tws, twt);
26634 break;
26635 case OPC_CLT_U_df:
26636 gen_helper_msa_clt_u_df(cpu_env, tdf, twd, tws, twt);
26637 break;
26638 case OPC_ADDS_U_df:
26639 gen_helper_msa_adds_u_df(cpu_env, tdf, twd, tws, twt);
26640 break;
26641 case OPC_SUBSUU_S_df:
26642 gen_helper_msa_subsuu_s_df(cpu_env, tdf, twd, tws, twt);
26643 break;
26644 case OPC_PCKOD_df:
26645 gen_helper_msa_pckod_df(cpu_env, tdf, twd, tws, twt);
26646 break;
26647 case OPC_BSET_df:
26648 gen_helper_msa_bset_df(cpu_env, tdf, twd, tws, twt);
26649 break;
26650 case OPC_MIN_S_df:
26651 gen_helper_msa_min_s_df(cpu_env, tdf, twd, tws, twt);
26652 break;
26653 case OPC_CLE_S_df:
26654 gen_helper_msa_cle_s_df(cpu_env, tdf, twd, tws, twt);
26655 break;
26656 case OPC_AVE_S_df:
26657 gen_helper_msa_ave_s_df(cpu_env, tdf, twd, tws, twt);
26658 break;
26659 case OPC_ASUB_S_df:
26660 gen_helper_msa_asub_s_df(cpu_env, tdf, twd, tws, twt);
26661 break;
26662 case OPC_DIV_S_df:
26663 gen_helper_msa_div_s_df(cpu_env, tdf, twd, tws, twt);
26664 break;
26665 case OPC_ILVL_df:
26666 gen_helper_msa_ilvl_df(cpu_env, tdf, twd, tws, twt);
26667 break;
26668 case OPC_BNEG_df:
26669 gen_helper_msa_bneg_df(cpu_env, tdf, twd, tws, twt);
26670 break;
26671 case OPC_MIN_U_df:
26672 gen_helper_msa_min_u_df(cpu_env, tdf, twd, tws, twt);
26673 break;
26674 case OPC_CLE_U_df:
26675 gen_helper_msa_cle_u_df(cpu_env, tdf, twd, tws, twt);
26676 break;
26677 case OPC_AVE_U_df:
26678 gen_helper_msa_ave_u_df(cpu_env, tdf, twd, tws, twt);
26679 break;
26680 case OPC_ASUB_U_df:
26681 gen_helper_msa_asub_u_df(cpu_env, tdf, twd, tws, twt);
26682 break;
26683 case OPC_DIV_U_df:
26684 gen_helper_msa_div_u_df(cpu_env, tdf, twd, tws, twt);
26685 break;
26686 case OPC_ILVR_df:
26687 gen_helper_msa_ilvr_df(cpu_env, tdf, twd, tws, twt);
26688 break;
26689 case OPC_BINSL_df:
26690 gen_helper_msa_binsl_df(cpu_env, tdf, twd, tws, twt);
26691 break;
26692 case OPC_MAX_A_df:
26693 gen_helper_msa_max_a_df(cpu_env, tdf, twd, tws, twt);
26694 break;
26695 case OPC_AVER_S_df:
26696 gen_helper_msa_aver_s_df(cpu_env, tdf, twd, tws, twt);
26697 break;
26698 case OPC_MOD_S_df:
26699 gen_helper_msa_mod_s_df(cpu_env, tdf, twd, tws, twt);
26700 break;
26701 case OPC_ILVEV_df:
26702 gen_helper_msa_ilvev_df(cpu_env, tdf, twd, tws, twt);
26703 break;
26704 case OPC_BINSR_df:
26705 gen_helper_msa_binsr_df(cpu_env, tdf, twd, tws, twt);
26706 break;
26707 case OPC_MIN_A_df:
26708 gen_helper_msa_min_a_df(cpu_env, tdf, twd, tws, twt);
26709 break;
26710 case OPC_AVER_U_df:
26711 gen_helper_msa_aver_u_df(cpu_env, tdf, twd, tws, twt);
26712 break;
26713 case OPC_MOD_U_df:
26714 gen_helper_msa_mod_u_df(cpu_env, tdf, twd, tws, twt);
26715 break;
26716 case OPC_ILVOD_df:
26717 gen_helper_msa_ilvod_df(cpu_env, tdf, twd, tws, twt);
26718 break;
26719
26720 case OPC_DOTP_S_df:
26721 case OPC_DOTP_U_df:
26722 case OPC_DPADD_S_df:
26723 case OPC_DPADD_U_df:
26724 case OPC_DPSUB_S_df:
26725 case OPC_HADD_S_df:
26726 case OPC_DPSUB_U_df:
26727 case OPC_HADD_U_df:
26728 case OPC_HSUB_S_df:
26729 case OPC_HSUB_U_df:
26730 if (df == DF_BYTE) {
9c708c7f
PD
26731 generate_exception_end(ctx, EXCP_RI);
26732 break;
28f99f08
YK
26733 }
26734 switch (MASK_MSA_3R(ctx->opcode)) {
26735 case OPC_DOTP_S_df:
26736 gen_helper_msa_dotp_s_df(cpu_env, tdf, twd, tws, twt);
26737 break;
26738 case OPC_DOTP_U_df:
26739 gen_helper_msa_dotp_u_df(cpu_env, tdf, twd, tws, twt);
26740 break;
26741 case OPC_DPADD_S_df:
26742 gen_helper_msa_dpadd_s_df(cpu_env, tdf, twd, tws, twt);
26743 break;
26744 case OPC_DPADD_U_df:
26745 gen_helper_msa_dpadd_u_df(cpu_env, tdf, twd, tws, twt);
26746 break;
26747 case OPC_DPSUB_S_df:
26748 gen_helper_msa_dpsub_s_df(cpu_env, tdf, twd, tws, twt);
26749 break;
26750 case OPC_HADD_S_df:
26751 gen_helper_msa_hadd_s_df(cpu_env, tdf, twd, tws, twt);
26752 break;
26753 case OPC_DPSUB_U_df:
26754 gen_helper_msa_dpsub_u_df(cpu_env, tdf, twd, tws, twt);
26755 break;
26756 case OPC_HADD_U_df:
26757 gen_helper_msa_hadd_u_df(cpu_env, tdf, twd, tws, twt);
26758 break;
26759 case OPC_HSUB_S_df:
26760 gen_helper_msa_hsub_s_df(cpu_env, tdf, twd, tws, twt);
26761 break;
26762 case OPC_HSUB_U_df:
26763 gen_helper_msa_hsub_u_df(cpu_env, tdf, twd, tws, twt);
26764 break;
26765 }
26766 break;
26767 default:
26768 MIPS_INVAL("MSA instruction");
9c708c7f 26769 generate_exception_end(ctx, EXCP_RI);
28f99f08
YK
26770 break;
26771 }
26772 tcg_temp_free_i32(twd);
26773 tcg_temp_free_i32(tws);
26774 tcg_temp_free_i32(twt);
26775 tcg_temp_free_i32(tdf);
26776}
26777
1e608ec1
YK
26778static void gen_msa_elm_3e(CPUMIPSState *env, DisasContext *ctx)
26779{
26780#define MASK_MSA_ELM_DF3E(op) (MASK_MSA_MINOR(op) | (op & (0x3FF << 16)))
26781 uint8_t source = (ctx->opcode >> 11) & 0x1f;
26782 uint8_t dest = (ctx->opcode >> 6) & 0x1f;
26783 TCGv telm = tcg_temp_new();
26784 TCGv_i32 tsr = tcg_const_i32(source);
26785 TCGv_i32 tdt = tcg_const_i32(dest);
26786
26787 switch (MASK_MSA_ELM_DF3E(ctx->opcode)) {
26788 case OPC_CTCMSA:
26789 gen_load_gpr(telm, source);
26790 gen_helper_msa_ctcmsa(cpu_env, telm, tdt);
26791 break;
26792 case OPC_CFCMSA:
26793 gen_helper_msa_cfcmsa(telm, cpu_env, tsr);
26794 gen_store_gpr(telm, dest);
26795 break;
26796 case OPC_MOVE_V:
26797 gen_helper_msa_move_v(cpu_env, tdt, tsr);
26798 break;
26799 default:
26800 MIPS_INVAL("MSA instruction");
9c708c7f 26801 generate_exception_end(ctx, EXCP_RI);
1e608ec1
YK
26802 break;
26803 }
26804
26805 tcg_temp_free(telm);
26806 tcg_temp_free_i32(tdt);
26807 tcg_temp_free_i32(tsr);
26808}
26809
26810static void gen_msa_elm_df(CPUMIPSState *env, DisasContext *ctx, uint32_t df,
26811 uint32_t n)
26812{
26813#define MASK_MSA_ELM(op) (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
26814 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
26815 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
26816
26817 TCGv_i32 tws = tcg_const_i32(ws);
26818 TCGv_i32 twd = tcg_const_i32(wd);
26819 TCGv_i32 tn = tcg_const_i32(n);
26820 TCGv_i32 tdf = tcg_const_i32(df);
26821
26822 switch (MASK_MSA_ELM(ctx->opcode)) {
26823 case OPC_SLDI_df:
26824 gen_helper_msa_sldi_df(cpu_env, tdf, twd, tws, tn);
26825 break;
26826 case OPC_SPLATI_df:
26827 gen_helper_msa_splati_df(cpu_env, tdf, twd, tws, tn);
26828 break;
26829 case OPC_INSVE_df:
26830 gen_helper_msa_insve_df(cpu_env, tdf, twd, tws, tn);
26831 break;
26832 case OPC_COPY_S_df:
26833 case OPC_COPY_U_df:
26834 case OPC_INSERT_df:
26835#if !defined(TARGET_MIPS64)
26836 /* Double format valid only for MIPS64 */
26837 if (df == DF_DOUBLE) {
9c708c7f 26838 generate_exception_end(ctx, EXCP_RI);
1e608ec1
YK
26839 break;
26840 }
26841#endif
26842 switch (MASK_MSA_ELM(ctx->opcode)) {
26843 case OPC_COPY_S_df:
cab48881
MD
26844 if (likely(wd != 0)) {
26845 gen_helper_msa_copy_s_df(cpu_env, tdf, twd, tws, tn);
26846 }
1e608ec1
YK
26847 break;
26848 case OPC_COPY_U_df:
cab48881
MD
26849 if (likely(wd != 0)) {
26850 gen_helper_msa_copy_u_df(cpu_env, tdf, twd, tws, tn);
26851 }
1e608ec1
YK
26852 break;
26853 case OPC_INSERT_df:
26854 gen_helper_msa_insert_df(cpu_env, tdf, twd, tws, tn);
26855 break;
26856 }
26857 break;
26858 default:
26859 MIPS_INVAL("MSA instruction");
9c708c7f 26860 generate_exception_end(ctx, EXCP_RI);
1e608ec1
YK
26861 }
26862 tcg_temp_free_i32(twd);
26863 tcg_temp_free_i32(tws);
26864 tcg_temp_free_i32(tn);
26865 tcg_temp_free_i32(tdf);
26866}
26867
26868static void gen_msa_elm(CPUMIPSState *env, DisasContext *ctx)
26869{
26870 uint8_t dfn = (ctx->opcode >> 16) & 0x3f;
26871 uint32_t df = 0, n = 0;
26872
26873 if ((dfn & 0x30) == 0x00) {
26874 n = dfn & 0x0f;
26875 df = DF_BYTE;
26876 } else if ((dfn & 0x38) == 0x20) {
26877 n = dfn & 0x07;
26878 df = DF_HALF;
26879 } else if ((dfn & 0x3c) == 0x30) {
26880 n = dfn & 0x03;
26881 df = DF_WORD;
26882 } else if ((dfn & 0x3e) == 0x38) {
26883 n = dfn & 0x01;
26884 df = DF_DOUBLE;
26885 } else if (dfn == 0x3E) {
26886 /* CTCMSA, CFCMSA, MOVE.V */
26887 gen_msa_elm_3e(env, ctx);
26888 return;
26889 } else {
9c708c7f 26890 generate_exception_end(ctx, EXCP_RI);
1e608ec1
YK
26891 return;
26892 }
26893
26894 gen_msa_elm_df(env, ctx, df, n);
26895}
26896
7d05b9c8
YK
26897static void gen_msa_3rf(CPUMIPSState *env, DisasContext *ctx)
26898{
26899#define MASK_MSA_3RF(op) (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
26900 uint8_t df = (ctx->opcode >> 21) & 0x1;
26901 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
26902 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
26903 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
26904
26905 TCGv_i32 twd = tcg_const_i32(wd);
26906 TCGv_i32 tws = tcg_const_i32(ws);
26907 TCGv_i32 twt = tcg_const_i32(wt);
26908 TCGv_i32 tdf = tcg_temp_new_i32();
26909
26910 /* adjust df value for floating-point instruction */
26911 tcg_gen_movi_i32(tdf, df + 2);
26912
26913 switch (MASK_MSA_3RF(ctx->opcode)) {
26914 case OPC_FCAF_df:
26915 gen_helper_msa_fcaf_df(cpu_env, tdf, twd, tws, twt);
26916 break;
26917 case OPC_FADD_df:
26918 gen_helper_msa_fadd_df(cpu_env, tdf, twd, tws, twt);
26919 break;
26920 case OPC_FCUN_df:
26921 gen_helper_msa_fcun_df(cpu_env, tdf, twd, tws, twt);
26922 break;
26923 case OPC_FSUB_df:
26924 gen_helper_msa_fsub_df(cpu_env, tdf, twd, tws, twt);
26925 break;
26926 case OPC_FCOR_df:
26927 gen_helper_msa_fcor_df(cpu_env, tdf, twd, tws, twt);
26928 break;
26929 case OPC_FCEQ_df:
26930 gen_helper_msa_fceq_df(cpu_env, tdf, twd, tws, twt);
26931 break;
26932 case OPC_FMUL_df:
26933 gen_helper_msa_fmul_df(cpu_env, tdf, twd, tws, twt);
26934 break;
26935 case OPC_FCUNE_df:
26936 gen_helper_msa_fcune_df(cpu_env, tdf, twd, tws, twt);
26937 break;
26938 case OPC_FCUEQ_df:
26939 gen_helper_msa_fcueq_df(cpu_env, tdf, twd, tws, twt);
26940 break;
26941 case OPC_FDIV_df:
26942 gen_helper_msa_fdiv_df(cpu_env, tdf, twd, tws, twt);
26943 break;
26944 case OPC_FCNE_df:
26945 gen_helper_msa_fcne_df(cpu_env, tdf, twd, tws, twt);
26946 break;
26947 case OPC_FCLT_df:
26948 gen_helper_msa_fclt_df(cpu_env, tdf, twd, tws, twt);
26949 break;
26950 case OPC_FMADD_df:
26951 gen_helper_msa_fmadd_df(cpu_env, tdf, twd, tws, twt);
26952 break;
26953 case OPC_MUL_Q_df:
26954 tcg_gen_movi_i32(tdf, df + 1);
26955 gen_helper_msa_mul_q_df(cpu_env, tdf, twd, tws, twt);
26956 break;
26957 case OPC_FCULT_df:
26958 gen_helper_msa_fcult_df(cpu_env, tdf, twd, tws, twt);
26959 break;
26960 case OPC_FMSUB_df:
26961 gen_helper_msa_fmsub_df(cpu_env, tdf, twd, tws, twt);
26962 break;
26963 case OPC_MADD_Q_df:
26964 tcg_gen_movi_i32(tdf, df + 1);
26965 gen_helper_msa_madd_q_df(cpu_env, tdf, twd, tws, twt);
26966 break;
26967 case OPC_FCLE_df:
26968 gen_helper_msa_fcle_df(cpu_env, tdf, twd, tws, twt);
26969 break;
26970 case OPC_MSUB_Q_df:
26971 tcg_gen_movi_i32(tdf, df + 1);
26972 gen_helper_msa_msub_q_df(cpu_env, tdf, twd, tws, twt);
26973 break;
26974 case OPC_FCULE_df:
26975 gen_helper_msa_fcule_df(cpu_env, tdf, twd, tws, twt);
26976 break;
26977 case OPC_FEXP2_df:
26978 gen_helper_msa_fexp2_df(cpu_env, tdf, twd, tws, twt);
26979 break;
26980 case OPC_FSAF_df:
26981 gen_helper_msa_fsaf_df(cpu_env, tdf, twd, tws, twt);
26982 break;
26983 case OPC_FEXDO_df:
26984 gen_helper_msa_fexdo_df(cpu_env, tdf, twd, tws, twt);
26985 break;
26986 case OPC_FSUN_df:
26987 gen_helper_msa_fsun_df(cpu_env, tdf, twd, tws, twt);
26988 break;
26989 case OPC_FSOR_df:
26990 gen_helper_msa_fsor_df(cpu_env, tdf, twd, tws, twt);
26991 break;
26992 case OPC_FSEQ_df:
26993 gen_helper_msa_fseq_df(cpu_env, tdf, twd, tws, twt);
26994 break;
26995 case OPC_FTQ_df:
26996 gen_helper_msa_ftq_df(cpu_env, tdf, twd, tws, twt);
26997 break;
26998 case OPC_FSUNE_df:
26999 gen_helper_msa_fsune_df(cpu_env, tdf, twd, tws, twt);
27000 break;
27001 case OPC_FSUEQ_df:
27002 gen_helper_msa_fsueq_df(cpu_env, tdf, twd, tws, twt);
27003 break;
27004 case OPC_FSNE_df:
27005 gen_helper_msa_fsne_df(cpu_env, tdf, twd, tws, twt);
27006 break;
27007 case OPC_FSLT_df:
27008 gen_helper_msa_fslt_df(cpu_env, tdf, twd, tws, twt);
27009 break;
27010 case OPC_FMIN_df:
27011 gen_helper_msa_fmin_df(cpu_env, tdf, twd, tws, twt);
27012 break;
27013 case OPC_MULR_Q_df:
27014 tcg_gen_movi_i32(tdf, df + 1);
27015 gen_helper_msa_mulr_q_df(cpu_env, tdf, twd, tws, twt);
27016 break;
27017 case OPC_FSULT_df:
27018 gen_helper_msa_fsult_df(cpu_env, tdf, twd, tws, twt);
27019 break;
27020 case OPC_FMIN_A_df:
27021 gen_helper_msa_fmin_a_df(cpu_env, tdf, twd, tws, twt);
27022 break;
27023 case OPC_MADDR_Q_df:
27024 tcg_gen_movi_i32(tdf, df + 1);
27025 gen_helper_msa_maddr_q_df(cpu_env, tdf, twd, tws, twt);
27026 break;
27027 case OPC_FSLE_df:
27028 gen_helper_msa_fsle_df(cpu_env, tdf, twd, tws, twt);
27029 break;
27030 case OPC_FMAX_df:
27031 gen_helper_msa_fmax_df(cpu_env, tdf, twd, tws, twt);
27032 break;
27033 case OPC_MSUBR_Q_df:
27034 tcg_gen_movi_i32(tdf, df + 1);
27035 gen_helper_msa_msubr_q_df(cpu_env, tdf, twd, tws, twt);
27036 break;
27037 case OPC_FSULE_df:
27038 gen_helper_msa_fsule_df(cpu_env, tdf, twd, tws, twt);
27039 break;
27040 case OPC_FMAX_A_df:
27041 gen_helper_msa_fmax_a_df(cpu_env, tdf, twd, tws, twt);
27042 break;
27043 default:
27044 MIPS_INVAL("MSA instruction");
9c708c7f 27045 generate_exception_end(ctx, EXCP_RI);
7d05b9c8
YK
27046 break;
27047 }
27048
27049 tcg_temp_free_i32(twd);
27050 tcg_temp_free_i32(tws);
27051 tcg_temp_free_i32(twt);
27052 tcg_temp_free_i32(tdf);
27053}
27054
cbe50b9a
YK
27055static void gen_msa_2r(CPUMIPSState *env, DisasContext *ctx)
27056{
27057#define MASK_MSA_2R(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
27058 (op & (0x7 << 18)))
27059 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
27060 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
27061 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
27062 uint8_t df = (ctx->opcode >> 16) & 0x3;
27063 TCGv_i32 twd = tcg_const_i32(wd);
27064 TCGv_i32 tws = tcg_const_i32(ws);
27065 TCGv_i32 twt = tcg_const_i32(wt);
27066 TCGv_i32 tdf = tcg_const_i32(df);
27067
27068 switch (MASK_MSA_2R(ctx->opcode)) {
27069 case OPC_FILL_df:
27070#if !defined(TARGET_MIPS64)
27071 /* Double format valid only for MIPS64 */
27072 if (df == DF_DOUBLE) {
9c708c7f 27073 generate_exception_end(ctx, EXCP_RI);
cbe50b9a
YK
27074 break;
27075 }
27076#endif
27077 gen_helper_msa_fill_df(cpu_env, tdf, twd, tws); /* trs */
27078 break;
27079 case OPC_PCNT_df:
27080 gen_helper_msa_pcnt_df(cpu_env, tdf, twd, tws);
27081 break;
27082 case OPC_NLOC_df:
27083 gen_helper_msa_nloc_df(cpu_env, tdf, twd, tws);
27084 break;
27085 case OPC_NLZC_df:
27086 gen_helper_msa_nlzc_df(cpu_env, tdf, twd, tws);
27087 break;
27088 default:
27089 MIPS_INVAL("MSA instruction");
9c708c7f 27090 generate_exception_end(ctx, EXCP_RI);
cbe50b9a
YK
27091 break;
27092 }
27093
27094 tcg_temp_free_i32(twd);
27095 tcg_temp_free_i32(tws);
27096 tcg_temp_free_i32(twt);
27097 tcg_temp_free_i32(tdf);
27098}
27099
3bdeb688
YK
27100static void gen_msa_2rf(CPUMIPSState *env, DisasContext *ctx)
27101{
27102#define MASK_MSA_2RF(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
27103 (op & (0xf << 17)))
27104 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
27105 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
27106 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
27107 uint8_t df = (ctx->opcode >> 16) & 0x1;
27108 TCGv_i32 twd = tcg_const_i32(wd);
27109 TCGv_i32 tws = tcg_const_i32(ws);
27110 TCGv_i32 twt = tcg_const_i32(wt);
27111 /* adjust df value for floating-point instruction */
27112 TCGv_i32 tdf = tcg_const_i32(df + 2);
27113
27114 switch (MASK_MSA_2RF(ctx->opcode)) {
27115 case OPC_FCLASS_df:
27116 gen_helper_msa_fclass_df(cpu_env, tdf, twd, tws);
27117 break;
27118 case OPC_FTRUNC_S_df:
27119 gen_helper_msa_ftrunc_s_df(cpu_env, tdf, twd, tws);
27120 break;
27121 case OPC_FTRUNC_U_df:
27122 gen_helper_msa_ftrunc_u_df(cpu_env, tdf, twd, tws);
27123 break;
27124 case OPC_FSQRT_df:
27125 gen_helper_msa_fsqrt_df(cpu_env, tdf, twd, tws);
27126 break;
27127 case OPC_FRSQRT_df:
27128 gen_helper_msa_frsqrt_df(cpu_env, tdf, twd, tws);
27129 break;
27130 case OPC_FRCP_df:
27131 gen_helper_msa_frcp_df(cpu_env, tdf, twd, tws);
27132 break;
27133 case OPC_FRINT_df:
27134 gen_helper_msa_frint_df(cpu_env, tdf, twd, tws);
27135 break;
27136 case OPC_FLOG2_df:
27137 gen_helper_msa_flog2_df(cpu_env, tdf, twd, tws);
27138 break;
27139 case OPC_FEXUPL_df:
27140 gen_helper_msa_fexupl_df(cpu_env, tdf, twd, tws);
27141 break;
27142 case OPC_FEXUPR_df:
27143 gen_helper_msa_fexupr_df(cpu_env, tdf, twd, tws);
27144 break;
27145 case OPC_FFQL_df:
27146 gen_helper_msa_ffql_df(cpu_env, tdf, twd, tws);
27147 break;
27148 case OPC_FFQR_df:
27149 gen_helper_msa_ffqr_df(cpu_env, tdf, twd, tws);
27150 break;
27151 case OPC_FTINT_S_df:
27152 gen_helper_msa_ftint_s_df(cpu_env, tdf, twd, tws);
27153 break;
27154 case OPC_FTINT_U_df:
27155 gen_helper_msa_ftint_u_df(cpu_env, tdf, twd, tws);
27156 break;
27157 case OPC_FFINT_S_df:
27158 gen_helper_msa_ffint_s_df(cpu_env, tdf, twd, tws);
27159 break;
27160 case OPC_FFINT_U_df:
27161 gen_helper_msa_ffint_u_df(cpu_env, tdf, twd, tws);
27162 break;
27163 }
27164
27165 tcg_temp_free_i32(twd);
27166 tcg_temp_free_i32(tws);
27167 tcg_temp_free_i32(twt);
27168 tcg_temp_free_i32(tdf);
27169}
27170
cbe50b9a
YK
27171static void gen_msa_vec_v(CPUMIPSState *env, DisasContext *ctx)
27172{
27173#define MASK_MSA_VEC(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)))
27174 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
27175 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
27176 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
27177 TCGv_i32 twd = tcg_const_i32(wd);
27178 TCGv_i32 tws = tcg_const_i32(ws);
27179 TCGv_i32 twt = tcg_const_i32(wt);
27180
27181 switch (MASK_MSA_VEC(ctx->opcode)) {
27182 case OPC_AND_V:
27183 gen_helper_msa_and_v(cpu_env, twd, tws, twt);
27184 break;
27185 case OPC_OR_V:
27186 gen_helper_msa_or_v(cpu_env, twd, tws, twt);
27187 break;
27188 case OPC_NOR_V:
27189 gen_helper_msa_nor_v(cpu_env, twd, tws, twt);
27190 break;
27191 case OPC_XOR_V:
27192 gen_helper_msa_xor_v(cpu_env, twd, tws, twt);
27193 break;
27194 case OPC_BMNZ_V:
27195 gen_helper_msa_bmnz_v(cpu_env, twd, tws, twt);
27196 break;
27197 case OPC_BMZ_V:
27198 gen_helper_msa_bmz_v(cpu_env, twd, tws, twt);
27199 break;
27200 case OPC_BSEL_V:
27201 gen_helper_msa_bsel_v(cpu_env, twd, tws, twt);
27202 break;
27203 default:
27204 MIPS_INVAL("MSA instruction");
9c708c7f 27205 generate_exception_end(ctx, EXCP_RI);
cbe50b9a
YK
27206 break;
27207 }
27208
27209 tcg_temp_free_i32(twd);
27210 tcg_temp_free_i32(tws);
27211 tcg_temp_free_i32(twt);
27212}
27213
27214static void gen_msa_vec(CPUMIPSState *env, DisasContext *ctx)
27215{
27216 switch (MASK_MSA_VEC(ctx->opcode)) {
27217 case OPC_AND_V:
27218 case OPC_OR_V:
27219 case OPC_NOR_V:
27220 case OPC_XOR_V:
27221 case OPC_BMNZ_V:
27222 case OPC_BMZ_V:
27223 case OPC_BSEL_V:
27224 gen_msa_vec_v(env, ctx);
27225 break;
27226 case OPC_MSA_2R:
27227 gen_msa_2r(env, ctx);
27228 break;
3bdeb688
YK
27229 case OPC_MSA_2RF:
27230 gen_msa_2rf(env, ctx);
27231 break;
cbe50b9a
YK
27232 default:
27233 MIPS_INVAL("MSA instruction");
9c708c7f 27234 generate_exception_end(ctx, EXCP_RI);
cbe50b9a
YK
27235 break;
27236 }
27237}
27238
4c789546
YK
27239static void gen_msa(CPUMIPSState *env, DisasContext *ctx)
27240{
27241 uint32_t opcode = ctx->opcode;
27242 check_insn(ctx, ASE_MSA);
27243 check_msa_access(ctx);
27244
27245 switch (MASK_MSA_MINOR(opcode)) {
27246 case OPC_MSA_I8_00:
27247 case OPC_MSA_I8_01:
27248 case OPC_MSA_I8_02:
27249 gen_msa_i8(env, ctx);
27250 break;
80e71591
YK
27251 case OPC_MSA_I5_06:
27252 case OPC_MSA_I5_07:
27253 gen_msa_i5(env, ctx);
27254 break;
d4cf28de
YK
27255 case OPC_MSA_BIT_09:
27256 case OPC_MSA_BIT_0A:
27257 gen_msa_bit(env, ctx);
27258 break;
28f99f08
YK
27259 case OPC_MSA_3R_0D:
27260 case OPC_MSA_3R_0E:
27261 case OPC_MSA_3R_0F:
27262 case OPC_MSA_3R_10:
27263 case OPC_MSA_3R_11:
27264 case OPC_MSA_3R_12:
27265 case OPC_MSA_3R_13:
27266 case OPC_MSA_3R_14:
27267 case OPC_MSA_3R_15:
27268 gen_msa_3r(env, ctx);
27269 break;
1e608ec1
YK
27270 case OPC_MSA_ELM:
27271 gen_msa_elm(env, ctx);
27272 break;
7d05b9c8
YK
27273 case OPC_MSA_3RF_1A:
27274 case OPC_MSA_3RF_1B:
27275 case OPC_MSA_3RF_1C:
27276 gen_msa_3rf(env, ctx);
27277 break;
cbe50b9a
YK
27278 case OPC_MSA_VEC:
27279 gen_msa_vec(env, ctx);
27280 break;
f7685877
YK
27281 case OPC_LD_B:
27282 case OPC_LD_H:
27283 case OPC_LD_W:
27284 case OPC_LD_D:
27285 case OPC_ST_B:
27286 case OPC_ST_H:
27287 case OPC_ST_W:
27288 case OPC_ST_D:
27289 {
27290 int32_t s10 = sextract32(ctx->opcode, 16, 10);
27291 uint8_t rs = (ctx->opcode >> 11) & 0x1f;
27292 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
27293 uint8_t df = (ctx->opcode >> 0) & 0x3;
27294
f7685877 27295 TCGv_i32 twd = tcg_const_i32(wd);
adc370a4
YK
27296 TCGv taddr = tcg_temp_new();
27297 gen_base_offset_addr(ctx, taddr, rs, s10 << df);
f7685877
YK
27298
27299 switch (MASK_MSA_MINOR(opcode)) {
27300 case OPC_LD_B:
adc370a4
YK
27301 gen_helper_msa_ld_b(cpu_env, twd, taddr);
27302 break;
f7685877 27303 case OPC_LD_H:
adc370a4
YK
27304 gen_helper_msa_ld_h(cpu_env, twd, taddr);
27305 break;
f7685877 27306 case OPC_LD_W:
adc370a4
YK
27307 gen_helper_msa_ld_w(cpu_env, twd, taddr);
27308 break;
f7685877 27309 case OPC_LD_D:
adc370a4 27310 gen_helper_msa_ld_d(cpu_env, twd, taddr);
f7685877
YK
27311 break;
27312 case OPC_ST_B:
adc370a4
YK
27313 gen_helper_msa_st_b(cpu_env, twd, taddr);
27314 break;
f7685877 27315 case OPC_ST_H:
adc370a4
YK
27316 gen_helper_msa_st_h(cpu_env, twd, taddr);
27317 break;
f7685877 27318 case OPC_ST_W:
adc370a4
YK
27319 gen_helper_msa_st_w(cpu_env, twd, taddr);
27320 break;
f7685877 27321 case OPC_ST_D:
adc370a4 27322 gen_helper_msa_st_d(cpu_env, twd, taddr);
f7685877
YK
27323 break;
27324 }
27325
27326 tcg_temp_free_i32(twd);
adc370a4 27327 tcg_temp_free(taddr);
f7685877
YK
27328 }
27329 break;
4c789546
YK
27330 default:
27331 MIPS_INVAL("MSA instruction");
9c708c7f 27332 generate_exception_end(ctx, EXCP_RI);
4c789546
YK
27333 break;
27334 }
27335
27336}
27337
d2bfa6e6 27338static void decode_opc(CPUMIPSState *env, DisasContext *ctx)
099e5b4d
LA
27339{
27340 int32_t offset;
27341 int rs, rt, rd, sa;
27342 uint32_t op, op1;
27343 int16_t imm;
27344
27345 /* make sure instructions are on a word boundary */
eeb3bba8
EC
27346 if (ctx->base.pc_next & 0x3) {
27347 env->CP0_BadVAddr = ctx->base.pc_next;
aea14095 27348 generate_exception_err(ctx, EXCP_AdEL, EXCP_INST_NOTAVAIL);
099e5b4d
LA
27349 return;
27350 }
27351
27352 /* Handle blikely not taken case */
27353 if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
42a268c2 27354 TCGLabel *l1 = gen_new_label();
099e5b4d 27355
099e5b4d
LA
27356 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
27357 tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
eeb3bba8 27358 gen_goto_tb(ctx, 1, ctx->base.pc_next + 4);
099e5b4d
LA
27359 gen_set_label(l1);
27360 }
27361
099e5b4d
LA
27362 op = MASK_OP_MAJOR(ctx->opcode);
27363 rs = (ctx->opcode >> 21) & 0x1f;
27364 rt = (ctx->opcode >> 16) & 0x1f;
27365 rd = (ctx->opcode >> 11) & 0x1f;
27366 sa = (ctx->opcode >> 6) & 0x1f;
27367 imm = (int16_t)ctx->opcode;
27368 switch (op) {
27369 case OPC_SPECIAL:
27370 decode_opc_special(env, ctx);
27371 break;
27372 case OPC_SPECIAL2:
71b8a6b3
FN
27373 if ((ctx->insn_flags & INSN_R5900) && (ctx->insn_flags & ASE_MMI)) {
27374 decode_tx79_mmi(env, ctx);
0a348b9a
AM
27375 } else if (ctx->insn_flags & ASE_MXU) {
27376 decode_opc_mxu(env, ctx);
71b8a6b3
FN
27377 } else {
27378 decode_opc_special2_legacy(env, ctx);
27379 }
099e5b4d
LA
27380 break;
27381 case OPC_SPECIAL3:
bb41e74b
FN
27382 if (ctx->insn_flags & INSN_R5900) {
27383 decode_tx79_sq(env, ctx); /* TX79_SQ */
27384 } else {
27385 decode_opc_special3(env, ctx);
27386 }
099e5b4d 27387 break;
7a387fff
TS
27388 case OPC_REGIMM:
27389 op1 = MASK_REGIMM(ctx->opcode);
27390 switch (op1) {
fecd2646
LA
27391 case OPC_BLTZL: /* REGIMM branches */
27392 case OPC_BGEZL:
27393 case OPC_BLTZALL:
27394 case OPC_BGEZALL:
d9224450 27395 check_insn(ctx, ISA_MIPS2);
fecd2646 27396 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d9224450 27397 /* Fallthrough */
fecd2646
LA
27398 case OPC_BLTZ:
27399 case OPC_BGEZ:
b231c103 27400 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
0aefa333 27401 break;
fecd2646
LA
27402 case OPC_BLTZAL:
27403 case OPC_BGEZAL:
0aefa333
YK
27404 if (ctx->insn_flags & ISA_MIPS32R6) {
27405 if (rs == 0) {
27406 /* OPC_NAL, OPC_BAL */
b231c103 27407 gen_compute_branch(ctx, op1, 4, 0, -1, imm << 2, 4);
0aefa333 27408 } else {
9c708c7f 27409 generate_exception_end(ctx, EXCP_RI);
0aefa333
YK
27410 }
27411 } else {
b231c103 27412 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
0aefa333 27413 }
c9602061 27414 break;
c2e19f3c
AM
27415 case OPC_TGEI: /* REGIMM traps */
27416 case OPC_TGEIU:
27417 case OPC_TLTI:
27418 case OPC_TLTIU:
27419 case OPC_TEQI:
27420
7a387fff 27421 case OPC_TNEI:
d9224450 27422 check_insn(ctx, ISA_MIPS2);
fecd2646 27423 check_insn_opc_removed(ctx, ISA_MIPS32R6);
7a387fff
TS
27424 gen_trap(ctx, op1, rs, -1, imm);
27425 break;
bb238210
YK
27426 case OPC_SIGRIE:
27427 check_insn(ctx, ISA_MIPS32R6);
27428 generate_exception_end(ctx, EXCP_RI);
27429 break;
7a387fff 27430 case OPC_SYNCI:
d75c135e 27431 check_insn(ctx, ISA_MIPS32R2);
a83bddd6
DZ
27432 /* Break the TB to be able to sync copied instructions
27433 immediately */
eeb3bba8 27434 ctx->base.is_jmp = DISAS_STOP;
6af0bf9c 27435 break;
e45a93e2
JL
27436 case OPC_BPOSGE32: /* MIPS DSP branch */
27437#if defined(TARGET_MIPS64)
27438 case OPC_BPOSGE64:
27439#endif
27440 check_dsp(ctx);
b231c103 27441 gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2, 4);
e45a93e2 27442 break;
d4ea6acd
LA
27443#if defined(TARGET_MIPS64)
27444 case OPC_DAHI:
27445 check_insn(ctx, ISA_MIPS32R6);
27446 check_mips_64(ctx);
27447 if (rs != 0) {
27448 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 32);
27449 }
d4ea6acd
LA
27450 break;
27451 case OPC_DATI:
27452 check_insn(ctx, ISA_MIPS32R6);
27453 check_mips_64(ctx);
27454 if (rs != 0) {
27455 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 48);
27456 }
d4ea6acd
LA
27457 break;
27458#endif
6af0bf9c 27459 default: /* Invalid */
923617a3 27460 MIPS_INVAL("regimm");
9c708c7f 27461 generate_exception_end(ctx, EXCP_RI);
6af0bf9c
FB
27462 break;
27463 }
27464 break;
7a387fff 27465 case OPC_CP0:
387a8fe5 27466 check_cp0_enabled(ctx);
7a387fff 27467 op1 = MASK_CP0(ctx->opcode);
6af0bf9c 27468 switch (op1) {
7a387fff
TS
27469 case OPC_MFC0:
27470 case OPC_MTC0:
ead9360e
TS
27471 case OPC_MFTR:
27472 case OPC_MTTR:
5204ea79
LA
27473 case OPC_MFHC0:
27474 case OPC_MTHC0:
d26bc211 27475#if defined(TARGET_MIPS64)
7a387fff
TS
27476 case OPC_DMFC0:
27477 case OPC_DMTC0:
27478#endif
f1aa6320 27479#ifndef CONFIG_USER_ONLY
932e71cd 27480 gen_cp0(env, ctx, op1, rt, rd);
0eaef5aa 27481#endif /* !CONFIG_USER_ONLY */
7a387fff 27482 break;
c38a1d52
AR
27483 case OPC_C0:
27484 case OPC_C0_1:
27485 case OPC_C0_2:
27486 case OPC_C0_3:
27487 case OPC_C0_4:
27488 case OPC_C0_5:
27489 case OPC_C0_6:
27490 case OPC_C0_7:
27491 case OPC_C0_8:
27492 case OPC_C0_9:
27493 case OPC_C0_A:
27494 case OPC_C0_B:
27495 case OPC_C0_C:
27496 case OPC_C0_D:
27497 case OPC_C0_E:
27498 case OPC_C0_F:
f1aa6320 27499#ifndef CONFIG_USER_ONLY
932e71cd 27500 gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
0eaef5aa 27501#endif /* !CONFIG_USER_ONLY */
7a387fff
TS
27502 break;
27503 case OPC_MFMC0:
8706c382 27504#ifndef CONFIG_USER_ONLY
932e71cd 27505 {
099e5b4d 27506 uint32_t op2;
35fbce2c 27507 TCGv t0 = tcg_temp_new();
6c5c1e20 27508
0eaef5aa 27509 op2 = MASK_MFMC0(ctx->opcode);
6c5c1e20
TS
27510 switch (op2) {
27511 case OPC_DMT:
9affc1c5 27512 check_cp0_mt(ctx);
9ed5726c 27513 gen_helper_dmt(t0);
35fbce2c 27514 gen_store_gpr(t0, rt);
6c5c1e20
TS
27515 break;
27516 case OPC_EMT:
9affc1c5 27517 check_cp0_mt(ctx);
9ed5726c 27518 gen_helper_emt(t0);
35fbce2c 27519 gen_store_gpr(t0, rt);
da80682b 27520 break;
6c5c1e20 27521 case OPC_DVPE:
9affc1c5 27522 check_cp0_mt(ctx);
895c2d04 27523 gen_helper_dvpe(t0, cpu_env);
35fbce2c 27524 gen_store_gpr(t0, rt);
6c5c1e20
TS
27525 break;
27526 case OPC_EVPE:
9affc1c5 27527 check_cp0_mt(ctx);
895c2d04 27528 gen_helper_evpe(t0, cpu_env);
35fbce2c 27529 gen_store_gpr(t0, rt);
6c5c1e20 27530 break;
01bc435b
YK
27531 case OPC_DVP:
27532 check_insn(ctx, ISA_MIPS32R6);
27533 if (ctx->vp) {
27534 gen_helper_dvp(t0, cpu_env);
27535 gen_store_gpr(t0, rt);
27536 }
27537 break;
27538 case OPC_EVP:
27539 check_insn(ctx, ISA_MIPS32R6);
27540 if (ctx->vp) {
27541 gen_helper_evp(t0, cpu_env);
27542 gen_store_gpr(t0, rt);
27543 }
27544 break;
6c5c1e20 27545 case OPC_DI:
d75c135e 27546 check_insn(ctx, ISA_MIPS32R2);
867abc7e 27547 save_cpu_state(ctx, 1);
895c2d04 27548 gen_helper_di(t0, cpu_env);
35fbce2c 27549 gen_store_gpr(t0, rt);
d2bfa6e6
MR
27550 /* Stop translation as we may have switched
27551 the execution mode. */
eeb3bba8 27552 ctx->base.is_jmp = DISAS_STOP;
6c5c1e20
TS
27553 break;
27554 case OPC_EI:
d75c135e 27555 check_insn(ctx, ISA_MIPS32R2);
867abc7e 27556 save_cpu_state(ctx, 1);
895c2d04 27557 gen_helper_ei(t0, cpu_env);
35fbce2c 27558 gen_store_gpr(t0, rt);
b28425ba
EC
27559 /* DISAS_STOP isn't sufficient, we need to ensure we break
27560 out of translated code to check for pending interrupts */
eeb3bba8
EC
27561 gen_save_pc(ctx->base.pc_next + 4);
27562 ctx->base.is_jmp = DISAS_EXIT;
6c5c1e20
TS
27563 break;
27564 default: /* Invalid */
27565 MIPS_INVAL("mfmc0");
9c708c7f 27566 generate_exception_end(ctx, EXCP_RI);
6c5c1e20
TS
27567 break;
27568 }
6c5c1e20 27569 tcg_temp_free(t0);
7a387fff 27570 }
0eaef5aa 27571#endif /* !CONFIG_USER_ONLY */
6af0bf9c 27572 break;
7a387fff 27573 case OPC_RDPGPR:
d75c135e 27574 check_insn(ctx, ISA_MIPS32R2);
be24bb4f 27575 gen_load_srsgpr(rt, rd);
ead9360e 27576 break;
7a387fff 27577 case OPC_WRPGPR:
d75c135e 27578 check_insn(ctx, ISA_MIPS32R2);
be24bb4f 27579 gen_store_srsgpr(rt, rd);
38121543 27580 break;
6af0bf9c 27581 default:
923617a3 27582 MIPS_INVAL("cp0");
9c708c7f 27583 generate_exception_end(ctx, EXCP_RI);
6af0bf9c
FB
27584 break;
27585 }
27586 break;
31837be3
YK
27587 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC, OPC_ADDI */
27588 if (ctx->insn_flags & ISA_MIPS32R6) {
27589 /* OPC_BOVC, OPC_BEQZALC, OPC_BEQC */
27590 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
27591 } else {
27592 /* OPC_ADDI */
27593 /* Arithmetic with immediate opcode */
27594 gen_arith_imm(ctx, op, rt, rs, imm);
27595 }
27596 break;
324d9e32 27597 case OPC_ADDIU:
d75c135e 27598 gen_arith_imm(ctx, op, rt, rs, imm);
7a387fff 27599 break;
324d9e32
AJ
27600 case OPC_SLTI: /* Set on less than with immediate opcode */
27601 case OPC_SLTIU:
d75c135e 27602 gen_slt_imm(ctx, op, rt, rs, imm);
324d9e32
AJ
27603 break;
27604 case OPC_ANDI: /* Arithmetic with immediate opcode */
d4ea6acd 27605 case OPC_LUI: /* OPC_AUI */
324d9e32
AJ
27606 case OPC_ORI:
27607 case OPC_XORI:
d75c135e 27608 gen_logic_imm(ctx, op, rt, rs, imm);
324d9e32 27609 break;
c2e19f3c
AM
27610 case OPC_J: /* Jump */
27611 case OPC_JAL:
7a387fff 27612 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
b231c103 27613 gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
c9602061 27614 break;
31837be3
YK
27615 /* Branch */
27616 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC, OPC_BLEZL */
27617 if (ctx->insn_flags & ISA_MIPS32R6) {
27618 if (rt == 0) {
9c708c7f 27619 generate_exception_end(ctx, EXCP_RI);
31837be3
YK
27620 break;
27621 }
27622 /* OPC_BLEZC, OPC_BGEZC, OPC_BGEC */
27623 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
27624 } else {
27625 /* OPC_BLEZL */
b231c103 27626 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
31837be3
YK
27627 }
27628 break;
27629 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC, OPC_BGTZL */
27630 if (ctx->insn_flags & ISA_MIPS32R6) {
27631 if (rt == 0) {
9c708c7f 27632 generate_exception_end(ctx, EXCP_RI);
31837be3
YK
27633 break;
27634 }
27635 /* OPC_BGTZC, OPC_BLTZC, OPC_BLTC */
27636 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
27637 } else {
27638 /* OPC_BGTZL */
b231c103 27639 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
31837be3
YK
27640 }
27641 break;
27642 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC, OPC_BLEZ */
27643 if (rt == 0) {
27644 /* OPC_BLEZ */
b231c103 27645 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
31837be3
YK
27646 } else {
27647 check_insn(ctx, ISA_MIPS32R6);
27648 /* OPC_BLEZALC, OPC_BGEZALC, OPC_BGEUC */
27649 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
27650 }
27651 break;
27652 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC, OPC_BGTZ */
27653 if (rt == 0) {
27654 /* OPC_BGTZ */
b231c103 27655 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
31837be3
YK
27656 } else {
27657 check_insn(ctx, ISA_MIPS32R6);
27658 /* OPC_BGTZALC, OPC_BLTZALC, OPC_BLTUC */
27659 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
27660 }
27661 break;
27662 case OPC_BEQL:
27663 case OPC_BNEL:
d9224450 27664 check_insn(ctx, ISA_MIPS2);
fecd2646 27665 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d9224450 27666 /* Fallthrough */
31837be3
YK
27667 case OPC_BEQ:
27668 case OPC_BNE:
b231c103 27669 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
c9602061 27670 break;
d9224450
MR
27671 case OPC_LL: /* Load and stores */
27672 check_insn(ctx, ISA_MIPS2);
96631327 27673 check_insn_opc_user_only(ctx, INSN_R5900);
d9224450
MR
27674 /* Fallthrough */
27675 case OPC_LWL:
fecd2646
LA
27676 case OPC_LWR:
27677 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d9224450 27678 /* Fallthrough */
c2e19f3c
AM
27679 case OPC_LB:
27680 case OPC_LH:
27681 case OPC_LW:
27682 case OPC_LWPC:
27683 case OPC_LBU:
27684 case OPC_LHU:
d75c135e 27685 gen_ld(ctx, op, rt, rs, imm);
5c13fdfd 27686 break;
fecd2646 27687 case OPC_SWL:
7a387fff 27688 case OPC_SWR:
fecd2646 27689 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b6f3b233 27690 /* fall through */
c2e19f3c
AM
27691 case OPC_SB:
27692 case OPC_SH:
fecd2646 27693 case OPC_SW:
5c13fdfd 27694 gen_st(ctx, op, rt, rs, imm);
7a387fff 27695 break;
d66c7132 27696 case OPC_SC:
d9224450 27697 check_insn(ctx, ISA_MIPS2);
4368b29a 27698 check_insn_opc_removed(ctx, ISA_MIPS32R6);
96631327 27699 check_insn_opc_user_only(ctx, INSN_R5900);
d66c7132
AJ
27700 gen_st_cond(ctx, op, rt, rs, imm);
27701 break;
7a387fff 27702 case OPC_CACHE:
bf7910c6 27703 check_insn_opc_removed(ctx, ISA_MIPS32R6);
2e15497c 27704 check_cp0_enabled(ctx);
d75c135e 27705 check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
0d74a222
LA
27706 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
27707 gen_cache_operation(ctx, rt, rs, imm);
27708 }
ead9360e 27709 /* Treat as NOP. */
34ae7b51 27710 break;
7a387fff 27711 case OPC_PREF:
bf7910c6 27712 check_insn_opc_removed(ctx, ISA_MIPS32R6);
5601e621
FN
27713 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32 |
27714 INSN_R5900);
ead9360e 27715 /* Treat as NOP. */
6af0bf9c 27716 break;
4ad40f36 27717
923617a3 27718 /* Floating point (COP1). */
7a387fff
TS
27719 case OPC_LWC1:
27720 case OPC_LDC1:
27721 case OPC_SWC1:
27722 case OPC_SDC1:
5ab5c041 27723 gen_cop1_ldst(ctx, op, rt, rs, imm);
6ea83fed
FB
27724 break;
27725
7a387fff 27726 case OPC_CP1:
5692c6e1
YK
27727 op1 = MASK_CP1(ctx->opcode);
27728
27729 switch (op1) {
27730 case OPC_MFHC1:
27731 case OPC_MTHC1:
5e755519 27732 check_cp1_enabled(ctx);
5692c6e1 27733 check_insn(ctx, ISA_MIPS32R2);
146dd620 27734 /* fall through */
5692c6e1
YK
27735 case OPC_MFC1:
27736 case OPC_CFC1:
27737 case OPC_MTC1:
27738 case OPC_CTC1:
27739 check_cp1_enabled(ctx);
27740 gen_cp1(ctx, op1, rt, rd);
27741 break;
d26bc211 27742#if defined(TARGET_MIPS64)
5692c6e1
YK
27743 case OPC_DMFC1:
27744 case OPC_DMTC1:
27745 check_cp1_enabled(ctx);
27746 check_insn(ctx, ISA_MIPS3);
d9224450 27747 check_mips_64(ctx);
5692c6e1
YK
27748 gen_cp1(ctx, op1, rt, rd);
27749 break;
e189e748 27750#endif
5692c6e1
YK
27751 case OPC_BC1EQZ: /* OPC_BC1ANY2 */
27752 check_cp1_enabled(ctx);
27753 if (ctx->insn_flags & ISA_MIPS32R6) {
27754 /* OPC_BC1EQZ */
31837be3 27755 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
65935f07 27756 rt, imm << 2, 4);
5692c6e1
YK
27757 } else {
27758 /* OPC_BC1ANY2 */
b8aa4598 27759 check_cop1x(ctx);
d75c135e 27760 check_insn(ctx, ASE_MIPS3D);
d75c135e 27761 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
5a5012ec 27762 (rt >> 2) & 0x7, imm << 2);
5692c6e1
YK
27763 }
27764 break;
27765 case OPC_BC1NEZ:
27766 check_cp1_enabled(ctx);
27767 check_insn(ctx, ISA_MIPS32R6);
27768 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
65935f07 27769 rt, imm << 2, 4);
5692c6e1
YK
27770 break;
27771 case OPC_BC1ANY4:
27772 check_cp1_enabled(ctx);
27773 check_insn_opc_removed(ctx, ISA_MIPS32R6);
27774 check_cop1x(ctx);
27775 check_insn(ctx, ASE_MIPS3D);
27776 /* fall through */
27777 case OPC_BC1:
27778 check_cp1_enabled(ctx);
27779 check_insn_opc_removed(ctx, ISA_MIPS32R6);
27780 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
27781 (rt >> 2) & 0x7, imm << 2);
27782 break;
27783 case OPC_PS_FMT:
e29c9628 27784 check_ps(ctx);
b6f3b233 27785 /* fall through */
5692c6e1
YK
27786 case OPC_S_FMT:
27787 case OPC_D_FMT:
27788 check_cp1_enabled(ctx);
27789 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
27790 (imm >> 8) & 0x7);
27791 break;
27792 case OPC_W_FMT:
27793 case OPC_L_FMT:
27794 {
27795 int r6_op = ctx->opcode & FOP(0x3f, 0x1f);
27796 check_cp1_enabled(ctx);
27797 if (ctx->insn_flags & ISA_MIPS32R6) {
27798 switch (r6_op) {
27799 case R6_OPC_CMP_AF_S:
27800 case R6_OPC_CMP_UN_S:
27801 case R6_OPC_CMP_EQ_S:
27802 case R6_OPC_CMP_UEQ_S:
27803 case R6_OPC_CMP_LT_S:
27804 case R6_OPC_CMP_ULT_S:
27805 case R6_OPC_CMP_LE_S:
27806 case R6_OPC_CMP_ULE_S:
27807 case R6_OPC_CMP_SAF_S:
27808 case R6_OPC_CMP_SUN_S:
27809 case R6_OPC_CMP_SEQ_S:
27810 case R6_OPC_CMP_SEUQ_S:
27811 case R6_OPC_CMP_SLT_S:
27812 case R6_OPC_CMP_SULT_S:
27813 case R6_OPC_CMP_SLE_S:
27814 case R6_OPC_CMP_SULE_S:
27815 case R6_OPC_CMP_OR_S:
27816 case R6_OPC_CMP_UNE_S:
27817 case R6_OPC_CMP_NE_S:
27818 case R6_OPC_CMP_SOR_S:
27819 case R6_OPC_CMP_SUNE_S:
27820 case R6_OPC_CMP_SNE_S:
27821 gen_r6_cmp_s(ctx, ctx->opcode & 0x1f, rt, rd, sa);
27822 break;
27823 case R6_OPC_CMP_AF_D:
27824 case R6_OPC_CMP_UN_D:
27825 case R6_OPC_CMP_EQ_D:
27826 case R6_OPC_CMP_UEQ_D:
27827 case R6_OPC_CMP_LT_D:
27828 case R6_OPC_CMP_ULT_D:
27829 case R6_OPC_CMP_LE_D:
27830 case R6_OPC_CMP_ULE_D:
27831 case R6_OPC_CMP_SAF_D:
27832 case R6_OPC_CMP_SUN_D:
27833 case R6_OPC_CMP_SEQ_D:
27834 case R6_OPC_CMP_SEUQ_D:
27835 case R6_OPC_CMP_SLT_D:
27836 case R6_OPC_CMP_SULT_D:
27837 case R6_OPC_CMP_SLE_D:
27838 case R6_OPC_CMP_SULE_D:
27839 case R6_OPC_CMP_OR_D:
27840 case R6_OPC_CMP_UNE_D:
27841 case R6_OPC_CMP_NE_D:
27842 case R6_OPC_CMP_SOR_D:
27843 case R6_OPC_CMP_SUNE_D:
27844 case R6_OPC_CMP_SNE_D:
27845 gen_r6_cmp_d(ctx, ctx->opcode & 0x1f, rt, rd, sa);
27846 break;
27847 default:
d2bfa6e6
MR
27848 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f),
27849 rt, rd, sa, (imm >> 8) & 0x7);
27850
5692c6e1 27851 break;
3f493883 27852 }
5692c6e1
YK
27853 } else {
27854 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
27855 (imm >> 8) & 0x7);
36d23958 27856 }
5692c6e1
YK
27857 break;
27858 }
27859 case OPC_BZ_V:
27860 case OPC_BNZ_V:
27861 case OPC_BZ_B:
27862 case OPC_BZ_H:
27863 case OPC_BZ_W:
27864 case OPC_BZ_D:
27865 case OPC_BNZ_B:
27866 case OPC_BNZ_H:
27867 case OPC_BNZ_W:
27868 case OPC_BNZ_D:
27869 check_insn(ctx, ASE_MSA);
27870 gen_msa_branch(env, ctx, op1);
27871 break;
27872 default:
27873 MIPS_INVAL("cp1");
9c708c7f 27874 generate_exception_end(ctx, EXCP_RI);
5692c6e1 27875 break;
6ea83fed 27876 }
4ad40f36
FB
27877 break;
27878
31837be3
YK
27879 /* Compact branches [R6] and COP2 [non-R6] */
27880 case OPC_BC: /* OPC_LWC2 */
27881 case OPC_BALC: /* OPC_SWC2 */
27882 if (ctx->insn_flags & ISA_MIPS32R6) {
27883 /* OPC_BC, OPC_BALC */
27884 gen_compute_compact_branch(ctx, op, 0, 0,
27885 sextract32(ctx->opcode << 2, 0, 28));
27886 } else {
27887 /* OPC_LWC2, OPC_SWC2 */
27888 /* COP2: Not implemented. */
27889 generate_exception_err(ctx, EXCP_CpU, 2);
27890 }
27891 break;
27892 case OPC_BEQZC: /* OPC_JIC, OPC_LDC2 */
27893 case OPC_BNEZC: /* OPC_JIALC, OPC_SDC2 */
27894 if (ctx->insn_flags & ISA_MIPS32R6) {
27895 if (rs != 0) {
27896 /* OPC_BEQZC, OPC_BNEZC */
27897 gen_compute_compact_branch(ctx, op, rs, 0,
27898 sextract32(ctx->opcode << 2, 0, 23));
27899 } else {
27900 /* OPC_JIC, OPC_JIALC */
27901 gen_compute_compact_branch(ctx, op, 0, rt, imm);
27902 }
27903 } else {
27904 /* OPC_LWC2, OPC_SWC2 */
27905 /* COP2: Not implemented. */
27906 generate_exception_err(ctx, EXCP_CpU, 2);
27907 }
4ad40f36 27908 break;
bd277fa1 27909 case OPC_CP2:
d75c135e 27910 check_insn(ctx, INSN_LOONGSON2F);
bd277fa1
RH
27911 /* Note that these instructions use different fields. */
27912 gen_loongson_multimedia(ctx, sa, rd, rt);
27913 break;
4ad40f36 27914
7a387fff 27915 case OPC_CP3:
fecd2646 27916 check_insn_opc_removed(ctx, ISA_MIPS32R6);
5ab5c041 27917 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
5e755519 27918 check_cp1_enabled(ctx);
36d23958
TS
27919 op1 = MASK_CP3(ctx->opcode);
27920 switch (op1) {
d9224450
MR
27921 case OPC_LUXC1:
27922 case OPC_SUXC1:
27923 check_insn(ctx, ISA_MIPS5 | ISA_MIPS32R2);
27924 /* Fallthrough */
5a5012ec
TS
27925 case OPC_LWXC1:
27926 case OPC_LDXC1:
5a5012ec
TS
27927 case OPC_SWXC1:
27928 case OPC_SDXC1:
d9224450 27929 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
93b12ccc 27930 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
5a5012ec 27931 break;
e0c84da7 27932 case OPC_PREFX:
d9224450 27933 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
ead9360e 27934 /* Treat as NOP. */
e0c84da7 27935 break;
5a5012ec 27936 case OPC_ALNV_PS:
d9224450
MR
27937 check_insn(ctx, ISA_MIPS5 | ISA_MIPS32R2);
27938 /* Fallthrough */
5a5012ec
TS
27939 case OPC_MADD_S:
27940 case OPC_MADD_D:
27941 case OPC_MADD_PS:
27942 case OPC_MSUB_S:
27943 case OPC_MSUB_D:
27944 case OPC_MSUB_PS:
27945 case OPC_NMADD_S:
27946 case OPC_NMADD_D:
27947 case OPC_NMADD_PS:
27948 case OPC_NMSUB_S:
27949 case OPC_NMSUB_D:
27950 case OPC_NMSUB_PS:
d9224450 27951 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
5a5012ec
TS
27952 gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
27953 break;
36d23958 27954 default:
923617a3 27955 MIPS_INVAL("cp3");
9c708c7f 27956 generate_exception_end(ctx, EXCP_RI);
36d23958
TS
27957 break;
27958 }
27959 } else {
e397ee33 27960 generate_exception_err(ctx, EXCP_CpU, 1);
7a387fff 27961 }
4ad40f36
FB
27962 break;
27963
d26bc211 27964#if defined(TARGET_MIPS64)
7a387fff 27965 /* MIPS64 opcodes */
96631327
FN
27966 case OPC_LLD:
27967 check_insn_opc_user_only(ctx, INSN_R5900);
27968 /* fall through */
c2e19f3c
AM
27969 case OPC_LDL:
27970 case OPC_LDR:
fecd2646 27971 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b6f3b233 27972 /* fall through */
fecd2646 27973 case OPC_LWU:
7a387fff 27974 case OPC_LD:
d75c135e 27975 check_insn(ctx, ISA_MIPS3);
5c13fdfd 27976 check_mips_64(ctx);
d75c135e 27977 gen_ld(ctx, op, rt, rs, imm);
5c13fdfd 27978 break;
c2e19f3c
AM
27979 case OPC_SDL:
27980 case OPC_SDR:
fecd2646 27981 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b6f3b233 27982 /* fall through */
7a387fff 27983 case OPC_SD:
d75c135e 27984 check_insn(ctx, ISA_MIPS3);
e189e748 27985 check_mips_64(ctx);
5c13fdfd 27986 gen_st(ctx, op, rt, rs, imm);
7a387fff 27987 break;
d66c7132 27988 case OPC_SCD:
bf7910c6 27989 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d75c135e 27990 check_insn(ctx, ISA_MIPS3);
96631327 27991 check_insn_opc_user_only(ctx, INSN_R5900);
d66c7132
AJ
27992 check_mips_64(ctx);
27993 gen_st_cond(ctx, op, rt, rs, imm);
27994 break;
31837be3
YK
27995 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC, OPC_DADDI */
27996 if (ctx->insn_flags & ISA_MIPS32R6) {
27997 /* OPC_BNVC, OPC_BNEZALC, OPC_BNEC */
27998 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
27999 } else {
28000 /* OPC_DADDI */
28001 check_insn(ctx, ISA_MIPS3);
28002 check_mips_64(ctx);
28003 gen_arith_imm(ctx, op, rt, rs, imm);
28004 }
28005 break;
324d9e32 28006 case OPC_DADDIU:
d75c135e 28007 check_insn(ctx, ISA_MIPS3);
e189e748 28008 check_mips_64(ctx);
d75c135e 28009 gen_arith_imm(ctx, op, rt, rs, imm);
7a387fff 28010 break;
31837be3
YK
28011#else
28012 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
28013 if (ctx->insn_flags & ISA_MIPS32R6) {
28014 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
28015 } else {
28016 MIPS_INVAL("major opcode");
9c708c7f 28017 generate_exception_end(ctx, EXCP_RI);
31837be3
YK
28018 }
28019 break;
6af0bf9c 28020#endif
d4ea6acd
LA
28021 case OPC_DAUI: /* OPC_JALX */
28022 if (ctx->insn_flags & ISA_MIPS32R6) {
28023#if defined(TARGET_MIPS64)
28024 /* OPC_DAUI */
28025 check_mips_64(ctx);
db77d852
LA
28026 if (rs == 0) {
28027 generate_exception(ctx, EXCP_RI);
28028 } else if (rt != 0) {
d4ea6acd
LA
28029 TCGv t0 = tcg_temp_new();
28030 gen_load_gpr(t0, rs);
28031 tcg_gen_addi_tl(cpu_gpr[rt], t0, imm << 16);
28032 tcg_temp_free(t0);
28033 }
d4ea6acd 28034#else
9c708c7f 28035 generate_exception_end(ctx, EXCP_RI);
d4ea6acd
LA
28036 MIPS_INVAL("major opcode");
28037#endif
28038 } else {
28039 /* OPC_JALX */
28040 check_insn(ctx, ASE_MIPS16 | ASE_MICROMIPS);
28041 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
b231c103 28042 gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
d4ea6acd 28043 }
364d4831 28044 break;
4c789546 28045 case OPC_MSA: /* OPC_MDMX */
f08099ad
FN
28046 if (ctx->insn_flags & INSN_R5900) {
28047 decode_tx79_lq(env, ctx); /* TX79_LQ */
28048 } else {
28049 /* MDMX: Not implemented. */
28050 gen_msa(env, ctx);
28051 }
d4ea6acd
LA
28052 break;
28053 case OPC_PCREL:
28054 check_insn(ctx, ISA_MIPS32R6);
eeb3bba8 28055 gen_pcrel(ctx, ctx->opcode, ctx->base.pc_next, rs);
d4ea6acd 28056 break;
6af0bf9c 28057 default: /* Invalid */
923617a3 28058 MIPS_INVAL("major opcode");
9c708c7f 28059 generate_exception_end(ctx, EXCP_RI);
6af0bf9c
FB
28060 break;
28061 }
6af0bf9c
FB
28062}
28063
18f440ed 28064static void mips_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
6af0bf9c 28065{
18f440ed 28066 DisasContext *ctx = container_of(dcbase, DisasContext, base);
9c489ea6 28067 CPUMIPSState *env = cs->env_ptr;
12be9258 28068
18f440ed 28069 ctx->page_start = ctx->base.pc_first & TARGET_PAGE_MASK;
12be9258
EC
28070 ctx->saved_pc = -1;
28071 ctx->insn_flags = env->insn_flags;
28072 ctx->CP0_Config1 = env->CP0_Config1;
49735f76 28073 ctx->CP0_Config2 = env->CP0_Config2;
ab77fc61
DN
28074 ctx->CP0_Config3 = env->CP0_Config3;
28075 ctx->CP0_Config5 = env->CP0_Config5;
12be9258
EC
28076 ctx->btarget = 0;
28077 ctx->kscrexist = (env->CP0_Config4 >> CP0C4_KScrExist) & 0xff;
28078 ctx->rxi = (env->CP0_Config3 >> CP0C3_RXI) & 1;
28079 ctx->ie = (env->CP0_Config4 >> CP0C4_IE) & 3;
28080 ctx->bi = (env->CP0_Config3 >> CP0C3_BI) & 1;
28081 ctx->bp = (env->CP0_Config3 >> CP0C3_BP) & 1;
28082 ctx->PAMask = env->PAMask;
28083 ctx->mvh = (env->CP0_Config5 >> CP0C5_MVH) & 1;
28084 ctx->eva = (env->CP0_Config5 >> CP0C5_EVA) & 1;
28085 ctx->sc = (env->CP0_Config3 >> CP0C3_SC) & 1;
28086 ctx->CP0_LLAddr_shift = env->CP0_LLAddr_shift;
28087 ctx->cmgcr = (env->CP0_Config3 >> CP0C3_CMGCR) & 1;
4ad40f36 28088 /* Restore delay slot state from the tb context. */
12be9258
EC
28089 ctx->hflags = (uint32_t)ctx->base.tb->flags; /* FIXME: maybe use 64 bits? */
28090 ctx->ulri = (env->CP0_Config3 >> CP0C3_ULRI) & 1;
28091 ctx->ps = ((env->active_fpu.fcr0 >> FCR0_PS) & 1) ||
e29c9628 28092 (env->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F));
12be9258
EC
28093 ctx->vp = (env->CP0_Config5 >> CP0C5_VP) & 1;
28094 ctx->mrp = (env->CP0_Config5 >> CP0C5_MRP) & 1;
28095 ctx->nan2008 = (env->active_fpu.fcr31 >> FCR31_NAN2008) & 1;
28096 ctx->abs2008 = (env->active_fpu.fcr31 >> FCR31_ABS2008) & 1;
28097 restore_cpu_state(env, ctx);
932e71cd 28098#ifdef CONFIG_USER_ONLY
12be9258 28099 ctx->mem_idx = MIPS_HFLAG_UM;
932e71cd 28100#else
12be9258 28101 ctx->mem_idx = hflags_mmu_index(ctx->hflags);
932e71cd 28102#endif
12be9258
EC
28103 ctx->default_tcg_memop_mask = (ctx->insn_flags & ISA_MIPS32R6) ?
28104 MO_UNALN : MO_ALIGN;
190ce7fb 28105
18f440ed
EC
28106 LOG_DISAS("\ntb %p idx %d hflags %04x\n", ctx->base.tb, ctx->mem_idx,
28107 ctx->hflags);
28108}
12be9258 28109
18f440ed
EC
28110static void mips_tr_tb_start(DisasContextBase *dcbase, CPUState *cs)
28111{
28112}
b933066a 28113
18f440ed
EC
28114static void mips_tr_insn_start(DisasContextBase *dcbase, CPUState *cs)
28115{
28116 DisasContext *ctx = container_of(dcbase, DisasContext, base);
c9602061 28117
18f440ed
EC
28118 tcg_gen_insn_start(ctx->base.pc_next, ctx->hflags & MIPS_HFLAG_BMASK,
28119 ctx->btarget);
28120}
31837be3 28121
18f440ed
EC
28122static bool mips_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cs,
28123 const CPUBreakpoint *bp)
28124{
28125 DisasContext *ctx = container_of(dcbase, DisasContext, base);
c9602061 28126
18f440ed
EC
28127 save_cpu_state(ctx, 1);
28128 ctx->base.is_jmp = DISAS_NORETURN;
28129 gen_helper_raise_exception_debug(cpu_env);
28130 /* The address covered by the breakpoint must be included in
28131 [tb->pc, tb->pc + tb->size) in order to for it to be
28132 properly cleared -- thus we increment the PC here so that
28133 the logic setting tb->size below does the right thing. */
28134 ctx->base.pc_next += 4;
28135 return true;
28136}
4ad40f36 28137
18f440ed
EC
28138static void mips_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
28139{
28140 CPUMIPSState *env = cs->env_ptr;
28141 DisasContext *ctx = container_of(dcbase, DisasContext, base);
28142 int insn_bytes;
28143 int is_slot;
4ad40f36 28144
18f440ed 28145 is_slot = ctx->hflags & MIPS_HFLAG_BMASK;
c533c0f4
AM
28146 if (ctx->insn_flags & ISA_NANOMIPS32) {
28147 ctx->opcode = cpu_lduw_code(env, ctx->base.pc_next);
28148 insn_bytes = decode_nanomips_opc(env, ctx);
28149 } else if (!(ctx->hflags & MIPS_HFLAG_M16)) {
18f440ed
EC
28150 ctx->opcode = cpu_ldl_code(env, ctx->base.pc_next);
28151 insn_bytes = 4;
28152 decode_opc(env, ctx);
28153 } else if (ctx->insn_flags & ASE_MICROMIPS) {
28154 ctx->opcode = cpu_lduw_code(env, ctx->base.pc_next);
28155 insn_bytes = decode_micromips_opc(env, ctx);
28156 } else if (ctx->insn_flags & ASE_MIPS16) {
28157 ctx->opcode = cpu_lduw_code(env, ctx->base.pc_next);
28158 insn_bytes = decode_mips16_opc(env, ctx);
28159 } else {
28160 generate_exception_end(ctx, EXCP_RI);
28161 g_assert(ctx->base.is_jmp == DISAS_NORETURN);
28162 return;
28163 }
faf7aaa9 28164
18f440ed
EC
28165 if (ctx->hflags & MIPS_HFLAG_BMASK) {
28166 if (!(ctx->hflags & (MIPS_HFLAG_BDS16 | MIPS_HFLAG_BDS32 |
28167 MIPS_HFLAG_FBNSLOT))) {
28168 /* force to generate branch as there is neither delay nor
28169 forbidden slot */
28170 is_slot = 1;
28171 }
28172 if ((ctx->hflags & MIPS_HFLAG_M16) &&
28173 (ctx->hflags & MIPS_HFLAG_FBNSLOT)) {
28174 /* Force to generate branch as microMIPS R6 doesn't restrict
28175 branches in the forbidden slot. */
28176 is_slot = 1;
eeb3bba8 28177 }
18f440ed
EC
28178 }
28179 if (is_slot) {
28180 gen_branch(ctx, insn_bytes);
28181 }
28182 ctx->base.pc_next += insn_bytes;
1b530a6d 28183
18f440ed
EC
28184 if (ctx->base.is_jmp != DISAS_NEXT) {
28185 return;
6af0bf9c 28186 }
18f440ed
EC
28187 /* Execute a branch and its delay slot as a single instruction.
28188 This is what GDB expects and is consistent with what the
28189 hardware does (e.g. if a delay slot instruction faults, the
28190 reported PC is the PC of the branch). */
28191 if (ctx->base.singlestep_enabled &&
28192 (ctx->hflags & MIPS_HFLAG_BMASK) == 0) {
28193 ctx->base.is_jmp = DISAS_TOO_MANY;
28194 }
28195 if (ctx->base.pc_next - ctx->page_start >= TARGET_PAGE_SIZE) {
28196 ctx->base.is_jmp = DISAS_TOO_MANY;
ed2803da 28197 }
18f440ed
EC
28198}
28199
28200static void mips_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
28201{
28202 DisasContext *ctx = container_of(dcbase, DisasContext, base);
28203
12be9258
EC
28204 if (ctx->base.singlestep_enabled && ctx->base.is_jmp != DISAS_NORETURN) {
28205 save_cpu_state(ctx, ctx->base.is_jmp != DISAS_EXIT);
9c708c7f 28206 gen_helper_raise_exception_debug(cpu_env);
16c00cb2 28207 } else {
12be9258 28208 switch (ctx->base.is_jmp) {
b28425ba 28209 case DISAS_STOP:
12be9258 28210 gen_save_pc(ctx->base.pc_next);
cd314a7d 28211 tcg_gen_lookup_and_goto_ptr();
df1561e2 28212 break;
b28425ba 28213 case DISAS_NEXT:
18f440ed 28214 case DISAS_TOO_MANY:
12be9258
EC
28215 save_cpu_state(ctx, 0);
28216 gen_goto_tb(ctx, 0, ctx->base.pc_next);
16c00cb2 28217 break;
b28425ba 28218 case DISAS_EXIT:
07ea28b4 28219 tcg_gen_exit_tb(NULL, 0);
16c00cb2 28220 break;
b28425ba 28221 case DISAS_NORETURN:
5a5012ec 28222 break;
18f440ed
EC
28223 default:
28224 g_assert_not_reached();
6958549d 28225 }
6af0bf9c 28226 }
18f440ed
EC
28227}
28228
28229static void mips_tr_disas_log(const DisasContextBase *dcbase, CPUState *cs)
28230{
28231 qemu_log("IN: %s\n", lookup_symbol(dcbase->pc_first));
28232 log_target_disas(cs, dcbase->pc_first, dcbase->tb->size);
28233}
28234
28235static const TranslatorOps mips_tr_ops = {
28236 .init_disas_context = mips_tr_init_disas_context,
28237 .tb_start = mips_tr_tb_start,
28238 .insn_start = mips_tr_insn_start,
28239 .breakpoint_check = mips_tr_breakpoint_check,
28240 .translate_insn = mips_tr_translate_insn,
28241 .tb_stop = mips_tr_tb_stop,
28242 .disas_log = mips_tr_disas_log,
28243};
28244
28245void gen_intermediate_code(CPUState *cs, struct TranslationBlock *tb)
28246{
28247 DisasContext ctx;
28248
28249 translator_loop(&mips_tr_ops, &ctx.base, cs, tb);
6af0bf9c
FB
28250}
28251
7db13fae 28252static void fpu_dump_state(CPUMIPSState *env, FILE *f, fprintf_function fpu_fprintf,
8706c382 28253 int flags)
6ea83fed
FB
28254{
28255 int i;
5e755519 28256 int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
5a5012ec 28257
2a5612e6
SW
28258#define printfpr(fp) \
28259 do { \
28260 if (is_fpu64) \
28261 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
28262 " fd:%13g fs:%13g psu: %13g\n", \
28263 (fp)->w[FP_ENDIAN_IDX], (fp)->d, \
28264 (double)(fp)->fd, \
28265 (double)(fp)->fs[FP_ENDIAN_IDX], \
28266 (double)(fp)->fs[!FP_ENDIAN_IDX]); \
28267 else { \
28268 fpr_t tmp; \
28269 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
28270 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
28271 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
28272 " fd:%13g fs:%13g psu:%13g\n", \
28273 tmp.w[FP_ENDIAN_IDX], tmp.d, \
28274 (double)tmp.fd, \
28275 (double)tmp.fs[FP_ENDIAN_IDX], \
28276 (double)tmp.fs[!FP_ENDIAN_IDX]); \
28277 } \
6ea83fed
FB
28278 } while(0)
28279
5a5012ec 28280
9a78eead
SW
28281 fpu_fprintf(f, "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%02x\n",
28282 env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64,
f01be154 28283 get_float_exception_flags(&env->active_fpu.fp_status));
5a5012ec
TS
28284 for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
28285 fpu_fprintf(f, "%3s: ", fregnames[i]);
f01be154 28286 printfpr(&env->active_fpu.fpr[i]);
6ea83fed
FB
28287 }
28288
28289#undef printfpr
28290}
28291
878096ee
AF
28292void mips_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
28293 int flags)
6af0bf9c 28294{
878096ee
AF
28295 MIPSCPU *cpu = MIPS_CPU(cs);
28296 CPUMIPSState *env = &cpu->env;
6af0bf9c 28297 int i;
3b46e624 28298
a7200c9f
SW
28299 cpu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
28300 " LO=0x" TARGET_FMT_lx " ds %04x "
28301 TARGET_FMT_lx " " TARGET_FMT_ld "\n",
3d5be870
TS
28302 env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
28303 env->hflags, env->btarget, env->bcond);
6af0bf9c
FB
28304 for (i = 0; i < 32; i++) {
28305 if ((i & 3) == 0)
28306 cpu_fprintf(f, "GPR%02d:", i);
b5dc7732 28307 cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
6af0bf9c
FB
28308 if ((i & 3) == 3)
28309 cpu_fprintf(f, "\n");
28310 }
568b600d 28311
3594c774 28312 cpu_fprintf(f, "CP0 Status 0x%08x Cause 0x%08x EPC 0x" TARGET_FMT_lx "\n",
5e755519 28313 env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
284b731a
LA
28314 cpu_fprintf(f, " Config0 0x%08x Config1 0x%08x LLAddr 0x%016"
28315 PRIx64 "\n",
5499b6ff 28316 env->CP0_Config0, env->CP0_Config1, env->lladdr);
27e1fb13
MR
28317 cpu_fprintf(f, " Config2 0x%08x Config3 0x%08x\n",
28318 env->CP0_Config2, env->CP0_Config3);
28319 cpu_fprintf(f, " Config4 0x%08x Config5 0x%08x\n",
28320 env->CP0_Config4, env->CP0_Config5);
1cc5af69 28321 if ((flags & CPU_DUMP_FPU) && (env->hflags & MIPS_HFLAG_FPU)) {
7a387fff 28322 fpu_dump_state(env, f, cpu_fprintf, flags);
1cc5af69 28323 }
6af0bf9c
FB
28324}
28325
78ce64f4 28326void mips_tcg_init(void)
39454628 28327{
f01be154 28328 int i;
39454628 28329
f764718d 28330 cpu_gpr[0] = NULL;
bb928dbe 28331 for (i = 1; i < 32; i++)
e1ccc054 28332 cpu_gpr[i] = tcg_global_mem_new(cpu_env,
7db13fae 28333 offsetof(CPUMIPSState, active_tc.gpr[i]),
4b2eb8d2 28334 regnames[i]);
d73ee8a2 28335
863f264d
YK
28336 for (i = 0; i < 32; i++) {
28337 int off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[0]);
28338 msa_wr_d[i * 2] =
e1ccc054 28339 tcg_global_mem_new_i64(cpu_env, off, msaregnames[i * 2]);
cb269f27
YK
28340 /* The scalar floating-point unit (FPU) registers are mapped on
28341 * the MSA vector registers. */
28342 fpu_f64[i] = msa_wr_d[i * 2];
863f264d
YK
28343 off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[1]);
28344 msa_wr_d[i * 2 + 1] =
e1ccc054 28345 tcg_global_mem_new_i64(cpu_env, off, msaregnames[i * 2 + 1]);
863f264d
YK
28346 }
28347
e1ccc054 28348 cpu_PC = tcg_global_mem_new(cpu_env,
7db13fae 28349 offsetof(CPUMIPSState, active_tc.PC), "PC");
4b2eb8d2 28350 for (i = 0; i < MIPS_DSP_ACC; i++) {
e1ccc054 28351 cpu_HI[i] = tcg_global_mem_new(cpu_env,
7db13fae 28352 offsetof(CPUMIPSState, active_tc.HI[i]),
4b2eb8d2 28353 regnames_HI[i]);
e1ccc054 28354 cpu_LO[i] = tcg_global_mem_new(cpu_env,
7db13fae 28355 offsetof(CPUMIPSState, active_tc.LO[i]),
4b2eb8d2 28356 regnames_LO[i]);
4b2eb8d2 28357 }
e1ccc054 28358 cpu_dspctrl = tcg_global_mem_new(cpu_env,
7db13fae 28359 offsetof(CPUMIPSState, active_tc.DSPControl),
4b2eb8d2 28360 "DSPControl");
e1ccc054 28361 bcond = tcg_global_mem_new(cpu_env,
7db13fae 28362 offsetof(CPUMIPSState, bcond), "bcond");
e1ccc054 28363 btarget = tcg_global_mem_new(cpu_env,
7db13fae 28364 offsetof(CPUMIPSState, btarget), "btarget");
e1ccc054 28365 hflags = tcg_global_mem_new_i32(cpu_env,
7db13fae 28366 offsetof(CPUMIPSState, hflags), "hflags");
41db4607 28367
e1ccc054 28368 fpu_fcr0 = tcg_global_mem_new_i32(cpu_env,
7db13fae 28369 offsetof(CPUMIPSState, active_fpu.fcr0),
a7812ae4 28370 "fcr0");
e1ccc054 28371 fpu_fcr31 = tcg_global_mem_new_i32(cpu_env,
7db13fae 28372 offsetof(CPUMIPSState, active_fpu.fcr31),
a7812ae4 28373 "fcr31");
eb5559f6
CJ
28374
28375 for (i = 0; i < NUMBER_OF_MXU_REGISTERS - 1; i++) {
28376 mxu_gpr[i] = tcg_global_mem_new(cpu_env,
28377 offsetof(CPUMIPSState,
28378 active_tc.mxu_gpr[i]),
28379 mxuregnames[i]);
28380 }
28381
28382 mxu_CR = tcg_global_mem_new(cpu_env,
28383 offsetof(CPUMIPSState, active_tc.mxu_cr),
28384 mxuregnames[NUMBER_OF_MXU_REGISTERS - 1]);
39454628
TS
28385}
28386
5b27a92d 28387#include "translate_init.inc.c"
aaed909a 28388
27e38392
PMD
28389void cpu_mips_realize_env(CPUMIPSState *env)
28390{
28391 env->exception_base = (int32_t)0xBFC00000;
28392
28393#ifndef CONFIG_USER_ONLY
28394 mmu_init(env, env->cpu_model);
28395#endif
28396 fpu_init(env, env->cpu_model);
28397 mvp_init(env, env->cpu_model);
28398}
28399
a7519f2b 28400bool cpu_supports_cps_smp(const char *cpu_type)
bff384a4 28401{
a7519f2b
IM
28402 const MIPSCPUClass *mcc = MIPS_CPU_CLASS(object_class_by_name(cpu_type));
28403 return (mcc->cpu_def->CP0_Config3 & (1 << CP0C3_CMGCR)) != 0;
bff384a4
LA
28404}
28405
a7519f2b 28406bool cpu_supports_isa(const char *cpu_type, unsigned int isa)
bed9e5ce 28407{
a7519f2b
IM
28408 const MIPSCPUClass *mcc = MIPS_CPU_CLASS(object_class_by_name(cpu_type));
28409 return (mcc->cpu_def->insn_flags & isa) != 0;
bed9e5ce
PB
28410}
28411
89777fd1
LA
28412void cpu_set_exception_base(int vp_index, target_ulong address)
28413{
28414 MIPSCPU *vp = MIPS_CPU(qemu_get_cpu(vp_index));
28415 vp->env.exception_base = address;
28416}
28417
1bba0dc9 28418void cpu_state_reset(CPUMIPSState *env)
6ae81775 28419{
55e5c285
AF
28420 MIPSCPU *cpu = mips_env_get_cpu(env);
28421 CPUState *cs = CPU(cpu);
6ae81775 28422
51cc2e78
BS
28423 /* Reset registers to their default values */
28424 env->CP0_PRid = env->cpu_model->CP0_PRid;
28425 env->CP0_Config0 = env->cpu_model->CP0_Config0;
28426#ifdef TARGET_WORDS_BIGENDIAN
28427 env->CP0_Config0 |= (1 << CP0C0_BE);
28428#endif
28429 env->CP0_Config1 = env->cpu_model->CP0_Config1;
28430 env->CP0_Config2 = env->cpu_model->CP0_Config2;
28431 env->CP0_Config3 = env->cpu_model->CP0_Config3;
b4160af1
PJ
28432 env->CP0_Config4 = env->cpu_model->CP0_Config4;
28433 env->CP0_Config4_rw_bitmask = env->cpu_model->CP0_Config4_rw_bitmask;
b4dd99a3
PJ
28434 env->CP0_Config5 = env->cpu_model->CP0_Config5;
28435 env->CP0_Config5_rw_bitmask = env->cpu_model->CP0_Config5_rw_bitmask;
51cc2e78
BS
28436 env->CP0_Config6 = env->cpu_model->CP0_Config6;
28437 env->CP0_Config7 = env->cpu_model->CP0_Config7;
2a6e32dd
AJ
28438 env->CP0_LLAddr_rw_bitmask = env->cpu_model->CP0_LLAddr_rw_bitmask
28439 << env->cpu_model->CP0_LLAddr_shift;
28440 env->CP0_LLAddr_shift = env->cpu_model->CP0_LLAddr_shift;
51cc2e78
BS
28441 env->SYNCI_Step = env->cpu_model->SYNCI_Step;
28442 env->CCRes = env->cpu_model->CCRes;
28443 env->CP0_Status_rw_bitmask = env->cpu_model->CP0_Status_rw_bitmask;
28444 env->CP0_TCStatus_rw_bitmask = env->cpu_model->CP0_TCStatus_rw_bitmask;
28445 env->CP0_SRSCtl = env->cpu_model->CP0_SRSCtl;
28446 env->current_tc = 0;
28447 env->SEGBITS = env->cpu_model->SEGBITS;
28448 env->SEGMask = (target_ulong)((1ULL << env->cpu_model->SEGBITS) - 1);
28449#if defined(TARGET_MIPS64)
28450 if (env->cpu_model->insn_flags & ISA_MIPS3) {
28451 env->SEGMask |= 3ULL << 62;
28452 }
28453#endif
28454 env->PABITS = env->cpu_model->PABITS;
51cc2e78
BS
28455 env->CP0_SRSConf0_rw_bitmask = env->cpu_model->CP0_SRSConf0_rw_bitmask;
28456 env->CP0_SRSConf0 = env->cpu_model->CP0_SRSConf0;
28457 env->CP0_SRSConf1_rw_bitmask = env->cpu_model->CP0_SRSConf1_rw_bitmask;
28458 env->CP0_SRSConf1 = env->cpu_model->CP0_SRSConf1;
28459 env->CP0_SRSConf2_rw_bitmask = env->cpu_model->CP0_SRSConf2_rw_bitmask;
28460 env->CP0_SRSConf2 = env->cpu_model->CP0_SRSConf2;
28461 env->CP0_SRSConf3_rw_bitmask = env->cpu_model->CP0_SRSConf3_rw_bitmask;
28462 env->CP0_SRSConf3 = env->cpu_model->CP0_SRSConf3;
28463 env->CP0_SRSConf4_rw_bitmask = env->cpu_model->CP0_SRSConf4_rw_bitmask;
28464 env->CP0_SRSConf4 = env->cpu_model->CP0_SRSConf4;
7207c7f9
LA
28465 env->CP0_PageGrain_rw_bitmask = env->cpu_model->CP0_PageGrain_rw_bitmask;
28466 env->CP0_PageGrain = env->cpu_model->CP0_PageGrain;
74dbf824 28467 env->CP0_EBaseWG_rw_bitmask = env->cpu_model->CP0_EBaseWG_rw_bitmask;
f1cb0951 28468 env->active_fpu.fcr0 = env->cpu_model->CP1_fcr0;
599bc5e8 28469 env->active_fpu.fcr31_rw_bitmask = env->cpu_model->CP1_fcr31_rw_bitmask;
ba5c79f2 28470 env->active_fpu.fcr31 = env->cpu_model->CP1_fcr31;
863f264d 28471 env->msair = env->cpu_model->MSAIR;
51cc2e78
BS
28472 env->insn_flags = env->cpu_model->insn_flags;
28473
0eaef5aa 28474#if defined(CONFIG_USER_ONLY)
03e6e501 28475 env->CP0_Status = (MIPS_HFLAG_UM << CP0St_KSU);
68473f15
RH
28476# ifdef TARGET_MIPS64
28477 /* Enable 64-bit register mode. */
28478 env->CP0_Status |= (1 << CP0St_PX);
28479# endif
28480# ifdef TARGET_ABI_MIPSN64
28481 /* Enable 64-bit address mode. */
28482 env->CP0_Status |= (1 << CP0St_UX);
28483# endif
94159135
MI
28484 /* Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
28485 hardware registers. */
28486 env->CP0_HWREna |= 0x0000000F;
91a75935 28487 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
03e6e501 28488 env->CP0_Status |= (1 << CP0St_CU1);
91a75935 28489 }
6f0af304
PJ
28490 if (env->CP0_Config3 & (1 << CP0C3_DSPP)) {
28491 env->CP0_Status |= (1 << CP0St_MX);
853c3240 28492 }
4d66261f
PJ
28493# if defined(TARGET_MIPS64)
28494 /* For MIPS64, init FR bit to 1 if FPU unit is there and bit is writable. */
28495 if ((env->CP0_Config1 & (1 << CP0C1_FP)) &&
28496 (env->CP0_Status_rw_bitmask & (1 << CP0St_FR))) {
68473f15
RH
28497 env->CP0_Status |= (1 << CP0St_FR);
28498 }
4d66261f 28499# endif
932e71cd
AJ
28500#else
28501 if (env->hflags & MIPS_HFLAG_BMASK) {
28502 /* If the exception was raised from a delay slot,
28503 come back to the jump. */
c3577479
MR
28504 env->CP0_ErrorEPC = (env->active_tc.PC
28505 - (env->hflags & MIPS_HFLAG_B16 ? 2 : 4));
aa328add 28506 } else {
932e71cd
AJ
28507 env->CP0_ErrorEPC = env->active_tc.PC;
28508 }
89777fd1 28509 env->active_tc.PC = env->exception_base;
51cc2e78
BS
28510 env->CP0_Random = env->tlb->nb_tlb - 1;
28511 env->tlb->tlb_in_use = env->tlb->nb_tlb;
932e71cd 28512 env->CP0_Wired = 0;
01bc435b 28513 env->CP0_GlobalNumber = (cs->cpu_index & 0xFF) << CP0GN_VPId;
0a2672b7 28514 env->CP0_EBase = (cs->cpu_index & 0x3FF);
d3d93c6c 28515 if (mips_um_ksegs_enabled()) {
0a2672b7
JH
28516 env->CP0_EBase |= 0x40000000;
28517 } else {
74dbf824 28518 env->CP0_EBase |= (int32_t)0x80000000;
0a2672b7 28519 }
c870e3f5
YK
28520 if (env->CP0_Config3 & (1 << CP0C3_CMGCR)) {
28521 env->CP0_CMGCRBase = 0x1fbf8000 >> 4;
28522 }
a0c80608
PB
28523 env->CP0_EntryHi_ASID_mask = (env->CP0_Config4 & (1 << CP0C4_AE)) ?
28524 0x3ff : 0xff;
932e71cd
AJ
28525 env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
28526 /* vectored interrupts not implemented, timer on int 7,
28527 no performance counters. */
28528 env->CP0_IntCtl = 0xe0000000;
28529 {
28530 int i;
28531
28532 for (i = 0; i < 7; i++) {
28533 env->CP0_WatchLo[i] = 0;
28534 env->CP0_WatchHi[i] = 0x80000000;
fd88b6ab 28535 }
932e71cd
AJ
28536 env->CP0_WatchLo[7] = 0;
28537 env->CP0_WatchHi[7] = 0;
fd88b6ab 28538 }
932e71cd
AJ
28539 /* Count register increments in debug mode, EJTAG version 1 */
28540 env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
9e56e756 28541
4b69c7e2
JH
28542 cpu_mips_store_count(env, 1);
28543
9e56e756
EI
28544 if (env->CP0_Config3 & (1 << CP0C3_MT)) {
28545 int i;
28546
28547 /* Only TC0 on VPE 0 starts as active. */
28548 for (i = 0; i < ARRAY_SIZE(env->tcs); i++) {
55e5c285 28549 env->tcs[i].CP0_TCBind = cs->cpu_index << CP0TCBd_CurVPE;
9e56e756
EI
28550 env->tcs[i].CP0_TCHalt = 1;
28551 }
28552 env->active_tc.CP0_TCHalt = 1;
259186a7 28553 cs->halted = 1;
9e56e756 28554
55e5c285 28555 if (cs->cpu_index == 0) {
9e56e756
EI
28556 /* VPE0 starts up enabled. */
28557 env->mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
28558 env->CP0_VPEConf0 |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
28559
28560 /* TC0 starts up unhalted. */
259186a7 28561 cs->halted = 0;
9e56e756
EI
28562 env->active_tc.CP0_TCHalt = 0;
28563 env->tcs[0].CP0_TCHalt = 0;
28564 /* With thread 0 active. */
28565 env->active_tc.CP0_TCStatus = (1 << CP0TCSt_A);
28566 env->tcs[0].CP0_TCStatus = (1 << CP0TCSt_A);
28567 }
28568 }
cec56a73
JH
28569
28570 /*
28571 * Configure default legacy segmentation control. We use this regardless of
28572 * whether segmentation control is presented to the guest.
28573 */
28574 /* KSeg3 (seg0 0xE0000000..0xFFFFFFFF) */
28575 env->CP0_SegCtl0 = (CP0SC_AM_MK << CP0SC_AM);
28576 /* KSeg2 (seg1 0xC0000000..0xDFFFFFFF) */
28577 env->CP0_SegCtl0 |= ((CP0SC_AM_MSK << CP0SC_AM)) << 16;
28578 /* KSeg1 (seg2 0xA0000000..0x9FFFFFFF) */
28579 env->CP0_SegCtl1 = (0 << CP0SC_PA) | (CP0SC_AM_UK << CP0SC_AM) |
28580 (2 << CP0SC_C);
28581 /* KSeg0 (seg3 0x80000000..0x9FFFFFFF) */
28582 env->CP0_SegCtl1 |= ((0 << CP0SC_PA) | (CP0SC_AM_UK << CP0SC_AM) |
28583 (3 << CP0SC_C)) << 16;
28584 /* USeg (seg4 0x40000000..0x7FFFFFFF) */
28585 env->CP0_SegCtl2 = (2 << CP0SC_PA) | (CP0SC_AM_MUSK << CP0SC_AM) |
28586 (1 << CP0SC_EU) | (2 << CP0SC_C);
28587 /* USeg (seg5 0x00000000..0x3FFFFFFF) */
28588 env->CP0_SegCtl2 |= ((0 << CP0SC_PA) | (CP0SC_AM_MUSK << CP0SC_AM) |
28589 (1 << CP0SC_EU) | (2 << CP0SC_C)) << 16;
28590 /* XKPhys (note, SegCtl2.XR = 0, so XAM won't be used) */
28591 env->CP0_SegCtl1 |= (CP0SC_AM_UK << CP0SC1_XAM);
51cc2e78 28592#endif
ddc584bd
LA
28593 if ((env->insn_flags & ISA_MIPS32R6) &&
28594 (env->active_fpu.fcr0 & (1 << FCR0_F64))) {
28595 /* Status.FR = 0 mode in 64-bit FPU not allowed in R6 */
28596 env->CP0_Status |= (1 << CP0St_FR);
28597 }
28598
63010795
YK
28599 if (env->insn_flags & ISA_MIPS32R6) {
28600 /* PTW = 1 */
28601 env->CP0_PWSize = 0x40;
28602 /* GDI = 12 */
28603 /* UDI = 12 */
28604 /* MDI = 12 */
28605 /* PRI = 12 */
28606 /* PTEI = 2 */
28607 env->CP0_PWField = 0x0C30C302;
28608 } else {
28609 /* GDI = 0 */
28610 /* UDI = 0 */
28611 /* MDI = 0 */
28612 /* PRI = 0 */
28613 /* PTEI = 2 */
28614 env->CP0_PWField = 0x02;
28615 }
28616
0bbc0396
SM
28617 if (env->CP0_Config3 & (1 << CP0C3_ISA) & (1 << (CP0C3_ISA + 1))) {
28618 /* microMIPS on reset when Config3.ISA is 3 */
0305d194
YK
28619 env->hflags |= MIPS_HFLAG_M16;
28620 }
28621
863f264d
YK
28622 /* MSA */
28623 if (env->CP0_Config3 & (1 << CP0C3_MSAP)) {
28624 msa_reset(env);
28625 }
28626
03e6e501 28627 compute_hflags(env);
599bc5e8 28628 restore_fp_status(env);
e117f526 28629 restore_pamask(env);
27103424 28630 cs->exception_index = EXCP_NONE;
3b3c1694
LA
28631
28632 if (semihosting_get_argc()) {
28633 /* UHI interface can be used to obtain argc and argv */
28634 env->active_tc.gpr[4] = -1;
28635 }
6af0bf9c 28636}
d2856f1a 28637
bad729e2
RH
28638void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb,
28639 target_ulong *data)
d2856f1a 28640{
bad729e2 28641 env->active_tc.PC = data[0];
d2856f1a 28642 env->hflags &= ~MIPS_HFLAG_BMASK;
bad729e2 28643 env->hflags |= data[1];
4636401d
AJ
28644 switch (env->hflags & MIPS_HFLAG_BMASK_BASE) {
28645 case MIPS_HFLAG_BR:
28646 break;
28647 case MIPS_HFLAG_BC:
28648 case MIPS_HFLAG_BL:
28649 case MIPS_HFLAG_B:
bad729e2 28650 env->btarget = data[2];
4636401d
AJ
28651 break;
28652 }
d2856f1a 28653}
This page took 6.176444 seconds and 4 git commands to generate.