]> Git Repo - qemu.git/blame - target/mips/translate.c
target/mips: Add emulation of nanoMIPS 16-bit branch instructions
[qemu.git] / target / mips / translate.c
CommitLineData
6af0bf9c
FB
1/*
2 * MIPS32 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,
466 OPC_ALIGN = (0x08 << 6) | OPC_BSHFL, /* 010.bp */
467 OPC_ALIGN_END = (0x0B << 6) | OPC_BSHFL, /* 010.00 to 010.11 */
468 OPC_BITSWAP = (0x00 << 6) | OPC_BSHFL /* 00000 */
e37e863f
FB
469};
470
7a387fff
TS
471/* DBSHFL opcodes */
472#define MASK_DBSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
473
e37e863f 474enum {
15eacb9b
YK
475 OPC_DSBH = (0x02 << 6) | OPC_DBSHFL,
476 OPC_DSHD = (0x05 << 6) | OPC_DBSHFL,
477 OPC_DALIGN = (0x08 << 6) | OPC_DBSHFL, /* 01.bp */
478 OPC_DALIGN_END = (0x0F << 6) | OPC_DBSHFL, /* 01.000 to 01.111 */
479 OPC_DBITSWAP = (0x00 << 6) | OPC_DBSHFL, /* 00000 */
e37e863f
FB
480};
481
e45a93e2
JL
482/* MIPS DSP REGIMM opcodes */
483enum {
484 OPC_BPOSGE32 = (0x1C << 16) | OPC_REGIMM,
e45a93e2 485 OPC_BPOSGE64 = (0x1D << 16) | OPC_REGIMM,
e45a93e2
JL
486};
487
9b1a1d68
JL
488#define MASK_LX(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
489/* MIPS DSP Load */
490enum {
491 OPC_LBUX = (0x06 << 6) | OPC_LX_DSP,
492 OPC_LHX = (0x04 << 6) | OPC_LX_DSP,
493 OPC_LWX = (0x00 << 6) | OPC_LX_DSP,
9b1a1d68 494 OPC_LDX = (0x08 << 6) | OPC_LX_DSP,
9b1a1d68
JL
495};
496
461c08df
JL
497#define MASK_ADDU_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
498enum {
499 /* MIPS DSP Arithmetic Sub-class */
500 OPC_ADDQ_PH = (0x0A << 6) | OPC_ADDU_QB_DSP,
501 OPC_ADDQ_S_PH = (0x0E << 6) | OPC_ADDU_QB_DSP,
502 OPC_ADDQ_S_W = (0x16 << 6) | OPC_ADDU_QB_DSP,
503 OPC_ADDU_QB = (0x00 << 6) | OPC_ADDU_QB_DSP,
504 OPC_ADDU_S_QB = (0x04 << 6) | OPC_ADDU_QB_DSP,
505 OPC_ADDU_PH = (0x08 << 6) | OPC_ADDU_QB_DSP,
506 OPC_ADDU_S_PH = (0x0C << 6) | OPC_ADDU_QB_DSP,
507 OPC_SUBQ_PH = (0x0B << 6) | OPC_ADDU_QB_DSP,
508 OPC_SUBQ_S_PH = (0x0F << 6) | OPC_ADDU_QB_DSP,
509 OPC_SUBQ_S_W = (0x17 << 6) | OPC_ADDU_QB_DSP,
510 OPC_SUBU_QB = (0x01 << 6) | OPC_ADDU_QB_DSP,
511 OPC_SUBU_S_QB = (0x05 << 6) | OPC_ADDU_QB_DSP,
512 OPC_SUBU_PH = (0x09 << 6) | OPC_ADDU_QB_DSP,
513 OPC_SUBU_S_PH = (0x0D << 6) | OPC_ADDU_QB_DSP,
514 OPC_ADDSC = (0x10 << 6) | OPC_ADDU_QB_DSP,
515 OPC_ADDWC = (0x11 << 6) | OPC_ADDU_QB_DSP,
516 OPC_MODSUB = (0x12 << 6) | OPC_ADDU_QB_DSP,
517 OPC_RADDU_W_QB = (0x14 << 6) | OPC_ADDU_QB_DSP,
a22260ae
JL
518 /* MIPS DSP Multiply Sub-class insns */
519 OPC_MULEU_S_PH_QBL = (0x06 << 6) | OPC_ADDU_QB_DSP,
520 OPC_MULEU_S_PH_QBR = (0x07 << 6) | OPC_ADDU_QB_DSP,
521 OPC_MULQ_RS_PH = (0x1F << 6) | OPC_ADDU_QB_DSP,
522 OPC_MULEQ_S_W_PHL = (0x1C << 6) | OPC_ADDU_QB_DSP,
523 OPC_MULEQ_S_W_PHR = (0x1D << 6) | OPC_ADDU_QB_DSP,
524 OPC_MULQ_S_PH = (0x1E << 6) | OPC_ADDU_QB_DSP,
461c08df
JL
525};
526
527#define OPC_ADDUH_QB_DSP OPC_MULT_G_2E
528#define MASK_ADDUH_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
529enum {
530 /* MIPS DSP Arithmetic Sub-class */
531 OPC_ADDUH_QB = (0x00 << 6) | OPC_ADDUH_QB_DSP,
532 OPC_ADDUH_R_QB = (0x02 << 6) | OPC_ADDUH_QB_DSP,
533 OPC_ADDQH_PH = (0x08 << 6) | OPC_ADDUH_QB_DSP,
534 OPC_ADDQH_R_PH = (0x0A << 6) | OPC_ADDUH_QB_DSP,
535 OPC_ADDQH_W = (0x10 << 6) | OPC_ADDUH_QB_DSP,
536 OPC_ADDQH_R_W = (0x12 << 6) | OPC_ADDUH_QB_DSP,
537 OPC_SUBUH_QB = (0x01 << 6) | OPC_ADDUH_QB_DSP,
538 OPC_SUBUH_R_QB = (0x03 << 6) | OPC_ADDUH_QB_DSP,
539 OPC_SUBQH_PH = (0x09 << 6) | OPC_ADDUH_QB_DSP,
540 OPC_SUBQH_R_PH = (0x0B << 6) | OPC_ADDUH_QB_DSP,
541 OPC_SUBQH_W = (0x11 << 6) | OPC_ADDUH_QB_DSP,
542 OPC_SUBQH_R_W = (0x13 << 6) | OPC_ADDUH_QB_DSP,
a22260ae
JL
543 /* MIPS DSP Multiply Sub-class insns */
544 OPC_MUL_PH = (0x0C << 6) | OPC_ADDUH_QB_DSP,
545 OPC_MUL_S_PH = (0x0E << 6) | OPC_ADDUH_QB_DSP,
546 OPC_MULQ_S_W = (0x16 << 6) | OPC_ADDUH_QB_DSP,
547 OPC_MULQ_RS_W = (0x17 << 6) | OPC_ADDUH_QB_DSP,
461c08df
JL
548};
549
550#define MASK_ABSQ_S_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
551enum {
552 /* MIPS DSP Arithmetic Sub-class */
553 OPC_ABSQ_S_QB = (0x01 << 6) | OPC_ABSQ_S_PH_DSP,
554 OPC_ABSQ_S_PH = (0x09 << 6) | OPC_ABSQ_S_PH_DSP,
555 OPC_ABSQ_S_W = (0x11 << 6) | OPC_ABSQ_S_PH_DSP,
556 OPC_PRECEQ_W_PHL = (0x0C << 6) | OPC_ABSQ_S_PH_DSP,
557 OPC_PRECEQ_W_PHR = (0x0D << 6) | OPC_ABSQ_S_PH_DSP,
558 OPC_PRECEQU_PH_QBL = (0x04 << 6) | OPC_ABSQ_S_PH_DSP,
559 OPC_PRECEQU_PH_QBR = (0x05 << 6) | OPC_ABSQ_S_PH_DSP,
560 OPC_PRECEQU_PH_QBLA = (0x06 << 6) | OPC_ABSQ_S_PH_DSP,
561 OPC_PRECEQU_PH_QBRA = (0x07 << 6) | OPC_ABSQ_S_PH_DSP,
562 OPC_PRECEU_PH_QBL = (0x1C << 6) | OPC_ABSQ_S_PH_DSP,
563 OPC_PRECEU_PH_QBR = (0x1D << 6) | OPC_ABSQ_S_PH_DSP,
564 OPC_PRECEU_PH_QBLA = (0x1E << 6) | OPC_ABSQ_S_PH_DSP,
565 OPC_PRECEU_PH_QBRA = (0x1F << 6) | OPC_ABSQ_S_PH_DSP,
1cb6686c
JL
566 /* DSP Bit/Manipulation Sub-class */
567 OPC_BITREV = (0x1B << 6) | OPC_ABSQ_S_PH_DSP,
568 OPC_REPL_QB = (0x02 << 6) | OPC_ABSQ_S_PH_DSP,
569 OPC_REPLV_QB = (0x03 << 6) | OPC_ABSQ_S_PH_DSP,
570 OPC_REPL_PH = (0x0A << 6) | OPC_ABSQ_S_PH_DSP,
571 OPC_REPLV_PH = (0x0B << 6) | OPC_ABSQ_S_PH_DSP,
461c08df
JL
572};
573
574#define MASK_CMPU_EQ_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
575enum {
576 /* MIPS DSP Arithmetic Sub-class */
577 OPC_PRECR_QB_PH = (0x0D << 6) | OPC_CMPU_EQ_QB_DSP,
578 OPC_PRECRQ_QB_PH = (0x0C << 6) | OPC_CMPU_EQ_QB_DSP,
579 OPC_PRECR_SRA_PH_W = (0x1E << 6) | OPC_CMPU_EQ_QB_DSP,
580 OPC_PRECR_SRA_R_PH_W = (0x1F << 6) | OPC_CMPU_EQ_QB_DSP,
581 OPC_PRECRQ_PH_W = (0x14 << 6) | OPC_CMPU_EQ_QB_DSP,
582 OPC_PRECRQ_RS_PH_W = (0x15 << 6) | OPC_CMPU_EQ_QB_DSP,
583 OPC_PRECRQU_S_QB_PH = (0x0F << 6) | OPC_CMPU_EQ_QB_DSP,
26690560
JL
584 /* DSP Compare-Pick Sub-class */
585 OPC_CMPU_EQ_QB = (0x00 << 6) | OPC_CMPU_EQ_QB_DSP,
586 OPC_CMPU_LT_QB = (0x01 << 6) | OPC_CMPU_EQ_QB_DSP,
587 OPC_CMPU_LE_QB = (0x02 << 6) | OPC_CMPU_EQ_QB_DSP,
588 OPC_CMPGU_EQ_QB = (0x04 << 6) | OPC_CMPU_EQ_QB_DSP,
589 OPC_CMPGU_LT_QB = (0x05 << 6) | OPC_CMPU_EQ_QB_DSP,
590 OPC_CMPGU_LE_QB = (0x06 << 6) | OPC_CMPU_EQ_QB_DSP,
591 OPC_CMPGDU_EQ_QB = (0x18 << 6) | OPC_CMPU_EQ_QB_DSP,
592 OPC_CMPGDU_LT_QB = (0x19 << 6) | OPC_CMPU_EQ_QB_DSP,
593 OPC_CMPGDU_LE_QB = (0x1A << 6) | OPC_CMPU_EQ_QB_DSP,
594 OPC_CMP_EQ_PH = (0x08 << 6) | OPC_CMPU_EQ_QB_DSP,
595 OPC_CMP_LT_PH = (0x09 << 6) | OPC_CMPU_EQ_QB_DSP,
596 OPC_CMP_LE_PH = (0x0A << 6) | OPC_CMPU_EQ_QB_DSP,
597 OPC_PICK_QB = (0x03 << 6) | OPC_CMPU_EQ_QB_DSP,
598 OPC_PICK_PH = (0x0B << 6) | OPC_CMPU_EQ_QB_DSP,
599 OPC_PACKRL_PH = (0x0E << 6) | OPC_CMPU_EQ_QB_DSP,
461c08df 600};
a22260ae 601
77c5fa8b
JL
602#define MASK_SHLL_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
603enum {
604 /* MIPS DSP GPR-Based Shift Sub-class */
605 OPC_SHLL_QB = (0x00 << 6) | OPC_SHLL_QB_DSP,
606 OPC_SHLLV_QB = (0x02 << 6) | OPC_SHLL_QB_DSP,
607 OPC_SHLL_PH = (0x08 << 6) | OPC_SHLL_QB_DSP,
608 OPC_SHLLV_PH = (0x0A << 6) | OPC_SHLL_QB_DSP,
609 OPC_SHLL_S_PH = (0x0C << 6) | OPC_SHLL_QB_DSP,
610 OPC_SHLLV_S_PH = (0x0E << 6) | OPC_SHLL_QB_DSP,
611 OPC_SHLL_S_W = (0x14 << 6) | OPC_SHLL_QB_DSP,
612 OPC_SHLLV_S_W = (0x16 << 6) | OPC_SHLL_QB_DSP,
613 OPC_SHRL_QB = (0x01 << 6) | OPC_SHLL_QB_DSP,
614 OPC_SHRLV_QB = (0x03 << 6) | OPC_SHLL_QB_DSP,
615 OPC_SHRL_PH = (0x19 << 6) | OPC_SHLL_QB_DSP,
616 OPC_SHRLV_PH = (0x1B << 6) | OPC_SHLL_QB_DSP,
617 OPC_SHRA_QB = (0x04 << 6) | OPC_SHLL_QB_DSP,
618 OPC_SHRA_R_QB = (0x05 << 6) | OPC_SHLL_QB_DSP,
619 OPC_SHRAV_QB = (0x06 << 6) | OPC_SHLL_QB_DSP,
620 OPC_SHRAV_R_QB = (0x07 << 6) | OPC_SHLL_QB_DSP,
621 OPC_SHRA_PH = (0x09 << 6) | OPC_SHLL_QB_DSP,
622 OPC_SHRAV_PH = (0x0B << 6) | OPC_SHLL_QB_DSP,
623 OPC_SHRA_R_PH = (0x0D << 6) | OPC_SHLL_QB_DSP,
624 OPC_SHRAV_R_PH = (0x0F << 6) | OPC_SHLL_QB_DSP,
625 OPC_SHRA_R_W = (0x15 << 6) | OPC_SHLL_QB_DSP,
626 OPC_SHRAV_R_W = (0x17 << 6) | OPC_SHLL_QB_DSP,
627};
461c08df 628
a22260ae
JL
629#define MASK_DPA_W_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
630enum {
631 /* MIPS DSP Multiply Sub-class insns */
632 OPC_DPAU_H_QBL = (0x03 << 6) | OPC_DPA_W_PH_DSP,
633 OPC_DPAU_H_QBR = (0x07 << 6) | OPC_DPA_W_PH_DSP,
634 OPC_DPSU_H_QBL = (0x0B << 6) | OPC_DPA_W_PH_DSP,
635 OPC_DPSU_H_QBR = (0x0F << 6) | OPC_DPA_W_PH_DSP,
636 OPC_DPA_W_PH = (0x00 << 6) | OPC_DPA_W_PH_DSP,
637 OPC_DPAX_W_PH = (0x08 << 6) | OPC_DPA_W_PH_DSP,
638 OPC_DPAQ_S_W_PH = (0x04 << 6) | OPC_DPA_W_PH_DSP,
639 OPC_DPAQX_S_W_PH = (0x18 << 6) | OPC_DPA_W_PH_DSP,
640 OPC_DPAQX_SA_W_PH = (0x1A << 6) | OPC_DPA_W_PH_DSP,
641 OPC_DPS_W_PH = (0x01 << 6) | OPC_DPA_W_PH_DSP,
642 OPC_DPSX_W_PH = (0x09 << 6) | OPC_DPA_W_PH_DSP,
643 OPC_DPSQ_S_W_PH = (0x05 << 6) | OPC_DPA_W_PH_DSP,
644 OPC_DPSQX_S_W_PH = (0x19 << 6) | OPC_DPA_W_PH_DSP,
645 OPC_DPSQX_SA_W_PH = (0x1B << 6) | OPC_DPA_W_PH_DSP,
646 OPC_MULSAQ_S_W_PH = (0x06 << 6) | OPC_DPA_W_PH_DSP,
647 OPC_DPAQ_SA_L_W = (0x0C << 6) | OPC_DPA_W_PH_DSP,
648 OPC_DPSQ_SA_L_W = (0x0D << 6) | OPC_DPA_W_PH_DSP,
649 OPC_MAQ_S_W_PHL = (0x14 << 6) | OPC_DPA_W_PH_DSP,
650 OPC_MAQ_S_W_PHR = (0x16 << 6) | OPC_DPA_W_PH_DSP,
651 OPC_MAQ_SA_W_PHL = (0x10 << 6) | OPC_DPA_W_PH_DSP,
652 OPC_MAQ_SA_W_PHR = (0x12 << 6) | OPC_DPA_W_PH_DSP,
653 OPC_MULSA_W_PH = (0x02 << 6) | OPC_DPA_W_PH_DSP,
654};
655
1cb6686c
JL
656#define MASK_INSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
657enum {
658 /* DSP Bit/Manipulation Sub-class */
659 OPC_INSV = (0x00 << 6) | OPC_INSV_DSP,
660};
661
26690560
JL
662#define MASK_APPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
663enum {
df6126a7 664 /* MIPS DSP Append Sub-class */
26690560
JL
665 OPC_APPEND = (0x00 << 6) | OPC_APPEND_DSP,
666 OPC_PREPEND = (0x01 << 6) | OPC_APPEND_DSP,
667 OPC_BALIGN = (0x10 << 6) | OPC_APPEND_DSP,
668};
669
b53371ed
JL
670#define MASK_EXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
671enum {
672 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
673 OPC_EXTR_W = (0x00 << 6) | OPC_EXTR_W_DSP,
674 OPC_EXTR_R_W = (0x04 << 6) | OPC_EXTR_W_DSP,
675 OPC_EXTR_RS_W = (0x06 << 6) | OPC_EXTR_W_DSP,
676 OPC_EXTR_S_H = (0x0E << 6) | OPC_EXTR_W_DSP,
677 OPC_EXTRV_S_H = (0x0F << 6) | OPC_EXTR_W_DSP,
678 OPC_EXTRV_W = (0x01 << 6) | OPC_EXTR_W_DSP,
679 OPC_EXTRV_R_W = (0x05 << 6) | OPC_EXTR_W_DSP,
680 OPC_EXTRV_RS_W = (0x07 << 6) | OPC_EXTR_W_DSP,
681 OPC_EXTP = (0x02 << 6) | OPC_EXTR_W_DSP,
682 OPC_EXTPV = (0x03 << 6) | OPC_EXTR_W_DSP,
683 OPC_EXTPDP = (0x0A << 6) | OPC_EXTR_W_DSP,
684 OPC_EXTPDPV = (0x0B << 6) | OPC_EXTR_W_DSP,
685 OPC_SHILO = (0x1A << 6) | OPC_EXTR_W_DSP,
686 OPC_SHILOV = (0x1B << 6) | OPC_EXTR_W_DSP,
687 OPC_MTHLIP = (0x1F << 6) | OPC_EXTR_W_DSP,
688 OPC_WRDSP = (0x13 << 6) | OPC_EXTR_W_DSP,
689 OPC_RDDSP = (0x12 << 6) | OPC_EXTR_W_DSP,
690};
691
461c08df
JL
692#define MASK_ABSQ_S_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
693enum {
694 /* MIPS DSP Arithmetic Sub-class */
695 OPC_PRECEQ_L_PWL = (0x14 << 6) | OPC_ABSQ_S_QH_DSP,
696 OPC_PRECEQ_L_PWR = (0x15 << 6) | OPC_ABSQ_S_QH_DSP,
697 OPC_PRECEQ_PW_QHL = (0x0C << 6) | OPC_ABSQ_S_QH_DSP,
698 OPC_PRECEQ_PW_QHR = (0x0D << 6) | OPC_ABSQ_S_QH_DSP,
699 OPC_PRECEQ_PW_QHLA = (0x0E << 6) | OPC_ABSQ_S_QH_DSP,
700 OPC_PRECEQ_PW_QHRA = (0x0F << 6) | OPC_ABSQ_S_QH_DSP,
701 OPC_PRECEQU_QH_OBL = (0x04 << 6) | OPC_ABSQ_S_QH_DSP,
702 OPC_PRECEQU_QH_OBR = (0x05 << 6) | OPC_ABSQ_S_QH_DSP,
703 OPC_PRECEQU_QH_OBLA = (0x06 << 6) | OPC_ABSQ_S_QH_DSP,
704 OPC_PRECEQU_QH_OBRA = (0x07 << 6) | OPC_ABSQ_S_QH_DSP,
705 OPC_PRECEU_QH_OBL = (0x1C << 6) | OPC_ABSQ_S_QH_DSP,
706 OPC_PRECEU_QH_OBR = (0x1D << 6) | OPC_ABSQ_S_QH_DSP,
707 OPC_PRECEU_QH_OBLA = (0x1E << 6) | OPC_ABSQ_S_QH_DSP,
708 OPC_PRECEU_QH_OBRA = (0x1F << 6) | OPC_ABSQ_S_QH_DSP,
709 OPC_ABSQ_S_OB = (0x01 << 6) | OPC_ABSQ_S_QH_DSP,
710 OPC_ABSQ_S_PW = (0x11 << 6) | OPC_ABSQ_S_QH_DSP,
711 OPC_ABSQ_S_QH = (0x09 << 6) | OPC_ABSQ_S_QH_DSP,
1cb6686c
JL
712 /* DSP Bit/Manipulation Sub-class */
713 OPC_REPL_OB = (0x02 << 6) | OPC_ABSQ_S_QH_DSP,
714 OPC_REPL_PW = (0x12 << 6) | OPC_ABSQ_S_QH_DSP,
715 OPC_REPL_QH = (0x0A << 6) | OPC_ABSQ_S_QH_DSP,
716 OPC_REPLV_OB = (0x03 << 6) | OPC_ABSQ_S_QH_DSP,
717 OPC_REPLV_PW = (0x13 << 6) | OPC_ABSQ_S_QH_DSP,
718 OPC_REPLV_QH = (0x0B << 6) | OPC_ABSQ_S_QH_DSP,
461c08df 719};
461c08df 720
461c08df
JL
721#define MASK_ADDU_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
722enum {
a22260ae
JL
723 /* MIPS DSP Multiply Sub-class insns */
724 OPC_MULEQ_S_PW_QHL = (0x1C << 6) | OPC_ADDU_OB_DSP,
725 OPC_MULEQ_S_PW_QHR = (0x1D << 6) | OPC_ADDU_OB_DSP,
726 OPC_MULEU_S_QH_OBL = (0x06 << 6) | OPC_ADDU_OB_DSP,
727 OPC_MULEU_S_QH_OBR = (0x07 << 6) | OPC_ADDU_OB_DSP,
728 OPC_MULQ_RS_QH = (0x1F << 6) | OPC_ADDU_OB_DSP,
461c08df
JL
729 /* MIPS DSP Arithmetic Sub-class */
730 OPC_RADDU_L_OB = (0x14 << 6) | OPC_ADDU_OB_DSP,
731 OPC_SUBQ_PW = (0x13 << 6) | OPC_ADDU_OB_DSP,
732 OPC_SUBQ_S_PW = (0x17 << 6) | OPC_ADDU_OB_DSP,
733 OPC_SUBQ_QH = (0x0B << 6) | OPC_ADDU_OB_DSP,
734 OPC_SUBQ_S_QH = (0x0F << 6) | OPC_ADDU_OB_DSP,
735 OPC_SUBU_OB = (0x01 << 6) | OPC_ADDU_OB_DSP,
736 OPC_SUBU_S_OB = (0x05 << 6) | OPC_ADDU_OB_DSP,
737 OPC_SUBU_QH = (0x09 << 6) | OPC_ADDU_OB_DSP,
738 OPC_SUBU_S_QH = (0x0D << 6) | OPC_ADDU_OB_DSP,
739 OPC_SUBUH_OB = (0x19 << 6) | OPC_ADDU_OB_DSP,
740 OPC_SUBUH_R_OB = (0x1B << 6) | OPC_ADDU_OB_DSP,
741 OPC_ADDQ_PW = (0x12 << 6) | OPC_ADDU_OB_DSP,
742 OPC_ADDQ_S_PW = (0x16 << 6) | OPC_ADDU_OB_DSP,
743 OPC_ADDQ_QH = (0x0A << 6) | OPC_ADDU_OB_DSP,
744 OPC_ADDQ_S_QH = (0x0E << 6) | OPC_ADDU_OB_DSP,
745 OPC_ADDU_OB = (0x00 << 6) | OPC_ADDU_OB_DSP,
746 OPC_ADDU_S_OB = (0x04 << 6) | OPC_ADDU_OB_DSP,
747 OPC_ADDU_QH = (0x08 << 6) | OPC_ADDU_OB_DSP,
748 OPC_ADDU_S_QH = (0x0C << 6) | OPC_ADDU_OB_DSP,
749 OPC_ADDUH_OB = (0x18 << 6) | OPC_ADDU_OB_DSP,
750 OPC_ADDUH_R_OB = (0x1A << 6) | OPC_ADDU_OB_DSP,
751};
461c08df 752
461c08df
JL
753#define MASK_CMPU_EQ_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
754enum {
26690560
JL
755 /* DSP Compare-Pick Sub-class */
756 OPC_CMP_EQ_PW = (0x10 << 6) | OPC_CMPU_EQ_OB_DSP,
757 OPC_CMP_LT_PW = (0x11 << 6) | OPC_CMPU_EQ_OB_DSP,
758 OPC_CMP_LE_PW = (0x12 << 6) | OPC_CMPU_EQ_OB_DSP,
759 OPC_CMP_EQ_QH = (0x08 << 6) | OPC_CMPU_EQ_OB_DSP,
760 OPC_CMP_LT_QH = (0x09 << 6) | OPC_CMPU_EQ_OB_DSP,
761 OPC_CMP_LE_QH = (0x0A << 6) | OPC_CMPU_EQ_OB_DSP,
762 OPC_CMPGDU_EQ_OB = (0x18 << 6) | OPC_CMPU_EQ_OB_DSP,
763 OPC_CMPGDU_LT_OB = (0x19 << 6) | OPC_CMPU_EQ_OB_DSP,
764 OPC_CMPGDU_LE_OB = (0x1A << 6) | OPC_CMPU_EQ_OB_DSP,
765 OPC_CMPGU_EQ_OB = (0x04 << 6) | OPC_CMPU_EQ_OB_DSP,
766 OPC_CMPGU_LT_OB = (0x05 << 6) | OPC_CMPU_EQ_OB_DSP,
767 OPC_CMPGU_LE_OB = (0x06 << 6) | OPC_CMPU_EQ_OB_DSP,
768 OPC_CMPU_EQ_OB = (0x00 << 6) | OPC_CMPU_EQ_OB_DSP,
769 OPC_CMPU_LT_OB = (0x01 << 6) | OPC_CMPU_EQ_OB_DSP,
770 OPC_CMPU_LE_OB = (0x02 << 6) | OPC_CMPU_EQ_OB_DSP,
771 OPC_PACKRL_PW = (0x0E << 6) | OPC_CMPU_EQ_OB_DSP,
772 OPC_PICK_OB = (0x03 << 6) | OPC_CMPU_EQ_OB_DSP,
773 OPC_PICK_PW = (0x13 << 6) | OPC_CMPU_EQ_OB_DSP,
774 OPC_PICK_QH = (0x0B << 6) | OPC_CMPU_EQ_OB_DSP,
461c08df
JL
775 /* MIPS DSP Arithmetic Sub-class */
776 OPC_PRECR_OB_QH = (0x0D << 6) | OPC_CMPU_EQ_OB_DSP,
777 OPC_PRECR_SRA_QH_PW = (0x1E << 6) | OPC_CMPU_EQ_OB_DSP,
778 OPC_PRECR_SRA_R_QH_PW = (0x1F << 6) | OPC_CMPU_EQ_OB_DSP,
779 OPC_PRECRQ_OB_QH = (0x0C << 6) | OPC_CMPU_EQ_OB_DSP,
780 OPC_PRECRQ_PW_L = (0x1C << 6) | OPC_CMPU_EQ_OB_DSP,
781 OPC_PRECRQ_QH_PW = (0x14 << 6) | OPC_CMPU_EQ_OB_DSP,
782 OPC_PRECRQ_RS_QH_PW = (0x15 << 6) | OPC_CMPU_EQ_OB_DSP,
783 OPC_PRECRQU_S_OB_QH = (0x0F << 6) | OPC_CMPU_EQ_OB_DSP,
784};
461c08df 785
26690560
JL
786#define MASK_DAPPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
787enum {
df6126a7 788 /* DSP Append Sub-class */
26690560
JL
789 OPC_DAPPEND = (0x00 << 6) | OPC_DAPPEND_DSP,
790 OPC_PREPENDD = (0x03 << 6) | OPC_DAPPEND_DSP,
791 OPC_PREPENDW = (0x01 << 6) | OPC_DAPPEND_DSP,
792 OPC_DBALIGN = (0x10 << 6) | OPC_DAPPEND_DSP,
793};
26690560 794
b53371ed
JL
795#define MASK_DEXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
796enum {
797 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
798 OPC_DMTHLIP = (0x1F << 6) | OPC_DEXTR_W_DSP,
799 OPC_DSHILO = (0x1A << 6) | OPC_DEXTR_W_DSP,
800 OPC_DEXTP = (0x02 << 6) | OPC_DEXTR_W_DSP,
801 OPC_DEXTPDP = (0x0A << 6) | OPC_DEXTR_W_DSP,
802 OPC_DEXTPDPV = (0x0B << 6) | OPC_DEXTR_W_DSP,
803 OPC_DEXTPV = (0x03 << 6) | OPC_DEXTR_W_DSP,
804 OPC_DEXTR_L = (0x10 << 6) | OPC_DEXTR_W_DSP,
805 OPC_DEXTR_R_L = (0x14 << 6) | OPC_DEXTR_W_DSP,
806 OPC_DEXTR_RS_L = (0x16 << 6) | OPC_DEXTR_W_DSP,
807 OPC_DEXTR_W = (0x00 << 6) | OPC_DEXTR_W_DSP,
808 OPC_DEXTR_R_W = (0x04 << 6) | OPC_DEXTR_W_DSP,
809 OPC_DEXTR_RS_W = (0x06 << 6) | OPC_DEXTR_W_DSP,
810 OPC_DEXTR_S_H = (0x0E << 6) | OPC_DEXTR_W_DSP,
811 OPC_DEXTRV_L = (0x11 << 6) | OPC_DEXTR_W_DSP,
812 OPC_DEXTRV_R_L = (0x15 << 6) | OPC_DEXTR_W_DSP,
813 OPC_DEXTRV_RS_L = (0x17 << 6) | OPC_DEXTR_W_DSP,
814 OPC_DEXTRV_S_H = (0x0F << 6) | OPC_DEXTR_W_DSP,
815 OPC_DEXTRV_W = (0x01 << 6) | OPC_DEXTR_W_DSP,
816 OPC_DEXTRV_R_W = (0x05 << 6) | OPC_DEXTR_W_DSP,
817 OPC_DEXTRV_RS_W = (0x07 << 6) | OPC_DEXTR_W_DSP,
818 OPC_DSHILOV = (0x1B << 6) | OPC_DEXTR_W_DSP,
819};
820
1cb6686c
JL
821#define MASK_DINSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
822enum {
823 /* DSP Bit/Manipulation Sub-class */
824 OPC_DINSV = (0x00 << 6) | OPC_DINSV_DSP,
825};
1cb6686c 826
a22260ae
JL
827#define MASK_DPAQ_W_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
828enum {
829 /* MIPS DSP Multiply Sub-class insns */
830 OPC_DMADD = (0x19 << 6) | OPC_DPAQ_W_QH_DSP,
831 OPC_DMADDU = (0x1D << 6) | OPC_DPAQ_W_QH_DSP,
832 OPC_DMSUB = (0x1B << 6) | OPC_DPAQ_W_QH_DSP,
833 OPC_DMSUBU = (0x1F << 6) | OPC_DPAQ_W_QH_DSP,
834 OPC_DPA_W_QH = (0x00 << 6) | OPC_DPAQ_W_QH_DSP,
835 OPC_DPAQ_S_W_QH = (0x04 << 6) | OPC_DPAQ_W_QH_DSP,
836 OPC_DPAQ_SA_L_PW = (0x0C << 6) | OPC_DPAQ_W_QH_DSP,
837 OPC_DPAU_H_OBL = (0x03 << 6) | OPC_DPAQ_W_QH_DSP,
838 OPC_DPAU_H_OBR = (0x07 << 6) | OPC_DPAQ_W_QH_DSP,
839 OPC_DPS_W_QH = (0x01 << 6) | OPC_DPAQ_W_QH_DSP,
840 OPC_DPSQ_S_W_QH = (0x05 << 6) | OPC_DPAQ_W_QH_DSP,
841 OPC_DPSQ_SA_L_PW = (0x0D << 6) | OPC_DPAQ_W_QH_DSP,
842 OPC_DPSU_H_OBL = (0x0B << 6) | OPC_DPAQ_W_QH_DSP,
843 OPC_DPSU_H_OBR = (0x0F << 6) | OPC_DPAQ_W_QH_DSP,
844 OPC_MAQ_S_L_PWL = (0x1C << 6) | OPC_DPAQ_W_QH_DSP,
845 OPC_MAQ_S_L_PWR = (0x1E << 6) | OPC_DPAQ_W_QH_DSP,
846 OPC_MAQ_S_W_QHLL = (0x14 << 6) | OPC_DPAQ_W_QH_DSP,
847 OPC_MAQ_SA_W_QHLL = (0x10 << 6) | OPC_DPAQ_W_QH_DSP,
848 OPC_MAQ_S_W_QHLR = (0x15 << 6) | OPC_DPAQ_W_QH_DSP,
849 OPC_MAQ_SA_W_QHLR = (0x11 << 6) | OPC_DPAQ_W_QH_DSP,
850 OPC_MAQ_S_W_QHRL = (0x16 << 6) | OPC_DPAQ_W_QH_DSP,
851 OPC_MAQ_SA_W_QHRL = (0x12 << 6) | OPC_DPAQ_W_QH_DSP,
852 OPC_MAQ_S_W_QHRR = (0x17 << 6) | OPC_DPAQ_W_QH_DSP,
853 OPC_MAQ_SA_W_QHRR = (0x13 << 6) | OPC_DPAQ_W_QH_DSP,
854 OPC_MULSAQ_S_L_PW = (0x0E << 6) | OPC_DPAQ_W_QH_DSP,
855 OPC_MULSAQ_S_W_QH = (0x06 << 6) | OPC_DPAQ_W_QH_DSP,
856};
a22260ae 857
77c5fa8b
JL
858#define MASK_SHLL_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
859enum {
860 /* MIPS DSP GPR-Based Shift Sub-class */
861 OPC_SHLL_PW = (0x10 << 6) | OPC_SHLL_OB_DSP,
862 OPC_SHLL_S_PW = (0x14 << 6) | OPC_SHLL_OB_DSP,
863 OPC_SHLLV_OB = (0x02 << 6) | OPC_SHLL_OB_DSP,
864 OPC_SHLLV_PW = (0x12 << 6) | OPC_SHLL_OB_DSP,
865 OPC_SHLLV_S_PW = (0x16 << 6) | OPC_SHLL_OB_DSP,
866 OPC_SHLLV_QH = (0x0A << 6) | OPC_SHLL_OB_DSP,
867 OPC_SHLLV_S_QH = (0x0E << 6) | OPC_SHLL_OB_DSP,
868 OPC_SHRA_PW = (0x11 << 6) | OPC_SHLL_OB_DSP,
869 OPC_SHRA_R_PW = (0x15 << 6) | OPC_SHLL_OB_DSP,
870 OPC_SHRAV_OB = (0x06 << 6) | OPC_SHLL_OB_DSP,
871 OPC_SHRAV_R_OB = (0x07 << 6) | OPC_SHLL_OB_DSP,
872 OPC_SHRAV_PW = (0x13 << 6) | OPC_SHLL_OB_DSP,
873 OPC_SHRAV_R_PW = (0x17 << 6) | OPC_SHLL_OB_DSP,
874 OPC_SHRAV_QH = (0x0B << 6) | OPC_SHLL_OB_DSP,
875 OPC_SHRAV_R_QH = (0x0F << 6) | OPC_SHLL_OB_DSP,
876 OPC_SHRLV_OB = (0x03 << 6) | OPC_SHLL_OB_DSP,
877 OPC_SHRLV_QH = (0x1B << 6) | OPC_SHLL_OB_DSP,
878 OPC_SHLL_OB = (0x00 << 6) | OPC_SHLL_OB_DSP,
879 OPC_SHLL_QH = (0x08 << 6) | OPC_SHLL_OB_DSP,
880 OPC_SHLL_S_QH = (0x0C << 6) | OPC_SHLL_OB_DSP,
881 OPC_SHRA_OB = (0x04 << 6) | OPC_SHLL_OB_DSP,
882 OPC_SHRA_R_OB = (0x05 << 6) | OPC_SHLL_OB_DSP,
883 OPC_SHRA_QH = (0x09 << 6) | OPC_SHLL_OB_DSP,
884 OPC_SHRA_R_QH = (0x0D << 6) | OPC_SHLL_OB_DSP,
885 OPC_SHRL_OB = (0x01 << 6) | OPC_SHLL_OB_DSP,
886 OPC_SHRL_QH = (0x19 << 6) | OPC_SHLL_OB_DSP,
887};
77c5fa8b 888
7a387fff
TS
889/* Coprocessor 0 (rs field) */
890#define MASK_CP0(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
891
6ea83fed 892enum {
7a387fff
TS
893 OPC_MFC0 = (0x00 << 21) | OPC_CP0,
894 OPC_DMFC0 = (0x01 << 21) | OPC_CP0,
5204ea79 895 OPC_MFHC0 = (0x02 << 21) | OPC_CP0,
7a387fff
TS
896 OPC_MTC0 = (0x04 << 21) | OPC_CP0,
897 OPC_DMTC0 = (0x05 << 21) | OPC_CP0,
5204ea79 898 OPC_MTHC0 = (0x06 << 21) | OPC_CP0,
ead9360e 899 OPC_MFTR = (0x08 << 21) | OPC_CP0,
7a387fff
TS
900 OPC_RDPGPR = (0x0A << 21) | OPC_CP0,
901 OPC_MFMC0 = (0x0B << 21) | OPC_CP0,
ead9360e 902 OPC_MTTR = (0x0C << 21) | OPC_CP0,
7a387fff
TS
903 OPC_WRPGPR = (0x0E << 21) | OPC_CP0,
904 OPC_C0 = (0x10 << 21) | OPC_CP0,
c38a1d52
AR
905 OPC_C0_1 = (0x11 << 21) | OPC_CP0,
906 OPC_C0_2 = (0x12 << 21) | OPC_CP0,
907 OPC_C0_3 = (0x13 << 21) | OPC_CP0,
908 OPC_C0_4 = (0x14 << 21) | OPC_CP0,
909 OPC_C0_5 = (0x15 << 21) | OPC_CP0,
910 OPC_C0_6 = (0x16 << 21) | OPC_CP0,
911 OPC_C0_7 = (0x17 << 21) | OPC_CP0,
912 OPC_C0_8 = (0x18 << 21) | OPC_CP0,
913 OPC_C0_9 = (0x19 << 21) | OPC_CP0,
914 OPC_C0_A = (0x1A << 21) | OPC_CP0,
915 OPC_C0_B = (0x1B << 21) | OPC_CP0,
916 OPC_C0_C = (0x1C << 21) | OPC_CP0,
917 OPC_C0_D = (0x1D << 21) | OPC_CP0,
918 OPC_C0_E = (0x1E << 21) | OPC_CP0,
919 OPC_C0_F = (0x1F << 21) | OPC_CP0,
6ea83fed 920};
7a387fff
TS
921
922/* MFMC0 opcodes */
b48cfdff 923#define MASK_MFMC0(op) MASK_CP0(op) | (op & 0xFFFF)
7a387fff
TS
924
925enum {
ead9360e
TS
926 OPC_DMT = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
927 OPC_EMT = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
928 OPC_DVPE = 0x01 | (0 << 5) | OPC_MFMC0,
929 OPC_EVPE = 0x01 | (1 << 5) | OPC_MFMC0,
7a387fff
TS
930 OPC_DI = (0 << 5) | (0x0C << 11) | OPC_MFMC0,
931 OPC_EI = (1 << 5) | (0x0C << 11) | OPC_MFMC0,
01bc435b
YK
932 OPC_DVP = 0x04 | (0 << 3) | (1 << 5) | (0 << 11) | OPC_MFMC0,
933 OPC_EVP = 0x04 | (0 << 3) | (0 << 5) | (0 << 11) | OPC_MFMC0,
7a387fff
TS
934};
935
936/* Coprocessor 0 (with rs == C0) */
937#define MASK_C0(op) MASK_CP0(op) | (op & 0x3F)
938
939enum {
940 OPC_TLBR = 0x01 | OPC_C0,
941 OPC_TLBWI = 0x02 | OPC_C0,
9456c2fb
LA
942 OPC_TLBINV = 0x03 | OPC_C0,
943 OPC_TLBINVF = 0x04 | OPC_C0,
7a387fff
TS
944 OPC_TLBWR = 0x06 | OPC_C0,
945 OPC_TLBP = 0x08 | OPC_C0,
946 OPC_RFE = 0x10 | OPC_C0,
947 OPC_ERET = 0x18 | OPC_C0,
948 OPC_DERET = 0x1F | OPC_C0,
949 OPC_WAIT = 0x20 | OPC_C0,
950};
951
952/* Coprocessor 1 (rs field) */
953#define MASK_CP1(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
954
bf4120ad
NF
955/* Values for the fmt field in FP instructions */
956enum {
957 /* 0 - 15 are reserved */
e459440a
AJ
958 FMT_S = 16, /* single fp */
959 FMT_D = 17, /* double fp */
960 FMT_E = 18, /* extended fp */
961 FMT_Q = 19, /* quad fp */
962 FMT_W = 20, /* 32-bit fixed */
963 FMT_L = 21, /* 64-bit fixed */
964 FMT_PS = 22, /* paired single fp */
bf4120ad
NF
965 /* 23 - 31 are reserved */
966};
967
7a387fff
TS
968enum {
969 OPC_MFC1 = (0x00 << 21) | OPC_CP1,
970 OPC_DMFC1 = (0x01 << 21) | OPC_CP1,
971 OPC_CFC1 = (0x02 << 21) | OPC_CP1,
5a5012ec 972 OPC_MFHC1 = (0x03 << 21) | OPC_CP1,
7a387fff
TS
973 OPC_MTC1 = (0x04 << 21) | OPC_CP1,
974 OPC_DMTC1 = (0x05 << 21) | OPC_CP1,
975 OPC_CTC1 = (0x06 << 21) | OPC_CP1,
5a5012ec 976 OPC_MTHC1 = (0x07 << 21) | OPC_CP1,
7a387fff 977 OPC_BC1 = (0x08 << 21) | OPC_CP1, /* bc */
5a5012ec
TS
978 OPC_BC1ANY2 = (0x09 << 21) | OPC_CP1,
979 OPC_BC1ANY4 = (0x0A << 21) | OPC_CP1,
239dfebe
YK
980 OPC_BZ_V = (0x0B << 21) | OPC_CP1,
981 OPC_BNZ_V = (0x0F << 21) | OPC_CP1,
e459440a
AJ
982 OPC_S_FMT = (FMT_S << 21) | OPC_CP1,
983 OPC_D_FMT = (FMT_D << 21) | OPC_CP1,
984 OPC_E_FMT = (FMT_E << 21) | OPC_CP1,
985 OPC_Q_FMT = (FMT_Q << 21) | OPC_CP1,
986 OPC_W_FMT = (FMT_W << 21) | OPC_CP1,
987 OPC_L_FMT = (FMT_L << 21) | OPC_CP1,
988 OPC_PS_FMT = (FMT_PS << 21) | OPC_CP1,
31837be3
YK
989 OPC_BC1EQZ = (0x09 << 21) | OPC_CP1,
990 OPC_BC1NEZ = (0x0D << 21) | OPC_CP1,
239dfebe
YK
991 OPC_BZ_B = (0x18 << 21) | OPC_CP1,
992 OPC_BZ_H = (0x19 << 21) | OPC_CP1,
993 OPC_BZ_W = (0x1A << 21) | OPC_CP1,
994 OPC_BZ_D = (0x1B << 21) | OPC_CP1,
995 OPC_BNZ_B = (0x1C << 21) | OPC_CP1,
996 OPC_BNZ_H = (0x1D << 21) | OPC_CP1,
997 OPC_BNZ_W = (0x1E << 21) | OPC_CP1,
998 OPC_BNZ_D = (0x1F << 21) | OPC_CP1,
7a387fff
TS
999};
1000
5a5012ec
TS
1001#define MASK_CP1_FUNC(op) MASK_CP1(op) | (op & 0x3F)
1002#define MASK_BC1(op) MASK_CP1(op) | (op & (0x3 << 16))
1003
7a387fff
TS
1004enum {
1005 OPC_BC1F = (0x00 << 16) | OPC_BC1,
1006 OPC_BC1T = (0x01 << 16) | OPC_BC1,
1007 OPC_BC1FL = (0x02 << 16) | OPC_BC1,
1008 OPC_BC1TL = (0x03 << 16) | OPC_BC1,
1009};
1010
5a5012ec
TS
1011enum {
1012 OPC_BC1FANY2 = (0x00 << 16) | OPC_BC1ANY2,
1013 OPC_BC1TANY2 = (0x01 << 16) | OPC_BC1ANY2,
1014};
1015
1016enum {
1017 OPC_BC1FANY4 = (0x00 << 16) | OPC_BC1ANY4,
1018 OPC_BC1TANY4 = (0x01 << 16) | OPC_BC1ANY4,
1019};
7a387fff
TS
1020
1021#define MASK_CP2(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
e0c84da7
TS
1022
1023enum {
1024 OPC_MFC2 = (0x00 << 21) | OPC_CP2,
1025 OPC_DMFC2 = (0x01 << 21) | OPC_CP2,
1026 OPC_CFC2 = (0x02 << 21) | OPC_CP2,
1027 OPC_MFHC2 = (0x03 << 21) | OPC_CP2,
1028 OPC_MTC2 = (0x04 << 21) | OPC_CP2,
1029 OPC_DMTC2 = (0x05 << 21) | OPC_CP2,
1030 OPC_CTC2 = (0x06 << 21) | OPC_CP2,
1031 OPC_MTHC2 = (0x07 << 21) | OPC_CP2,
1032 OPC_BC2 = (0x08 << 21) | OPC_CP2,
31837be3
YK
1033 OPC_BC2EQZ = (0x09 << 21) | OPC_CP2,
1034 OPC_BC2NEZ = (0x0D << 21) | OPC_CP2,
e0c84da7
TS
1035};
1036
bd277fa1
RH
1037#define MASK_LMI(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)) | (op & 0x1F))
1038
1039enum {
1040 OPC_PADDSH = (24 << 21) | (0x00) | OPC_CP2,
1041 OPC_PADDUSH = (25 << 21) | (0x00) | OPC_CP2,
1042 OPC_PADDH = (26 << 21) | (0x00) | OPC_CP2,
1043 OPC_PADDW = (27 << 21) | (0x00) | OPC_CP2,
1044 OPC_PADDSB = (28 << 21) | (0x00) | OPC_CP2,
1045 OPC_PADDUSB = (29 << 21) | (0x00) | OPC_CP2,
1046 OPC_PADDB = (30 << 21) | (0x00) | OPC_CP2,
1047 OPC_PADDD = (31 << 21) | (0x00) | OPC_CP2,
1048
1049 OPC_PSUBSH = (24 << 21) | (0x01) | OPC_CP2,
1050 OPC_PSUBUSH = (25 << 21) | (0x01) | OPC_CP2,
1051 OPC_PSUBH = (26 << 21) | (0x01) | OPC_CP2,
1052 OPC_PSUBW = (27 << 21) | (0x01) | OPC_CP2,
1053 OPC_PSUBSB = (28 << 21) | (0x01) | OPC_CP2,
1054 OPC_PSUBUSB = (29 << 21) | (0x01) | OPC_CP2,
1055 OPC_PSUBB = (30 << 21) | (0x01) | OPC_CP2,
1056 OPC_PSUBD = (31 << 21) | (0x01) | OPC_CP2,
1057
1058 OPC_PSHUFH = (24 << 21) | (0x02) | OPC_CP2,
1059 OPC_PACKSSWH = (25 << 21) | (0x02) | OPC_CP2,
1060 OPC_PACKSSHB = (26 << 21) | (0x02) | OPC_CP2,
1061 OPC_PACKUSHB = (27 << 21) | (0x02) | OPC_CP2,
1062 OPC_XOR_CP2 = (28 << 21) | (0x02) | OPC_CP2,
1063 OPC_NOR_CP2 = (29 << 21) | (0x02) | OPC_CP2,
1064 OPC_AND_CP2 = (30 << 21) | (0x02) | OPC_CP2,
1065 OPC_PANDN = (31 << 21) | (0x02) | OPC_CP2,
1066
1067 OPC_PUNPCKLHW = (24 << 21) | (0x03) | OPC_CP2,
1068 OPC_PUNPCKHHW = (25 << 21) | (0x03) | OPC_CP2,
1069 OPC_PUNPCKLBH = (26 << 21) | (0x03) | OPC_CP2,
1070 OPC_PUNPCKHBH = (27 << 21) | (0x03) | OPC_CP2,
1071 OPC_PINSRH_0 = (28 << 21) | (0x03) | OPC_CP2,
1072 OPC_PINSRH_1 = (29 << 21) | (0x03) | OPC_CP2,
1073 OPC_PINSRH_2 = (30 << 21) | (0x03) | OPC_CP2,
1074 OPC_PINSRH_3 = (31 << 21) | (0x03) | OPC_CP2,
1075
1076 OPC_PAVGH = (24 << 21) | (0x08) | OPC_CP2,
1077 OPC_PAVGB = (25 << 21) | (0x08) | OPC_CP2,
1078 OPC_PMAXSH = (26 << 21) | (0x08) | OPC_CP2,
1079 OPC_PMINSH = (27 << 21) | (0x08) | OPC_CP2,
1080 OPC_PMAXUB = (28 << 21) | (0x08) | OPC_CP2,
1081 OPC_PMINUB = (29 << 21) | (0x08) | OPC_CP2,
1082
1083 OPC_PCMPEQW = (24 << 21) | (0x09) | OPC_CP2,
1084 OPC_PCMPGTW = (25 << 21) | (0x09) | OPC_CP2,
1085 OPC_PCMPEQH = (26 << 21) | (0x09) | OPC_CP2,
1086 OPC_PCMPGTH = (27 << 21) | (0x09) | OPC_CP2,
1087 OPC_PCMPEQB = (28 << 21) | (0x09) | OPC_CP2,
1088 OPC_PCMPGTB = (29 << 21) | (0x09) | OPC_CP2,
1089
1090 OPC_PSLLW = (24 << 21) | (0x0A) | OPC_CP2,
1091 OPC_PSLLH = (25 << 21) | (0x0A) | OPC_CP2,
1092 OPC_PMULLH = (26 << 21) | (0x0A) | OPC_CP2,
1093 OPC_PMULHH = (27 << 21) | (0x0A) | OPC_CP2,
1094 OPC_PMULUW = (28 << 21) | (0x0A) | OPC_CP2,
1095 OPC_PMULHUH = (29 << 21) | (0x0A) | OPC_CP2,
1096
1097 OPC_PSRLW = (24 << 21) | (0x0B) | OPC_CP2,
1098 OPC_PSRLH = (25 << 21) | (0x0B) | OPC_CP2,
1099 OPC_PSRAW = (26 << 21) | (0x0B) | OPC_CP2,
1100 OPC_PSRAH = (27 << 21) | (0x0B) | OPC_CP2,
1101 OPC_PUNPCKLWD = (28 << 21) | (0x0B) | OPC_CP2,
1102 OPC_PUNPCKHWD = (29 << 21) | (0x0B) | OPC_CP2,
1103
1104 OPC_ADDU_CP2 = (24 << 21) | (0x0C) | OPC_CP2,
1105 OPC_OR_CP2 = (25 << 21) | (0x0C) | OPC_CP2,
1106 OPC_ADD_CP2 = (26 << 21) | (0x0C) | OPC_CP2,
1107 OPC_DADD_CP2 = (27 << 21) | (0x0C) | OPC_CP2,
1108 OPC_SEQU_CP2 = (28 << 21) | (0x0C) | OPC_CP2,
1109 OPC_SEQ_CP2 = (29 << 21) | (0x0C) | OPC_CP2,
1110
1111 OPC_SUBU_CP2 = (24 << 21) | (0x0D) | OPC_CP2,
1112 OPC_PASUBUB = (25 << 21) | (0x0D) | OPC_CP2,
1113 OPC_SUB_CP2 = (26 << 21) | (0x0D) | OPC_CP2,
1114 OPC_DSUB_CP2 = (27 << 21) | (0x0D) | OPC_CP2,
1115 OPC_SLTU_CP2 = (28 << 21) | (0x0D) | OPC_CP2,
1116 OPC_SLT_CP2 = (29 << 21) | (0x0D) | OPC_CP2,
1117
1118 OPC_SLL_CP2 = (24 << 21) | (0x0E) | OPC_CP2,
1119 OPC_DSLL_CP2 = (25 << 21) | (0x0E) | OPC_CP2,
1120 OPC_PEXTRH = (26 << 21) | (0x0E) | OPC_CP2,
1121 OPC_PMADDHW = (27 << 21) | (0x0E) | OPC_CP2,
1122 OPC_SLEU_CP2 = (28 << 21) | (0x0E) | OPC_CP2,
1123 OPC_SLE_CP2 = (29 << 21) | (0x0E) | OPC_CP2,
1124
1125 OPC_SRL_CP2 = (24 << 21) | (0x0F) | OPC_CP2,
1126 OPC_DSRL_CP2 = (25 << 21) | (0x0F) | OPC_CP2,
1127 OPC_SRA_CP2 = (26 << 21) | (0x0F) | OPC_CP2,
1128 OPC_DSRA_CP2 = (27 << 21) | (0x0F) | OPC_CP2,
1129 OPC_BIADD = (28 << 21) | (0x0F) | OPC_CP2,
1130 OPC_PMOVMSKB = (29 << 21) | (0x0F) | OPC_CP2,
1131};
1132
1133
e0c84da7
TS
1134#define MASK_CP3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
1135
1136enum {
1137 OPC_LWXC1 = 0x00 | OPC_CP3,
1138 OPC_LDXC1 = 0x01 | OPC_CP3,
1139 OPC_LUXC1 = 0x05 | OPC_CP3,
1140 OPC_SWXC1 = 0x08 | OPC_CP3,
1141 OPC_SDXC1 = 0x09 | OPC_CP3,
1142 OPC_SUXC1 = 0x0D | OPC_CP3,
1143 OPC_PREFX = 0x0F | OPC_CP3,
1144 OPC_ALNV_PS = 0x1E | OPC_CP3,
1145 OPC_MADD_S = 0x20 | OPC_CP3,
1146 OPC_MADD_D = 0x21 | OPC_CP3,
1147 OPC_MADD_PS = 0x26 | OPC_CP3,
1148 OPC_MSUB_S = 0x28 | OPC_CP3,
1149 OPC_MSUB_D = 0x29 | OPC_CP3,
1150 OPC_MSUB_PS = 0x2E | OPC_CP3,
1151 OPC_NMADD_S = 0x30 | OPC_CP3,
fbcc6828 1152 OPC_NMADD_D = 0x31 | OPC_CP3,
e0c84da7
TS
1153 OPC_NMADD_PS= 0x36 | OPC_CP3,
1154 OPC_NMSUB_S = 0x38 | OPC_CP3,
1155 OPC_NMSUB_D = 0x39 | OPC_CP3,
1156 OPC_NMSUB_PS= 0x3E | OPC_CP3,
1157};
1158
239dfebe
YK
1159/* MSA Opcodes */
1160#define MASK_MSA_MINOR(op) (MASK_OP_MAJOR(op) | (op & 0x3F))
1161enum {
1162 OPC_MSA_I8_00 = 0x00 | OPC_MSA,
1163 OPC_MSA_I8_01 = 0x01 | OPC_MSA,
1164 OPC_MSA_I8_02 = 0x02 | OPC_MSA,
1165 OPC_MSA_I5_06 = 0x06 | OPC_MSA,
1166 OPC_MSA_I5_07 = 0x07 | OPC_MSA,
1167 OPC_MSA_BIT_09 = 0x09 | OPC_MSA,
1168 OPC_MSA_BIT_0A = 0x0A | OPC_MSA,
1169 OPC_MSA_3R_0D = 0x0D | OPC_MSA,
1170 OPC_MSA_3R_0E = 0x0E | OPC_MSA,
1171 OPC_MSA_3R_0F = 0x0F | OPC_MSA,
1172 OPC_MSA_3R_10 = 0x10 | OPC_MSA,
1173 OPC_MSA_3R_11 = 0x11 | OPC_MSA,
1174 OPC_MSA_3R_12 = 0x12 | OPC_MSA,
1175 OPC_MSA_3R_13 = 0x13 | OPC_MSA,
1176 OPC_MSA_3R_14 = 0x14 | OPC_MSA,
1177 OPC_MSA_3R_15 = 0x15 | OPC_MSA,
1178 OPC_MSA_ELM = 0x19 | OPC_MSA,
1179 OPC_MSA_3RF_1A = 0x1A | OPC_MSA,
1180 OPC_MSA_3RF_1B = 0x1B | OPC_MSA,
1181 OPC_MSA_3RF_1C = 0x1C | OPC_MSA,
1182 OPC_MSA_VEC = 0x1E | OPC_MSA,
1183
1184 /* MI10 instruction */
1185 OPC_LD_B = (0x20) | OPC_MSA,
1186 OPC_LD_H = (0x21) | OPC_MSA,
1187 OPC_LD_W = (0x22) | OPC_MSA,
1188 OPC_LD_D = (0x23) | OPC_MSA,
1189 OPC_ST_B = (0x24) | OPC_MSA,
1190 OPC_ST_H = (0x25) | OPC_MSA,
1191 OPC_ST_W = (0x26) | OPC_MSA,
1192 OPC_ST_D = (0x27) | OPC_MSA,
1193};
1194
1195enum {
1196 /* I5 instruction df(bits 22..21) = _b, _h, _w, _d */
1197 OPC_ADDVI_df = (0x0 << 23) | OPC_MSA_I5_06,
1198 OPC_CEQI_df = (0x0 << 23) | OPC_MSA_I5_07,
1199 OPC_SUBVI_df = (0x1 << 23) | OPC_MSA_I5_06,
1200 OPC_MAXI_S_df = (0x2 << 23) | OPC_MSA_I5_06,
1201 OPC_CLTI_S_df = (0x2 << 23) | OPC_MSA_I5_07,
1202 OPC_MAXI_U_df = (0x3 << 23) | OPC_MSA_I5_06,
1203 OPC_CLTI_U_df = (0x3 << 23) | OPC_MSA_I5_07,
1204 OPC_MINI_S_df = (0x4 << 23) | OPC_MSA_I5_06,
1205 OPC_CLEI_S_df = (0x4 << 23) | OPC_MSA_I5_07,
1206 OPC_MINI_U_df = (0x5 << 23) | OPC_MSA_I5_06,
1207 OPC_CLEI_U_df = (0x5 << 23) | OPC_MSA_I5_07,
1208 OPC_LDI_df = (0x6 << 23) | OPC_MSA_I5_07,
1209
1210 /* I8 instruction */
1211 OPC_ANDI_B = (0x0 << 24) | OPC_MSA_I8_00,
1212 OPC_BMNZI_B = (0x0 << 24) | OPC_MSA_I8_01,
1213 OPC_SHF_B = (0x0 << 24) | OPC_MSA_I8_02,
1214 OPC_ORI_B = (0x1 << 24) | OPC_MSA_I8_00,
1215 OPC_BMZI_B = (0x1 << 24) | OPC_MSA_I8_01,
1216 OPC_SHF_H = (0x1 << 24) | OPC_MSA_I8_02,
1217 OPC_NORI_B = (0x2 << 24) | OPC_MSA_I8_00,
1218 OPC_BSELI_B = (0x2 << 24) | OPC_MSA_I8_01,
1219 OPC_SHF_W = (0x2 << 24) | OPC_MSA_I8_02,
1220 OPC_XORI_B = (0x3 << 24) | OPC_MSA_I8_00,
1221
1222 /* VEC/2R/2RF instruction */
1223 OPC_AND_V = (0x00 << 21) | OPC_MSA_VEC,
1224 OPC_OR_V = (0x01 << 21) | OPC_MSA_VEC,
1225 OPC_NOR_V = (0x02 << 21) | OPC_MSA_VEC,
1226 OPC_XOR_V = (0x03 << 21) | OPC_MSA_VEC,
1227 OPC_BMNZ_V = (0x04 << 21) | OPC_MSA_VEC,
1228 OPC_BMZ_V = (0x05 << 21) | OPC_MSA_VEC,
1229 OPC_BSEL_V = (0x06 << 21) | OPC_MSA_VEC,
1230
1231 OPC_MSA_2R = (0x18 << 21) | OPC_MSA_VEC,
1232 OPC_MSA_2RF = (0x19 << 21) | OPC_MSA_VEC,
1233
1234 /* 2R instruction df(bits 17..16) = _b, _h, _w, _d */
1235 OPC_FILL_df = (0x00 << 18) | OPC_MSA_2R,
1236 OPC_PCNT_df = (0x01 << 18) | OPC_MSA_2R,
1237 OPC_NLOC_df = (0x02 << 18) | OPC_MSA_2R,
1238 OPC_NLZC_df = (0x03 << 18) | OPC_MSA_2R,
1239
1240 /* 2RF instruction df(bit 16) = _w, _d */
1241 OPC_FCLASS_df = (0x00 << 17) | OPC_MSA_2RF,
1242 OPC_FTRUNC_S_df = (0x01 << 17) | OPC_MSA_2RF,
1243 OPC_FTRUNC_U_df = (0x02 << 17) | OPC_MSA_2RF,
1244 OPC_FSQRT_df = (0x03 << 17) | OPC_MSA_2RF,
1245 OPC_FRSQRT_df = (0x04 << 17) | OPC_MSA_2RF,
1246 OPC_FRCP_df = (0x05 << 17) | OPC_MSA_2RF,
1247 OPC_FRINT_df = (0x06 << 17) | OPC_MSA_2RF,
1248 OPC_FLOG2_df = (0x07 << 17) | OPC_MSA_2RF,
1249 OPC_FEXUPL_df = (0x08 << 17) | OPC_MSA_2RF,
1250 OPC_FEXUPR_df = (0x09 << 17) | OPC_MSA_2RF,
1251 OPC_FFQL_df = (0x0A << 17) | OPC_MSA_2RF,
1252 OPC_FFQR_df = (0x0B << 17) | OPC_MSA_2RF,
1253 OPC_FTINT_S_df = (0x0C << 17) | OPC_MSA_2RF,
1254 OPC_FTINT_U_df = (0x0D << 17) | OPC_MSA_2RF,
1255 OPC_FFINT_S_df = (0x0E << 17) | OPC_MSA_2RF,
1256 OPC_FFINT_U_df = (0x0F << 17) | OPC_MSA_2RF,
1257
1258 /* 3R instruction df(bits 22..21) = _b, _h, _w, d */
1259 OPC_SLL_df = (0x0 << 23) | OPC_MSA_3R_0D,
1260 OPC_ADDV_df = (0x0 << 23) | OPC_MSA_3R_0E,
1261 OPC_CEQ_df = (0x0 << 23) | OPC_MSA_3R_0F,
1262 OPC_ADD_A_df = (0x0 << 23) | OPC_MSA_3R_10,
1263 OPC_SUBS_S_df = (0x0 << 23) | OPC_MSA_3R_11,
1264 OPC_MULV_df = (0x0 << 23) | OPC_MSA_3R_12,
1265 OPC_DOTP_S_df = (0x0 << 23) | OPC_MSA_3R_13,
1266 OPC_SLD_df = (0x0 << 23) | OPC_MSA_3R_14,
1267 OPC_VSHF_df = (0x0 << 23) | OPC_MSA_3R_15,
1268 OPC_SRA_df = (0x1 << 23) | OPC_MSA_3R_0D,
1269 OPC_SUBV_df = (0x1 << 23) | OPC_MSA_3R_0E,
1270 OPC_ADDS_A_df = (0x1 << 23) | OPC_MSA_3R_10,
1271 OPC_SUBS_U_df = (0x1 << 23) | OPC_MSA_3R_11,
1272 OPC_MADDV_df = (0x1 << 23) | OPC_MSA_3R_12,
1273 OPC_DOTP_U_df = (0x1 << 23) | OPC_MSA_3R_13,
1274 OPC_SPLAT_df = (0x1 << 23) | OPC_MSA_3R_14,
1275 OPC_SRAR_df = (0x1 << 23) | OPC_MSA_3R_15,
1276 OPC_SRL_df = (0x2 << 23) | OPC_MSA_3R_0D,
1277 OPC_MAX_S_df = (0x2 << 23) | OPC_MSA_3R_0E,
1278 OPC_CLT_S_df = (0x2 << 23) | OPC_MSA_3R_0F,
1279 OPC_ADDS_S_df = (0x2 << 23) | OPC_MSA_3R_10,
1280 OPC_SUBSUS_U_df = (0x2 << 23) | OPC_MSA_3R_11,
1281 OPC_MSUBV_df = (0x2 << 23) | OPC_MSA_3R_12,
1282 OPC_DPADD_S_df = (0x2 << 23) | OPC_MSA_3R_13,
1283 OPC_PCKEV_df = (0x2 << 23) | OPC_MSA_3R_14,
1284 OPC_SRLR_df = (0x2 << 23) | OPC_MSA_3R_15,
1285 OPC_BCLR_df = (0x3 << 23) | OPC_MSA_3R_0D,
1286 OPC_MAX_U_df = (0x3 << 23) | OPC_MSA_3R_0E,
1287 OPC_CLT_U_df = (0x3 << 23) | OPC_MSA_3R_0F,
1288 OPC_ADDS_U_df = (0x3 << 23) | OPC_MSA_3R_10,
1289 OPC_SUBSUU_S_df = (0x3 << 23) | OPC_MSA_3R_11,
1290 OPC_DPADD_U_df = (0x3 << 23) | OPC_MSA_3R_13,
1291 OPC_PCKOD_df = (0x3 << 23) | OPC_MSA_3R_14,
1292 OPC_BSET_df = (0x4 << 23) | OPC_MSA_3R_0D,
1293 OPC_MIN_S_df = (0x4 << 23) | OPC_MSA_3R_0E,
1294 OPC_CLE_S_df = (0x4 << 23) | OPC_MSA_3R_0F,
1295 OPC_AVE_S_df = (0x4 << 23) | OPC_MSA_3R_10,
1296 OPC_ASUB_S_df = (0x4 << 23) | OPC_MSA_3R_11,
1297 OPC_DIV_S_df = (0x4 << 23) | OPC_MSA_3R_12,
1298 OPC_DPSUB_S_df = (0x4 << 23) | OPC_MSA_3R_13,
1299 OPC_ILVL_df = (0x4 << 23) | OPC_MSA_3R_14,
1300 OPC_HADD_S_df = (0x4 << 23) | OPC_MSA_3R_15,
1301 OPC_BNEG_df = (0x5 << 23) | OPC_MSA_3R_0D,
1302 OPC_MIN_U_df = (0x5 << 23) | OPC_MSA_3R_0E,
1303 OPC_CLE_U_df = (0x5 << 23) | OPC_MSA_3R_0F,
1304 OPC_AVE_U_df = (0x5 << 23) | OPC_MSA_3R_10,
1305 OPC_ASUB_U_df = (0x5 << 23) | OPC_MSA_3R_11,
1306 OPC_DIV_U_df = (0x5 << 23) | OPC_MSA_3R_12,
1307 OPC_DPSUB_U_df = (0x5 << 23) | OPC_MSA_3R_13,
1308 OPC_ILVR_df = (0x5 << 23) | OPC_MSA_3R_14,
1309 OPC_HADD_U_df = (0x5 << 23) | OPC_MSA_3R_15,
1310 OPC_BINSL_df = (0x6 << 23) | OPC_MSA_3R_0D,
1311 OPC_MAX_A_df = (0x6 << 23) | OPC_MSA_3R_0E,
1312 OPC_AVER_S_df = (0x6 << 23) | OPC_MSA_3R_10,
1313 OPC_MOD_S_df = (0x6 << 23) | OPC_MSA_3R_12,
1314 OPC_ILVEV_df = (0x6 << 23) | OPC_MSA_3R_14,
1315 OPC_HSUB_S_df = (0x6 << 23) | OPC_MSA_3R_15,
1316 OPC_BINSR_df = (0x7 << 23) | OPC_MSA_3R_0D,
1317 OPC_MIN_A_df = (0x7 << 23) | OPC_MSA_3R_0E,
1318 OPC_AVER_U_df = (0x7 << 23) | OPC_MSA_3R_10,
1319 OPC_MOD_U_df = (0x7 << 23) | OPC_MSA_3R_12,
1320 OPC_ILVOD_df = (0x7 << 23) | OPC_MSA_3R_14,
1321 OPC_HSUB_U_df = (0x7 << 23) | OPC_MSA_3R_15,
1322
1323 /* ELM instructions df(bits 21..16) = _b, _h, _w, _d */
1324 OPC_SLDI_df = (0x0 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1325 OPC_CTCMSA = (0x0 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1326 OPC_SPLATI_df = (0x1 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1327 OPC_CFCMSA = (0x1 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1328 OPC_COPY_S_df = (0x2 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1329 OPC_MOVE_V = (0x2 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1330 OPC_COPY_U_df = (0x3 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1331 OPC_INSERT_df = (0x4 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1332 OPC_INSVE_df = (0x5 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1333
1334 /* 3RF instruction _df(bit 21) = _w, _d */
1335 OPC_FCAF_df = (0x0 << 22) | OPC_MSA_3RF_1A,
1336 OPC_FADD_df = (0x0 << 22) | OPC_MSA_3RF_1B,
1337 OPC_FCUN_df = (0x1 << 22) | OPC_MSA_3RF_1A,
1338 OPC_FSUB_df = (0x1 << 22) | OPC_MSA_3RF_1B,
1339 OPC_FCOR_df = (0x1 << 22) | OPC_MSA_3RF_1C,
1340 OPC_FCEQ_df = (0x2 << 22) | OPC_MSA_3RF_1A,
1341 OPC_FMUL_df = (0x2 << 22) | OPC_MSA_3RF_1B,
1342 OPC_FCUNE_df = (0x2 << 22) | OPC_MSA_3RF_1C,
1343 OPC_FCUEQ_df = (0x3 << 22) | OPC_MSA_3RF_1A,
1344 OPC_FDIV_df = (0x3 << 22) | OPC_MSA_3RF_1B,
1345 OPC_FCNE_df = (0x3 << 22) | OPC_MSA_3RF_1C,
1346 OPC_FCLT_df = (0x4 << 22) | OPC_MSA_3RF_1A,
1347 OPC_FMADD_df = (0x4 << 22) | OPC_MSA_3RF_1B,
1348 OPC_MUL_Q_df = (0x4 << 22) | OPC_MSA_3RF_1C,
1349 OPC_FCULT_df = (0x5 << 22) | OPC_MSA_3RF_1A,
1350 OPC_FMSUB_df = (0x5 << 22) | OPC_MSA_3RF_1B,
1351 OPC_MADD_Q_df = (0x5 << 22) | OPC_MSA_3RF_1C,
1352 OPC_FCLE_df = (0x6 << 22) | OPC_MSA_3RF_1A,
1353 OPC_MSUB_Q_df = (0x6 << 22) | OPC_MSA_3RF_1C,
1354 OPC_FCULE_df = (0x7 << 22) | OPC_MSA_3RF_1A,
1355 OPC_FEXP2_df = (0x7 << 22) | OPC_MSA_3RF_1B,
1356 OPC_FSAF_df = (0x8 << 22) | OPC_MSA_3RF_1A,
1357 OPC_FEXDO_df = (0x8 << 22) | OPC_MSA_3RF_1B,
1358 OPC_FSUN_df = (0x9 << 22) | OPC_MSA_3RF_1A,
1359 OPC_FSOR_df = (0x9 << 22) | OPC_MSA_3RF_1C,
1360 OPC_FSEQ_df = (0xA << 22) | OPC_MSA_3RF_1A,
1361 OPC_FTQ_df = (0xA << 22) | OPC_MSA_3RF_1B,
1362 OPC_FSUNE_df = (0xA << 22) | OPC_MSA_3RF_1C,
1363 OPC_FSUEQ_df = (0xB << 22) | OPC_MSA_3RF_1A,
1364 OPC_FSNE_df = (0xB << 22) | OPC_MSA_3RF_1C,
1365 OPC_FSLT_df = (0xC << 22) | OPC_MSA_3RF_1A,
1366 OPC_FMIN_df = (0xC << 22) | OPC_MSA_3RF_1B,
1367 OPC_MULR_Q_df = (0xC << 22) | OPC_MSA_3RF_1C,
1368 OPC_FSULT_df = (0xD << 22) | OPC_MSA_3RF_1A,
1369 OPC_FMIN_A_df = (0xD << 22) | OPC_MSA_3RF_1B,
1370 OPC_MADDR_Q_df = (0xD << 22) | OPC_MSA_3RF_1C,
1371 OPC_FSLE_df = (0xE << 22) | OPC_MSA_3RF_1A,
1372 OPC_FMAX_df = (0xE << 22) | OPC_MSA_3RF_1B,
1373 OPC_MSUBR_Q_df = (0xE << 22) | OPC_MSA_3RF_1C,
1374 OPC_FSULE_df = (0xF << 22) | OPC_MSA_3RF_1A,
1375 OPC_FMAX_A_df = (0xF << 22) | OPC_MSA_3RF_1B,
1376
1377 /* BIT instruction df(bits 22..16) = _B _H _W _D */
1378 OPC_SLLI_df = (0x0 << 23) | OPC_MSA_BIT_09,
1379 OPC_SAT_S_df = (0x0 << 23) | OPC_MSA_BIT_0A,
1380 OPC_SRAI_df = (0x1 << 23) | OPC_MSA_BIT_09,
1381 OPC_SAT_U_df = (0x1 << 23) | OPC_MSA_BIT_0A,
1382 OPC_SRLI_df = (0x2 << 23) | OPC_MSA_BIT_09,
1383 OPC_SRARI_df = (0x2 << 23) | OPC_MSA_BIT_0A,
1384 OPC_BCLRI_df = (0x3 << 23) | OPC_MSA_BIT_09,
1385 OPC_SRLRI_df = (0x3 << 23) | OPC_MSA_BIT_0A,
1386 OPC_BSETI_df = (0x4 << 23) | OPC_MSA_BIT_09,
1387 OPC_BNEGI_df = (0x5 << 23) | OPC_MSA_BIT_09,
1388 OPC_BINSLI_df = (0x6 << 23) | OPC_MSA_BIT_09,
1389 OPC_BINSRI_df = (0x7 << 23) | OPC_MSA_BIT_09,
1390};
1391
39454628 1392/* global register indices */
a7812ae4 1393static TCGv cpu_gpr[32], cpu_PC;
340fff72 1394static TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC];
41db4607
AJ
1395static TCGv cpu_dspctrl, btarget, bcond;
1396static TCGv_i32 hflags;
a7812ae4 1397static TCGv_i32 fpu_fcr0, fpu_fcr31;
d73ee8a2 1398static TCGv_i64 fpu_f64[32];
863f264d 1399static TCGv_i64 msa_wr_d[64];
aa0bf00b 1400
022c62cb 1401#include "exec/gen-icount.h"
2e70f6ef 1402
895c2d04 1403#define gen_helper_0e0i(name, arg) do { \
a7812ae4 1404 TCGv_i32 helper_tmp = tcg_const_i32(arg); \
895c2d04 1405 gen_helper_##name(cpu_env, helper_tmp); \
a7812ae4
PB
1406 tcg_temp_free_i32(helper_tmp); \
1407 } while(0)
be24bb4f 1408
895c2d04 1409#define gen_helper_0e1i(name, arg1, arg2) do { \
a7812ae4 1410 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
895c2d04 1411 gen_helper_##name(cpu_env, arg1, helper_tmp); \
a7812ae4
PB
1412 tcg_temp_free_i32(helper_tmp); \
1413 } while(0)
be24bb4f 1414
895c2d04
BS
1415#define gen_helper_1e0i(name, ret, arg1) do { \
1416 TCGv_i32 helper_tmp = tcg_const_i32(arg1); \
1417 gen_helper_##name(ret, cpu_env, helper_tmp); \
1418 tcg_temp_free_i32(helper_tmp); \
1419 } while(0)
1420
1421#define gen_helper_1e1i(name, ret, arg1, arg2) do { \
1422 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
1423 gen_helper_##name(ret, cpu_env, arg1, helper_tmp); \
1424 tcg_temp_free_i32(helper_tmp); \
1425 } while(0)
1426
1427#define gen_helper_0e2i(name, arg1, arg2, arg3) do { \
1428 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
1429 gen_helper_##name(cpu_env, arg1, arg2, helper_tmp); \
1430 tcg_temp_free_i32(helper_tmp); \
1431 } while(0)
1432
1433#define gen_helper_1e2i(name, ret, arg1, arg2, arg3) do { \
a7812ae4 1434 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
895c2d04 1435 gen_helper_##name(ret, cpu_env, arg1, arg2, helper_tmp); \
a7812ae4
PB
1436 tcg_temp_free_i32(helper_tmp); \
1437 } while(0)
be24bb4f 1438
895c2d04 1439#define gen_helper_0e3i(name, arg1, arg2, arg3, arg4) do { \
a7812ae4 1440 TCGv_i32 helper_tmp = tcg_const_i32(arg4); \
895c2d04 1441 gen_helper_##name(cpu_env, arg1, arg2, arg3, helper_tmp); \
a7812ae4
PB
1442 tcg_temp_free_i32(helper_tmp); \
1443 } while(0)
c239529e 1444
8e9ade68 1445typedef struct DisasContext {
eeb3bba8
EC
1446 DisasContextBase base;
1447 target_ulong saved_pc;
18f440ed 1448 target_ulong page_start;
8e9ade68 1449 uint32_t opcode;
d75c135e 1450 int insn_flags;
5ab5c041 1451 int32_t CP0_Config1;
8e9ade68
TS
1452 /* Routine used to access memory */
1453 int mem_idx;
be3a8c53 1454 TCGMemOp default_tcg_memop_mask;
8e9ade68 1455 uint32_t hflags, saved_hflags;
8e9ade68 1456 target_ulong btarget;
d279279e 1457 bool ulri;
e98c0d17 1458 int kscrexist;
7207c7f9 1459 bool rxi;
9456c2fb 1460 int ie;
aea14095
LA
1461 bool bi;
1462 bool bp;
5204ea79
LA
1463 uint64_t PAMask;
1464 bool mvh;
76964147 1465 bool eva;
cec56a73 1466 bool sc;
5204ea79 1467 int CP0_LLAddr_shift;
e29c9628 1468 bool ps;
01bc435b 1469 bool vp;
c870e3f5 1470 bool cmgcr;
f6d4dd81 1471 bool mrp;
87552089 1472 bool nan2008;
6be77480 1473 bool abs2008;
8e9ade68
TS
1474} DisasContext;
1475
b28425ba
EC
1476#define DISAS_STOP DISAS_TARGET_0
1477#define DISAS_EXIT DISAS_TARGET_1
8e9ade68 1478
d73ee8a2
RH
1479static const char * const regnames[] = {
1480 "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
1481 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
1482 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
1483 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
1484};
6af0bf9c 1485
d73ee8a2
RH
1486static const char * const regnames_HI[] = {
1487 "HI0", "HI1", "HI2", "HI3",
1488};
4b2eb8d2 1489
d73ee8a2
RH
1490static const char * const regnames_LO[] = {
1491 "LO0", "LO1", "LO2", "LO3",
1492};
4b2eb8d2 1493
d73ee8a2
RH
1494static const char * const fregnames[] = {
1495 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
1496 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
1497 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
1498 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
1499};
958fb4a9 1500
863f264d
YK
1501static const char * const msaregnames[] = {
1502 "w0.d0", "w0.d1", "w1.d0", "w1.d1",
1503 "w2.d0", "w2.d1", "w3.d0", "w3.d1",
1504 "w4.d0", "w4.d1", "w5.d0", "w5.d1",
1505 "w6.d0", "w6.d1", "w7.d0", "w7.d1",
1506 "w8.d0", "w8.d1", "w9.d0", "w9.d1",
1507 "w10.d0", "w10.d1", "w11.d0", "w11.d1",
1508 "w12.d0", "w12.d1", "w13.d0", "w13.d1",
1509 "w14.d0", "w14.d1", "w15.d0", "w15.d1",
1510 "w16.d0", "w16.d1", "w17.d0", "w17.d1",
1511 "w18.d0", "w18.d1", "w19.d0", "w19.d1",
1512 "w20.d0", "w20.d1", "w21.d0", "w21.d1",
1513 "w22.d0", "w22.d1", "w23.d0", "w23.d1",
1514 "w24.d0", "w24.d1", "w25.d0", "w25.d1",
1515 "w26.d0", "w26.d1", "w27.d0", "w27.d1",
1516 "w28.d0", "w28.d1", "w29.d0", "w29.d1",
1517 "w30.d0", "w30.d1", "w31.d0", "w31.d1",
1518};
1519
9d68ac14 1520#define LOG_DISAS(...) \
fb7729e2
RH
1521 do { \
1522 if (MIPS_DEBUG_DISAS) { \
9d68ac14 1523 qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__); \
fb7729e2
RH
1524 } \
1525 } while (0)
1526
9d68ac14 1527#define MIPS_INVAL(op) \
fb7729e2
RH
1528 do { \
1529 if (MIPS_DEBUG_DISAS) { \
9d68ac14
AJ
1530 qemu_log_mask(CPU_LOG_TB_IN_ASM, \
1531 TARGET_FMT_lx ": %08x Invalid %s %03x %03x %03x\n", \
eeb3bba8
EC
1532 ctx->base.pc_next, ctx->opcode, op, \
1533 ctx->opcode >> 26, ctx->opcode & 0x3F, \
1534 ((ctx->opcode >> 16) & 0x1F)); \
fb7729e2
RH
1535 } \
1536 } while (0)
958fb4a9 1537
8e9ade68
TS
1538/* General purpose registers moves. */
1539static inline void gen_load_gpr (TCGv t, int reg)
aaa9128a 1540{
8e9ade68
TS
1541 if (reg == 0)
1542 tcg_gen_movi_tl(t, 0);
1543 else
4b2eb8d2 1544 tcg_gen_mov_tl(t, cpu_gpr[reg]);
aaa9128a
TS
1545}
1546
8e9ade68 1547static inline void gen_store_gpr (TCGv t, int reg)
aaa9128a 1548{
8e9ade68 1549 if (reg != 0)
4b2eb8d2 1550 tcg_gen_mov_tl(cpu_gpr[reg], t);
aaa9128a
TS
1551}
1552
8e9ade68 1553/* Moves to/from shadow registers. */
be24bb4f 1554static inline void gen_load_srsgpr (int from, int to)
aaa9128a 1555{
d9bea114 1556 TCGv t0 = tcg_temp_new();
be24bb4f
TS
1557
1558 if (from == 0)
d9bea114 1559 tcg_gen_movi_tl(t0, 0);
8e9ade68 1560 else {
d9bea114 1561 TCGv_i32 t2 = tcg_temp_new_i32();
a7812ae4 1562 TCGv_ptr addr = tcg_temp_new_ptr();
aaa9128a 1563
7db13fae 1564 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
d9bea114
AJ
1565 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1566 tcg_gen_andi_i32(t2, t2, 0xf);
1567 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1568 tcg_gen_ext_i32_ptr(addr, t2);
a7812ae4 1569 tcg_gen_add_ptr(addr, cpu_env, addr);
aaa9128a 1570
d9bea114 1571 tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from);
a7812ae4 1572 tcg_temp_free_ptr(addr);
d9bea114 1573 tcg_temp_free_i32(t2);
8e9ade68 1574 }
d9bea114
AJ
1575 gen_store_gpr(t0, to);
1576 tcg_temp_free(t0);
aaa9128a
TS
1577}
1578
be24bb4f 1579static inline void gen_store_srsgpr (int from, int to)
aaa9128a 1580{
be24bb4f 1581 if (to != 0) {
d9bea114
AJ
1582 TCGv t0 = tcg_temp_new();
1583 TCGv_i32 t2 = tcg_temp_new_i32();
a7812ae4 1584 TCGv_ptr addr = tcg_temp_new_ptr();
be24bb4f 1585
d9bea114 1586 gen_load_gpr(t0, from);
7db13fae 1587 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
d9bea114
AJ
1588 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1589 tcg_gen_andi_i32(t2, t2, 0xf);
1590 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1591 tcg_gen_ext_i32_ptr(addr, t2);
a7812ae4 1592 tcg_gen_add_ptr(addr, cpu_env, addr);
be24bb4f 1593
d9bea114 1594 tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to);
a7812ae4 1595 tcg_temp_free_ptr(addr);
d9bea114
AJ
1596 tcg_temp_free_i32(t2);
1597 tcg_temp_free(t0);
8e9ade68 1598 }
aaa9128a
TS
1599}
1600
eab9944c
LA
1601/* Tests */
1602static inline void gen_save_pc(target_ulong pc)
1603{
1604 tcg_gen_movi_tl(cpu_PC, pc);
1605}
1606
1607static inline void save_cpu_state(DisasContext *ctx, int do_save_pc)
1608{
1609 LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
eeb3bba8
EC
1610 if (do_save_pc && ctx->base.pc_next != ctx->saved_pc) {
1611 gen_save_pc(ctx->base.pc_next);
1612 ctx->saved_pc = ctx->base.pc_next;
eab9944c
LA
1613 }
1614 if (ctx->hflags != ctx->saved_hflags) {
1615 tcg_gen_movi_i32(hflags, ctx->hflags);
1616 ctx->saved_hflags = ctx->hflags;
1617 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
1618 case MIPS_HFLAG_BR:
1619 break;
1620 case MIPS_HFLAG_BC:
1621 case MIPS_HFLAG_BL:
1622 case MIPS_HFLAG_B:
1623 tcg_gen_movi_tl(btarget, ctx->btarget);
1624 break;
1625 }
1626 }
1627}
1628
1629static inline void restore_cpu_state(CPUMIPSState *env, DisasContext *ctx)
1630{
1631 ctx->saved_hflags = ctx->hflags;
1632 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
1633 case MIPS_HFLAG_BR:
1634 break;
1635 case MIPS_HFLAG_BC:
1636 case MIPS_HFLAG_BL:
1637 case MIPS_HFLAG_B:
1638 ctx->btarget = env->btarget;
1639 break;
1640 }
1641}
1642
1643static inline void generate_exception_err(DisasContext *ctx, int excp, int err)
1644{
1645 TCGv_i32 texcp = tcg_const_i32(excp);
1646 TCGv_i32 terr = tcg_const_i32(err);
1647 save_cpu_state(ctx, 1);
1648 gen_helper_raise_exception_err(cpu_env, texcp, terr);
1649 tcg_temp_free_i32(terr);
1650 tcg_temp_free_i32(texcp);
eeb3bba8 1651 ctx->base.is_jmp = DISAS_NORETURN;
eab9944c
LA
1652}
1653
1654static inline void generate_exception(DisasContext *ctx, int excp)
1655{
eab9944c
LA
1656 gen_helper_0e0i(raise_exception, excp);
1657}
1658
9c708c7f
PD
1659static inline void generate_exception_end(DisasContext *ctx, int excp)
1660{
1661 generate_exception_err(ctx, excp, 0);
1662}
1663
aaa9128a 1664/* Floating point register moves. */
7c979afd 1665static void gen_load_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
aa0bf00b 1666{
7c979afd
LA
1667 if (ctx->hflags & MIPS_HFLAG_FRE) {
1668 generate_exception(ctx, EXCP_RI);
1669 }
ecc7b3aa 1670 tcg_gen_extrl_i64_i32(t, fpu_f64[reg]);
6ea83fed
FB
1671}
1672
7c979afd 1673static void gen_store_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
aa0bf00b 1674{
7c979afd
LA
1675 TCGv_i64 t64;
1676 if (ctx->hflags & MIPS_HFLAG_FRE) {
1677 generate_exception(ctx, EXCP_RI);
1678 }
1679 t64 = tcg_temp_new_i64();
d73ee8a2
RH
1680 tcg_gen_extu_i32_i64(t64, t);
1681 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 0, 32);
1682 tcg_temp_free_i64(t64);
6d066274
AJ
1683}
1684
7f6613ce 1685static void gen_load_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
6d066274 1686{
7f6613ce 1687 if (ctx->hflags & MIPS_HFLAG_F64) {
71f303cd 1688 tcg_gen_extrh_i64_i32(t, fpu_f64[reg]);
7f6613ce 1689 } else {
7c979afd 1690 gen_load_fpr32(ctx, t, reg | 1);
7f6613ce 1691 }
6d066274
AJ
1692}
1693
7f6613ce 1694static void gen_store_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
6d066274 1695{
7f6613ce
PJ
1696 if (ctx->hflags & MIPS_HFLAG_F64) {
1697 TCGv_i64 t64 = tcg_temp_new_i64();
1698 tcg_gen_extu_i32_i64(t64, t);
1699 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 32, 32);
1700 tcg_temp_free_i64(t64);
1701 } else {
7c979afd 1702 gen_store_fpr32(ctx, t, reg | 1);
7f6613ce 1703 }
aa0bf00b 1704}
6ea83fed 1705
d73ee8a2 1706static void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
aa0bf00b 1707{
f364515c 1708 if (ctx->hflags & MIPS_HFLAG_F64) {
d73ee8a2 1709 tcg_gen_mov_i64(t, fpu_f64[reg]);
f364515c 1710 } else {
d73ee8a2 1711 tcg_gen_concat32_i64(t, fpu_f64[reg & ~1], fpu_f64[reg | 1]);
aa0bf00b
TS
1712 }
1713}
6ea83fed 1714
d73ee8a2 1715static void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
aa0bf00b 1716{
f364515c 1717 if (ctx->hflags & MIPS_HFLAG_F64) {
d73ee8a2 1718 tcg_gen_mov_i64(fpu_f64[reg], t);
f364515c 1719 } else {
d73ee8a2
RH
1720 TCGv_i64 t0;
1721 tcg_gen_deposit_i64(fpu_f64[reg & ~1], fpu_f64[reg & ~1], t, 0, 32);
1722 t0 = tcg_temp_new_i64();
6d066274 1723 tcg_gen_shri_i64(t0, t, 32);
d73ee8a2 1724 tcg_gen_deposit_i64(fpu_f64[reg | 1], fpu_f64[reg | 1], t0, 0, 32);
6d066274 1725 tcg_temp_free_i64(t0);
aa0bf00b
TS
1726 }
1727}
6ea83fed 1728
d94536f4 1729static inline int get_fp_bit (int cc)
a16336e4 1730{
d94536f4
AJ
1731 if (cc)
1732 return 24 + cc;
1733 else
1734 return 23;
a16336e4
TS
1735}
1736
48d38ca5 1737/* Addresses computation */
941694d0 1738static inline void gen_op_addr_add (DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1)
4ad40f36 1739{
941694d0 1740 tcg_gen_add_tl(ret, arg0, arg1);
48d38ca5
TS
1741
1742#if defined(TARGET_MIPS64)
01f72885 1743 if (ctx->hflags & MIPS_HFLAG_AWRAP) {
941694d0 1744 tcg_gen_ext32s_i64(ret, ret);
48d38ca5
TS
1745 }
1746#endif
4ad40f36
FB
1747}
1748
31837be3
YK
1749/* Addresses computation (translation time) */
1750static target_long addr_add(DisasContext *ctx, target_long base,
1751 target_long offset)
1752{
1753 target_long sum = base + offset;
1754
1755#if defined(TARGET_MIPS64)
1756 if (ctx->hflags & MIPS_HFLAG_AWRAP) {
1757 sum = (int32_t)sum;
1758 }
1759#endif
1760 return sum;
1761}
1762
71f303cd 1763/* Sign-extract the low 32-bits to a target_long. */
1f1b4c00
YK
1764static inline void gen_move_low32(TCGv ret, TCGv_i64 arg)
1765{
1766#if defined(TARGET_MIPS64)
71f303cd
RH
1767 tcg_gen_ext32s_i64(ret, arg);
1768#else
1769 tcg_gen_extrl_i64_i32(ret, arg);
1770#endif
1771}
1772
1773/* Sign-extract the high 32-bits to a target_long. */
1774static inline void gen_move_high32(TCGv ret, TCGv_i64 arg)
1775{
1776#if defined(TARGET_MIPS64)
1777 tcg_gen_sari_i64(ret, arg, 32);
1f1b4c00 1778#else
71f303cd 1779 tcg_gen_extrh_i64_i32(ret, arg);
1f1b4c00
YK
1780#endif
1781}
1782
356265ae 1783static inline void check_cp0_enabled(DisasContext *ctx)
387a8fe5 1784{
fe253235 1785 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
c2c65dab 1786 generate_exception_err(ctx, EXCP_CpU, 0);
387a8fe5
TS
1787}
1788
356265ae 1789static inline void check_cp1_enabled(DisasContext *ctx)
5e755519 1790{
fe253235 1791 if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
5e755519
TS
1792 generate_exception_err(ctx, EXCP_CpU, 1);
1793}
1794
b8aa4598
TS
1795/* Verify that the processor is running with COP1X instructions enabled.
1796 This is associated with the nabla symbol in the MIPS32 and MIPS64
1797 opcode tables. */
1798
356265ae 1799static inline void check_cop1x(DisasContext *ctx)
b8aa4598
TS
1800{
1801 if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
9c708c7f 1802 generate_exception_end(ctx, EXCP_RI);
b8aa4598
TS
1803}
1804
1805/* Verify that the processor is running with 64-bit floating-point
1806 operations enabled. */
1807
356265ae 1808static inline void check_cp1_64bitmode(DisasContext *ctx)
5e755519 1809{
b8aa4598 1810 if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
9c708c7f 1811 generate_exception_end(ctx, EXCP_RI);
5e755519
TS
1812}
1813
1814/*
1815 * Verify if floating point register is valid; an operation is not defined
1816 * if bit 0 of any register specification is set and the FR bit in the
1817 * Status register equals zero, since the register numbers specify an
1818 * even-odd pair of adjacent coprocessor general registers. When the FR bit
1819 * in the Status register equals one, both even and odd register numbers
1820 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
1821 *
1822 * Multiple 64 bit wide registers can be checked by calling
1823 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
1824 */
356265ae 1825static inline void check_cp1_registers(DisasContext *ctx, int regs)
5e755519 1826{
fe253235 1827 if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)))
9c708c7f 1828 generate_exception_end(ctx, EXCP_RI);
5e755519
TS
1829}
1830
853c3240
JL
1831/* Verify that the processor is running with DSP instructions enabled.
1832 This is enabled by CP0 Status register MX(24) bit.
1833 */
1834
1835static inline void check_dsp(DisasContext *ctx)
1836{
1837 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP))) {
ad153f15 1838 if (ctx->insn_flags & ASE_DSP) {
9c708c7f 1839 generate_exception_end(ctx, EXCP_DSPDIS);
ad153f15 1840 } else {
9c708c7f 1841 generate_exception_end(ctx, EXCP_RI);
ad153f15 1842 }
853c3240
JL
1843 }
1844}
1845
1846static inline void check_dspr2(DisasContext *ctx)
1847{
1848 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSPR2))) {
ad153f15 1849 if (ctx->insn_flags & ASE_DSP) {
9c708c7f 1850 generate_exception_end(ctx, EXCP_DSPDIS);
ad153f15 1851 } else {
9c708c7f 1852 generate_exception_end(ctx, EXCP_RI);
ad153f15 1853 }
853c3240
JL
1854 }
1855}
1856
3a95e3a7 1857/* This code generates a "reserved instruction" exception if the
e189e748 1858 CPU does not support the instruction set corresponding to flags. */
d75c135e 1859static inline void check_insn(DisasContext *ctx, int flags)
3a95e3a7 1860{
d75c135e 1861 if (unlikely(!(ctx->insn_flags & flags))) {
9c708c7f 1862 generate_exception_end(ctx, EXCP_RI);
d75c135e 1863 }
3a95e3a7
TS
1864}
1865
fecd2646
LA
1866/* This code generates a "reserved instruction" exception if the
1867 CPU has corresponding flag set which indicates that the instruction
1868 has been removed. */
1869static inline void check_insn_opc_removed(DisasContext *ctx, int flags)
1870{
1871 if (unlikely(ctx->insn_flags & flags)) {
9c708c7f 1872 generate_exception_end(ctx, EXCP_RI);
fecd2646
LA
1873 }
1874}
1875
e29c9628
YK
1876/* This code generates a "reserved instruction" exception if the
1877 CPU does not support 64-bit paired-single (PS) floating point data type */
1878static inline void check_ps(DisasContext *ctx)
1879{
1880 if (unlikely(!ctx->ps)) {
1881 generate_exception(ctx, EXCP_RI);
1882 }
1883 check_cp1_64bitmode(ctx);
1884}
1885
c7986fd6 1886#ifdef TARGET_MIPS64
e189e748
TS
1887/* This code generates a "reserved instruction" exception if 64-bit
1888 instructions are not enabled. */
356265ae 1889static inline void check_mips_64(DisasContext *ctx)
e189e748 1890{
fe253235 1891 if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
9c708c7f 1892 generate_exception_end(ctx, EXCP_RI);
e189e748 1893}
c7986fd6 1894#endif
e189e748 1895
5204ea79
LA
1896#ifndef CONFIG_USER_ONLY
1897static inline void check_mvh(DisasContext *ctx)
1898{
1899 if (unlikely(!ctx->mvh)) {
1900 generate_exception(ctx, EXCP_RI);
1901 }
1902}
1903#endif
1904
8153667c
NF
1905/* Define small wrappers for gen_load_fpr* so that we have a uniform
1906 calling interface for 32 and 64-bit FPRs. No sense in changing
1907 all callers for gen_load_fpr32 when we need the CTX parameter for
1908 this one use. */
7c979afd 1909#define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(ctx, x, y)
8153667c
NF
1910#define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
1911#define FOP_CONDS(type, abs, fmt, ifmt, bits) \
1912static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \
1913 int ft, int fs, int cc) \
1914{ \
1915 TCGv_i##bits fp0 = tcg_temp_new_i##bits (); \
1916 TCGv_i##bits fp1 = tcg_temp_new_i##bits (); \
1917 switch (ifmt) { \
1918 case FMT_PS: \
e29c9628 1919 check_ps(ctx); \
8153667c
NF
1920 break; \
1921 case FMT_D: \
1922 if (abs) { \
1923 check_cop1x(ctx); \
1924 } \
1925 check_cp1_registers(ctx, fs | ft); \
1926 break; \
1927 case FMT_S: \
1928 if (abs) { \
1929 check_cop1x(ctx); \
1930 } \
1931 break; \
1932 } \
1933 gen_ldcmp_fpr##bits (ctx, fp0, fs); \
1934 gen_ldcmp_fpr##bits (ctx, fp1, ft); \
1935 switch (n) { \
895c2d04
BS
1936 case 0: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc); break;\
1937 case 1: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc); break;\
1938 case 2: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc); break;\
1939 case 3: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc); break;\
1940 case 4: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc); break;\
1941 case 5: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc); break;\
1942 case 6: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc); break;\
1943 case 7: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc); break;\
1944 case 8: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc); break;\
1945 case 9: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); break;\
1946 case 10: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc); break;\
1947 case 11: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc); break;\
1948 case 12: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc); break;\
1949 case 13: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc); break;\
1950 case 14: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc); break;\
1951 case 15: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc); break;\
8153667c
NF
1952 default: abort(); \
1953 } \
1954 tcg_temp_free_i##bits (fp0); \
1955 tcg_temp_free_i##bits (fp1); \
1956}
1957
1958FOP_CONDS(, 0, d, FMT_D, 64)
1959FOP_CONDS(abs, 1, d, FMT_D, 64)
1960FOP_CONDS(, 0, s, FMT_S, 32)
1961FOP_CONDS(abs, 1, s, FMT_S, 32)
1962FOP_CONDS(, 0, ps, FMT_PS, 64)
1963FOP_CONDS(abs, 1, ps, FMT_PS, 64)
1964#undef FOP_CONDS
3f493883
YK
1965
1966#define FOP_CONDNS(fmt, ifmt, bits, STORE) \
1967static inline void gen_r6_cmp_ ## fmt(DisasContext * ctx, int n, \
1968 int ft, int fs, int fd) \
1969{ \
1970 TCGv_i ## bits fp0 = tcg_temp_new_i ## bits(); \
1971 TCGv_i ## bits fp1 = tcg_temp_new_i ## bits(); \
00fb4a11 1972 if (ifmt == FMT_D) { \
3f493883 1973 check_cp1_registers(ctx, fs | ft | fd); \
3f493883
YK
1974 } \
1975 gen_ldcmp_fpr ## bits(ctx, fp0, fs); \
1976 gen_ldcmp_fpr ## bits(ctx, fp1, ft); \
1977 switch (n) { \
1978 case 0: \
1979 gen_helper_r6_cmp_ ## fmt ## _af(fp0, cpu_env, fp0, fp1); \
1980 break; \
1981 case 1: \
1982 gen_helper_r6_cmp_ ## fmt ## _un(fp0, cpu_env, fp0, fp1); \
1983 break; \
1984 case 2: \
1985 gen_helper_r6_cmp_ ## fmt ## _eq(fp0, cpu_env, fp0, fp1); \
1986 break; \
1987 case 3: \
1988 gen_helper_r6_cmp_ ## fmt ## _ueq(fp0, cpu_env, fp0, fp1); \
1989 break; \
1990 case 4: \
1991 gen_helper_r6_cmp_ ## fmt ## _lt(fp0, cpu_env, fp0, fp1); \
1992 break; \
1993 case 5: \
1994 gen_helper_r6_cmp_ ## fmt ## _ult(fp0, cpu_env, fp0, fp1); \
1995 break; \
1996 case 6: \
1997 gen_helper_r6_cmp_ ## fmt ## _le(fp0, cpu_env, fp0, fp1); \
1998 break; \
1999 case 7: \
2000 gen_helper_r6_cmp_ ## fmt ## _ule(fp0, cpu_env, fp0, fp1); \
2001 break; \
2002 case 8: \
2003 gen_helper_r6_cmp_ ## fmt ## _saf(fp0, cpu_env, fp0, fp1); \
2004 break; \
2005 case 9: \
2006 gen_helper_r6_cmp_ ## fmt ## _sun(fp0, cpu_env, fp0, fp1); \
2007 break; \
2008 case 10: \
2009 gen_helper_r6_cmp_ ## fmt ## _seq(fp0, cpu_env, fp0, fp1); \
2010 break; \
2011 case 11: \
2012 gen_helper_r6_cmp_ ## fmt ## _sueq(fp0, cpu_env, fp0, fp1); \
2013 break; \
2014 case 12: \
2015 gen_helper_r6_cmp_ ## fmt ## _slt(fp0, cpu_env, fp0, fp1); \
2016 break; \
2017 case 13: \
2018 gen_helper_r6_cmp_ ## fmt ## _sult(fp0, cpu_env, fp0, fp1); \
2019 break; \
2020 case 14: \
2021 gen_helper_r6_cmp_ ## fmt ## _sle(fp0, cpu_env, fp0, fp1); \
2022 break; \
2023 case 15: \
2024 gen_helper_r6_cmp_ ## fmt ## _sule(fp0, cpu_env, fp0, fp1); \
2025 break; \
2026 case 17: \
2027 gen_helper_r6_cmp_ ## fmt ## _or(fp0, cpu_env, fp0, fp1); \
2028 break; \
2029 case 18: \
2030 gen_helper_r6_cmp_ ## fmt ## _une(fp0, cpu_env, fp0, fp1); \
2031 break; \
2032 case 19: \
2033 gen_helper_r6_cmp_ ## fmt ## _ne(fp0, cpu_env, fp0, fp1); \
2034 break; \
2035 case 25: \
2036 gen_helper_r6_cmp_ ## fmt ## _sor(fp0, cpu_env, fp0, fp1); \
2037 break; \
2038 case 26: \
2039 gen_helper_r6_cmp_ ## fmt ## _sune(fp0, cpu_env, fp0, fp1); \
2040 break; \
2041 case 27: \
2042 gen_helper_r6_cmp_ ## fmt ## _sne(fp0, cpu_env, fp0, fp1); \
2043 break; \
2044 default: \
2045 abort(); \
2046 } \
2047 STORE; \
2048 tcg_temp_free_i ## bits (fp0); \
2049 tcg_temp_free_i ## bits (fp1); \
2050}
2051
2052FOP_CONDNS(d, FMT_D, 64, gen_store_fpr64(ctx, fp0, fd))
7c979afd 2053FOP_CONDNS(s, FMT_S, 32, gen_store_fpr32(ctx, fp0, fd))
3f493883 2054#undef FOP_CONDNS
8153667c
NF
2055#undef gen_ldcmp_fpr32
2056#undef gen_ldcmp_fpr64
2057
958fb4a9 2058/* load/store instructions. */
e7139c44 2059#ifdef CONFIG_USER_ONLY
d9bea114 2060#define OP_LD_ATOMIC(insn,fname) \
dd4096cd
JH
2061static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx, \
2062 DisasContext *ctx) \
d9bea114
AJ
2063{ \
2064 TCGv t0 = tcg_temp_new(); \
2065 tcg_gen_mov_tl(t0, arg1); \
2066 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
7db13fae
AF
2067 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
2068 tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval)); \
d9bea114 2069 tcg_temp_free(t0); \
aaa9128a 2070}
e7139c44
AJ
2071#else
2072#define OP_LD_ATOMIC(insn,fname) \
dd4096cd
JH
2073static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx, \
2074 DisasContext *ctx) \
e7139c44 2075{ \
dd4096cd 2076 gen_helper_1e1i(insn, ret, arg1, mem_idx); \
e7139c44
AJ
2077}
2078#endif
aaa9128a
TS
2079OP_LD_ATOMIC(ll,ld32s);
2080#if defined(TARGET_MIPS64)
2081OP_LD_ATOMIC(lld,ld64);
2082#endif
2083#undef OP_LD_ATOMIC
2084
590bc601
PB
2085#ifdef CONFIG_USER_ONLY
2086#define OP_ST_ATOMIC(insn,fname,ldname,almask) \
dd4096cd
JH
2087static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, int mem_idx, \
2088 DisasContext *ctx) \
590bc601
PB
2089{ \
2090 TCGv t0 = tcg_temp_new(); \
42a268c2
RH
2091 TCGLabel *l1 = gen_new_label(); \
2092 TCGLabel *l2 = gen_new_label(); \
590bc601
PB
2093 \
2094 tcg_gen_andi_tl(t0, arg2, almask); \
2095 tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1); \
7db13fae 2096 tcg_gen_st_tl(arg2, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr)); \
590bc601
PB
2097 generate_exception(ctx, EXCP_AdES); \
2098 gen_set_label(l1); \
7db13fae 2099 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
590bc601
PB
2100 tcg_gen_brcond_tl(TCG_COND_NE, arg2, t0, l2); \
2101 tcg_gen_movi_tl(t0, rt | ((almask << 3) & 0x20)); \
7db13fae
AF
2102 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, llreg)); \
2103 tcg_gen_st_tl(arg1, cpu_env, offsetof(CPUMIPSState, llnewval)); \
9c708c7f 2104 generate_exception_end(ctx, EXCP_SC); \
590bc601
PB
2105 gen_set_label(l2); \
2106 tcg_gen_movi_tl(t0, 0); \
2107 gen_store_gpr(t0, rt); \
2108 tcg_temp_free(t0); \
2109}
2110#else
2111#define OP_ST_ATOMIC(insn,fname,ldname,almask) \
dd4096cd
JH
2112static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, int mem_idx, \
2113 DisasContext *ctx) \
590bc601
PB
2114{ \
2115 TCGv t0 = tcg_temp_new(); \
dd4096cd 2116 gen_helper_1e2i(insn, t0, arg1, arg2, mem_idx); \
590bc601 2117 gen_store_gpr(t0, rt); \
590bc601
PB
2118 tcg_temp_free(t0); \
2119}
2120#endif
590bc601 2121OP_ST_ATOMIC(sc,st32,ld32s,0x3);
aaa9128a 2122#if defined(TARGET_MIPS64)
590bc601 2123OP_ST_ATOMIC(scd,st64,ld64,0x7);
aaa9128a
TS
2124#endif
2125#undef OP_ST_ATOMIC
2126
662d7485 2127static void gen_base_offset_addr (DisasContext *ctx, TCGv addr,
72e1f16f 2128 int base, int offset)
662d7485
NF
2129{
2130 if (base == 0) {
2131 tcg_gen_movi_tl(addr, offset);
2132 } else if (offset == 0) {
2133 gen_load_gpr(addr, base);
2134 } else {
2135 tcg_gen_movi_tl(addr, offset);
2136 gen_op_addr_add(ctx, addr, cpu_gpr[base], addr);
2137 }
2138}
2139
364d4831
NF
2140static target_ulong pc_relative_pc (DisasContext *ctx)
2141{
eeb3bba8 2142 target_ulong pc = ctx->base.pc_next;
364d4831
NF
2143
2144 if (ctx->hflags & MIPS_HFLAG_BMASK) {
2145 int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
2146
2147 pc -= branch_bytes;
2148 }
2149
2150 pc &= ~(target_ulong)3;
2151 return pc;
2152}
2153
5c13fdfd 2154/* Load */
d75c135e 2155static void gen_ld(DisasContext *ctx, uint32_t opc,
72e1f16f 2156 int rt, int base, int offset)
6af0bf9c 2157{
fc40787a 2158 TCGv t0, t1, t2;
dd4096cd 2159 int mem_idx = ctx->mem_idx;
afa88c3a 2160
d75c135e 2161 if (rt == 0 && ctx->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)) {
afa88c3a
AJ
2162 /* Loongson CPU uses a load to zero register for prefetch.
2163 We emulate it as a NOP. On other CPU we must perform the
2164 actual memory access. */
afa88c3a
AJ
2165 return;
2166 }
6af0bf9c 2167
afa88c3a 2168 t0 = tcg_temp_new();
662d7485 2169 gen_base_offset_addr(ctx, t0, base, offset);
afa88c3a 2170
6af0bf9c 2171 switch (opc) {
d26bc211 2172#if defined(TARGET_MIPS64)
6e473128 2173 case OPC_LWU:
dd4096cd 2174 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL |
be3a8c53 2175 ctx->default_tcg_memop_mask);
78723684 2176 gen_store_gpr(t0, rt);
6e473128 2177 break;
6af0bf9c 2178 case OPC_LD:
dd4096cd 2179 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ |
be3a8c53 2180 ctx->default_tcg_memop_mask);
78723684 2181 gen_store_gpr(t0, rt);
6af0bf9c 2182 break;
7a387fff 2183 case OPC_LLD:
bf7910c6 2184 case R6_OPC_LLD:
dd4096cd 2185 op_ld_lld(t0, t0, mem_idx, ctx);
78723684 2186 gen_store_gpr(t0, rt);
7a387fff 2187 break;
6af0bf9c 2188 case OPC_LDL:
3cee3050 2189 t1 = tcg_temp_new();
908680c6
AJ
2190 /* Do a byte access to possibly trigger a page
2191 fault with the unaligned address. */
dd4096cd 2192 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
fc40787a
AJ
2193 tcg_gen_andi_tl(t1, t0, 7);
2194#ifndef TARGET_WORDS_BIGENDIAN
2195 tcg_gen_xori_tl(t1, t1, 7);
2196#endif
2197 tcg_gen_shli_tl(t1, t1, 3);
2198 tcg_gen_andi_tl(t0, t0, ~7);
dd4096cd 2199 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
fc40787a 2200 tcg_gen_shl_tl(t0, t0, t1);
eb02cc3f
AJ
2201 t2 = tcg_const_tl(-1);
2202 tcg_gen_shl_tl(t2, t2, t1);
78723684 2203 gen_load_gpr(t1, rt);
eb02cc3f 2204 tcg_gen_andc_tl(t1, t1, t2);
fc40787a
AJ
2205 tcg_temp_free(t2);
2206 tcg_gen_or_tl(t0, t0, t1);
3cee3050 2207 tcg_temp_free(t1);
fc40787a 2208 gen_store_gpr(t0, rt);
6af0bf9c 2209 break;
6af0bf9c 2210 case OPC_LDR:
3cee3050 2211 t1 = tcg_temp_new();
908680c6
AJ
2212 /* Do a byte access to possibly trigger a page
2213 fault with the unaligned address. */
dd4096cd 2214 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
fc40787a
AJ
2215 tcg_gen_andi_tl(t1, t0, 7);
2216#ifdef TARGET_WORDS_BIGENDIAN
2217 tcg_gen_xori_tl(t1, t1, 7);
2218#endif
2219 tcg_gen_shli_tl(t1, t1, 3);
2220 tcg_gen_andi_tl(t0, t0, ~7);
dd4096cd 2221 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
fc40787a
AJ
2222 tcg_gen_shr_tl(t0, t0, t1);
2223 tcg_gen_xori_tl(t1, t1, 63);
2224 t2 = tcg_const_tl(0xfffffffffffffffeull);
2225 tcg_gen_shl_tl(t2, t2, t1);
78723684 2226 gen_load_gpr(t1, rt);
fc40787a
AJ
2227 tcg_gen_and_tl(t1, t1, t2);
2228 tcg_temp_free(t2);
2229 tcg_gen_or_tl(t0, t0, t1);
3cee3050 2230 tcg_temp_free(t1);
fc40787a 2231 gen_store_gpr(t0, rt);
6af0bf9c 2232 break;
364d4831 2233 case OPC_LDPC:
3cee3050 2234 t1 = tcg_const_tl(pc_relative_pc(ctx));
364d4831 2235 gen_op_addr_add(ctx, t0, t0, t1);
3cee3050 2236 tcg_temp_free(t1);
dd4096cd 2237 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
364d4831
NF
2238 gen_store_gpr(t0, rt);
2239 break;
6af0bf9c 2240#endif
364d4831 2241 case OPC_LWPC:
3cee3050 2242 t1 = tcg_const_tl(pc_relative_pc(ctx));
364d4831 2243 gen_op_addr_add(ctx, t0, t0, t1);
3cee3050 2244 tcg_temp_free(t1);
dd4096cd 2245 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESL);
364d4831
NF
2246 gen_store_gpr(t0, rt);
2247 break;
76964147
JH
2248 case OPC_LWE:
2249 mem_idx = MIPS_HFLAG_UM;
2250 /* fall through */
6af0bf9c 2251 case OPC_LW:
dd4096cd 2252 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESL |
be3a8c53 2253 ctx->default_tcg_memop_mask);
78723684 2254 gen_store_gpr(t0, rt);
6af0bf9c 2255 break;
76964147
JH
2256 case OPC_LHE:
2257 mem_idx = MIPS_HFLAG_UM;
2258 /* fall through */
6af0bf9c 2259 case OPC_LH:
dd4096cd 2260 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESW |
be3a8c53 2261 ctx->default_tcg_memop_mask);
78723684 2262 gen_store_gpr(t0, rt);
6af0bf9c 2263 break;
76964147
JH
2264 case OPC_LHUE:
2265 mem_idx = MIPS_HFLAG_UM;
2266 /* fall through */
6af0bf9c 2267 case OPC_LHU:
dd4096cd 2268 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUW |
be3a8c53 2269 ctx->default_tcg_memop_mask);
78723684 2270 gen_store_gpr(t0, rt);
6af0bf9c 2271 break;
76964147
JH
2272 case OPC_LBE:
2273 mem_idx = MIPS_HFLAG_UM;
2274 /* fall through */
6af0bf9c 2275 case OPC_LB:
dd4096cd 2276 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_SB);
78723684 2277 gen_store_gpr(t0, rt);
6af0bf9c 2278 break;
76964147
JH
2279 case OPC_LBUE:
2280 mem_idx = MIPS_HFLAG_UM;
2281 /* fall through */
6af0bf9c 2282 case OPC_LBU:
dd4096cd 2283 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_UB);
78723684 2284 gen_store_gpr(t0, rt);
6af0bf9c 2285 break;
76964147
JH
2286 case OPC_LWLE:
2287 mem_idx = MIPS_HFLAG_UM;
2288 /* fall through */
6af0bf9c 2289 case OPC_LWL:
3cee3050 2290 t1 = tcg_temp_new();
908680c6
AJ
2291 /* Do a byte access to possibly trigger a page
2292 fault with the unaligned address. */
dd4096cd 2293 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
fc40787a
AJ
2294 tcg_gen_andi_tl(t1, t0, 3);
2295#ifndef TARGET_WORDS_BIGENDIAN
2296 tcg_gen_xori_tl(t1, t1, 3);
2297#endif
2298 tcg_gen_shli_tl(t1, t1, 3);
2299 tcg_gen_andi_tl(t0, t0, ~3);
dd4096cd 2300 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL);
fc40787a 2301 tcg_gen_shl_tl(t0, t0, t1);
eb02cc3f
AJ
2302 t2 = tcg_const_tl(-1);
2303 tcg_gen_shl_tl(t2, t2, t1);
6958549d 2304 gen_load_gpr(t1, rt);
eb02cc3f 2305 tcg_gen_andc_tl(t1, t1, t2);
fc40787a
AJ
2306 tcg_temp_free(t2);
2307 tcg_gen_or_tl(t0, t0, t1);
3cee3050 2308 tcg_temp_free(t1);
fc40787a
AJ
2309 tcg_gen_ext32s_tl(t0, t0);
2310 gen_store_gpr(t0, rt);
6af0bf9c 2311 break;
76964147
JH
2312 case OPC_LWRE:
2313 mem_idx = MIPS_HFLAG_UM;
2314 /* fall through */
6af0bf9c 2315 case OPC_LWR:
3cee3050 2316 t1 = tcg_temp_new();
908680c6
AJ
2317 /* Do a byte access to possibly trigger a page
2318 fault with the unaligned address. */
dd4096cd 2319 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
fc40787a
AJ
2320 tcg_gen_andi_tl(t1, t0, 3);
2321#ifdef TARGET_WORDS_BIGENDIAN
2322 tcg_gen_xori_tl(t1, t1, 3);
2323#endif
2324 tcg_gen_shli_tl(t1, t1, 3);
2325 tcg_gen_andi_tl(t0, t0, ~3);
dd4096cd 2326 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL);
fc40787a
AJ
2327 tcg_gen_shr_tl(t0, t0, t1);
2328 tcg_gen_xori_tl(t1, t1, 31);
2329 t2 = tcg_const_tl(0xfffffffeull);
2330 tcg_gen_shl_tl(t2, t2, t1);
6958549d 2331 gen_load_gpr(t1, rt);
fc40787a
AJ
2332 tcg_gen_and_tl(t1, t1, t2);
2333 tcg_temp_free(t2);
2334 tcg_gen_or_tl(t0, t0, t1);
3cee3050 2335 tcg_temp_free(t1);
c728154b 2336 tcg_gen_ext32s_tl(t0, t0);
fc40787a 2337 gen_store_gpr(t0, rt);
6af0bf9c 2338 break;
76964147
JH
2339 case OPC_LLE:
2340 mem_idx = MIPS_HFLAG_UM;
2341 /* fall through */
6af0bf9c 2342 case OPC_LL:
4368b29a 2343 case R6_OPC_LL:
dd4096cd 2344 op_ld_ll(t0, t0, mem_idx, ctx);
78723684 2345 gen_store_gpr(t0, rt);
6af0bf9c 2346 break;
d66c7132 2347 }
d66c7132 2348 tcg_temp_free(t0);
d66c7132
AJ
2349}
2350
5c13fdfd
AJ
2351/* Store */
2352static void gen_st (DisasContext *ctx, uint32_t opc, int rt,
72e1f16f 2353 int base, int offset)
5c13fdfd 2354{
5c13fdfd
AJ
2355 TCGv t0 = tcg_temp_new();
2356 TCGv t1 = tcg_temp_new();
dd4096cd 2357 int mem_idx = ctx->mem_idx;
5c13fdfd
AJ
2358
2359 gen_base_offset_addr(ctx, t0, base, offset);
2360 gen_load_gpr(t1, rt);
2361 switch (opc) {
2362#if defined(TARGET_MIPS64)
2363 case OPC_SD:
dd4096cd 2364 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEQ |
be3a8c53 2365 ctx->default_tcg_memop_mask);
5c13fdfd
AJ
2366 break;
2367 case OPC_SDL:
dd4096cd 2368 gen_helper_0e2i(sdl, t1, t0, mem_idx);
5c13fdfd
AJ
2369 break;
2370 case OPC_SDR:
dd4096cd 2371 gen_helper_0e2i(sdr, t1, t0, mem_idx);
5c13fdfd
AJ
2372 break;
2373#endif
76964147
JH
2374 case OPC_SWE:
2375 mem_idx = MIPS_HFLAG_UM;
2376 /* fall through */
5c13fdfd 2377 case OPC_SW:
dd4096cd 2378 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUL |
be3a8c53 2379 ctx->default_tcg_memop_mask);
5c13fdfd 2380 break;
76964147
JH
2381 case OPC_SHE:
2382 mem_idx = MIPS_HFLAG_UM;
2383 /* fall through */
5c13fdfd 2384 case OPC_SH:
dd4096cd 2385 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUW |
be3a8c53 2386 ctx->default_tcg_memop_mask);
5c13fdfd 2387 break;
76964147
JH
2388 case OPC_SBE:
2389 mem_idx = MIPS_HFLAG_UM;
2390 /* fall through */
5c13fdfd 2391 case OPC_SB:
dd4096cd 2392 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_8);
5c13fdfd 2393 break;
76964147
JH
2394 case OPC_SWLE:
2395 mem_idx = MIPS_HFLAG_UM;
2396 /* fall through */
5c13fdfd 2397 case OPC_SWL:
dd4096cd 2398 gen_helper_0e2i(swl, t1, t0, mem_idx);
5c13fdfd 2399 break;
76964147
JH
2400 case OPC_SWRE:
2401 mem_idx = MIPS_HFLAG_UM;
2402 /* fall through */
5c13fdfd 2403 case OPC_SWR:
dd4096cd 2404 gen_helper_0e2i(swr, t1, t0, mem_idx);
5c13fdfd
AJ
2405 break;
2406 }
5c13fdfd
AJ
2407 tcg_temp_free(t0);
2408 tcg_temp_free(t1);
2409}
2410
2411
d66c7132
AJ
2412/* Store conditional */
2413static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt,
2414 int base, int16_t offset)
2415{
d66c7132 2416 TCGv t0, t1;
dd4096cd 2417 int mem_idx = ctx->mem_idx;
d66c7132 2418
2d2826b9 2419#ifdef CONFIG_USER_ONLY
d66c7132 2420 t0 = tcg_temp_local_new();
d66c7132 2421 t1 = tcg_temp_local_new();
2d2826b9
AJ
2422#else
2423 t0 = tcg_temp_new();
2424 t1 = tcg_temp_new();
2425#endif
2426 gen_base_offset_addr(ctx, t0, base, offset);
d66c7132
AJ
2427 gen_load_gpr(t1, rt);
2428 switch (opc) {
2429#if defined(TARGET_MIPS64)
2430 case OPC_SCD:
bf7910c6 2431 case R6_OPC_SCD:
dd4096cd 2432 op_st_scd(t1, t0, rt, mem_idx, ctx);
d66c7132
AJ
2433 break;
2434#endif
76964147
JH
2435 case OPC_SCE:
2436 mem_idx = MIPS_HFLAG_UM;
2437 /* fall through */
6af0bf9c 2438 case OPC_SC:
4368b29a 2439 case R6_OPC_SC:
dd4096cd 2440 op_st_sc(t1, t0, rt, mem_idx, ctx);
6af0bf9c 2441 break;
6af0bf9c 2442 }
78723684 2443 tcg_temp_free(t1);
d66c7132 2444 tcg_temp_free(t0);
6af0bf9c
FB
2445}
2446
6ea83fed 2447/* Load and store */
7a387fff 2448static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
b52d3bfa 2449 TCGv t0)
6ea83fed 2450{
6ea83fed 2451 /* Don't do NOP if destination is zero: we must perform the actual
ead9360e 2452 memory access. */
6ea83fed
FB
2453 switch (opc) {
2454 case OPC_LWC1:
b6d96bed 2455 {
a7812ae4 2456 TCGv_i32 fp0 = tcg_temp_new_i32();
be3a8c53
YK
2457 tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, MO_TESL |
2458 ctx->default_tcg_memop_mask);
7c979afd 2459 gen_store_fpr32(ctx, fp0, ft);
a7812ae4 2460 tcg_temp_free_i32(fp0);
b6d96bed 2461 }
6ea83fed
FB
2462 break;
2463 case OPC_SWC1:
b6d96bed 2464 {
a7812ae4 2465 TCGv_i32 fp0 = tcg_temp_new_i32();
7c979afd 2466 gen_load_fpr32(ctx, fp0, ft);
be3a8c53
YK
2467 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL |
2468 ctx->default_tcg_memop_mask);
a7812ae4 2469 tcg_temp_free_i32(fp0);
b6d96bed 2470 }
6ea83fed
FB
2471 break;
2472 case OPC_LDC1:
b6d96bed 2473 {
a7812ae4 2474 TCGv_i64 fp0 = tcg_temp_new_i64();
be3a8c53
YK
2475 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ |
2476 ctx->default_tcg_memop_mask);
b6d96bed 2477 gen_store_fpr64(ctx, fp0, ft);
a7812ae4 2478 tcg_temp_free_i64(fp0);
b6d96bed 2479 }
6ea83fed
FB
2480 break;
2481 case OPC_SDC1:
b6d96bed 2482 {
a7812ae4 2483 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 2484 gen_load_fpr64(ctx, fp0, ft);
be3a8c53
YK
2485 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ |
2486 ctx->default_tcg_memop_mask);
a7812ae4 2487 tcg_temp_free_i64(fp0);
b6d96bed 2488 }
6ea83fed
FB
2489 break;
2490 default:
9d68ac14 2491 MIPS_INVAL("flt_ldst");
9c708c7f 2492 generate_exception_end(ctx, EXCP_RI);
b52d3bfa 2493 break;
6ea83fed 2494 }
6ea83fed 2495}
6ea83fed 2496
5ab5c041
AJ
2497static void gen_cop1_ldst(DisasContext *ctx, uint32_t op, int rt,
2498 int rs, int16_t imm)
26ebe468 2499{
b52d3bfa
YK
2500 TCGv t0 = tcg_temp_new();
2501
5ab5c041 2502 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
26ebe468 2503 check_cp1_enabled(ctx);
d9224450
MR
2504 switch (op) {
2505 case OPC_LDC1:
2506 case OPC_SDC1:
2507 check_insn(ctx, ISA_MIPS2);
2508 /* Fallthrough */
2509 default:
b52d3bfa
YK
2510 gen_base_offset_addr(ctx, t0, rs, imm);
2511 gen_flt_ldst(ctx, op, rt, t0);
d9224450 2512 }
26ebe468
NF
2513 } else {
2514 generate_exception_err(ctx, EXCP_CpU, 1);
2515 }
b52d3bfa 2516 tcg_temp_free(t0);
26ebe468
NF
2517}
2518
6af0bf9c 2519/* Arithmetic with immediate operand */
d75c135e 2520static void gen_arith_imm(DisasContext *ctx, uint32_t opc,
72e1f16f 2521 int rt, int rs, int imm)
6af0bf9c 2522{
324d9e32 2523 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
6af0bf9c 2524
7a387fff 2525 if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
ead9360e
TS
2526 /* If no destination, treat it as a NOP.
2527 For addi, we must generate the overflow exception when needed. */
324d9e32 2528 return;
6af0bf9c
FB
2529 }
2530 switch (opc) {
2531 case OPC_ADDI:
48d38ca5 2532 {
324d9e32
AJ
2533 TCGv t0 = tcg_temp_local_new();
2534 TCGv t1 = tcg_temp_new();
2535 TCGv t2 = tcg_temp_new();
42a268c2 2536 TCGLabel *l1 = gen_new_label();
48d38ca5 2537
324d9e32
AJ
2538 gen_load_gpr(t1, rs);
2539 tcg_gen_addi_tl(t0, t1, uimm);
2540 tcg_gen_ext32s_tl(t0, t0);
48d38ca5 2541
324d9e32
AJ
2542 tcg_gen_xori_tl(t1, t1, ~uimm);
2543 tcg_gen_xori_tl(t2, t0, uimm);
2544 tcg_gen_and_tl(t1, t1, t2);
2545 tcg_temp_free(t2);
2546 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2547 tcg_temp_free(t1);
48d38ca5
TS
2548 /* operands of same sign, result different sign */
2549 generate_exception(ctx, EXCP_OVERFLOW);
2550 gen_set_label(l1);
78723684 2551 tcg_gen_ext32s_tl(t0, t0);
324d9e32
AJ
2552 gen_store_gpr(t0, rt);
2553 tcg_temp_free(t0);
48d38ca5 2554 }
6af0bf9c
FB
2555 break;
2556 case OPC_ADDIU:
324d9e32
AJ
2557 if (rs != 0) {
2558 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2559 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
2560 } else {
2561 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2562 }
6af0bf9c 2563 break;
d26bc211 2564#if defined(TARGET_MIPS64)
7a387fff 2565 case OPC_DADDI:
48d38ca5 2566 {
324d9e32
AJ
2567 TCGv t0 = tcg_temp_local_new();
2568 TCGv t1 = tcg_temp_new();
2569 TCGv t2 = tcg_temp_new();
42a268c2 2570 TCGLabel *l1 = gen_new_label();
48d38ca5 2571
324d9e32
AJ
2572 gen_load_gpr(t1, rs);
2573 tcg_gen_addi_tl(t0, t1, uimm);
48d38ca5 2574
324d9e32
AJ
2575 tcg_gen_xori_tl(t1, t1, ~uimm);
2576 tcg_gen_xori_tl(t2, t0, uimm);
2577 tcg_gen_and_tl(t1, t1, t2);
2578 tcg_temp_free(t2);
2579 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2580 tcg_temp_free(t1);
48d38ca5
TS
2581 /* operands of same sign, result different sign */
2582 generate_exception(ctx, EXCP_OVERFLOW);
2583 gen_set_label(l1);
324d9e32
AJ
2584 gen_store_gpr(t0, rt);
2585 tcg_temp_free(t0);
48d38ca5 2586 }
7a387fff
TS
2587 break;
2588 case OPC_DADDIU:
324d9e32
AJ
2589 if (rs != 0) {
2590 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2591 } else {
2592 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2593 }
7a387fff
TS
2594 break;
2595#endif
324d9e32 2596 }
324d9e32
AJ
2597}
2598
2599/* Logic with immediate operand */
d75c135e 2600static void gen_logic_imm(DisasContext *ctx, uint32_t opc,
9fa77488 2601 int rt, int rs, int16_t imm)
324d9e32
AJ
2602{
2603 target_ulong uimm;
324d9e32
AJ
2604
2605 if (rt == 0) {
2606 /* If no destination, treat it as a NOP. */
324d9e32
AJ
2607 return;
2608 }
2609 uimm = (uint16_t)imm;
2610 switch (opc) {
6af0bf9c 2611 case OPC_ANDI:
324d9e32
AJ
2612 if (likely(rs != 0))
2613 tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2614 else
2615 tcg_gen_movi_tl(cpu_gpr[rt], 0);
6af0bf9c
FB
2616 break;
2617 case OPC_ORI:
324d9e32
AJ
2618 if (rs != 0)
2619 tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2620 else
2621 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
6af0bf9c
FB
2622 break;
2623 case OPC_XORI:
324d9e32
AJ
2624 if (likely(rs != 0))
2625 tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2626 else
2627 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
6af0bf9c
FB
2628 break;
2629 case OPC_LUI:
d4ea6acd
LA
2630 if (rs != 0 && (ctx->insn_flags & ISA_MIPS32R6)) {
2631 /* OPC_AUI */
2632 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm << 16);
2633 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
d4ea6acd
LA
2634 } else {
2635 tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
d4ea6acd 2636 }
7c2c3ea3
EJ
2637 break;
2638
2639 default:
6af0bf9c 2640 break;
324d9e32 2641 }
324d9e32
AJ
2642}
2643
2644/* Set on less than with immediate operand */
d75c135e 2645static void gen_slt_imm(DisasContext *ctx, uint32_t opc,
9fa77488 2646 int rt, int rs, int16_t imm)
324d9e32
AJ
2647{
2648 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
324d9e32
AJ
2649 TCGv t0;
2650
2651 if (rt == 0) {
2652 /* If no destination, treat it as a NOP. */
324d9e32
AJ
2653 return;
2654 }
2655 t0 = tcg_temp_new();
2656 gen_load_gpr(t0, rs);
2657 switch (opc) {
2658 case OPC_SLTI:
e68dd28f 2659 tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
324d9e32
AJ
2660 break;
2661 case OPC_SLTIU:
e68dd28f 2662 tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
324d9e32
AJ
2663 break;
2664 }
324d9e32
AJ
2665 tcg_temp_free(t0);
2666}
2667
2668/* Shifts with immediate operand */
d75c135e 2669static void gen_shift_imm(DisasContext *ctx, uint32_t opc,
324d9e32
AJ
2670 int rt, int rs, int16_t imm)
2671{
2672 target_ulong uimm = ((uint16_t)imm) & 0x1f;
324d9e32
AJ
2673 TCGv t0;
2674
2675 if (rt == 0) {
2676 /* If no destination, treat it as a NOP. */
324d9e32
AJ
2677 return;
2678 }
2679
2680 t0 = tcg_temp_new();
2681 gen_load_gpr(t0, rs);
2682 switch (opc) {
6af0bf9c 2683 case OPC_SLL:
78723684 2684 tcg_gen_shli_tl(t0, t0, uimm);
324d9e32 2685 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
6af0bf9c
FB
2686 break;
2687 case OPC_SRA:
324d9e32 2688 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
6af0bf9c
FB
2689 break;
2690 case OPC_SRL:
ea63e2c3
NF
2691 if (uimm != 0) {
2692 tcg_gen_ext32u_tl(t0, t0);
2693 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2694 } else {
2695 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
5a63bcb2 2696 }
ea63e2c3
NF
2697 break;
2698 case OPC_ROTR:
2699 if (uimm != 0) {
2700 TCGv_i32 t1 = tcg_temp_new_i32();
2701
2702 tcg_gen_trunc_tl_i32(t1, t0);
2703 tcg_gen_rotri_i32(t1, t1, uimm);
2704 tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
2705 tcg_temp_free_i32(t1);
3399e30f
NF
2706 } else {
2707 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
ea63e2c3 2708 }
7a387fff 2709 break;
d26bc211 2710#if defined(TARGET_MIPS64)
7a387fff 2711 case OPC_DSLL:
324d9e32 2712 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
7a387fff
TS
2713 break;
2714 case OPC_DSRA:
324d9e32 2715 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
7a387fff
TS
2716 break;
2717 case OPC_DSRL:
ea63e2c3 2718 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
ea63e2c3
NF
2719 break;
2720 case OPC_DROTR:
2721 if (uimm != 0) {
2722 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
3399e30f
NF
2723 } else {
2724 tcg_gen_mov_tl(cpu_gpr[rt], t0);
5a63bcb2 2725 }
7a387fff
TS
2726 break;
2727 case OPC_DSLL32:
324d9e32 2728 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
7a387fff
TS
2729 break;
2730 case OPC_DSRA32:
324d9e32 2731 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
7a387fff
TS
2732 break;
2733 case OPC_DSRL32:
ea63e2c3 2734 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
ea63e2c3
NF
2735 break;
2736 case OPC_DROTR32:
2737 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
6af0bf9c 2738 break;
7a387fff 2739#endif
6af0bf9c 2740 }
78723684 2741 tcg_temp_free(t0);
6af0bf9c
FB
2742}
2743
2744/* Arithmetic */
d75c135e
AJ
2745static void gen_arith(DisasContext *ctx, uint32_t opc,
2746 int rd, int rs, int rt)
6af0bf9c 2747{
7a387fff
TS
2748 if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
2749 && opc != OPC_DADD && opc != OPC_DSUB) {
ead9360e
TS
2750 /* If no destination, treat it as a NOP.
2751 For add & sub, we must generate the overflow exception when needed. */
460f00c4 2752 return;
185f0762 2753 }
460f00c4 2754
6af0bf9c
FB
2755 switch (opc) {
2756 case OPC_ADD:
48d38ca5 2757 {
460f00c4
AJ
2758 TCGv t0 = tcg_temp_local_new();
2759 TCGv t1 = tcg_temp_new();
2760 TCGv t2 = tcg_temp_new();
42a268c2 2761 TCGLabel *l1 = gen_new_label();
48d38ca5 2762
460f00c4
AJ
2763 gen_load_gpr(t1, rs);
2764 gen_load_gpr(t2, rt);
2765 tcg_gen_add_tl(t0, t1, t2);
2766 tcg_gen_ext32s_tl(t0, t0);
2767 tcg_gen_xor_tl(t1, t1, t2);
460f00c4 2768 tcg_gen_xor_tl(t2, t0, t2);
deb4203d 2769 tcg_gen_andc_tl(t1, t2, t1);
460f00c4
AJ
2770 tcg_temp_free(t2);
2771 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2772 tcg_temp_free(t1);
48d38ca5
TS
2773 /* operands of same sign, result different sign */
2774 generate_exception(ctx, EXCP_OVERFLOW);
2775 gen_set_label(l1);
460f00c4
AJ
2776 gen_store_gpr(t0, rd);
2777 tcg_temp_free(t0);
48d38ca5 2778 }
6af0bf9c
FB
2779 break;
2780 case OPC_ADDU:
460f00c4
AJ
2781 if (rs != 0 && rt != 0) {
2782 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2783 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2784 } else if (rs == 0 && rt != 0) {
2785 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2786 } else if (rs != 0 && rt == 0) {
2787 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2788 } else {
2789 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2790 }
6af0bf9c
FB
2791 break;
2792 case OPC_SUB:
48d38ca5 2793 {
460f00c4
AJ
2794 TCGv t0 = tcg_temp_local_new();
2795 TCGv t1 = tcg_temp_new();
2796 TCGv t2 = tcg_temp_new();
42a268c2 2797 TCGLabel *l1 = gen_new_label();
48d38ca5 2798
460f00c4
AJ
2799 gen_load_gpr(t1, rs);
2800 gen_load_gpr(t2, rt);
2801 tcg_gen_sub_tl(t0, t1, t2);
2802 tcg_gen_ext32s_tl(t0, t0);
2803 tcg_gen_xor_tl(t2, t1, t2);
2804 tcg_gen_xor_tl(t1, t0, t1);
2805 tcg_gen_and_tl(t1, t1, t2);
2806 tcg_temp_free(t2);
2807 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2808 tcg_temp_free(t1);
31e3104f 2809 /* operands of different sign, first operand and result different sign */
48d38ca5
TS
2810 generate_exception(ctx, EXCP_OVERFLOW);
2811 gen_set_label(l1);
460f00c4
AJ
2812 gen_store_gpr(t0, rd);
2813 tcg_temp_free(t0);
48d38ca5 2814 }
6af0bf9c
FB
2815 break;
2816 case OPC_SUBU:
460f00c4
AJ
2817 if (rs != 0 && rt != 0) {
2818 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2819 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2820 } else if (rs == 0 && rt != 0) {
2821 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
6bb72b18 2822 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
460f00c4
AJ
2823 } else if (rs != 0 && rt == 0) {
2824 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2825 } else {
2826 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2827 }
6af0bf9c 2828 break;
d26bc211 2829#if defined(TARGET_MIPS64)
7a387fff 2830 case OPC_DADD:
48d38ca5 2831 {
460f00c4
AJ
2832 TCGv t0 = tcg_temp_local_new();
2833 TCGv t1 = tcg_temp_new();
2834 TCGv t2 = tcg_temp_new();
42a268c2 2835 TCGLabel *l1 = gen_new_label();
48d38ca5 2836
460f00c4
AJ
2837 gen_load_gpr(t1, rs);
2838 gen_load_gpr(t2, rt);
2839 tcg_gen_add_tl(t0, t1, t2);
2840 tcg_gen_xor_tl(t1, t1, t2);
460f00c4 2841 tcg_gen_xor_tl(t2, t0, t2);
deb4203d 2842 tcg_gen_andc_tl(t1, t2, t1);
460f00c4
AJ
2843 tcg_temp_free(t2);
2844 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2845 tcg_temp_free(t1);
48d38ca5
TS
2846 /* operands of same sign, result different sign */
2847 generate_exception(ctx, EXCP_OVERFLOW);
2848 gen_set_label(l1);
460f00c4
AJ
2849 gen_store_gpr(t0, rd);
2850 tcg_temp_free(t0);
48d38ca5 2851 }
7a387fff
TS
2852 break;
2853 case OPC_DADDU:
460f00c4
AJ
2854 if (rs != 0 && rt != 0) {
2855 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2856 } else if (rs == 0 && rt != 0) {
2857 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2858 } else if (rs != 0 && rt == 0) {
2859 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2860 } else {
2861 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2862 }
7a387fff
TS
2863 break;
2864 case OPC_DSUB:
48d38ca5 2865 {
460f00c4
AJ
2866 TCGv t0 = tcg_temp_local_new();
2867 TCGv t1 = tcg_temp_new();
2868 TCGv t2 = tcg_temp_new();
42a268c2 2869 TCGLabel *l1 = gen_new_label();
48d38ca5 2870
460f00c4
AJ
2871 gen_load_gpr(t1, rs);
2872 gen_load_gpr(t2, rt);
2873 tcg_gen_sub_tl(t0, t1, t2);
2874 tcg_gen_xor_tl(t2, t1, t2);
2875 tcg_gen_xor_tl(t1, t0, t1);
2876 tcg_gen_and_tl(t1, t1, t2);
2877 tcg_temp_free(t2);
2878 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2879 tcg_temp_free(t1);
31e3104f 2880 /* operands of different sign, first operand and result different sign */
48d38ca5
TS
2881 generate_exception(ctx, EXCP_OVERFLOW);
2882 gen_set_label(l1);
460f00c4
AJ
2883 gen_store_gpr(t0, rd);
2884 tcg_temp_free(t0);
48d38ca5 2885 }
7a387fff
TS
2886 break;
2887 case OPC_DSUBU:
460f00c4
AJ
2888 if (rs != 0 && rt != 0) {
2889 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2890 } else if (rs == 0 && rt != 0) {
2891 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2892 } else if (rs != 0 && rt == 0) {
2893 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2894 } else {
2895 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2896 }
7a387fff
TS
2897 break;
2898#endif
460f00c4
AJ
2899 case OPC_MUL:
2900 if (likely(rs != 0 && rt != 0)) {
2901 tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2902 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2903 } else {
2904 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2905 }
6af0bf9c 2906 break;
460f00c4 2907 }
460f00c4
AJ
2908}
2909
2910/* Conditional move */
d75c135e 2911static void gen_cond_move(DisasContext *ctx, uint32_t opc,
9fa77488 2912 int rd, int rs, int rt)
460f00c4 2913{
acf12465 2914 TCGv t0, t1, t2;
460f00c4
AJ
2915
2916 if (rd == 0) {
acf12465 2917 /* If no destination, treat it as a NOP. */
460f00c4
AJ
2918 return;
2919 }
2920
acf12465
AJ
2921 t0 = tcg_temp_new();
2922 gen_load_gpr(t0, rt);
2923 t1 = tcg_const_tl(0);
2924 t2 = tcg_temp_new();
2925 gen_load_gpr(t2, rs);
460f00c4
AJ
2926 switch (opc) {
2927 case OPC_MOVN:
acf12465 2928 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
6af0bf9c 2929 break;
460f00c4 2930 case OPC_MOVZ:
acf12465 2931 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
460f00c4 2932 break;
b691d9d2
LA
2933 case OPC_SELNEZ:
2934 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, t1);
b691d9d2
LA
2935 break;
2936 case OPC_SELEQZ:
2937 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, t1);
b691d9d2 2938 break;
460f00c4 2939 }
acf12465
AJ
2940 tcg_temp_free(t2);
2941 tcg_temp_free(t1);
2942 tcg_temp_free(t0);
460f00c4
AJ
2943}
2944
2945/* Logic */
d75c135e 2946static void gen_logic(DisasContext *ctx, uint32_t opc,
9fa77488 2947 int rd, int rs, int rt)
460f00c4 2948{
460f00c4
AJ
2949 if (rd == 0) {
2950 /* If no destination, treat it as a NOP. */
460f00c4
AJ
2951 return;
2952 }
2953
2954 switch (opc) {
6af0bf9c 2955 case OPC_AND:
460f00c4
AJ
2956 if (likely(rs != 0 && rt != 0)) {
2957 tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2958 } else {
2959 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2960 }
6af0bf9c
FB
2961 break;
2962 case OPC_NOR:
460f00c4
AJ
2963 if (rs != 0 && rt != 0) {
2964 tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2965 } else if (rs == 0 && rt != 0) {
2966 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
2967 } else if (rs != 0 && rt == 0) {
2968 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
2969 } else {
2970 tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
2971 }
6af0bf9c
FB
2972 break;
2973 case OPC_OR:
460f00c4
AJ
2974 if (likely(rs != 0 && rt != 0)) {
2975 tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2976 } else if (rs == 0 && rt != 0) {
2977 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2978 } else if (rs != 0 && rt == 0) {
2979 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2980 } else {
2981 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2982 }
6af0bf9c
FB
2983 break;
2984 case OPC_XOR:
460f00c4
AJ
2985 if (likely(rs != 0 && rt != 0)) {
2986 tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2987 } else if (rs == 0 && rt != 0) {
2988 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2989 } else if (rs != 0 && rt == 0) {
2990 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2991 } else {
2992 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2993 }
6af0bf9c 2994 break;
460f00c4 2995 }
460f00c4
AJ
2996}
2997
2998/* Set on lower than */
d75c135e 2999static void gen_slt(DisasContext *ctx, uint32_t opc,
9fa77488 3000 int rd, int rs, int rt)
460f00c4 3001{
460f00c4
AJ
3002 TCGv t0, t1;
3003
3004 if (rd == 0) {
3005 /* If no destination, treat it as a NOP. */
460f00c4
AJ
3006 return;
3007 }
3008
3009 t0 = tcg_temp_new();
3010 t1 = tcg_temp_new();
3011 gen_load_gpr(t0, rs);
3012 gen_load_gpr(t1, rt);
3013 switch (opc) {
3014 case OPC_SLT:
e68dd28f 3015 tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
6af0bf9c 3016 break;
460f00c4 3017 case OPC_SLTU:
e68dd28f 3018 tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
460f00c4
AJ
3019 break;
3020 }
460f00c4
AJ
3021 tcg_temp_free(t0);
3022 tcg_temp_free(t1);
3023}
20c4c97c 3024
460f00c4 3025/* Shifts */
d75c135e
AJ
3026static void gen_shift(DisasContext *ctx, uint32_t opc,
3027 int rd, int rs, int rt)
460f00c4 3028{
460f00c4 3029 TCGv t0, t1;
20c4c97c 3030
460f00c4
AJ
3031 if (rd == 0) {
3032 /* If no destination, treat it as a NOP.
3033 For add & sub, we must generate the overflow exception when needed. */
460f00c4
AJ
3034 return;
3035 }
3036
3037 t0 = tcg_temp_new();
3038 t1 = tcg_temp_new();
3039 gen_load_gpr(t0, rs);
3040 gen_load_gpr(t1, rt);
3041 switch (opc) {
6af0bf9c 3042 case OPC_SLLV:
78723684
TS
3043 tcg_gen_andi_tl(t0, t0, 0x1f);
3044 tcg_gen_shl_tl(t0, t1, t0);
460f00c4 3045 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
6af0bf9c
FB
3046 break;
3047 case OPC_SRAV:
78723684 3048 tcg_gen_andi_tl(t0, t0, 0x1f);
460f00c4 3049 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
6af0bf9c
FB
3050 break;
3051 case OPC_SRLV:
ea63e2c3
NF
3052 tcg_gen_ext32u_tl(t1, t1);
3053 tcg_gen_andi_tl(t0, t0, 0x1f);
3054 tcg_gen_shr_tl(t0, t1, t0);
3055 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
ea63e2c3
NF
3056 break;
3057 case OPC_ROTRV:
3058 {
3059 TCGv_i32 t2 = tcg_temp_new_i32();
3060 TCGv_i32 t3 = tcg_temp_new_i32();
3061
3062 tcg_gen_trunc_tl_i32(t2, t0);
3063 tcg_gen_trunc_tl_i32(t3, t1);
3064 tcg_gen_andi_i32(t2, t2, 0x1f);
3065 tcg_gen_rotr_i32(t2, t3, t2);
3066 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3067 tcg_temp_free_i32(t2);
3068 tcg_temp_free_i32(t3);
5a63bcb2 3069 }
7a387fff 3070 break;
d26bc211 3071#if defined(TARGET_MIPS64)
7a387fff 3072 case OPC_DSLLV:
78723684 3073 tcg_gen_andi_tl(t0, t0, 0x3f);
460f00c4 3074 tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
7a387fff
TS
3075 break;
3076 case OPC_DSRAV:
78723684 3077 tcg_gen_andi_tl(t0, t0, 0x3f);
460f00c4 3078 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
7a387fff
TS
3079 break;
3080 case OPC_DSRLV:
ea63e2c3
NF
3081 tcg_gen_andi_tl(t0, t0, 0x3f);
3082 tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
ea63e2c3
NF
3083 break;
3084 case OPC_DROTRV:
3085 tcg_gen_andi_tl(t0, t0, 0x3f);
3086 tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
6af0bf9c 3087 break;
7a387fff 3088#endif
6af0bf9c 3089 }
78723684
TS
3090 tcg_temp_free(t0);
3091 tcg_temp_free(t1);
6af0bf9c
FB
3092}
3093
3094/* Arithmetic on HI/LO registers */
26135ead 3095static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg)
6af0bf9c 3096{
6af0bf9c 3097 if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
ead9360e 3098 /* Treat as NOP. */
a1f6684d 3099 return;
6af0bf9c 3100 }
4133498f 3101
4133498f
JL
3102 if (acc != 0) {
3103 check_dsp(ctx);
3104 }
3105
6af0bf9c
FB
3106 switch (opc) {
3107 case OPC_MFHI:
4133498f
JL
3108#if defined(TARGET_MIPS64)
3109 if (acc != 0) {
3110 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]);
3111 } else
3112#endif
3113 {
3114 tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]);
3115 }
6af0bf9c
FB
3116 break;
3117 case OPC_MFLO:
4133498f
JL
3118#if defined(TARGET_MIPS64)
3119 if (acc != 0) {
3120 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]);
3121 } else
3122#endif
3123 {
3124 tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]);
3125 }
6af0bf9c
FB
3126 break;
3127 case OPC_MTHI:
4133498f
JL
3128 if (reg != 0) {
3129#if defined(TARGET_MIPS64)
3130 if (acc != 0) {
3131 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_gpr[reg]);
3132 } else
3133#endif
3134 {
3135 tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]);
3136 }
3137 } else {
3138 tcg_gen_movi_tl(cpu_HI[acc], 0);
3139 }
6af0bf9c
FB
3140 break;
3141 case OPC_MTLO:
4133498f
JL
3142 if (reg != 0) {
3143#if defined(TARGET_MIPS64)
3144 if (acc != 0) {
3145 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_gpr[reg]);
3146 } else
3147#endif
3148 {
3149 tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]);
3150 }
3151 } else {
3152 tcg_gen_movi_tl(cpu_LO[acc], 0);
3153 }
6af0bf9c 3154 break;
6af0bf9c 3155 }
6af0bf9c
FB
3156}
3157
d4ea6acd
LA
3158static inline void gen_r6_ld(target_long addr, int reg, int memidx,
3159 TCGMemOp memop)
3160{
3161 TCGv t0 = tcg_const_tl(addr);
3162 tcg_gen_qemu_ld_tl(t0, t0, memidx, memop);
3163 gen_store_gpr(t0, reg);
3164 tcg_temp_free(t0);
3165}
3166
ab39ee45
YK
3167static inline void gen_pcrel(DisasContext *ctx, int opc, target_ulong pc,
3168 int rs)
d4ea6acd
LA
3169{
3170 target_long offset;
3171 target_long addr;
3172
ab39ee45 3173 switch (MASK_OPC_PCREL_TOP2BITS(opc)) {
d4ea6acd
LA
3174 case OPC_ADDIUPC:
3175 if (rs != 0) {
3176 offset = sextract32(ctx->opcode << 2, 0, 21);
ab39ee45 3177 addr = addr_add(ctx, pc, offset);
d4ea6acd
LA
3178 tcg_gen_movi_tl(cpu_gpr[rs], addr);
3179 }
3180 break;
3181 case R6_OPC_LWPC:
3182 offset = sextract32(ctx->opcode << 2, 0, 21);
ab39ee45 3183 addr = addr_add(ctx, pc, offset);
d4ea6acd
LA
3184 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TESL);
3185 break;
3186#if defined(TARGET_MIPS64)
3187 case OPC_LWUPC:
3188 check_mips_64(ctx);
3189 offset = sextract32(ctx->opcode << 2, 0, 21);
ab39ee45 3190 addr = addr_add(ctx, pc, offset);
d4ea6acd
LA
3191 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEUL);
3192 break;
3193#endif
3194 default:
ab39ee45 3195 switch (MASK_OPC_PCREL_TOP5BITS(opc)) {
d4ea6acd
LA
3196 case OPC_AUIPC:
3197 if (rs != 0) {
ab39ee45
YK
3198 offset = sextract32(ctx->opcode, 0, 16) << 16;
3199 addr = addr_add(ctx, pc, offset);
d4ea6acd
LA
3200 tcg_gen_movi_tl(cpu_gpr[rs], addr);
3201 }
3202 break;
3203 case OPC_ALUIPC:
3204 if (rs != 0) {
ab39ee45
YK
3205 offset = sextract32(ctx->opcode, 0, 16) << 16;
3206 addr = ~0xFFFF & addr_add(ctx, pc, offset);
d4ea6acd
LA
3207 tcg_gen_movi_tl(cpu_gpr[rs], addr);
3208 }
3209 break;
3210#if defined(TARGET_MIPS64)
3211 case R6_OPC_LDPC: /* bits 16 and 17 are part of immediate */
3212 case R6_OPC_LDPC + (1 << 16):
3213 case R6_OPC_LDPC + (2 << 16):
3214 case R6_OPC_LDPC + (3 << 16):
3215 check_mips_64(ctx);
3216 offset = sextract32(ctx->opcode << 3, 0, 21);
ab39ee45 3217 addr = addr_add(ctx, (pc & ~0x7), offset);
d4ea6acd
LA
3218 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEQ);
3219 break;
3220#endif
3221 default:
3222 MIPS_INVAL("OPC_PCREL");
9c708c7f 3223 generate_exception_end(ctx, EXCP_RI);
d4ea6acd
LA
3224 break;
3225 }
3226 break;
3227 }
3228}
3229
b42ee5e1
LA
3230static void gen_r6_muldiv(DisasContext *ctx, int opc, int rd, int rs, int rt)
3231{
b42ee5e1
LA
3232 TCGv t0, t1;
3233
3234 if (rd == 0) {
3235 /* Treat as NOP. */
b42ee5e1
LA
3236 return;
3237 }
3238
3239 t0 = tcg_temp_new();
3240 t1 = tcg_temp_new();
3241
3242 gen_load_gpr(t0, rs);
3243 gen_load_gpr(t1, rt);
3244
3245 switch (opc) {
3246 case R6_OPC_DIV:
3247 {
3248 TCGv t2 = tcg_temp_new();
3249 TCGv t3 = tcg_temp_new();
3250 tcg_gen_ext32s_tl(t0, t0);
3251 tcg_gen_ext32s_tl(t1, t1);
3252 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3253 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3254 tcg_gen_and_tl(t2, t2, t3);
3255 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3256 tcg_gen_or_tl(t2, t2, t3);
3257 tcg_gen_movi_tl(t3, 0);
3258 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3259 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3260 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3261 tcg_temp_free(t3);
3262 tcg_temp_free(t2);
3263 }
b42ee5e1
LA
3264 break;
3265 case R6_OPC_MOD:
3266 {
3267 TCGv t2 = tcg_temp_new();
3268 TCGv t3 = tcg_temp_new();
3269 tcg_gen_ext32s_tl(t0, t0);
3270 tcg_gen_ext32s_tl(t1, t1);
3271 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3272 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3273 tcg_gen_and_tl(t2, t2, t3);
3274 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3275 tcg_gen_or_tl(t2, t2, t3);
3276 tcg_gen_movi_tl(t3, 0);
3277 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3278 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3279 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3280 tcg_temp_free(t3);
3281 tcg_temp_free(t2);
3282 }
b42ee5e1
LA
3283 break;
3284 case R6_OPC_DIVU:
3285 {
3286 TCGv t2 = tcg_const_tl(0);
3287 TCGv t3 = tcg_const_tl(1);
3288 tcg_gen_ext32u_tl(t0, t0);
3289 tcg_gen_ext32u_tl(t1, t1);
3290 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3291 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3292 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3293 tcg_temp_free(t3);
3294 tcg_temp_free(t2);
3295 }
b42ee5e1
LA
3296 break;
3297 case R6_OPC_MODU:
3298 {
3299 TCGv t2 = tcg_const_tl(0);
3300 TCGv t3 = tcg_const_tl(1);
3301 tcg_gen_ext32u_tl(t0, t0);
3302 tcg_gen_ext32u_tl(t1, t1);
3303 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3304 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3305 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3306 tcg_temp_free(t3);
3307 tcg_temp_free(t2);
3308 }
b42ee5e1
LA
3309 break;
3310 case R6_OPC_MUL:
3311 {
3312 TCGv_i32 t2 = tcg_temp_new_i32();
3313 TCGv_i32 t3 = tcg_temp_new_i32();
3314 tcg_gen_trunc_tl_i32(t2, t0);
3315 tcg_gen_trunc_tl_i32(t3, t1);
3316 tcg_gen_mul_i32(t2, t2, t3);
3317 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3318 tcg_temp_free_i32(t2);
3319 tcg_temp_free_i32(t3);
3320 }
b42ee5e1
LA
3321 break;
3322 case R6_OPC_MUH:
3323 {
3324 TCGv_i32 t2 = tcg_temp_new_i32();
3325 TCGv_i32 t3 = tcg_temp_new_i32();
3326 tcg_gen_trunc_tl_i32(t2, t0);
3327 tcg_gen_trunc_tl_i32(t3, t1);
3328 tcg_gen_muls2_i32(t2, t3, t2, t3);
3329 tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
3330 tcg_temp_free_i32(t2);
3331 tcg_temp_free_i32(t3);
3332 }
b42ee5e1
LA
3333 break;
3334 case R6_OPC_MULU:
3335 {
3336 TCGv_i32 t2 = tcg_temp_new_i32();
3337 TCGv_i32 t3 = tcg_temp_new_i32();
3338 tcg_gen_trunc_tl_i32(t2, t0);
3339 tcg_gen_trunc_tl_i32(t3, t1);
3340 tcg_gen_mul_i32(t2, t2, t3);
3341 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3342 tcg_temp_free_i32(t2);
3343 tcg_temp_free_i32(t3);
3344 }
b42ee5e1
LA
3345 break;
3346 case R6_OPC_MUHU:
3347 {
3348 TCGv_i32 t2 = tcg_temp_new_i32();
3349 TCGv_i32 t3 = tcg_temp_new_i32();
3350 tcg_gen_trunc_tl_i32(t2, t0);
3351 tcg_gen_trunc_tl_i32(t3, t1);
3352 tcg_gen_mulu2_i32(t2, t3, t2, t3);
3353 tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
3354 tcg_temp_free_i32(t2);
3355 tcg_temp_free_i32(t3);
3356 }
b42ee5e1
LA
3357 break;
3358#if defined(TARGET_MIPS64)
3359 case R6_OPC_DDIV:
3360 {
3361 TCGv t2 = tcg_temp_new();
3362 TCGv t3 = tcg_temp_new();
3363 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3364 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3365 tcg_gen_and_tl(t2, t2, t3);
3366 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3367 tcg_gen_or_tl(t2, t2, t3);
3368 tcg_gen_movi_tl(t3, 0);
3369 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3370 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3371 tcg_temp_free(t3);
3372 tcg_temp_free(t2);
3373 }
b42ee5e1
LA
3374 break;
3375 case R6_OPC_DMOD:
3376 {
3377 TCGv t2 = tcg_temp_new();
3378 TCGv t3 = tcg_temp_new();
3379 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3380 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3381 tcg_gen_and_tl(t2, t2, t3);
3382 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3383 tcg_gen_or_tl(t2, t2, t3);
3384 tcg_gen_movi_tl(t3, 0);
3385 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3386 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3387 tcg_temp_free(t3);
3388 tcg_temp_free(t2);
3389 }
b42ee5e1
LA
3390 break;
3391 case R6_OPC_DDIVU:
3392 {
3393 TCGv t2 = tcg_const_tl(0);
3394 TCGv t3 = tcg_const_tl(1);
3395 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3396 tcg_gen_divu_i64(cpu_gpr[rd], t0, t1);
3397 tcg_temp_free(t3);
3398 tcg_temp_free(t2);
3399 }
b42ee5e1
LA
3400 break;
3401 case R6_OPC_DMODU:
3402 {
3403 TCGv t2 = tcg_const_tl(0);
3404 TCGv t3 = tcg_const_tl(1);
3405 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3406 tcg_gen_remu_i64(cpu_gpr[rd], t0, t1);
3407 tcg_temp_free(t3);
3408 tcg_temp_free(t2);
3409 }
b42ee5e1
LA
3410 break;
3411 case R6_OPC_DMUL:
3412 tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
b42ee5e1
LA
3413 break;
3414 case R6_OPC_DMUH:
3415 {
3416 TCGv t2 = tcg_temp_new();
3417 tcg_gen_muls2_i64(t2, cpu_gpr[rd], t0, t1);
3418 tcg_temp_free(t2);
3419 }
b42ee5e1
LA
3420 break;
3421 case R6_OPC_DMULU:
3422 tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
b42ee5e1
LA
3423 break;
3424 case R6_OPC_DMUHU:
3425 {
3426 TCGv t2 = tcg_temp_new();
3427 tcg_gen_mulu2_i64(t2, cpu_gpr[rd], t0, t1);
3428 tcg_temp_free(t2);
3429 }
b42ee5e1
LA
3430 break;
3431#endif
3432 default:
9d68ac14 3433 MIPS_INVAL("r6 mul/div");
9c708c7f 3434 generate_exception_end(ctx, EXCP_RI);
b42ee5e1
LA
3435 goto out;
3436 }
b42ee5e1
LA
3437 out:
3438 tcg_temp_free(t0);
3439 tcg_temp_free(t1);
3440}
3441
26135ead
RS
3442static void gen_muldiv(DisasContext *ctx, uint32_t opc,
3443 int acc, int rs, int rt)
6af0bf9c 3444{
d45f89f4
AJ
3445 TCGv t0, t1;
3446
51127181
AJ
3447 t0 = tcg_temp_new();
3448 t1 = tcg_temp_new();
6af0bf9c 3449
78723684
TS
3450 gen_load_gpr(t0, rs);
3451 gen_load_gpr(t1, rt);
51127181 3452
26135ead
RS
3453 if (acc != 0) {
3454 check_dsp(ctx);
3455 }
3456
6af0bf9c
FB
3457 switch (opc) {
3458 case OPC_DIV:
48d38ca5 3459 {
51127181
AJ
3460 TCGv t2 = tcg_temp_new();
3461 TCGv t3 = tcg_temp_new();
d45f89f4
AJ
3462 tcg_gen_ext32s_tl(t0, t0);
3463 tcg_gen_ext32s_tl(t1, t1);
51127181
AJ
3464 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3465 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3466 tcg_gen_and_tl(t2, t2, t3);
3467 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3468 tcg_gen_or_tl(t2, t2, t3);
3469 tcg_gen_movi_tl(t3, 0);
3470 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
26135ead
RS
3471 tcg_gen_div_tl(cpu_LO[acc], t0, t1);
3472 tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
3473 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
3474 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
51127181
AJ
3475 tcg_temp_free(t3);
3476 tcg_temp_free(t2);
48d38ca5 3477 }
6af0bf9c
FB
3478 break;
3479 case OPC_DIVU:
48d38ca5 3480 {
51127181
AJ
3481 TCGv t2 = tcg_const_tl(0);
3482 TCGv t3 = tcg_const_tl(1);
0c0ed03b
AJ
3483 tcg_gen_ext32u_tl(t0, t0);
3484 tcg_gen_ext32u_tl(t1, t1);
51127181 3485 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
26135ead
RS
3486 tcg_gen_divu_tl(cpu_LO[acc], t0, t1);
3487 tcg_gen_remu_tl(cpu_HI[acc], t0, t1);
3488 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
3489 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
51127181
AJ
3490 tcg_temp_free(t3);
3491 tcg_temp_free(t2);
48d38ca5 3492 }
6af0bf9c
FB
3493 break;
3494 case OPC_MULT:
214c465f 3495 {
ce1dd5d1
RH
3496 TCGv_i32 t2 = tcg_temp_new_i32();
3497 TCGv_i32 t3 = tcg_temp_new_i32();
ce1dd5d1
RH
3498 tcg_gen_trunc_tl_i32(t2, t0);
3499 tcg_gen_trunc_tl_i32(t3, t1);
3500 tcg_gen_muls2_i32(t2, t3, t2, t3);
3501 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
3502 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
3503 tcg_temp_free_i32(t2);
3504 tcg_temp_free_i32(t3);
214c465f 3505 }
6af0bf9c
FB
3506 break;
3507 case OPC_MULTU:
214c465f 3508 {
ce1dd5d1
RH
3509 TCGv_i32 t2 = tcg_temp_new_i32();
3510 TCGv_i32 t3 = tcg_temp_new_i32();
ce1dd5d1
RH
3511 tcg_gen_trunc_tl_i32(t2, t0);
3512 tcg_gen_trunc_tl_i32(t3, t1);
3513 tcg_gen_mulu2_i32(t2, t3, t2, t3);
3514 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
3515 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
3516 tcg_temp_free_i32(t2);
3517 tcg_temp_free_i32(t3);
214c465f 3518 }
6af0bf9c 3519 break;
d26bc211 3520#if defined(TARGET_MIPS64)
7a387fff 3521 case OPC_DDIV:
48d38ca5 3522 {
51127181
AJ
3523 TCGv t2 = tcg_temp_new();
3524 TCGv t3 = tcg_temp_new();
3525 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3526 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3527 tcg_gen_and_tl(t2, t2, t3);
3528 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3529 tcg_gen_or_tl(t2, t2, t3);
3530 tcg_gen_movi_tl(t3, 0);
3531 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
26135ead
RS
3532 tcg_gen_div_tl(cpu_LO[acc], t0, t1);
3533 tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
51127181
AJ
3534 tcg_temp_free(t3);
3535 tcg_temp_free(t2);
48d38ca5 3536 }
7a387fff
TS
3537 break;
3538 case OPC_DDIVU:
48d38ca5 3539 {
51127181
AJ
3540 TCGv t2 = tcg_const_tl(0);
3541 TCGv t3 = tcg_const_tl(1);
3542 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
26135ead
RS
3543 tcg_gen_divu_i64(cpu_LO[acc], t0, t1);
3544 tcg_gen_remu_i64(cpu_HI[acc], t0, t1);
51127181
AJ
3545 tcg_temp_free(t3);
3546 tcg_temp_free(t2);
48d38ca5 3547 }
7a387fff
TS
3548 break;
3549 case OPC_DMULT:
26135ead 3550 tcg_gen_muls2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
7a387fff
TS
3551 break;
3552 case OPC_DMULTU:
26135ead 3553 tcg_gen_mulu2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
7a387fff
TS
3554 break;
3555#endif
6af0bf9c 3556 case OPC_MADD:
214c465f 3557 {
d45f89f4
AJ
3558 TCGv_i64 t2 = tcg_temp_new_i64();
3559 TCGv_i64 t3 = tcg_temp_new_i64();
3560
3561 tcg_gen_ext_tl_i64(t2, t0);
3562 tcg_gen_ext_tl_i64(t3, t1);
3563 tcg_gen_mul_i64(t2, t2, t3);
4133498f 3564 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
d45f89f4
AJ
3565 tcg_gen_add_i64(t2, t2, t3);
3566 tcg_temp_free_i64(t3);
71f303cd
RH
3567 gen_move_low32(cpu_LO[acc], t2);
3568 gen_move_high32(cpu_HI[acc], t2);
d45f89f4 3569 tcg_temp_free_i64(t2);
214c465f 3570 }
6af0bf9c
FB
3571 break;
3572 case OPC_MADDU:
4133498f 3573 {
d45f89f4
AJ
3574 TCGv_i64 t2 = tcg_temp_new_i64();
3575 TCGv_i64 t3 = tcg_temp_new_i64();
214c465f 3576
78723684
TS
3577 tcg_gen_ext32u_tl(t0, t0);
3578 tcg_gen_ext32u_tl(t1, t1);
d45f89f4
AJ
3579 tcg_gen_extu_tl_i64(t2, t0);
3580 tcg_gen_extu_tl_i64(t3, t1);
3581 tcg_gen_mul_i64(t2, t2, t3);
4133498f 3582 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
d45f89f4
AJ
3583 tcg_gen_add_i64(t2, t2, t3);
3584 tcg_temp_free_i64(t3);
71f303cd
RH
3585 gen_move_low32(cpu_LO[acc], t2);
3586 gen_move_high32(cpu_HI[acc], t2);
d45f89f4 3587 tcg_temp_free_i64(t2);
214c465f 3588 }
6af0bf9c
FB
3589 break;
3590 case OPC_MSUB:
214c465f 3591 {
d45f89f4
AJ
3592 TCGv_i64 t2 = tcg_temp_new_i64();
3593 TCGv_i64 t3 = tcg_temp_new_i64();
3594
3595 tcg_gen_ext_tl_i64(t2, t0);
3596 tcg_gen_ext_tl_i64(t3, t1);
3597 tcg_gen_mul_i64(t2, t2, t3);
4133498f 3598 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
98070ce0 3599 tcg_gen_sub_i64(t2, t3, t2);
d45f89f4 3600 tcg_temp_free_i64(t3);
71f303cd
RH
3601 gen_move_low32(cpu_LO[acc], t2);
3602 gen_move_high32(cpu_HI[acc], t2);
d45f89f4 3603 tcg_temp_free_i64(t2);
214c465f 3604 }
6af0bf9c
FB
3605 break;
3606 case OPC_MSUBU:
214c465f 3607 {
d45f89f4
AJ
3608 TCGv_i64 t2 = tcg_temp_new_i64();
3609 TCGv_i64 t3 = tcg_temp_new_i64();
214c465f 3610
78723684
TS
3611 tcg_gen_ext32u_tl(t0, t0);
3612 tcg_gen_ext32u_tl(t1, t1);
d45f89f4
AJ
3613 tcg_gen_extu_tl_i64(t2, t0);
3614 tcg_gen_extu_tl_i64(t3, t1);
3615 tcg_gen_mul_i64(t2, t2, t3);
4133498f 3616 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
98070ce0 3617 tcg_gen_sub_i64(t2, t3, t2);
d45f89f4 3618 tcg_temp_free_i64(t3);
71f303cd
RH
3619 gen_move_low32(cpu_LO[acc], t2);
3620 gen_move_high32(cpu_HI[acc], t2);
d45f89f4 3621 tcg_temp_free_i64(t2);
214c465f 3622 }
6af0bf9c
FB
3623 break;
3624 default:
9d68ac14 3625 MIPS_INVAL("mul/div");
9c708c7f 3626 generate_exception_end(ctx, EXCP_RI);
78723684 3627 goto out;
6af0bf9c 3628 }
78723684
TS
3629 out:
3630 tcg_temp_free(t0);
3631 tcg_temp_free(t1);
6af0bf9c
FB
3632}
3633
e9c71dd1
TS
3634static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
3635 int rd, int rs, int rt)
3636{
f157bfe1
AJ
3637 TCGv t0 = tcg_temp_new();
3638 TCGv t1 = tcg_temp_new();
e9c71dd1 3639
6c5c1e20
TS
3640 gen_load_gpr(t0, rs);
3641 gen_load_gpr(t1, rt);
e9c71dd1
TS
3642
3643 switch (opc) {
3644 case OPC_VR54XX_MULS:
895c2d04 3645 gen_helper_muls(t0, cpu_env, t0, t1);
6958549d 3646 break;
e9c71dd1 3647 case OPC_VR54XX_MULSU:
895c2d04 3648 gen_helper_mulsu(t0, cpu_env, t0, t1);
6958549d 3649 break;
e9c71dd1 3650 case OPC_VR54XX_MACC:
895c2d04 3651 gen_helper_macc(t0, cpu_env, t0, t1);
6958549d 3652 break;
e9c71dd1 3653 case OPC_VR54XX_MACCU:
895c2d04 3654 gen_helper_maccu(t0, cpu_env, t0, t1);
6958549d 3655 break;
e9c71dd1 3656 case OPC_VR54XX_MSAC:
895c2d04 3657 gen_helper_msac(t0, cpu_env, t0, t1);
6958549d 3658 break;
e9c71dd1 3659 case OPC_VR54XX_MSACU:
895c2d04 3660 gen_helper_msacu(t0, cpu_env, t0, t1);
6958549d 3661 break;
e9c71dd1 3662 case OPC_VR54XX_MULHI:
895c2d04 3663 gen_helper_mulhi(t0, cpu_env, t0, t1);
6958549d 3664 break;
e9c71dd1 3665 case OPC_VR54XX_MULHIU:
895c2d04 3666 gen_helper_mulhiu(t0, cpu_env, t0, t1);
6958549d 3667 break;
e9c71dd1 3668 case OPC_VR54XX_MULSHI:
895c2d04 3669 gen_helper_mulshi(t0, cpu_env, t0, t1);
6958549d 3670 break;
e9c71dd1 3671 case OPC_VR54XX_MULSHIU:
895c2d04 3672 gen_helper_mulshiu(t0, cpu_env, t0, t1);
6958549d 3673 break;
e9c71dd1 3674 case OPC_VR54XX_MACCHI:
895c2d04 3675 gen_helper_macchi(t0, cpu_env, t0, t1);
6958549d 3676 break;
e9c71dd1 3677 case OPC_VR54XX_MACCHIU:
895c2d04 3678 gen_helper_macchiu(t0, cpu_env, t0, t1);
6958549d 3679 break;
e9c71dd1 3680 case OPC_VR54XX_MSACHI:
895c2d04 3681 gen_helper_msachi(t0, cpu_env, t0, t1);
6958549d 3682 break;
e9c71dd1 3683 case OPC_VR54XX_MSACHIU:
895c2d04 3684 gen_helper_msachiu(t0, cpu_env, t0, t1);
6958549d 3685 break;
e9c71dd1
TS
3686 default:
3687 MIPS_INVAL("mul vr54xx");
9c708c7f 3688 generate_exception_end(ctx, EXCP_RI);
6c5c1e20 3689 goto out;
e9c71dd1 3690 }
6c5c1e20 3691 gen_store_gpr(t0, rd);
6c5c1e20
TS
3692
3693 out:
3694 tcg_temp_free(t0);
3695 tcg_temp_free(t1);
e9c71dd1
TS
3696}
3697
7a387fff 3698static void gen_cl (DisasContext *ctx, uint32_t opc,
6af0bf9c
FB
3699 int rd, int rs)
3700{
20e1fb52 3701 TCGv t0;
6c5c1e20 3702
6af0bf9c 3703 if (rd == 0) {
ead9360e 3704 /* Treat as NOP. */
20e1fb52 3705 return;
6af0bf9c 3706 }
1a0196c5 3707 t0 = cpu_gpr[rd];
6c5c1e20 3708 gen_load_gpr(t0, rs);
1a0196c5 3709
6af0bf9c
FB
3710 switch (opc) {
3711 case OPC_CLO:
4267d3e6 3712 case R6_OPC_CLO:
1a0196c5
RH
3713#if defined(TARGET_MIPS64)
3714 case OPC_DCLO:
3715 case R6_OPC_DCLO:
3716#endif
3717 tcg_gen_not_tl(t0, t0);
6af0bf9c 3718 break;
1a0196c5
RH
3719 }
3720
3721 switch (opc) {
3722 case OPC_CLO:
3723 case R6_OPC_CLO:
6af0bf9c 3724 case OPC_CLZ:
4267d3e6 3725 case R6_OPC_CLZ:
1a0196c5
RH
3726 tcg_gen_ext32u_tl(t0, t0);
3727 tcg_gen_clzi_tl(t0, t0, TARGET_LONG_BITS);
3728 tcg_gen_subi_tl(t0, t0, TARGET_LONG_BITS - 32);
6af0bf9c 3729 break;
d26bc211 3730#if defined(TARGET_MIPS64)
7a387fff 3731 case OPC_DCLO:
4267d3e6 3732 case R6_OPC_DCLO:
7a387fff 3733 case OPC_DCLZ:
4267d3e6 3734 case R6_OPC_DCLZ:
1a0196c5 3735 tcg_gen_clzi_i64(t0, t0, 64);
7a387fff
TS
3736 break;
3737#endif
6af0bf9c 3738 }
6af0bf9c
FB
3739}
3740
161f85e6 3741/* Godson integer instructions */
bd277fa1
RH
3742static void gen_loongson_integer(DisasContext *ctx, uint32_t opc,
3743 int rd, int rs, int rt)
161f85e6 3744{
161f85e6
AJ
3745 TCGv t0, t1;
3746
3747 if (rd == 0) {
3748 /* Treat as NOP. */
161f85e6
AJ
3749 return;
3750 }
3751
3752 switch (opc) {
3753 case OPC_MULT_G_2E:
3754 case OPC_MULT_G_2F:
3755 case OPC_MULTU_G_2E:
3756 case OPC_MULTU_G_2F:
3757#if defined(TARGET_MIPS64)
3758 case OPC_DMULT_G_2E:
3759 case OPC_DMULT_G_2F:
3760 case OPC_DMULTU_G_2E:
3761 case OPC_DMULTU_G_2F:
3762#endif
3763 t0 = tcg_temp_new();
3764 t1 = tcg_temp_new();
3765 break;
3766 default:
3767 t0 = tcg_temp_local_new();
3768 t1 = tcg_temp_local_new();
3769 break;
3770 }
3771
3772 gen_load_gpr(t0, rs);
3773 gen_load_gpr(t1, rt);
3774
3775 switch (opc) {
3776 case OPC_MULT_G_2E:
3777 case OPC_MULT_G_2F:
3778 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3779 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
161f85e6
AJ
3780 break;
3781 case OPC_MULTU_G_2E:
3782 case OPC_MULTU_G_2F:
3783 tcg_gen_ext32u_tl(t0, t0);
3784 tcg_gen_ext32u_tl(t1, t1);
3785 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3786 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
161f85e6
AJ
3787 break;
3788 case OPC_DIV_G_2E:
3789 case OPC_DIV_G_2F:
3790 {
42a268c2
RH
3791 TCGLabel *l1 = gen_new_label();
3792 TCGLabel *l2 = gen_new_label();
3793 TCGLabel *l3 = gen_new_label();
161f85e6
AJ
3794 tcg_gen_ext32s_tl(t0, t0);
3795 tcg_gen_ext32s_tl(t1, t1);
3796 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3797 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3798 tcg_gen_br(l3);
3799 gen_set_label(l1);
3800 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3801 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3802 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3803 tcg_gen_br(l3);
3804 gen_set_label(l2);
3805 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3806 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3807 gen_set_label(l3);
3808 }
161f85e6
AJ
3809 break;
3810 case OPC_DIVU_G_2E:
3811 case OPC_DIVU_G_2F:
3812 {
42a268c2
RH
3813 TCGLabel *l1 = gen_new_label();
3814 TCGLabel *l2 = gen_new_label();
161f85e6
AJ
3815 tcg_gen_ext32u_tl(t0, t0);
3816 tcg_gen_ext32u_tl(t1, t1);
3817 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3818 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3819 tcg_gen_br(l2);
3820 gen_set_label(l1);
3821 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3822 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3823 gen_set_label(l2);
3824 }
161f85e6
AJ
3825 break;
3826 case OPC_MOD_G_2E:
3827 case OPC_MOD_G_2F:
3828 {
42a268c2
RH
3829 TCGLabel *l1 = gen_new_label();
3830 TCGLabel *l2 = gen_new_label();
3831 TCGLabel *l3 = gen_new_label();
161f85e6
AJ
3832 tcg_gen_ext32u_tl(t0, t0);
3833 tcg_gen_ext32u_tl(t1, t1);
3834 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3835 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3836 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3837 gen_set_label(l1);
3838 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3839 tcg_gen_br(l3);
3840 gen_set_label(l2);
3841 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3842 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3843 gen_set_label(l3);
3844 }
161f85e6
AJ
3845 break;
3846 case OPC_MODU_G_2E:
3847 case OPC_MODU_G_2F:
3848 {
42a268c2
RH
3849 TCGLabel *l1 = gen_new_label();
3850 TCGLabel *l2 = gen_new_label();
161f85e6
AJ
3851 tcg_gen_ext32u_tl(t0, t0);
3852 tcg_gen_ext32u_tl(t1, t1);
3853 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3854 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3855 tcg_gen_br(l2);
3856 gen_set_label(l1);
3857 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3858 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3859 gen_set_label(l2);
3860 }
161f85e6
AJ
3861 break;
3862#if defined(TARGET_MIPS64)
3863 case OPC_DMULT_G_2E:
3864 case OPC_DMULT_G_2F:
3865 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
161f85e6
AJ
3866 break;
3867 case OPC_DMULTU_G_2E:
3868 case OPC_DMULTU_G_2F:
3869 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
161f85e6
AJ
3870 break;
3871 case OPC_DDIV_G_2E:
3872 case OPC_DDIV_G_2F:
3873 {
42a268c2
RH
3874 TCGLabel *l1 = gen_new_label();
3875 TCGLabel *l2 = gen_new_label();
3876 TCGLabel *l3 = gen_new_label();
161f85e6
AJ
3877 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3878 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3879 tcg_gen_br(l3);
3880 gen_set_label(l1);
3881 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3882 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3883 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3884 tcg_gen_br(l3);
3885 gen_set_label(l2);
3886 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3887 gen_set_label(l3);
3888 }
161f85e6
AJ
3889 break;
3890 case OPC_DDIVU_G_2E:
3891 case OPC_DDIVU_G_2F:
3892 {
42a268c2
RH
3893 TCGLabel *l1 = gen_new_label();
3894 TCGLabel *l2 = gen_new_label();
161f85e6
AJ
3895 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3896 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3897 tcg_gen_br(l2);
3898 gen_set_label(l1);
3899 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3900 gen_set_label(l2);
3901 }
161f85e6
AJ
3902 break;
3903 case OPC_DMOD_G_2E:
3904 case OPC_DMOD_G_2F:
3905 {
42a268c2
RH
3906 TCGLabel *l1 = gen_new_label();
3907 TCGLabel *l2 = gen_new_label();
3908 TCGLabel *l3 = gen_new_label();
161f85e6
AJ
3909 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3910 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3911 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3912 gen_set_label(l1);
3913 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3914 tcg_gen_br(l3);
3915 gen_set_label(l2);
3916 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3917 gen_set_label(l3);
3918 }
161f85e6
AJ
3919 break;
3920 case OPC_DMODU_G_2E:
3921 case OPC_DMODU_G_2F:
3922 {
42a268c2
RH
3923 TCGLabel *l1 = gen_new_label();
3924 TCGLabel *l2 = gen_new_label();
161f85e6
AJ
3925 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3926 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3927 tcg_gen_br(l2);
3928 gen_set_label(l1);
3929 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3930 gen_set_label(l2);
3931 }
161f85e6
AJ
3932 break;
3933#endif
3934 }
3935
161f85e6
AJ
3936 tcg_temp_free(t0);
3937 tcg_temp_free(t1);
3938}
3939
bd277fa1
RH
3940/* Loongson multimedia instructions */
3941static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt)
3942{
bd277fa1
RH
3943 uint32_t opc, shift_max;
3944 TCGv_i64 t0, t1;
3945
3946 opc = MASK_LMI(ctx->opcode);
3947 switch (opc) {
3948 case OPC_ADD_CP2:
3949 case OPC_SUB_CP2:
3950 case OPC_DADD_CP2:
3951 case OPC_DSUB_CP2:
3952 t0 = tcg_temp_local_new_i64();
3953 t1 = tcg_temp_local_new_i64();
3954 break;
3955 default:
3956 t0 = tcg_temp_new_i64();
3957 t1 = tcg_temp_new_i64();
3958 break;
3959 }
3960
b5a587b6 3961 check_cp1_enabled(ctx);
bd277fa1
RH
3962 gen_load_fpr64(ctx, t0, rs);
3963 gen_load_fpr64(ctx, t1, rt);
3964
3965#define LMI_HELPER(UP, LO) \
9d68ac14 3966 case OPC_##UP: gen_helper_##LO(t0, t0, t1); break
bd277fa1 3967#define LMI_HELPER_1(UP, LO) \
9d68ac14 3968 case OPC_##UP: gen_helper_##LO(t0, t0); break
bd277fa1 3969#define LMI_DIRECT(UP, LO, OP) \
9d68ac14 3970 case OPC_##UP: tcg_gen_##OP##_i64(t0, t0, t1); break
bd277fa1
RH
3971
3972 switch (opc) {
3973 LMI_HELPER(PADDSH, paddsh);
3974 LMI_HELPER(PADDUSH, paddush);
3975 LMI_HELPER(PADDH, paddh);
3976 LMI_HELPER(PADDW, paddw);
3977 LMI_HELPER(PADDSB, paddsb);
3978 LMI_HELPER(PADDUSB, paddusb);
3979 LMI_HELPER(PADDB, paddb);
3980
3981 LMI_HELPER(PSUBSH, psubsh);
3982 LMI_HELPER(PSUBUSH, psubush);
3983 LMI_HELPER(PSUBH, psubh);
3984 LMI_HELPER(PSUBW, psubw);
3985 LMI_HELPER(PSUBSB, psubsb);
3986 LMI_HELPER(PSUBUSB, psubusb);
3987 LMI_HELPER(PSUBB, psubb);
3988
3989 LMI_HELPER(PSHUFH, pshufh);
3990 LMI_HELPER(PACKSSWH, packsswh);
3991 LMI_HELPER(PACKSSHB, packsshb);
3992 LMI_HELPER(PACKUSHB, packushb);
3993
3994 LMI_HELPER(PUNPCKLHW, punpcklhw);
3995 LMI_HELPER(PUNPCKHHW, punpckhhw);
3996 LMI_HELPER(PUNPCKLBH, punpcklbh);
3997 LMI_HELPER(PUNPCKHBH, punpckhbh);
3998 LMI_HELPER(PUNPCKLWD, punpcklwd);
3999 LMI_HELPER(PUNPCKHWD, punpckhwd);
4000
4001 LMI_HELPER(PAVGH, pavgh);
4002 LMI_HELPER(PAVGB, pavgb);
4003 LMI_HELPER(PMAXSH, pmaxsh);
4004 LMI_HELPER(PMINSH, pminsh);
4005 LMI_HELPER(PMAXUB, pmaxub);
4006 LMI_HELPER(PMINUB, pminub);
4007
4008 LMI_HELPER(PCMPEQW, pcmpeqw);
4009 LMI_HELPER(PCMPGTW, pcmpgtw);
4010 LMI_HELPER(PCMPEQH, pcmpeqh);
4011 LMI_HELPER(PCMPGTH, pcmpgth);
4012 LMI_HELPER(PCMPEQB, pcmpeqb);
4013 LMI_HELPER(PCMPGTB, pcmpgtb);
4014
4015 LMI_HELPER(PSLLW, psllw);
4016 LMI_HELPER(PSLLH, psllh);
4017 LMI_HELPER(PSRLW, psrlw);
4018 LMI_HELPER(PSRLH, psrlh);
4019 LMI_HELPER(PSRAW, psraw);
4020 LMI_HELPER(PSRAH, psrah);
4021
4022 LMI_HELPER(PMULLH, pmullh);
4023 LMI_HELPER(PMULHH, pmulhh);
4024 LMI_HELPER(PMULHUH, pmulhuh);
4025 LMI_HELPER(PMADDHW, pmaddhw);
4026
4027 LMI_HELPER(PASUBUB, pasubub);
4028 LMI_HELPER_1(BIADD, biadd);
4029 LMI_HELPER_1(PMOVMSKB, pmovmskb);
4030
4031 LMI_DIRECT(PADDD, paddd, add);
4032 LMI_DIRECT(PSUBD, psubd, sub);
4033 LMI_DIRECT(XOR_CP2, xor, xor);
4034 LMI_DIRECT(NOR_CP2, nor, nor);
4035 LMI_DIRECT(AND_CP2, and, and);
bb7cab5f 4036 LMI_DIRECT(OR_CP2, or, or);
bd277fa1 4037
9099a36b
H
4038 case OPC_PANDN:
4039 tcg_gen_andc_i64(t0, t1, t0);
4040 break;
4041
bd277fa1
RH
4042 case OPC_PINSRH_0:
4043 tcg_gen_deposit_i64(t0, t0, t1, 0, 16);
bd277fa1
RH
4044 break;
4045 case OPC_PINSRH_1:
4046 tcg_gen_deposit_i64(t0, t0, t1, 16, 16);
bd277fa1
RH
4047 break;
4048 case OPC_PINSRH_2:
4049 tcg_gen_deposit_i64(t0, t0, t1, 32, 16);
bd277fa1
RH
4050 break;
4051 case OPC_PINSRH_3:
4052 tcg_gen_deposit_i64(t0, t0, t1, 48, 16);
bd277fa1
RH
4053 break;
4054
4055 case OPC_PEXTRH:
4056 tcg_gen_andi_i64(t1, t1, 3);
4057 tcg_gen_shli_i64(t1, t1, 4);
4058 tcg_gen_shr_i64(t0, t0, t1);
4059 tcg_gen_ext16u_i64(t0, t0);
bd277fa1
RH
4060 break;
4061
4062 case OPC_ADDU_CP2:
4063 tcg_gen_add_i64(t0, t0, t1);
4064 tcg_gen_ext32s_i64(t0, t0);
bd277fa1
RH
4065 break;
4066 case OPC_SUBU_CP2:
4067 tcg_gen_sub_i64(t0, t0, t1);
4068 tcg_gen_ext32s_i64(t0, t0);
bd277fa1
RH
4069 break;
4070
4071 case OPC_SLL_CP2:
bd277fa1
RH
4072 shift_max = 32;
4073 goto do_shift;
4074 case OPC_SRL_CP2:
bd277fa1
RH
4075 shift_max = 32;
4076 goto do_shift;
4077 case OPC_SRA_CP2:
bd277fa1
RH
4078 shift_max = 32;
4079 goto do_shift;
4080 case OPC_DSLL_CP2:
bd277fa1
RH
4081 shift_max = 64;
4082 goto do_shift;
4083 case OPC_DSRL_CP2:
bd277fa1
RH
4084 shift_max = 64;
4085 goto do_shift;
4086 case OPC_DSRA_CP2:
bd277fa1
RH
4087 shift_max = 64;
4088 goto do_shift;
4089 do_shift:
4090 /* Make sure shift count isn't TCG undefined behaviour. */
4091 tcg_gen_andi_i64(t1, t1, shift_max - 1);
4092
4093 switch (opc) {
4094 case OPC_SLL_CP2:
4095 case OPC_DSLL_CP2:
4096 tcg_gen_shl_i64(t0, t0, t1);
4097 break;
4098 case OPC_SRA_CP2:
4099 case OPC_DSRA_CP2:
4100 /* Since SRA is UndefinedResult without sign-extended inputs,
4101 we can treat SRA and DSRA the same. */
4102 tcg_gen_sar_i64(t0, t0, t1);
4103 break;
4104 case OPC_SRL_CP2:
4105 /* We want to shift in zeros for SRL; zero-extend first. */
4106 tcg_gen_ext32u_i64(t0, t0);
4107 /* FALLTHRU */
4108 case OPC_DSRL_CP2:
4109 tcg_gen_shr_i64(t0, t0, t1);
4110 break;
4111 }
4112
4113 if (shift_max == 32) {
4114 tcg_gen_ext32s_i64(t0, t0);
4115 }
4116
4117 /* Shifts larger than MAX produce zero. */
4118 tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max);
4119 tcg_gen_neg_i64(t1, t1);
4120 tcg_gen_and_i64(t0, t0, t1);
4121 break;
4122
4123 case OPC_ADD_CP2:
4124 case OPC_DADD_CP2:
4125 {
4126 TCGv_i64 t2 = tcg_temp_new_i64();
42a268c2 4127 TCGLabel *lab = gen_new_label();
bd277fa1
RH
4128
4129 tcg_gen_mov_i64(t2, t0);
4130 tcg_gen_add_i64(t0, t1, t2);
4131 if (opc == OPC_ADD_CP2) {
4132 tcg_gen_ext32s_i64(t0, t0);
4133 }
4134 tcg_gen_xor_i64(t1, t1, t2);
4135 tcg_gen_xor_i64(t2, t2, t0);
4136 tcg_gen_andc_i64(t1, t2, t1);
4137 tcg_temp_free_i64(t2);
4138 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
4139 generate_exception(ctx, EXCP_OVERFLOW);
4140 gen_set_label(lab);
bd277fa1
RH
4141 break;
4142 }
4143
4144 case OPC_SUB_CP2:
4145 case OPC_DSUB_CP2:
4146 {
4147 TCGv_i64 t2 = tcg_temp_new_i64();
42a268c2 4148 TCGLabel *lab = gen_new_label();
bd277fa1
RH
4149
4150 tcg_gen_mov_i64(t2, t0);
4151 tcg_gen_sub_i64(t0, t1, t2);
4152 if (opc == OPC_SUB_CP2) {
4153 tcg_gen_ext32s_i64(t0, t0);
4154 }
4155 tcg_gen_xor_i64(t1, t1, t2);
4156 tcg_gen_xor_i64(t2, t2, t0);
4157 tcg_gen_and_i64(t1, t1, t2);
4158 tcg_temp_free_i64(t2);
4159 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
4160 generate_exception(ctx, EXCP_OVERFLOW);
4161 gen_set_label(lab);
bd277fa1
RH
4162 break;
4163 }
4164
4165 case OPC_PMULUW:
4166 tcg_gen_ext32u_i64(t0, t0);
4167 tcg_gen_ext32u_i64(t1, t1);
4168 tcg_gen_mul_i64(t0, t0, t1);
bd277fa1
RH
4169 break;
4170
4171 case OPC_SEQU_CP2:
4172 case OPC_SEQ_CP2:
4173 case OPC_SLTU_CP2:
4174 case OPC_SLT_CP2:
4175 case OPC_SLEU_CP2:
4176 case OPC_SLE_CP2:
4177 /* ??? Document is unclear: Set FCC[CC]. Does that mean the
4178 FD field is the CC field? */
4179 default:
9d68ac14 4180 MIPS_INVAL("loongson_cp2");
9c708c7f 4181 generate_exception_end(ctx, EXCP_RI);
bd277fa1
RH
4182 return;
4183 }
4184
4185#undef LMI_HELPER
4186#undef LMI_DIRECT
4187
4188 gen_store_fpr64(ctx, t0, rd);
4189
bd277fa1
RH
4190 tcg_temp_free_i64(t0);
4191 tcg_temp_free_i64(t1);
4192}
4193
6af0bf9c 4194/* Traps */
7a387fff 4195static void gen_trap (DisasContext *ctx, uint32_t opc,
6af0bf9c
FB
4196 int rs, int rt, int16_t imm)
4197{
4198 int cond;
cdc0faa6 4199 TCGv t0 = tcg_temp_new();
1ba74fb8 4200 TCGv t1 = tcg_temp_new();
6af0bf9c
FB
4201
4202 cond = 0;
4203 /* Load needed operands */
4204 switch (opc) {
4205 case OPC_TEQ:
4206 case OPC_TGE:
4207 case OPC_TGEU:
4208 case OPC_TLT:
4209 case OPC_TLTU:
4210 case OPC_TNE:
4211 /* Compare two registers */
4212 if (rs != rt) {
be24bb4f
TS
4213 gen_load_gpr(t0, rs);
4214 gen_load_gpr(t1, rt);
6af0bf9c
FB
4215 cond = 1;
4216 }
179e32bb 4217 break;
6af0bf9c
FB
4218 case OPC_TEQI:
4219 case OPC_TGEI:
4220 case OPC_TGEIU:
4221 case OPC_TLTI:
4222 case OPC_TLTIU:
4223 case OPC_TNEI:
4224 /* Compare register to immediate */
4225 if (rs != 0 || imm != 0) {
be24bb4f
TS
4226 gen_load_gpr(t0, rs);
4227 tcg_gen_movi_tl(t1, (int32_t)imm);
6af0bf9c
FB
4228 cond = 1;
4229 }
4230 break;
4231 }
4232 if (cond == 0) {
4233 switch (opc) {
4234 case OPC_TEQ: /* rs == rs */
4235 case OPC_TEQI: /* r0 == 0 */
4236 case OPC_TGE: /* rs >= rs */
4237 case OPC_TGEI: /* r0 >= 0 */
4238 case OPC_TGEU: /* rs >= rs unsigned */
4239 case OPC_TGEIU: /* r0 >= 0 unsigned */
4240 /* Always trap */
9c708c7f 4241 generate_exception_end(ctx, EXCP_TRAP);
6af0bf9c
FB
4242 break;
4243 case OPC_TLT: /* rs < rs */
4244 case OPC_TLTI: /* r0 < 0 */
4245 case OPC_TLTU: /* rs < rs unsigned */
4246 case OPC_TLTIU: /* r0 < 0 unsigned */
4247 case OPC_TNE: /* rs != rs */
4248 case OPC_TNEI: /* r0 != 0 */
ead9360e 4249 /* Never trap: treat as NOP. */
cdc0faa6 4250 break;
6af0bf9c
FB
4251 }
4252 } else {
42a268c2 4253 TCGLabel *l1 = gen_new_label();
cdc0faa6 4254
6af0bf9c
FB
4255 switch (opc) {
4256 case OPC_TEQ:
4257 case OPC_TEQI:
cdc0faa6 4258 tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
6af0bf9c
FB
4259 break;
4260 case OPC_TGE:
4261 case OPC_TGEI:
cdc0faa6 4262 tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
6af0bf9c
FB
4263 break;
4264 case OPC_TGEU:
4265 case OPC_TGEIU:
cdc0faa6 4266 tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
6af0bf9c
FB
4267 break;
4268 case OPC_TLT:
4269 case OPC_TLTI:
cdc0faa6 4270 tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
6af0bf9c
FB
4271 break;
4272 case OPC_TLTU:
4273 case OPC_TLTIU:
cdc0faa6 4274 tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
6af0bf9c
FB
4275 break;
4276 case OPC_TNE:
4277 case OPC_TNEI:
cdc0faa6 4278 tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
6af0bf9c 4279 break;
6af0bf9c 4280 }
cdc0faa6 4281 generate_exception(ctx, EXCP_TRAP);
08ba7963
TS
4282 gen_set_label(l1);
4283 }
be24bb4f
TS
4284 tcg_temp_free(t0);
4285 tcg_temp_free(t1);
6af0bf9c
FB
4286}
4287
90aa39a1
SF
4288static inline bool use_goto_tb(DisasContext *ctx, target_ulong dest)
4289{
eeb3bba8 4290 if (unlikely(ctx->base.singlestep_enabled)) {
90aa39a1
SF
4291 return false;
4292 }
4293
4294#ifndef CONFIG_USER_ONLY
eeb3bba8 4295 return (ctx->base.tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
90aa39a1
SF
4296#else
4297 return true;
4298#endif
4299}
4300
356265ae 4301static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
c53be334 4302{
90aa39a1 4303 if (use_goto_tb(ctx, dest)) {
57fec1fe 4304 tcg_gen_goto_tb(n);
9b9e4393 4305 gen_save_pc(dest);
07ea28b4 4306 tcg_gen_exit_tb(ctx->base.tb, n);
6e256c93 4307 } else {
9b9e4393 4308 gen_save_pc(dest);
eeb3bba8 4309 if (ctx->base.singlestep_enabled) {
7b270ef2 4310 save_cpu_state(ctx, 0);
9c708c7f 4311 gen_helper_raise_exception_debug(cpu_env);
7b270ef2 4312 }
7f11636d 4313 tcg_gen_lookup_and_goto_ptr();
6e256c93 4314 }
c53be334
FB
4315}
4316
6af0bf9c 4317/* Branches (before delay slot) */
7a387fff 4318static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
7dca4ad0 4319 int insn_bytes,
b231c103
YK
4320 int rs, int rt, int32_t offset,
4321 int delayslot_size)
6af0bf9c 4322{
d077b6f7 4323 target_ulong btgt = -1;
3ad4bb2d 4324 int blink = 0;
2fdbad25 4325 int bcond_compute = 0;
1ba74fb8
AJ
4326 TCGv t0 = tcg_temp_new();
4327 TCGv t1 = tcg_temp_new();
3ad4bb2d
TS
4328
4329 if (ctx->hflags & MIPS_HFLAG_BMASK) {
923617a3 4330#ifdef MIPS_DEBUG_DISAS
339cd2a8 4331 LOG_DISAS("Branch in delay / forbidden slot at PC 0x"
eeb3bba8 4332 TARGET_FMT_lx "\n", ctx->base.pc_next);
923617a3 4333#endif
9c708c7f 4334 generate_exception_end(ctx, EXCP_RI);
6c5c1e20 4335 goto out;
3ad4bb2d 4336 }
6af0bf9c 4337
6af0bf9c
FB
4338 /* Load needed operands */
4339 switch (opc) {
4340 case OPC_BEQ:
4341 case OPC_BEQL:
4342 case OPC_BNE:
4343 case OPC_BNEL:
4344 /* Compare two registers */
4345 if (rs != rt) {
6c5c1e20
TS
4346 gen_load_gpr(t0, rs);
4347 gen_load_gpr(t1, rt);
2fdbad25 4348 bcond_compute = 1;
6af0bf9c 4349 }
eeb3bba8 4350 btgt = ctx->base.pc_next + insn_bytes + offset;
6af0bf9c
FB
4351 break;
4352 case OPC_BGEZ:
4353 case OPC_BGEZAL:
4354 case OPC_BGEZALL:
4355 case OPC_BGEZL:
4356 case OPC_BGTZ:
4357 case OPC_BGTZL:
4358 case OPC_BLEZ:
4359 case OPC_BLEZL:
4360 case OPC_BLTZ:
4361 case OPC_BLTZAL:
4362 case OPC_BLTZALL:
4363 case OPC_BLTZL:
4364 /* Compare to zero */
4365 if (rs != 0) {
6c5c1e20 4366 gen_load_gpr(t0, rs);
2fdbad25 4367 bcond_compute = 1;
6af0bf9c 4368 }
eeb3bba8 4369 btgt = ctx->base.pc_next + insn_bytes + offset;
6af0bf9c 4370 break;
e45a93e2
JL
4371 case OPC_BPOSGE32:
4372#if defined(TARGET_MIPS64)
4373 case OPC_BPOSGE64:
4374 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x7F);
4375#else
4376 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
4377#endif
4378 bcond_compute = 1;
eeb3bba8 4379 btgt = ctx->base.pc_next + insn_bytes + offset;
e45a93e2 4380 break;
6af0bf9c
FB
4381 case OPC_J:
4382 case OPC_JAL:
364d4831 4383 case OPC_JALX:
6af0bf9c 4384 /* Jump to immediate */
eeb3bba8
EC
4385 btgt = ((ctx->base.pc_next + insn_bytes) & (int32_t)0xF0000000) |
4386 (uint32_t)offset;
6af0bf9c
FB
4387 break;
4388 case OPC_JR:
4389 case OPC_JALR:
4390 /* Jump to register */
7a387fff
TS
4391 if (offset != 0 && offset != 16) {
4392 /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
cbeb0857 4393 others are reserved. */
923617a3 4394 MIPS_INVAL("jump hint");
9c708c7f 4395 generate_exception_end(ctx, EXCP_RI);
6c5c1e20 4396 goto out;
6af0bf9c 4397 }
d077b6f7 4398 gen_load_gpr(btarget, rs);
6af0bf9c
FB
4399 break;
4400 default:
4401 MIPS_INVAL("branch/jump");
9c708c7f 4402 generate_exception_end(ctx, EXCP_RI);
6c5c1e20 4403 goto out;
6af0bf9c 4404 }
2fdbad25 4405 if (bcond_compute == 0) {
6af0bf9c
FB
4406 /* No condition to be computed */
4407 switch (opc) {
4408 case OPC_BEQ: /* rx == rx */
4409 case OPC_BEQL: /* rx == rx likely */
4410 case OPC_BGEZ: /* 0 >= 0 */
4411 case OPC_BGEZL: /* 0 >= 0 likely */
4412 case OPC_BLEZ: /* 0 <= 0 */
4413 case OPC_BLEZL: /* 0 <= 0 likely */
4414 /* Always take */
4ad40f36 4415 ctx->hflags |= MIPS_HFLAG_B;
6af0bf9c
FB
4416 break;
4417 case OPC_BGEZAL: /* 0 >= 0 */
4418 case OPC_BGEZALL: /* 0 >= 0 likely */
4419 /* Always take and link */
4420 blink = 31;
4ad40f36 4421 ctx->hflags |= MIPS_HFLAG_B;
6af0bf9c
FB
4422 break;
4423 case OPC_BNE: /* rx != rx */
4424 case OPC_BGTZ: /* 0 > 0 */
4425 case OPC_BLTZ: /* 0 < 0 */
ead9360e 4426 /* Treat as NOP. */
6c5c1e20 4427 goto out;
eeef26cd 4428 case OPC_BLTZAL: /* 0 < 0 */
3c824109
NF
4429 /* Handle as an unconditional branch to get correct delay
4430 slot checking. */
4431 blink = 31;
eeb3bba8 4432 btgt = ctx->base.pc_next + insn_bytes + delayslot_size;
3c824109 4433 ctx->hflags |= MIPS_HFLAG_B;
3c824109 4434 break;
eeef26cd 4435 case OPC_BLTZALL: /* 0 < 0 likely */
eeb3bba8 4436 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 8);
9898128f 4437 /* Skip the instruction in the delay slot */
eeb3bba8 4438 ctx->base.pc_next += 4;
6c5c1e20 4439 goto out;
6af0bf9c
FB
4440 case OPC_BNEL: /* rx != rx likely */
4441 case OPC_BGTZL: /* 0 > 0 likely */
6af0bf9c
FB
4442 case OPC_BLTZL: /* 0 < 0 likely */
4443 /* Skip the instruction in the delay slot */
eeb3bba8 4444 ctx->base.pc_next += 4;
6c5c1e20 4445 goto out;
6af0bf9c 4446 case OPC_J:
4ad40f36 4447 ctx->hflags |= MIPS_HFLAG_B;
6af0bf9c 4448 break;
364d4831
NF
4449 case OPC_JALX:
4450 ctx->hflags |= MIPS_HFLAG_BX;
4451 /* Fallthrough */
6af0bf9c
FB
4452 case OPC_JAL:
4453 blink = 31;
4ad40f36 4454 ctx->hflags |= MIPS_HFLAG_B;
6af0bf9c
FB
4455 break;
4456 case OPC_JR:
4ad40f36 4457 ctx->hflags |= MIPS_HFLAG_BR;
6af0bf9c
FB
4458 break;
4459 case OPC_JALR:
4460 blink = rt;
4ad40f36 4461 ctx->hflags |= MIPS_HFLAG_BR;
6af0bf9c
FB
4462 break;
4463 default:
4464 MIPS_INVAL("branch/jump");
9c708c7f 4465 generate_exception_end(ctx, EXCP_RI);
6c5c1e20 4466 goto out;
6af0bf9c
FB
4467 }
4468 } else {
4469 switch (opc) {
4470 case OPC_BEQ:
e68dd28f 4471 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
6af0bf9c
FB
4472 goto not_likely;
4473 case OPC_BEQL:
e68dd28f 4474 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
6af0bf9c
FB
4475 goto likely;
4476 case OPC_BNE:
e68dd28f 4477 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
6af0bf9c
FB
4478 goto not_likely;
4479 case OPC_BNEL:
e68dd28f 4480 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
6af0bf9c
FB
4481 goto likely;
4482 case OPC_BGEZ:
e68dd28f 4483 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6af0bf9c
FB
4484 goto not_likely;
4485 case OPC_BGEZL:
e68dd28f 4486 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6af0bf9c
FB
4487 goto likely;
4488 case OPC_BGEZAL:
e68dd28f 4489 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6af0bf9c
FB
4490 blink = 31;
4491 goto not_likely;
4492 case OPC_BGEZALL:
e68dd28f 4493 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6af0bf9c 4494 blink = 31;
6af0bf9c
FB
4495 goto likely;
4496 case OPC_BGTZ:
e68dd28f 4497 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
6af0bf9c
FB
4498 goto not_likely;
4499 case OPC_BGTZL:
e68dd28f 4500 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
6af0bf9c
FB
4501 goto likely;
4502 case OPC_BLEZ:
e68dd28f 4503 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
6af0bf9c
FB
4504 goto not_likely;
4505 case OPC_BLEZL:
e68dd28f 4506 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
6af0bf9c
FB
4507 goto likely;
4508 case OPC_BLTZ:
e68dd28f 4509 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6af0bf9c
FB
4510 goto not_likely;
4511 case OPC_BLTZL:
e68dd28f 4512 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6af0bf9c 4513 goto likely;
e45a93e2
JL
4514 case OPC_BPOSGE32:
4515 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
e45a93e2
JL
4516 goto not_likely;
4517#if defined(TARGET_MIPS64)
4518 case OPC_BPOSGE64:
4519 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 64);
e45a93e2
JL
4520 goto not_likely;
4521#endif
6af0bf9c 4522 case OPC_BLTZAL:
e68dd28f 4523 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6af0bf9c 4524 blink = 31;
6af0bf9c 4525 not_likely:
4ad40f36 4526 ctx->hflags |= MIPS_HFLAG_BC;
6af0bf9c
FB
4527 break;
4528 case OPC_BLTZALL:
e68dd28f 4529 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6af0bf9c 4530 blink = 31;
6af0bf9c 4531 likely:
4ad40f36 4532 ctx->hflags |= MIPS_HFLAG_BL;
6af0bf9c 4533 break;
c53f4a62
TS
4534 default:
4535 MIPS_INVAL("conditional branch/jump");
9c708c7f 4536 generate_exception_end(ctx, EXCP_RI);
6c5c1e20 4537 goto out;
6af0bf9c 4538 }
6af0bf9c 4539 }
9b9e4393 4540
d077b6f7 4541 ctx->btarget = btgt;
b231c103
YK
4542
4543 switch (delayslot_size) {
4544 case 2:
4545 ctx->hflags |= MIPS_HFLAG_BDS16;
4546 break;
4547 case 4:
4548 ctx->hflags |= MIPS_HFLAG_BDS32;
4549 break;
4550 }
4551
6af0bf9c 4552 if (blink > 0) {
b231c103 4553 int post_delay = insn_bytes + delayslot_size;
364d4831
NF
4554 int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
4555
eeb3bba8
EC
4556 tcg_gen_movi_tl(cpu_gpr[blink],
4557 ctx->base.pc_next + post_delay + lowbit);
6af0bf9c 4558 }
6c5c1e20
TS
4559
4560 out:
364d4831
NF
4561 if (insn_bytes == 2)
4562 ctx->hflags |= MIPS_HFLAG_B16;
6c5c1e20
TS
4563 tcg_temp_free(t0);
4564 tcg_temp_free(t1);
6af0bf9c
FB
4565}
4566
764371d2
SM
4567
4568/* nanoMIPS Branches */
4569static void gen_compute_branch_nm(DisasContext *ctx, uint32_t opc,
4570 int insn_bytes,
4571 int rs, int rt, int32_t offset)
4572{
4573 target_ulong btgt = -1;
4574 int bcond_compute = 0;
4575 TCGv t0 = tcg_temp_new();
4576 TCGv t1 = tcg_temp_new();
4577
4578 /* Load needed operands */
4579 switch (opc) {
4580 case OPC_BEQ:
4581 case OPC_BNE:
4582 /* Compare two registers */
4583 if (rs != rt) {
4584 gen_load_gpr(t0, rs);
4585 gen_load_gpr(t1, rt);
4586 bcond_compute = 1;
4587 }
4588 btgt = ctx->base.pc_next + insn_bytes + offset;
4589 break;
4590 case OPC_BGEZAL:
4591 /* Compare to zero */
4592 if (rs != 0) {
4593 gen_load_gpr(t0, rs);
4594 bcond_compute = 1;
4595 }
4596 btgt = ctx->base.pc_next + insn_bytes + offset;
4597 break;
4598 case OPC_BPOSGE32:
4599 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
4600 bcond_compute = 1;
4601 btgt = ctx->base.pc_next + insn_bytes + offset;
4602 break;
4603 case OPC_JR:
4604 case OPC_JALR:
4605 /* Jump to register */
4606 if (offset != 0 && offset != 16) {
4607 /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
4608 others are reserved. */
4609 MIPS_INVAL("jump hint");
4610 generate_exception_end(ctx, EXCP_RI);
4611 goto out;
4612 }
4613 gen_load_gpr(btarget, rs);
4614 break;
4615 default:
4616 MIPS_INVAL("branch/jump");
4617 generate_exception_end(ctx, EXCP_RI);
4618 goto out;
4619 }
4620 if (bcond_compute == 0) {
4621 /* No condition to be computed */
4622 switch (opc) {
4623 case OPC_BEQ: /* rx == rx */
4624 /* Always take */
4625 ctx->hflags |= MIPS_HFLAG_B;
4626 break;
4627 case OPC_BGEZAL: /* 0 >= 0 */
4628 /* Always take and link */
4629 tcg_gen_movi_tl(cpu_gpr[31],
4630 ctx->base.pc_next + insn_bytes);
4631 ctx->hflags |= MIPS_HFLAG_B;
4632 break;
4633 case OPC_BNE: /* rx != rx */
4634 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 8);
4635 /* Skip the instruction in the delay slot */
4636 ctx->base.pc_next += 4;
4637 goto out;
4638 case OPC_JR:
4639 ctx->hflags |= MIPS_HFLAG_BR;
4640 break;
4641 case OPC_JALR:
4642 if (rt > 0) {
4643 tcg_gen_movi_tl(cpu_gpr[rt],
4644 ctx->base.pc_next + insn_bytes);
4645 }
4646 ctx->hflags |= MIPS_HFLAG_BR;
4647 break;
4648 default:
4649 MIPS_INVAL("branch/jump");
4650 generate_exception_end(ctx, EXCP_RI);
4651 goto out;
4652 }
4653 } else {
4654 switch (opc) {
4655 case OPC_BEQ:
4656 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
4657 goto not_likely;
4658 case OPC_BNE:
4659 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
4660 goto not_likely;
4661 case OPC_BGEZAL:
4662 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
4663 tcg_gen_movi_tl(cpu_gpr[31],
4664 ctx->base.pc_next + insn_bytes);
4665 goto not_likely;
4666 case OPC_BPOSGE32:
4667 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
4668 not_likely:
4669 ctx->hflags |= MIPS_HFLAG_BC;
4670 break;
4671 default:
4672 MIPS_INVAL("conditional branch/jump");
4673 generate_exception_end(ctx, EXCP_RI);
4674 goto out;
4675 }
4676 }
4677
4678 ctx->btarget = btgt;
4679
4680 out:
4681 if (insn_bytes == 2) {
4682 ctx->hflags |= MIPS_HFLAG_B16;
4683 }
4684 tcg_temp_free(t0);
4685 tcg_temp_free(t1);
4686}
4687
4688
7a387fff
TS
4689/* special3 bitfield operations */
4690static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
356265ae 4691 int rs, int lsb, int msb)
7a387fff 4692{
a7812ae4
PB
4693 TCGv t0 = tcg_temp_new();
4694 TCGv t1 = tcg_temp_new();
6c5c1e20
TS
4695
4696 gen_load_gpr(t1, rs);
7a387fff
TS
4697 switch (opc) {
4698 case OPC_EXT:
b7f26e52 4699 if (lsb + msb > 31) {
7a387fff 4700 goto fail;
b7f26e52 4701 }
505ad7c2 4702 if (msb != 31) {
6eebb7a4 4703 tcg_gen_extract_tl(t0, t1, lsb, msb + 1);
505ad7c2 4704 } else {
6eebb7a4
RH
4705 /* The two checks together imply that lsb == 0,
4706 so this is a simple sign-extension. */
4707 tcg_gen_ext32s_tl(t0, t1);
505ad7c2 4708 }
7a387fff 4709 break;
c6d6dd7c 4710#if defined(TARGET_MIPS64)
7a387fff 4711 case OPC_DEXTU:
b7f26e52
RH
4712 lsb += 32;
4713 goto do_dext;
4714 case OPC_DEXTM:
4715 msb += 32;
4716 goto do_dext;
7a387fff 4717 case OPC_DEXT:
b7f26e52
RH
4718 do_dext:
4719 if (lsb + msb > 63) {
4720 goto fail;
4721 }
6eebb7a4 4722 tcg_gen_extract_tl(t0, t1, lsb, msb + 1);
7a387fff 4723 break;
c6d6dd7c 4724#endif
7a387fff 4725 case OPC_INS:
b7f26e52 4726 if (lsb > msb) {
7a387fff 4727 goto fail;
b7f26e52 4728 }
6c5c1e20 4729 gen_load_gpr(t0, rt);
e0d002f1 4730 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
505ad7c2 4731 tcg_gen_ext32s_tl(t0, t0);
7a387fff 4732 break;
c6d6dd7c 4733#if defined(TARGET_MIPS64)
7a387fff 4734 case OPC_DINSU:
b7f26e52
RH
4735 lsb += 32;
4736 /* FALLTHRU */
4737 case OPC_DINSM:
4738 msb += 32;
4739 /* FALLTHRU */
7a387fff 4740 case OPC_DINS:
b7f26e52
RH
4741 if (lsb > msb) {
4742 goto fail;
4743 }
6c5c1e20 4744 gen_load_gpr(t0, rt);
e0d002f1 4745 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
7a387fff 4746 break;
c6d6dd7c 4747#endif
7a387fff
TS
4748 default:
4749fail:
4750 MIPS_INVAL("bitops");
9c708c7f 4751 generate_exception_end(ctx, EXCP_RI);
6c5c1e20
TS
4752 tcg_temp_free(t0);
4753 tcg_temp_free(t1);
7a387fff
TS
4754 return;
4755 }
6c5c1e20
TS
4756 gen_store_gpr(t0, rt);
4757 tcg_temp_free(t0);
4758 tcg_temp_free(t1);
7a387fff
TS
4759}
4760
49bcf33c
AJ
4761static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
4762{
3a55fa47 4763 TCGv t0;
49bcf33c 4764
3a55fa47
AJ
4765 if (rd == 0) {
4766 /* If no destination, treat it as a NOP. */
3a55fa47
AJ
4767 return;
4768 }
4769
4770 t0 = tcg_temp_new();
4771 gen_load_gpr(t0, rt);
49bcf33c
AJ
4772 switch (op2) {
4773 case OPC_WSBH:
3a55fa47
AJ
4774 {
4775 TCGv t1 = tcg_temp_new();
06a57e5c 4776 TCGv t2 = tcg_const_tl(0x00FF00FF);
3a55fa47
AJ
4777
4778 tcg_gen_shri_tl(t1, t0, 8);
06a57e5c
AJ
4779 tcg_gen_and_tl(t1, t1, t2);
4780 tcg_gen_and_tl(t0, t0, t2);
3a55fa47 4781 tcg_gen_shli_tl(t0, t0, 8);
3a55fa47 4782 tcg_gen_or_tl(t0, t0, t1);
06a57e5c 4783 tcg_temp_free(t2);
3a55fa47
AJ
4784 tcg_temp_free(t1);
4785 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
4786 }
49bcf33c
AJ
4787 break;
4788 case OPC_SEB:
3a55fa47 4789 tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
49bcf33c
AJ
4790 break;
4791 case OPC_SEH:
3a55fa47 4792 tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
49bcf33c
AJ
4793 break;
4794#if defined(TARGET_MIPS64)
4795 case OPC_DSBH:
3a55fa47
AJ
4796 {
4797 TCGv t1 = tcg_temp_new();
06a57e5c 4798 TCGv t2 = tcg_const_tl(0x00FF00FF00FF00FFULL);
3a55fa47
AJ
4799
4800 tcg_gen_shri_tl(t1, t0, 8);
06a57e5c
AJ
4801 tcg_gen_and_tl(t1, t1, t2);
4802 tcg_gen_and_tl(t0, t0, t2);
3a55fa47 4803 tcg_gen_shli_tl(t0, t0, 8);
3a55fa47 4804 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
06a57e5c 4805 tcg_temp_free(t2);
3a55fa47
AJ
4806 tcg_temp_free(t1);
4807 }
49bcf33c
AJ
4808 break;
4809 case OPC_DSHD:
3a55fa47
AJ
4810 {
4811 TCGv t1 = tcg_temp_new();
06a57e5c 4812 TCGv t2 = tcg_const_tl(0x0000FFFF0000FFFFULL);
3a55fa47
AJ
4813
4814 tcg_gen_shri_tl(t1, t0, 16);
06a57e5c
AJ
4815 tcg_gen_and_tl(t1, t1, t2);
4816 tcg_gen_and_tl(t0, t0, t2);
3a55fa47 4817 tcg_gen_shli_tl(t0, t0, 16);
3a55fa47
AJ
4818 tcg_gen_or_tl(t0, t0, t1);
4819 tcg_gen_shri_tl(t1, t0, 32);
4820 tcg_gen_shli_tl(t0, t0, 32);
4821 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
06a57e5c 4822 tcg_temp_free(t2);
3a55fa47
AJ
4823 tcg_temp_free(t1);
4824 }
49bcf33c
AJ
4825 break;
4826#endif
4827 default:
4828 MIPS_INVAL("bsfhl");
9c708c7f 4829 generate_exception_end(ctx, EXCP_RI);
49bcf33c 4830 tcg_temp_free(t0);
49bcf33c
AJ
4831 return;
4832 }
49bcf33c 4833 tcg_temp_free(t0);
49bcf33c
AJ
4834}
4835
1f1b4c00
YK
4836static void gen_lsa(DisasContext *ctx, int opc, int rd, int rs, int rt,
4837 int imm2)
4838{
4839 TCGv t0;
4840 TCGv t1;
4841 if (rd == 0) {
4842 /* Treat as NOP. */
4843 return;
4844 }
4845 t0 = tcg_temp_new();
4846 t1 = tcg_temp_new();
4847 gen_load_gpr(t0, rs);
4848 gen_load_gpr(t1, rt);
4849 tcg_gen_shli_tl(t0, t0, imm2 + 1);
4850 tcg_gen_add_tl(cpu_gpr[rd], t0, t1);
4851 if (opc == OPC_LSA) {
4852 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4853 }
4854
4855 tcg_temp_free(t1);
4856 tcg_temp_free(t0);
4857
4858 return;
4859}
4860
4861static void gen_align(DisasContext *ctx, int opc, int rd, int rs, int rt,
4862 int bp)
284b731a 4863{
1f1b4c00
YK
4864 TCGv t0;
4865 if (rd == 0) {
4866 /* Treat as NOP. */
4867 return;
4868 }
4869 t0 = tcg_temp_new();
4870 gen_load_gpr(t0, rt);
4871 if (bp == 0) {
51243852
MD
4872 switch (opc) {
4873 case OPC_ALIGN:
4874 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
4875 break;
4876#if defined(TARGET_MIPS64)
4877 case OPC_DALIGN:
4878 tcg_gen_mov_tl(cpu_gpr[rd], t0);
4879 break;
4880#endif
4881 }
1f1b4c00
YK
4882 } else {
4883 TCGv t1 = tcg_temp_new();
4884 gen_load_gpr(t1, rs);
4885 switch (opc) {
4886 case OPC_ALIGN:
4887 {
4888 TCGv_i64 t2 = tcg_temp_new_i64();
4889 tcg_gen_concat_tl_i64(t2, t1, t0);
4890 tcg_gen_shri_i64(t2, t2, 8 * (4 - bp));
4891 gen_move_low32(cpu_gpr[rd], t2);
4892 tcg_temp_free_i64(t2);
4893 }
4894 break;
284b731a 4895#if defined(TARGET_MIPS64)
1f1b4c00
YK
4896 case OPC_DALIGN:
4897 tcg_gen_shli_tl(t0, t0, 8 * bp);
4898 tcg_gen_shri_tl(t1, t1, 8 * (8 - bp));
4899 tcg_gen_or_tl(cpu_gpr[rd], t1, t0);
4900 break;
284b731a 4901#endif
1f1b4c00
YK
4902 }
4903 tcg_temp_free(t1);
4904 }
4905
4906 tcg_temp_free(t0);
4907}
4908
4909static void gen_bitswap(DisasContext *ctx, int opc, int rd, int rt)
4910{
4911 TCGv t0;
4912 if (rd == 0) {
4913 /* Treat as NOP. */
4914 return;
4915 }
4916 t0 = tcg_temp_new();
4917 gen_load_gpr(t0, rt);
4918 switch (opc) {
4919 case OPC_BITSWAP:
4920 gen_helper_bitswap(cpu_gpr[rd], t0);
4921 break;
4922#if defined(TARGET_MIPS64)
4923 case OPC_DBITSWAP:
4924 gen_helper_dbitswap(cpu_gpr[rd], t0);
4925 break;
4926#endif
4927 }
4928 tcg_temp_free(t0);
284b731a
LA
4929}
4930
1f1b4c00
YK
4931#ifndef CONFIG_USER_ONLY
4932/* CP0 (MMU and control) */
5204ea79
LA
4933static inline void gen_mthc0_entrylo(TCGv arg, target_ulong off)
4934{
4935 TCGv_i64 t0 = tcg_temp_new_i64();
4936 TCGv_i64 t1 = tcg_temp_new_i64();
4937
4938 tcg_gen_ext_tl_i64(t0, arg);
4939 tcg_gen_ld_i64(t1, cpu_env, off);
4940#if defined(TARGET_MIPS64)
4941 tcg_gen_deposit_i64(t1, t1, t0, 30, 32);
4942#else
4943 tcg_gen_concat32_i64(t1, t1, t0);
4944#endif
4945 tcg_gen_st_i64(t1, cpu_env, off);
4946 tcg_temp_free_i64(t1);
4947 tcg_temp_free_i64(t0);
4948}
4949
4950static inline void gen_mthc0_store64(TCGv arg, target_ulong off)
4951{
4952 TCGv_i64 t0 = tcg_temp_new_i64();
4953 TCGv_i64 t1 = tcg_temp_new_i64();
4954
4955 tcg_gen_ext_tl_i64(t0, arg);
4956 tcg_gen_ld_i64(t1, cpu_env, off);
4957 tcg_gen_concat32_i64(t1, t1, t0);
4958 tcg_gen_st_i64(t1, cpu_env, off);
4959 tcg_temp_free_i64(t1);
4960 tcg_temp_free_i64(t0);
4961}
4962
4963static inline void gen_mfhc0_entrylo(TCGv arg, target_ulong off)
4964{
4965 TCGv_i64 t0 = tcg_temp_new_i64();
4966
4967 tcg_gen_ld_i64(t0, cpu_env, off);
4968#if defined(TARGET_MIPS64)
4969 tcg_gen_shri_i64(t0, t0, 30);
4970#else
4971 tcg_gen_shri_i64(t0, t0, 32);
4972#endif
4973 gen_move_low32(arg, t0);
4974 tcg_temp_free_i64(t0);
4975}
4976
4977static inline void gen_mfhc0_load64(TCGv arg, target_ulong off, int shift)
4978{
4979 TCGv_i64 t0 = tcg_temp_new_i64();
4980
4981 tcg_gen_ld_i64(t0, cpu_env, off);
4982 tcg_gen_shri_i64(t0, t0, 32 + shift);
4983 gen_move_low32(arg, t0);
4984 tcg_temp_free_i64(t0);
4985}
4986
d9bea114 4987static inline void gen_mfc0_load32 (TCGv arg, target_ulong off)
4f57689a 4988{
d9bea114 4989 TCGv_i32 t0 = tcg_temp_new_i32();
4f57689a 4990
d9bea114
AJ
4991 tcg_gen_ld_i32(t0, cpu_env, off);
4992 tcg_gen_ext_i32_tl(arg, t0);
4993 tcg_temp_free_i32(t0);
4f57689a
TS
4994}
4995
d9bea114 4996static inline void gen_mfc0_load64 (TCGv arg, target_ulong off)
4f57689a 4997{
d9bea114
AJ
4998 tcg_gen_ld_tl(arg, cpu_env, off);
4999 tcg_gen_ext32s_tl(arg, arg);
4f57689a
TS
5000}
5001
d9bea114 5002static inline void gen_mtc0_store32 (TCGv arg, target_ulong off)
f1aa6320 5003{
d9bea114 5004 TCGv_i32 t0 = tcg_temp_new_i32();
f1aa6320 5005
d9bea114
AJ
5006 tcg_gen_trunc_tl_i32(t0, arg);
5007 tcg_gen_st_i32(t0, cpu_env, off);
5008 tcg_temp_free_i32(t0);
f1aa6320
TS
5009}
5010
c98d3d79
YK
5011#define CP0_CHECK(c) \
5012 do { \
5013 if (!(c)) { \
5014 goto cp0_unimplemented; \
5015 } \
5016 } while (0)
5017
5204ea79
LA
5018static void gen_mfhc0(DisasContext *ctx, TCGv arg, int reg, int sel)
5019{
5020 const char *rn = "invalid";
5021
5204ea79
LA
5022 switch (reg) {
5023 case 2:
5024 switch (sel) {
5025 case 0:
59488dda 5026 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
5204ea79
LA
5027 gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
5028 rn = "EntryLo0";
5029 break;
5030 default:
c98d3d79 5031 goto cp0_unimplemented;
5204ea79
LA
5032 }
5033 break;
5034 case 3:
5035 switch (sel) {
5036 case 0:
59488dda 5037 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
5204ea79
LA
5038 gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
5039 rn = "EntryLo1";
5040 break;
5041 default:
c98d3d79 5042 goto cp0_unimplemented;
5204ea79
LA
5043 }
5044 break;
5045 case 17:
5046 switch (sel) {
5047 case 0:
5048 gen_mfhc0_load64(arg, offsetof(CPUMIPSState, lladdr),
5049 ctx->CP0_LLAddr_shift);
5050 rn = "LLAddr";
5051 break;
f6d4dd81
YK
5052 case 1:
5053 CP0_CHECK(ctx->mrp);
5054 gen_helper_mfhc0_maar(arg, cpu_env);
5055 rn = "MAAR";
5056 break;
5204ea79 5057 default:
c98d3d79 5058 goto cp0_unimplemented;
5204ea79
LA
5059 }
5060 break;
5061 case 28:
5062 switch (sel) {
5063 case 0:
5064 case 2:
5065 case 4:
5066 case 6:
5067 gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_TagLo), 0);
5068 rn = "TagLo";
5069 break;
5070 default:
c98d3d79 5071 goto cp0_unimplemented;
5204ea79
LA
5072 }
5073 break;
5074 default:
c98d3d79 5075 goto cp0_unimplemented;
5204ea79 5076 }
b44a7fb1 5077 trace_mips_translate_c0("mfhc0", rn, reg, sel);
5204ea79
LA
5078 return;
5079
c98d3d79 5080cp0_unimplemented:
965447ee 5081 qemu_log_mask(LOG_UNIMP, "mfhc0 %s (reg %d sel %d)\n", rn, reg, sel);
5204ea79
LA
5082 tcg_gen_movi_tl(arg, 0);
5083}
5084
5085static void gen_mthc0(DisasContext *ctx, TCGv arg, int reg, int sel)
5086{
5087 const char *rn = "invalid";
5088 uint64_t mask = ctx->PAMask >> 36;
5089
5204ea79
LA
5090 switch (reg) {
5091 case 2:
5092 switch (sel) {
5093 case 0:
59488dda 5094 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
5204ea79
LA
5095 tcg_gen_andi_tl(arg, arg, mask);
5096 gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
5097 rn = "EntryLo0";
5098 break;
5099 default:
c98d3d79 5100 goto cp0_unimplemented;
5204ea79
LA
5101 }
5102 break;
5103 case 3:
5104 switch (sel) {
5105 case 0:
59488dda 5106 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
5204ea79
LA
5107 tcg_gen_andi_tl(arg, arg, mask);
5108 gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
5109 rn = "EntryLo1";
5110 break;
5111 default:
c98d3d79 5112 goto cp0_unimplemented;
5204ea79
LA
5113 }
5114 break;
5115 case 17:
5116 switch (sel) {
5117 case 0:
5118 /* LLAddr is read-only (the only exception is bit 0 if LLB is
5119 supported); the CP0_LLAddr_rw_bitmask does not seem to be
5120 relevant for modern MIPS cores supporting MTHC0, therefore
5121 treating MTHC0 to LLAddr as NOP. */
5122 rn = "LLAddr";
5123 break;
f6d4dd81
YK
5124 case 1:
5125 CP0_CHECK(ctx->mrp);
5126 gen_helper_mthc0_maar(cpu_env, arg);
5127 rn = "MAAR";
5128 break;
5204ea79 5129 default:
c98d3d79 5130 goto cp0_unimplemented;
5204ea79
LA
5131 }
5132 break;
5133 case 28:
5134 switch (sel) {
5135 case 0:
5136 case 2:
5137 case 4:
5138 case 6:
5139 tcg_gen_andi_tl(arg, arg, mask);
5140 gen_mthc0_store64(arg, offsetof(CPUMIPSState, CP0_TagLo));
5141 rn = "TagLo";
5142 break;
5143 default:
c98d3d79 5144 goto cp0_unimplemented;
5204ea79
LA
5145 }
5146 break;
5147 default:
c98d3d79 5148 goto cp0_unimplemented;
5204ea79 5149 }
b44a7fb1 5150 trace_mips_translate_c0("mthc0", rn, reg, sel);
5204ea79 5151
c98d3d79 5152cp0_unimplemented:
965447ee 5153 qemu_log_mask(LOG_UNIMP, "mthc0 %s (reg %d sel %d)\n", rn, reg, sel);
5204ea79
LA
5154}
5155
e98c0d17
LA
5156static inline void gen_mfc0_unimplemented(DisasContext *ctx, TCGv arg)
5157{
5158 if (ctx->insn_flags & ISA_MIPS32R6) {
5159 tcg_gen_movi_tl(arg, 0);
5160 } else {
5161 tcg_gen_movi_tl(arg, ~0);
5162 }
5163}
5164
d75c135e 5165static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
873eb012 5166{
7a387fff 5167 const char *rn = "invalid";
873eb012 5168
e189e748 5169 if (sel != 0)
d75c135e 5170 check_insn(ctx, ISA_MIPS32);
e189e748 5171
873eb012
TS
5172 switch (reg) {
5173 case 0:
7a387fff
TS
5174 switch (sel) {
5175 case 0:
7db13fae 5176 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
7a387fff
TS
5177 rn = "Index";
5178 break;
5179 case 1:
f31b035a 5180 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5181 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
7a387fff 5182 rn = "MVPControl";
ead9360e 5183 break;
7a387fff 5184 case 2:
f31b035a 5185 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5186 gen_helper_mfc0_mvpconf0(arg, cpu_env);
7a387fff 5187 rn = "MVPConf0";
ead9360e 5188 break;
7a387fff 5189 case 3:
f31b035a 5190 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5191 gen_helper_mfc0_mvpconf1(arg, cpu_env);
7a387fff 5192 rn = "MVPConf1";
ead9360e 5193 break;
01bc435b
YK
5194 case 4:
5195 CP0_CHECK(ctx->vp);
5196 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl));
5197 rn = "VPControl";
5198 break;
7a387fff 5199 default:
f31b035a 5200 goto cp0_unimplemented;
7a387fff 5201 }
873eb012
TS
5202 break;
5203 case 1:
7a387fff
TS
5204 switch (sel) {
5205 case 0:
f31b035a 5206 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
895c2d04 5207 gen_helper_mfc0_random(arg, cpu_env);
7a387fff 5208 rn = "Random";
2423f660 5209 break;
7a387fff 5210 case 1:
f31b035a 5211 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 5212 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
7a387fff 5213 rn = "VPEControl";
ead9360e 5214 break;
7a387fff 5215 case 2:
f31b035a 5216 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 5217 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
7a387fff 5218 rn = "VPEConf0";
ead9360e 5219 break;
7a387fff 5220 case 3:
f31b035a 5221 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 5222 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
7a387fff 5223 rn = "VPEConf1";
ead9360e 5224 break;
7a387fff 5225 case 4:
f31b035a 5226 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 5227 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask));
7a387fff 5228 rn = "YQMask";
ead9360e 5229 break;
7a387fff 5230 case 5:
f31b035a 5231 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 5232 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
7a387fff 5233 rn = "VPESchedule";
ead9360e 5234 break;
7a387fff 5235 case 6:
f31b035a 5236 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 5237 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
7a387fff 5238 rn = "VPEScheFBack";
ead9360e 5239 break;
7a387fff 5240 case 7:
f31b035a 5241 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 5242 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
7a387fff 5243 rn = "VPEOpt";
ead9360e 5244 break;
7a387fff 5245 default:
f31b035a 5246 goto cp0_unimplemented;
7a387fff 5247 }
873eb012
TS
5248 break;
5249 case 2:
7a387fff
TS
5250 switch (sel) {
5251 case 0:
284b731a
LA
5252 {
5253 TCGv_i64 tmp = tcg_temp_new_i64();
5254 tcg_gen_ld_i64(tmp, cpu_env,
5255 offsetof(CPUMIPSState, CP0_EntryLo0));
7207c7f9 5256#if defined(TARGET_MIPS64)
284b731a
LA
5257 if (ctx->rxi) {
5258 /* Move RI/XI fields to bits 31:30 */
5259 tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
5260 tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
5261 }
7207c7f9 5262#endif
284b731a
LA
5263 gen_move_low32(arg, tmp);
5264 tcg_temp_free_i64(tmp);
5265 }
2423f660
TS
5266 rn = "EntryLo0";
5267 break;
7a387fff 5268 case 1:
f31b035a 5269 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5270 gen_helper_mfc0_tcstatus(arg, cpu_env);
2423f660 5271 rn = "TCStatus";
ead9360e 5272 break;
7a387fff 5273 case 2:
f31b035a 5274 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5275 gen_helper_mfc0_tcbind(arg, cpu_env);
2423f660 5276 rn = "TCBind";
ead9360e 5277 break;
7a387fff 5278 case 3:
f31b035a 5279 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5280 gen_helper_mfc0_tcrestart(arg, cpu_env);
2423f660 5281 rn = "TCRestart";
ead9360e 5282 break;
7a387fff 5283 case 4:
f31b035a 5284 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5285 gen_helper_mfc0_tchalt(arg, cpu_env);
2423f660 5286 rn = "TCHalt";
ead9360e 5287 break;
7a387fff 5288 case 5:
f31b035a 5289 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5290 gen_helper_mfc0_tccontext(arg, cpu_env);
2423f660 5291 rn = "TCContext";
ead9360e 5292 break;
7a387fff 5293 case 6:
f31b035a 5294 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5295 gen_helper_mfc0_tcschedule(arg, cpu_env);
2423f660 5296 rn = "TCSchedule";
ead9360e 5297 break;
7a387fff 5298 case 7:
f31b035a 5299 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5300 gen_helper_mfc0_tcschefback(arg, cpu_env);
2423f660 5301 rn = "TCScheFBack";
ead9360e 5302 break;
7a387fff 5303 default:
f31b035a 5304 goto cp0_unimplemented;
7a387fff 5305 }
873eb012
TS
5306 break;
5307 case 3:
7a387fff
TS
5308 switch (sel) {
5309 case 0:
284b731a
LA
5310 {
5311 TCGv_i64 tmp = tcg_temp_new_i64();
5312 tcg_gen_ld_i64(tmp, cpu_env,
5313 offsetof(CPUMIPSState, CP0_EntryLo1));
7207c7f9 5314#if defined(TARGET_MIPS64)
284b731a
LA
5315 if (ctx->rxi) {
5316 /* Move RI/XI fields to bits 31:30 */
5317 tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
5318 tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
5319 }
7207c7f9 5320#endif
284b731a
LA
5321 gen_move_low32(arg, tmp);
5322 tcg_temp_free_i64(tmp);
5323 }
2423f660
TS
5324 rn = "EntryLo1";
5325 break;
01bc435b
YK
5326 case 1:
5327 CP0_CHECK(ctx->vp);
5328 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber));
5329 rn = "GlobalNumber";
5330 break;
7a387fff 5331 default:
f31b035a 5332 goto cp0_unimplemented;
1579a72e 5333 }
873eb012
TS
5334 break;
5335 case 4:
7a387fff
TS
5336 switch (sel) {
5337 case 0:
7db13fae 5338 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
d9bea114 5339 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
5340 rn = "Context";
5341 break;
7a387fff 5342 case 1:
d9bea114 5343// gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
2423f660 5344 rn = "ContextConfig";
f31b035a 5345 goto cp0_unimplemented;
d279279e 5346 case 2:
f31b035a 5347 CP0_CHECK(ctx->ulri);
e40df9a8
JH
5348 tcg_gen_ld_tl(arg, cpu_env,
5349 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
5350 tcg_gen_ext32s_tl(arg, arg);
f31b035a 5351 rn = "UserLocal";
d279279e 5352 break;
7a387fff 5353 default:
f31b035a 5354 goto cp0_unimplemented;
1579a72e 5355 }
873eb012
TS
5356 break;
5357 case 5:
7a387fff
TS
5358 switch (sel) {
5359 case 0:
7db13fae 5360 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
2423f660
TS
5361 rn = "PageMask";
5362 break;
7a387fff 5363 case 1:
d75c135e 5364 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5365 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
2423f660
TS
5366 rn = "PageGrain";
5367 break;
cec56a73
JH
5368 case 2:
5369 CP0_CHECK(ctx->sc);
5370 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl0));
5371 tcg_gen_ext32s_tl(arg, arg);
5372 rn = "SegCtl0";
5373 break;
5374 case 3:
5375 CP0_CHECK(ctx->sc);
5376 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl1));
5377 tcg_gen_ext32s_tl(arg, arg);
5378 rn = "SegCtl1";
5379 break;
5380 case 4:
5381 CP0_CHECK(ctx->sc);
5382 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl2));
5383 tcg_gen_ext32s_tl(arg, arg);
5384 rn = "SegCtl2";
5385 break;
7a387fff 5386 default:
f31b035a 5387 goto cp0_unimplemented;
1579a72e 5388 }
873eb012
TS
5389 break;
5390 case 6:
7a387fff
TS
5391 switch (sel) {
5392 case 0:
7db13fae 5393 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
2423f660
TS
5394 rn = "Wired";
5395 break;
7a387fff 5396 case 1:
d75c135e 5397 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5398 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
2423f660 5399 rn = "SRSConf0";
ead9360e 5400 break;
7a387fff 5401 case 2:
d75c135e 5402 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5403 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
2423f660 5404 rn = "SRSConf1";
ead9360e 5405 break;
7a387fff 5406 case 3:
d75c135e 5407 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5408 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
2423f660 5409 rn = "SRSConf2";
ead9360e 5410 break;
7a387fff 5411 case 4:
d75c135e 5412 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5413 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
2423f660 5414 rn = "SRSConf3";
ead9360e 5415 break;
7a387fff 5416 case 5:
d75c135e 5417 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5418 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
2423f660 5419 rn = "SRSConf4";
ead9360e 5420 break;
7a387fff 5421 default:
f31b035a 5422 goto cp0_unimplemented;
1579a72e 5423 }
873eb012 5424 break;
8c0fdd85 5425 case 7:
7a387fff
TS
5426 switch (sel) {
5427 case 0:
d75c135e 5428 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5429 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
2423f660
TS
5430 rn = "HWREna";
5431 break;
7a387fff 5432 default:
f31b035a 5433 goto cp0_unimplemented;
1579a72e 5434 }
8c0fdd85 5435 break;
873eb012 5436 case 8:
7a387fff
TS
5437 switch (sel) {
5438 case 0:
7db13fae 5439 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
d9bea114 5440 tcg_gen_ext32s_tl(arg, arg);
f0b3f3ae 5441 rn = "BadVAddr";
2423f660 5442 break;
aea14095 5443 case 1:
f31b035a
LA
5444 CP0_CHECK(ctx->bi);
5445 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
5446 rn = "BadInstr";
aea14095
LA
5447 break;
5448 case 2:
f31b035a
LA
5449 CP0_CHECK(ctx->bp);
5450 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
5451 rn = "BadInstrP";
aea14095 5452 break;
25beba9b
SM
5453 case 3:
5454 CP0_CHECK(ctx->bi);
5455 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrX));
5456 tcg_gen_andi_tl(arg, arg, ~0xffff);
5457 rn = "BadInstrX";
5458 break;
5459 default:
f31b035a 5460 goto cp0_unimplemented;
aea14095 5461 }
873eb012
TS
5462 break;
5463 case 9:
7a387fff
TS
5464 switch (sel) {
5465 case 0:
2e70f6ef 5466 /* Mark as an IO operation because we read the time. */
eeb3bba8 5467 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
2e70f6ef 5468 gen_io_start();
bd79255d 5469 }
895c2d04 5470 gen_helper_mfc0_count(arg, cpu_env);
eeb3bba8 5471 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
2e70f6ef 5472 gen_io_end();
2e70f6ef 5473 }
55807224 5474 /* Break the TB to be able to take timer interrupts immediately
b28425ba
EC
5475 after reading count. DISAS_STOP isn't sufficient, we need to
5476 ensure we break completely out of translated code. */
eeb3bba8
EC
5477 gen_save_pc(ctx->base.pc_next + 4);
5478 ctx->base.is_jmp = DISAS_EXIT;
2423f660
TS
5479 rn = "Count";
5480 break;
5481 /* 6,7 are implementation dependent */
7a387fff 5482 default:
f31b035a 5483 goto cp0_unimplemented;
2423f660 5484 }
873eb012
TS
5485 break;
5486 case 10:
7a387fff
TS
5487 switch (sel) {
5488 case 0:
7db13fae 5489 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
d9bea114 5490 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
5491 rn = "EntryHi";
5492 break;
7a387fff 5493 default:
f31b035a 5494 goto cp0_unimplemented;
1579a72e 5495 }
873eb012
TS
5496 break;
5497 case 11:
7a387fff
TS
5498 switch (sel) {
5499 case 0:
7db13fae 5500 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
2423f660
TS
5501 rn = "Compare";
5502 break;
5503 /* 6,7 are implementation dependent */
7a387fff 5504 default:
f31b035a 5505 goto cp0_unimplemented;
2423f660 5506 }
873eb012
TS
5507 break;
5508 case 12:
7a387fff
TS
5509 switch (sel) {
5510 case 0:
7db13fae 5511 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
2423f660
TS
5512 rn = "Status";
5513 break;
7a387fff 5514 case 1:
d75c135e 5515 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5516 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
2423f660
TS
5517 rn = "IntCtl";
5518 break;
7a387fff 5519 case 2:
d75c135e 5520 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5521 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
2423f660
TS
5522 rn = "SRSCtl";
5523 break;
7a387fff 5524 case 3:
d75c135e 5525 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5526 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
2423f660 5527 rn = "SRSMap";
fd88b6ab 5528 break;
7a387fff 5529 default:
f31b035a 5530 goto cp0_unimplemented;
7a387fff 5531 }
873eb012
TS
5532 break;
5533 case 13:
7a387fff
TS
5534 switch (sel) {
5535 case 0:
7db13fae 5536 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
2423f660
TS
5537 rn = "Cause";
5538 break;
7a387fff 5539 default:
f31b035a 5540 goto cp0_unimplemented;
7a387fff 5541 }
873eb012
TS
5542 break;
5543 case 14:
7a387fff
TS
5544 switch (sel) {
5545 case 0:
7db13fae 5546 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
d9bea114 5547 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
5548 rn = "EPC";
5549 break;
7a387fff 5550 default:
f31b035a 5551 goto cp0_unimplemented;
1579a72e 5552 }
873eb012
TS
5553 break;
5554 case 15:
7a387fff
TS
5555 switch (sel) {
5556 case 0:
7db13fae 5557 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
2423f660
TS
5558 rn = "PRid";
5559 break;
7a387fff 5560 case 1:
d75c135e 5561 check_insn(ctx, ISA_MIPS32R2);
74dbf824
JH
5562 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EBase));
5563 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
5564 rn = "EBase";
5565 break;
c870e3f5
YK
5566 case 3:
5567 check_insn(ctx, ISA_MIPS32R2);
5568 CP0_CHECK(ctx->cmgcr);
5569 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase));
5570 tcg_gen_ext32s_tl(arg, arg);
5571 rn = "CMGCRBase";
5572 break;
7a387fff 5573 default:
f31b035a 5574 goto cp0_unimplemented;
7a387fff 5575 }
873eb012
TS
5576 break;
5577 case 16:
5578 switch (sel) {
5579 case 0:
7db13fae 5580 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
873eb012
TS
5581 rn = "Config";
5582 break;
5583 case 1:
7db13fae 5584 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
873eb012
TS
5585 rn = "Config1";
5586 break;
7a387fff 5587 case 2:
7db13fae 5588 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
7a387fff
TS
5589 rn = "Config2";
5590 break;
5591 case 3:
7db13fae 5592 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
7a387fff
TS
5593 rn = "Config3";
5594 break;
b4160af1
PJ
5595 case 4:
5596 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
5597 rn = "Config4";
5598 break;
b4dd99a3
PJ
5599 case 5:
5600 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
5601 rn = "Config5";
5602 break;
e397ee33
TS
5603 /* 6,7 are implementation dependent */
5604 case 6:
7db13fae 5605 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
e397ee33
TS
5606 rn = "Config6";
5607 break;
5608 case 7:
7db13fae 5609 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
e397ee33
TS
5610 rn = "Config7";
5611 break;
873eb012 5612 default:
f31b035a 5613 goto cp0_unimplemented;
873eb012
TS
5614 }
5615 break;
5616 case 17:
7a387fff
TS
5617 switch (sel) {
5618 case 0:
895c2d04 5619 gen_helper_mfc0_lladdr(arg, cpu_env);
2423f660
TS
5620 rn = "LLAddr";
5621 break;
f6d4dd81
YK
5622 case 1:
5623 CP0_CHECK(ctx->mrp);
5624 gen_helper_mfc0_maar(arg, cpu_env);
5625 rn = "MAAR";
5626 break;
5627 case 2:
5628 CP0_CHECK(ctx->mrp);
5629 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI));
5630 rn = "MAARI";
5631 break;
7a387fff 5632 default:
f31b035a 5633 goto cp0_unimplemented;
7a387fff 5634 }
873eb012
TS
5635 break;
5636 case 18:
7a387fff 5637 switch (sel) {
c2e19f3c
AM
5638 case 0:
5639 case 1:
5640 case 2:
5641 case 3:
5642 case 4:
5643 case 5:
5644 case 6:
5645 case 7:
fa192d49 5646 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
895c2d04 5647 gen_helper_1e0i(mfc0_watchlo, arg, sel);
2423f660
TS
5648 rn = "WatchLo";
5649 break;
7a387fff 5650 default:
f31b035a 5651 goto cp0_unimplemented;
7a387fff 5652 }
873eb012
TS
5653 break;
5654 case 19:
7a387fff 5655 switch (sel) {
c2e19f3c
AM
5656 case 0:
5657 case 1:
5658 case 2:
5659 case 3:
5660 case 4:
5661 case 5:
5662 case 6:
5663 case 7:
fa192d49 5664 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
895c2d04 5665 gen_helper_1e0i(mfc0_watchhi, arg, sel);
2423f660
TS
5666 rn = "WatchHi";
5667 break;
7a387fff 5668 default:
f31b035a 5669 goto cp0_unimplemented;
7a387fff 5670 }
873eb012 5671 break;
8c0fdd85 5672 case 20:
7a387fff
TS
5673 switch (sel) {
5674 case 0:
d26bc211 5675#if defined(TARGET_MIPS64)
d75c135e 5676 check_insn(ctx, ISA_MIPS3);
7db13fae 5677 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
d9bea114 5678 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
5679 rn = "XContext";
5680 break;
703eaf37 5681#endif
7a387fff 5682 default:
f31b035a 5683 goto cp0_unimplemented;
7a387fff 5684 }
8c0fdd85
TS
5685 break;
5686 case 21:
7a387fff 5687 /* Officially reserved, but sel 0 is used for R1x000 framemask */
f31b035a 5688 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
7a387fff
TS
5689 switch (sel) {
5690 case 0:
7db13fae 5691 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
2423f660
TS
5692 rn = "Framemask";
5693 break;
7a387fff 5694 default:
f31b035a 5695 goto cp0_unimplemented;
7a387fff 5696 }
8c0fdd85
TS
5697 break;
5698 case 22:
d9bea114 5699 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
5700 rn = "'Diagnostic"; /* implementation dependent */
5701 break;
873eb012 5702 case 23:
7a387fff
TS
5703 switch (sel) {
5704 case 0:
895c2d04 5705 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
2423f660
TS
5706 rn = "Debug";
5707 break;
7a387fff 5708 case 1:
d9bea114 5709// gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
2423f660 5710 rn = "TraceControl";
3570d7f6 5711 goto cp0_unimplemented;
7a387fff 5712 case 2:
d9bea114 5713// gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
2423f660 5714 rn = "TraceControl2";
3570d7f6 5715 goto cp0_unimplemented;
7a387fff 5716 case 3:
d9bea114 5717// gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
2423f660 5718 rn = "UserTraceData";
3570d7f6 5719 goto cp0_unimplemented;
7a387fff 5720 case 4:
d9bea114 5721// gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
2423f660 5722 rn = "TraceBPC";
3570d7f6 5723 goto cp0_unimplemented;
7a387fff 5724 default:
f31b035a 5725 goto cp0_unimplemented;
7a387fff 5726 }
873eb012
TS
5727 break;
5728 case 24:
7a387fff
TS
5729 switch (sel) {
5730 case 0:
f0b3f3ae 5731 /* EJTAG support */
7db13fae 5732 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
d9bea114 5733 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
5734 rn = "DEPC";
5735 break;
7a387fff 5736 default:
f31b035a 5737 goto cp0_unimplemented;
7a387fff 5738 }
873eb012 5739 break;
8c0fdd85 5740 case 25:
7a387fff
TS
5741 switch (sel) {
5742 case 0:
7db13fae 5743 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
2423f660 5744 rn = "Performance0";
7a387fff
TS
5745 break;
5746 case 1:
d9bea114 5747// gen_helper_mfc0_performance1(arg);
2423f660 5748 rn = "Performance1";
3570d7f6 5749 goto cp0_unimplemented;
7a387fff 5750 case 2:
d9bea114 5751// gen_helper_mfc0_performance2(arg);
2423f660 5752 rn = "Performance2";
3570d7f6 5753 goto cp0_unimplemented;
7a387fff 5754 case 3:
d9bea114 5755// gen_helper_mfc0_performance3(arg);
2423f660 5756 rn = "Performance3";
3570d7f6 5757 goto cp0_unimplemented;
7a387fff 5758 case 4:
d9bea114 5759// gen_helper_mfc0_performance4(arg);
2423f660 5760 rn = "Performance4";
3570d7f6 5761 goto cp0_unimplemented;
7a387fff 5762 case 5:
d9bea114 5763// gen_helper_mfc0_performance5(arg);
2423f660 5764 rn = "Performance5";
3570d7f6 5765 goto cp0_unimplemented;
7a387fff 5766 case 6:
d9bea114 5767// gen_helper_mfc0_performance6(arg);
2423f660 5768 rn = "Performance6";
3570d7f6 5769 goto cp0_unimplemented;
7a387fff 5770 case 7:
d9bea114 5771// gen_helper_mfc0_performance7(arg);
2423f660 5772 rn = "Performance7";
3570d7f6 5773 goto cp0_unimplemented;
7a387fff 5774 default:
f31b035a 5775 goto cp0_unimplemented;
7a387fff 5776 }
8c0fdd85
TS
5777 break;
5778 case 26:
0d74a222
LA
5779 switch (sel) {
5780 case 0:
5781 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl));
5782 rn = "ErrCtl";
5783 break;
5784 default:
5785 goto cp0_unimplemented;
5786 }
da80682b 5787 break;
8c0fdd85 5788 case 27:
7a387fff 5789 switch (sel) {
c2e19f3c
AM
5790 case 0:
5791 case 1:
5792 case 2:
5793 case 3:
d9bea114 5794 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
5795 rn = "CacheErr";
5796 break;
7a387fff 5797 default:
f31b035a 5798 goto cp0_unimplemented;
7a387fff 5799 }
8c0fdd85 5800 break;
873eb012
TS
5801 case 28:
5802 switch (sel) {
5803 case 0:
7a387fff
TS
5804 case 2:
5805 case 4:
5806 case 6:
284b731a
LA
5807 {
5808 TCGv_i64 tmp = tcg_temp_new_i64();
5809 tcg_gen_ld_i64(tmp, cpu_env, offsetof(CPUMIPSState, CP0_TagLo));
5810 gen_move_low32(arg, tmp);
5811 tcg_temp_free_i64(tmp);
5812 }
873eb012
TS
5813 rn = "TagLo";
5814 break;
5815 case 1:
7a387fff
TS
5816 case 3:
5817 case 5:
5818 case 7:
7db13fae 5819 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
873eb012
TS
5820 rn = "DataLo";
5821 break;
5822 default:
f31b035a 5823 goto cp0_unimplemented;
873eb012
TS
5824 }
5825 break;
8c0fdd85 5826 case 29:
7a387fff
TS
5827 switch (sel) {
5828 case 0:
5829 case 2:
5830 case 4:
5831 case 6:
7db13fae 5832 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
7a387fff
TS
5833 rn = "TagHi";
5834 break;
5835 case 1:
5836 case 3:
5837 case 5:
5838 case 7:
7db13fae 5839 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
7a387fff
TS
5840 rn = "DataHi";
5841 break;
5842 default:
f31b035a 5843 goto cp0_unimplemented;
7a387fff 5844 }
8c0fdd85 5845 break;
873eb012 5846 case 30:
7a387fff
TS
5847 switch (sel) {
5848 case 0:
7db13fae 5849 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
d9bea114 5850 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
5851 rn = "ErrorEPC";
5852 break;
7a387fff 5853 default:
f31b035a 5854 goto cp0_unimplemented;
7a387fff 5855 }
873eb012
TS
5856 break;
5857 case 31:
7a387fff
TS
5858 switch (sel) {
5859 case 0:
f0b3f3ae 5860 /* EJTAG support */
7db13fae 5861 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
5862 rn = "DESAVE";
5863 break;
c2e19f3c
AM
5864 case 2:
5865 case 3:
5866 case 4:
5867 case 5:
5868 case 6:
5869 case 7:
f31b035a
LA
5870 CP0_CHECK(ctx->kscrexist & (1 << sel));
5871 tcg_gen_ld_tl(arg, cpu_env,
5872 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
5873 tcg_gen_ext32s_tl(arg, arg);
5874 rn = "KScratch";
e98c0d17 5875 break;
7a387fff 5876 default:
f31b035a 5877 goto cp0_unimplemented;
7a387fff 5878 }
873eb012
TS
5879 break;
5880 default:
f31b035a 5881 goto cp0_unimplemented;
873eb012 5882 }
b44a7fb1 5883 trace_mips_translate_c0("mfc0", rn, reg, sel);
873eb012
TS
5884 return;
5885
f31b035a 5886cp0_unimplemented:
965447ee 5887 qemu_log_mask(LOG_UNIMP, "mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
f31b035a 5888 gen_mfc0_unimplemented(ctx, arg);
873eb012
TS
5889}
5890
d75c135e 5891static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
8c0fdd85 5892{
7a387fff
TS
5893 const char *rn = "invalid";
5894
e189e748 5895 if (sel != 0)
d75c135e 5896 check_insn(ctx, ISA_MIPS32);
e189e748 5897
eeb3bba8 5898 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
2e70f6ef 5899 gen_io_start();
bd79255d 5900 }
2e70f6ef 5901
8c0fdd85
TS
5902 switch (reg) {
5903 case 0:
7a387fff
TS
5904 switch (sel) {
5905 case 0:
895c2d04 5906 gen_helper_mtc0_index(cpu_env, arg);
7a387fff
TS
5907 rn = "Index";
5908 break;
5909 case 1:
f31b035a 5910 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5911 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
7a387fff 5912 rn = "MVPControl";
ead9360e 5913 break;
7a387fff 5914 case 2:
f31b035a 5915 CP0_CHECK(ctx->insn_flags & ASE_MT);
ead9360e 5916 /* ignored */
7a387fff 5917 rn = "MVPConf0";
ead9360e 5918 break;
7a387fff 5919 case 3:
f31b035a 5920 CP0_CHECK(ctx->insn_flags & ASE_MT);
ead9360e 5921 /* ignored */
7a387fff 5922 rn = "MVPConf1";
ead9360e 5923 break;
01bc435b
YK
5924 case 4:
5925 CP0_CHECK(ctx->vp);
5926 /* ignored */
5927 rn = "VPControl";
5928 break;
7a387fff 5929 default:
f31b035a 5930 goto cp0_unimplemented;
7a387fff 5931 }
8c0fdd85
TS
5932 break;
5933 case 1:
7a387fff
TS
5934 switch (sel) {
5935 case 0:
2423f660 5936 /* ignored */
7a387fff 5937 rn = "Random";
2423f660 5938 break;
7a387fff 5939 case 1:
f31b035a 5940 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5941 gen_helper_mtc0_vpecontrol(cpu_env, arg);
7a387fff 5942 rn = "VPEControl";
ead9360e 5943 break;
7a387fff 5944 case 2:
f31b035a 5945 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5946 gen_helper_mtc0_vpeconf0(cpu_env, arg);
7a387fff 5947 rn = "VPEConf0";
ead9360e 5948 break;
7a387fff 5949 case 3:
f31b035a 5950 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5951 gen_helper_mtc0_vpeconf1(cpu_env, arg);
7a387fff 5952 rn = "VPEConf1";
ead9360e 5953 break;
7a387fff 5954 case 4:
f31b035a 5955 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5956 gen_helper_mtc0_yqmask(cpu_env, arg);
7a387fff 5957 rn = "YQMask";
ead9360e 5958 break;
7a387fff 5959 case 5:
f31b035a 5960 CP0_CHECK(ctx->insn_flags & ASE_MT);
d54a299b
LA
5961 tcg_gen_st_tl(arg, cpu_env,
5962 offsetof(CPUMIPSState, CP0_VPESchedule));
7a387fff 5963 rn = "VPESchedule";
ead9360e 5964 break;
7a387fff 5965 case 6:
f31b035a 5966 CP0_CHECK(ctx->insn_flags & ASE_MT);
d54a299b
LA
5967 tcg_gen_st_tl(arg, cpu_env,
5968 offsetof(CPUMIPSState, CP0_VPEScheFBack));
7a387fff 5969 rn = "VPEScheFBack";
ead9360e 5970 break;
7a387fff 5971 case 7:
f31b035a 5972 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5973 gen_helper_mtc0_vpeopt(cpu_env, arg);
7a387fff 5974 rn = "VPEOpt";
ead9360e 5975 break;
7a387fff 5976 default:
f31b035a 5977 goto cp0_unimplemented;
7a387fff 5978 }
8c0fdd85
TS
5979 break;
5980 case 2:
7a387fff
TS
5981 switch (sel) {
5982 case 0:
895c2d04 5983 gen_helper_mtc0_entrylo0(cpu_env, arg);
2423f660
TS
5984 rn = "EntryLo0";
5985 break;
7a387fff 5986 case 1:
f31b035a 5987 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5988 gen_helper_mtc0_tcstatus(cpu_env, arg);
2423f660 5989 rn = "TCStatus";
ead9360e 5990 break;
7a387fff 5991 case 2:
f31b035a 5992 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5993 gen_helper_mtc0_tcbind(cpu_env, arg);
2423f660 5994 rn = "TCBind";
ead9360e 5995 break;
7a387fff 5996 case 3:
f31b035a 5997 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5998 gen_helper_mtc0_tcrestart(cpu_env, arg);
2423f660 5999 rn = "TCRestart";
ead9360e 6000 break;
7a387fff 6001 case 4:
f31b035a 6002 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6003 gen_helper_mtc0_tchalt(cpu_env, arg);
2423f660 6004 rn = "TCHalt";
ead9360e 6005 break;
7a387fff 6006 case 5:
f31b035a 6007 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6008 gen_helper_mtc0_tccontext(cpu_env, arg);
2423f660 6009 rn = "TCContext";
ead9360e 6010 break;
7a387fff 6011 case 6:
f31b035a 6012 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6013 gen_helper_mtc0_tcschedule(cpu_env, arg);
2423f660 6014 rn = "TCSchedule";
ead9360e 6015 break;
7a387fff 6016 case 7:
f31b035a 6017 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6018 gen_helper_mtc0_tcschefback(cpu_env, arg);
2423f660 6019 rn = "TCScheFBack";
ead9360e 6020 break;
7a387fff 6021 default:
f31b035a 6022 goto cp0_unimplemented;
7a387fff 6023 }
8c0fdd85
TS
6024 break;
6025 case 3:
7a387fff
TS
6026 switch (sel) {
6027 case 0:
895c2d04 6028 gen_helper_mtc0_entrylo1(cpu_env, arg);
2423f660
TS
6029 rn = "EntryLo1";
6030 break;
01bc435b
YK
6031 case 1:
6032 CP0_CHECK(ctx->vp);
6033 /* ignored */
6034 rn = "GlobalNumber";
6035 break;
7a387fff 6036 default:
f31b035a 6037 goto cp0_unimplemented;
876d4b07 6038 }
8c0fdd85
TS
6039 break;
6040 case 4:
7a387fff
TS
6041 switch (sel) {
6042 case 0:
895c2d04 6043 gen_helper_mtc0_context(cpu_env, arg);
2423f660
TS
6044 rn = "Context";
6045 break;
7a387fff 6046 case 1:
895c2d04 6047// gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
2423f660 6048 rn = "ContextConfig";
f31b035a 6049 goto cp0_unimplemented;
d279279e 6050 case 2:
f31b035a
LA
6051 CP0_CHECK(ctx->ulri);
6052 tcg_gen_st_tl(arg, cpu_env,
6053 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
6054 rn = "UserLocal";
d279279e 6055 break;
7a387fff 6056 default:
f31b035a 6057 goto cp0_unimplemented;
876d4b07 6058 }
8c0fdd85
TS
6059 break;
6060 case 5:
7a387fff
TS
6061 switch (sel) {
6062 case 0:
895c2d04 6063 gen_helper_mtc0_pagemask(cpu_env, arg);
2423f660
TS
6064 rn = "PageMask";
6065 break;
7a387fff 6066 case 1:
d75c135e 6067 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6068 gen_helper_mtc0_pagegrain(cpu_env, arg);
2423f660 6069 rn = "PageGrain";
eeb3bba8 6070 ctx->base.is_jmp = DISAS_STOP;
2423f660 6071 break;
cec56a73
JH
6072 case 2:
6073 CP0_CHECK(ctx->sc);
6074 gen_helper_mtc0_segctl0(cpu_env, arg);
6075 rn = "SegCtl0";
6076 break;
6077 case 3:
6078 CP0_CHECK(ctx->sc);
6079 gen_helper_mtc0_segctl1(cpu_env, arg);
6080 rn = "SegCtl1";
6081 break;
6082 case 4:
6083 CP0_CHECK(ctx->sc);
6084 gen_helper_mtc0_segctl2(cpu_env, arg);
6085 rn = "SegCtl2";
6086 break;
7a387fff 6087 default:
f31b035a 6088 goto cp0_unimplemented;
876d4b07 6089 }
8c0fdd85
TS
6090 break;
6091 case 6:
7a387fff
TS
6092 switch (sel) {
6093 case 0:
895c2d04 6094 gen_helper_mtc0_wired(cpu_env, arg);
2423f660
TS
6095 rn = "Wired";
6096 break;
7a387fff 6097 case 1:
d75c135e 6098 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6099 gen_helper_mtc0_srsconf0(cpu_env, arg);
2423f660 6100 rn = "SRSConf0";
ead9360e 6101 break;
7a387fff 6102 case 2:
d75c135e 6103 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6104 gen_helper_mtc0_srsconf1(cpu_env, arg);
2423f660 6105 rn = "SRSConf1";
ead9360e 6106 break;
7a387fff 6107 case 3:
d75c135e 6108 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6109 gen_helper_mtc0_srsconf2(cpu_env, arg);
2423f660 6110 rn = "SRSConf2";
ead9360e 6111 break;
7a387fff 6112 case 4:
d75c135e 6113 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6114 gen_helper_mtc0_srsconf3(cpu_env, arg);
2423f660 6115 rn = "SRSConf3";
ead9360e 6116 break;
7a387fff 6117 case 5:
d75c135e 6118 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6119 gen_helper_mtc0_srsconf4(cpu_env, arg);
2423f660 6120 rn = "SRSConf4";
ead9360e 6121 break;
7a387fff 6122 default:
f31b035a 6123 goto cp0_unimplemented;
876d4b07 6124 }
8c0fdd85
TS
6125 break;
6126 case 7:
7a387fff
TS
6127 switch (sel) {
6128 case 0:
d75c135e 6129 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6130 gen_helper_mtc0_hwrena(cpu_env, arg);
eeb3bba8 6131 ctx->base.is_jmp = DISAS_STOP;
2423f660
TS
6132 rn = "HWREna";
6133 break;
7a387fff 6134 default:
f31b035a 6135 goto cp0_unimplemented;
876d4b07 6136 }
8c0fdd85
TS
6137 break;
6138 case 8:
aea14095
LA
6139 switch (sel) {
6140 case 0:
6141 /* ignored */
6142 rn = "BadVAddr";
6143 break;
6144 case 1:
6145 /* ignored */
6146 rn = "BadInstr";
6147 break;
6148 case 2:
6149 /* ignored */
6150 rn = "BadInstrP";
6151 break;
25beba9b
SM
6152 case 3:
6153 /* ignored */
6154 rn = "BadInstrX";
6155 break;
aea14095 6156 default:
f31b035a 6157 goto cp0_unimplemented;
aea14095 6158 }
8c0fdd85
TS
6159 break;
6160 case 9:
7a387fff
TS
6161 switch (sel) {
6162 case 0:
895c2d04 6163 gen_helper_mtc0_count(cpu_env, arg);
2423f660
TS
6164 rn = "Count";
6165 break;
876d4b07 6166 /* 6,7 are implementation dependent */
7a387fff 6167 default:
f31b035a 6168 goto cp0_unimplemented;
876d4b07 6169 }
8c0fdd85
TS
6170 break;
6171 case 10:
7a387fff
TS
6172 switch (sel) {
6173 case 0:
895c2d04 6174 gen_helper_mtc0_entryhi(cpu_env, arg);
2423f660
TS
6175 rn = "EntryHi";
6176 break;
7a387fff 6177 default:
f31b035a 6178 goto cp0_unimplemented;
876d4b07 6179 }
8c0fdd85
TS
6180 break;
6181 case 11:
7a387fff
TS
6182 switch (sel) {
6183 case 0:
895c2d04 6184 gen_helper_mtc0_compare(cpu_env, arg);
2423f660
TS
6185 rn = "Compare";
6186 break;
6187 /* 6,7 are implementation dependent */
7a387fff 6188 default:
f31b035a 6189 goto cp0_unimplemented;
876d4b07 6190 }
8c0fdd85
TS
6191 break;
6192 case 12:
7a387fff
TS
6193 switch (sel) {
6194 case 0:
867abc7e 6195 save_cpu_state(ctx, 1);
895c2d04 6196 gen_helper_mtc0_status(cpu_env, arg);
b28425ba 6197 /* DISAS_STOP isn't good enough here, hflags may have changed. */
eeb3bba8
EC
6198 gen_save_pc(ctx->base.pc_next + 4);
6199 ctx->base.is_jmp = DISAS_EXIT;
2423f660
TS
6200 rn = "Status";
6201 break;
7a387fff 6202 case 1:
d75c135e 6203 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6204 gen_helper_mtc0_intctl(cpu_env, arg);
8487327a 6205 /* Stop translation as we may have switched the execution mode */
eeb3bba8 6206 ctx->base.is_jmp = DISAS_STOP;
2423f660
TS
6207 rn = "IntCtl";
6208 break;
7a387fff 6209 case 2:
d75c135e 6210 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6211 gen_helper_mtc0_srsctl(cpu_env, arg);
8487327a 6212 /* Stop translation as we may have switched the execution mode */
eeb3bba8 6213 ctx->base.is_jmp = DISAS_STOP;
2423f660
TS
6214 rn = "SRSCtl";
6215 break;
7a387fff 6216 case 3:
d75c135e 6217 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6218 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
8487327a 6219 /* Stop translation as we may have switched the execution mode */
eeb3bba8 6220 ctx->base.is_jmp = DISAS_STOP;
2423f660 6221 rn = "SRSMap";
fd88b6ab 6222 break;
7a387fff 6223 default:
f31b035a 6224 goto cp0_unimplemented;
876d4b07 6225 }
8c0fdd85
TS
6226 break;
6227 case 13:
7a387fff
TS
6228 switch (sel) {
6229 case 0:
867abc7e 6230 save_cpu_state(ctx, 1);
895c2d04 6231 gen_helper_mtc0_cause(cpu_env, arg);
b28425ba
EC
6232 /* Stop translation as we may have triggered an interrupt.
6233 * DISAS_STOP isn't sufficient, we need to ensure we break out of
6234 * translated code to check for pending interrupts. */
eeb3bba8
EC
6235 gen_save_pc(ctx->base.pc_next + 4);
6236 ctx->base.is_jmp = DISAS_EXIT;
2423f660
TS
6237 rn = "Cause";
6238 break;
7a387fff 6239 default:
f31b035a 6240 goto cp0_unimplemented;
876d4b07 6241 }
8c0fdd85
TS
6242 break;
6243 case 14:
7a387fff
TS
6244 switch (sel) {
6245 case 0:
d54a299b 6246 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
2423f660
TS
6247 rn = "EPC";
6248 break;
7a387fff 6249 default:
f31b035a 6250 goto cp0_unimplemented;
876d4b07 6251 }
8c0fdd85
TS
6252 break;
6253 case 15:
7a387fff
TS
6254 switch (sel) {
6255 case 0:
2423f660
TS
6256 /* ignored */
6257 rn = "PRid";
6258 break;
7a387fff 6259 case 1:
d75c135e 6260 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6261 gen_helper_mtc0_ebase(cpu_env, arg);
2423f660
TS
6262 rn = "EBase";
6263 break;
7a387fff 6264 default:
f31b035a 6265 goto cp0_unimplemented;
1579a72e 6266 }
8c0fdd85
TS
6267 break;
6268 case 16:
6269 switch (sel) {
6270 case 0:
895c2d04 6271 gen_helper_mtc0_config0(cpu_env, arg);
7a387fff 6272 rn = "Config";
2423f660 6273 /* Stop translation as we may have switched the execution mode */
eeb3bba8 6274 ctx->base.is_jmp = DISAS_STOP;
7a387fff
TS
6275 break;
6276 case 1:
e397ee33 6277 /* ignored, read only */
7a387fff
TS
6278 rn = "Config1";
6279 break;
6280 case 2:
895c2d04 6281 gen_helper_mtc0_config2(cpu_env, arg);
7a387fff 6282 rn = "Config2";
2423f660 6283 /* Stop translation as we may have switched the execution mode */
eeb3bba8 6284 ctx->base.is_jmp = DISAS_STOP;
8c0fdd85 6285 break;
7a387fff 6286 case 3:
90f12d73 6287 gen_helper_mtc0_config3(cpu_env, arg);
7a387fff 6288 rn = "Config3";
90f12d73 6289 /* Stop translation as we may have switched the execution mode */
eeb3bba8 6290 ctx->base.is_jmp = DISAS_STOP;
7a387fff 6291 break;
b4160af1
PJ
6292 case 4:
6293 gen_helper_mtc0_config4(cpu_env, arg);
6294 rn = "Config4";
eeb3bba8 6295 ctx->base.is_jmp = DISAS_STOP;
b4160af1 6296 break;
b4dd99a3
PJ
6297 case 5:
6298 gen_helper_mtc0_config5(cpu_env, arg);
6299 rn = "Config5";
6300 /* Stop translation as we may have switched the execution mode */
eeb3bba8 6301 ctx->base.is_jmp = DISAS_STOP;
b4dd99a3 6302 break;
e397ee33
TS
6303 /* 6,7 are implementation dependent */
6304 case 6:
6305 /* ignored */
6306 rn = "Config6";
6307 break;
6308 case 7:
6309 /* ignored */
6310 rn = "Config7";
6311 break;
8c0fdd85
TS
6312 default:
6313 rn = "Invalid config selector";
f31b035a 6314 goto cp0_unimplemented;
8c0fdd85
TS
6315 }
6316 break;
6317 case 17:
7a387fff
TS
6318 switch (sel) {
6319 case 0:
895c2d04 6320 gen_helper_mtc0_lladdr(cpu_env, arg);
2423f660
TS
6321 rn = "LLAddr";
6322 break;
f6d4dd81
YK
6323 case 1:
6324 CP0_CHECK(ctx->mrp);
6325 gen_helper_mtc0_maar(cpu_env, arg);
6326 rn = "MAAR";
6327 break;
6328 case 2:
6329 CP0_CHECK(ctx->mrp);
6330 gen_helper_mtc0_maari(cpu_env, arg);
6331 rn = "MAARI";
6332 break;
7a387fff 6333 default:
f31b035a 6334 goto cp0_unimplemented;
7a387fff 6335 }
8c0fdd85
TS
6336 break;
6337 case 18:
7a387fff 6338 switch (sel) {
c2e19f3c
AM
6339 case 0:
6340 case 1:
6341 case 2:
6342 case 3:
6343 case 4:
6344 case 5:
6345 case 6:
6346 case 7:
fa192d49 6347 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
895c2d04 6348 gen_helper_0e1i(mtc0_watchlo, arg, sel);
2423f660
TS
6349 rn = "WatchLo";
6350 break;
7a387fff 6351 default:
f31b035a 6352 goto cp0_unimplemented;
7a387fff 6353 }
8c0fdd85
TS
6354 break;
6355 case 19:
7a387fff 6356 switch (sel) {
c2e19f3c
AM
6357 case 0:
6358 case 1:
6359 case 2:
6360 case 3:
6361 case 4:
6362 case 5:
6363 case 6:
6364 case 7:
fa192d49 6365 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
895c2d04 6366 gen_helper_0e1i(mtc0_watchhi, arg, sel);
2423f660
TS
6367 rn = "WatchHi";
6368 break;
7a387fff 6369 default:
f31b035a 6370 goto cp0_unimplemented;
7a387fff 6371 }
8c0fdd85
TS
6372 break;
6373 case 20:
7a387fff
TS
6374 switch (sel) {
6375 case 0:
d26bc211 6376#if defined(TARGET_MIPS64)
d75c135e 6377 check_insn(ctx, ISA_MIPS3);
895c2d04 6378 gen_helper_mtc0_xcontext(cpu_env, arg);
2423f660
TS
6379 rn = "XContext";
6380 break;
703eaf37 6381#endif
7a387fff 6382 default:
f31b035a 6383 goto cp0_unimplemented;
7a387fff 6384 }
8c0fdd85
TS
6385 break;
6386 case 21:
7a387fff 6387 /* Officially reserved, but sel 0 is used for R1x000 framemask */
f31b035a 6388 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
7a387fff
TS
6389 switch (sel) {
6390 case 0:
895c2d04 6391 gen_helper_mtc0_framemask(cpu_env, arg);
2423f660
TS
6392 rn = "Framemask";
6393 break;
7a387fff 6394 default:
f31b035a 6395 goto cp0_unimplemented;
7a387fff
TS
6396 }
6397 break;
8c0fdd85 6398 case 22:
7a387fff
TS
6399 /* ignored */
6400 rn = "Diagnostic"; /* implementation dependent */
2423f660 6401 break;
8c0fdd85 6402 case 23:
7a387fff
TS
6403 switch (sel) {
6404 case 0:
895c2d04 6405 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
b28425ba 6406 /* DISAS_STOP isn't good enough here, hflags may have changed. */
eeb3bba8
EC
6407 gen_save_pc(ctx->base.pc_next + 4);
6408 ctx->base.is_jmp = DISAS_EXIT;
2423f660
TS
6409 rn = "Debug";
6410 break;
7a387fff 6411 case 1:
895c2d04 6412// gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
2423f660 6413 rn = "TraceControl";
8487327a 6414 /* Stop translation as we may have switched the execution mode */
eeb3bba8 6415 ctx->base.is_jmp = DISAS_STOP;
3570d7f6 6416 goto cp0_unimplemented;
7a387fff 6417 case 2:
895c2d04 6418// gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
2423f660 6419 rn = "TraceControl2";
8487327a 6420 /* Stop translation as we may have switched the execution mode */
eeb3bba8 6421 ctx->base.is_jmp = DISAS_STOP;
3570d7f6 6422 goto cp0_unimplemented;
7a387fff 6423 case 3:
8487327a 6424 /* Stop translation as we may have switched the execution mode */
eeb3bba8 6425 ctx->base.is_jmp = DISAS_STOP;
895c2d04 6426// gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
2423f660 6427 rn = "UserTraceData";
8487327a 6428 /* Stop translation as we may have switched the execution mode */
eeb3bba8 6429 ctx->base.is_jmp = DISAS_STOP;
3570d7f6 6430 goto cp0_unimplemented;
7a387fff 6431 case 4:
895c2d04 6432// gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
8487327a 6433 /* Stop translation as we may have switched the execution mode */
eeb3bba8 6434 ctx->base.is_jmp = DISAS_STOP;
2423f660 6435 rn = "TraceBPC";
3570d7f6 6436 goto cp0_unimplemented;
7a387fff 6437 default:
f31b035a 6438 goto cp0_unimplemented;
7a387fff 6439 }
8c0fdd85
TS
6440 break;
6441 case 24:
7a387fff
TS
6442 switch (sel) {
6443 case 0:
f1aa6320 6444 /* EJTAG support */
d54a299b 6445 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
2423f660
TS
6446 rn = "DEPC";
6447 break;
7a387fff 6448 default:
f31b035a 6449 goto cp0_unimplemented;
7a387fff 6450 }
8c0fdd85
TS
6451 break;
6452 case 25:
7a387fff
TS
6453 switch (sel) {
6454 case 0:
895c2d04 6455 gen_helper_mtc0_performance0(cpu_env, arg);
2423f660
TS
6456 rn = "Performance0";
6457 break;
7a387fff 6458 case 1:
d9bea114 6459// gen_helper_mtc0_performance1(arg);
2423f660 6460 rn = "Performance1";
3570d7f6 6461 goto cp0_unimplemented;
7a387fff 6462 case 2:
d9bea114 6463// gen_helper_mtc0_performance2(arg);
2423f660 6464 rn = "Performance2";
3570d7f6 6465 goto cp0_unimplemented;
7a387fff 6466 case 3:
d9bea114 6467// gen_helper_mtc0_performance3(arg);
2423f660 6468 rn = "Performance3";
3570d7f6 6469 goto cp0_unimplemented;
7a387fff 6470 case 4:
d9bea114 6471// gen_helper_mtc0_performance4(arg);
2423f660 6472 rn = "Performance4";
3570d7f6 6473 goto cp0_unimplemented;
7a387fff 6474 case 5:
d9bea114 6475// gen_helper_mtc0_performance5(arg);
2423f660 6476 rn = "Performance5";
3570d7f6 6477 goto cp0_unimplemented;
7a387fff 6478 case 6:
d9bea114 6479// gen_helper_mtc0_performance6(arg);
2423f660 6480 rn = "Performance6";
3570d7f6 6481 goto cp0_unimplemented;
7a387fff 6482 case 7:
d9bea114 6483// gen_helper_mtc0_performance7(arg);
2423f660 6484 rn = "Performance7";
3570d7f6 6485 goto cp0_unimplemented;
7a387fff 6486 default:
f31b035a 6487 goto cp0_unimplemented;
7a387fff 6488 }
8c0fdd85
TS
6489 break;
6490 case 26:
0d74a222
LA
6491 switch (sel) {
6492 case 0:
6493 gen_helper_mtc0_errctl(cpu_env, arg);
eeb3bba8 6494 ctx->base.is_jmp = DISAS_STOP;
0d74a222
LA
6495 rn = "ErrCtl";
6496 break;
6497 default:
6498 goto cp0_unimplemented;
6499 }
2423f660 6500 break;
8c0fdd85 6501 case 27:
7a387fff 6502 switch (sel) {
c2e19f3c
AM
6503 case 0:
6504 case 1:
6505 case 2:
6506 case 3:
2423f660
TS
6507 /* ignored */
6508 rn = "CacheErr";
6509 break;
7a387fff 6510 default:
f31b035a 6511 goto cp0_unimplemented;
7a387fff 6512 }
8c0fdd85
TS
6513 break;
6514 case 28:
6515 switch (sel) {
6516 case 0:
7a387fff
TS
6517 case 2:
6518 case 4:
6519 case 6:
895c2d04 6520 gen_helper_mtc0_taglo(cpu_env, arg);
8c0fdd85
TS
6521 rn = "TagLo";
6522 break;
7a387fff
TS
6523 case 1:
6524 case 3:
6525 case 5:
6526 case 7:
895c2d04 6527 gen_helper_mtc0_datalo(cpu_env, arg);
7a387fff
TS
6528 rn = "DataLo";
6529 break;
8c0fdd85 6530 default:
f31b035a 6531 goto cp0_unimplemented;
8c0fdd85
TS
6532 }
6533 break;
6534 case 29:
7a387fff
TS
6535 switch (sel) {
6536 case 0:
6537 case 2:
6538 case 4:
6539 case 6:
895c2d04 6540 gen_helper_mtc0_taghi(cpu_env, arg);
7a387fff
TS
6541 rn = "TagHi";
6542 break;
6543 case 1:
6544 case 3:
6545 case 5:
6546 case 7:
895c2d04 6547 gen_helper_mtc0_datahi(cpu_env, arg);
7a387fff
TS
6548 rn = "DataHi";
6549 break;
6550 default:
6551 rn = "invalid sel";
f31b035a 6552 goto cp0_unimplemented;
7a387fff 6553 }
8c0fdd85
TS
6554 break;
6555 case 30:
7a387fff
TS
6556 switch (sel) {
6557 case 0:
d54a299b 6558 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
2423f660
TS
6559 rn = "ErrorEPC";
6560 break;
7a387fff 6561 default:
f31b035a 6562 goto cp0_unimplemented;
7a387fff 6563 }
8c0fdd85
TS
6564 break;
6565 case 31:
7a387fff
TS
6566 switch (sel) {
6567 case 0:
f1aa6320 6568 /* EJTAG support */
7db13fae 6569 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
6570 rn = "DESAVE";
6571 break;
c2e19f3c
AM
6572 case 2:
6573 case 3:
6574 case 4:
6575 case 5:
6576 case 6:
6577 case 7:
f31b035a
LA
6578 CP0_CHECK(ctx->kscrexist & (1 << sel));
6579 tcg_gen_st_tl(arg, cpu_env,
6580 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
6581 rn = "KScratch";
e98c0d17 6582 break;
7a387fff 6583 default:
f31b035a 6584 goto cp0_unimplemented;
7a387fff 6585 }
8c0fdd85
TS
6586 break;
6587 default:
f31b035a 6588 goto cp0_unimplemented;
8c0fdd85 6589 }
b44a7fb1
PMD
6590 trace_mips_translate_c0("mtc0", rn, reg, sel);
6591
bf20dc07 6592 /* For simplicity assume that all writes can cause interrupts. */
eeb3bba8 6593 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
2e70f6ef 6594 gen_io_end();
b28425ba 6595 /* DISAS_STOP isn't sufficient, we need to ensure we break out of
b74cddcb 6596 * translated code to check for pending interrupts. */
eeb3bba8
EC
6597 gen_save_pc(ctx->base.pc_next + 4);
6598 ctx->base.is_jmp = DISAS_EXIT;
2e70f6ef 6599 }
8c0fdd85
TS
6600 return;
6601
f31b035a 6602cp0_unimplemented:
965447ee 6603 qemu_log_mask(LOG_UNIMP, "mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
8c0fdd85
TS
6604}
6605
d26bc211 6606#if defined(TARGET_MIPS64)
d75c135e 6607static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
9c2149c8
TS
6608{
6609 const char *rn = "invalid";
6610
e189e748 6611 if (sel != 0)
d75c135e 6612 check_insn(ctx, ISA_MIPS64);
e189e748 6613
9c2149c8
TS
6614 switch (reg) {
6615 case 0:
6616 switch (sel) {
6617 case 0:
7db13fae 6618 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
9c2149c8
TS
6619 rn = "Index";
6620 break;
6621 case 1:
f31b035a 6622 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6623 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
9c2149c8 6624 rn = "MVPControl";
ead9360e 6625 break;
9c2149c8 6626 case 2:
f31b035a 6627 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6628 gen_helper_mfc0_mvpconf0(arg, cpu_env);
9c2149c8 6629 rn = "MVPConf0";
ead9360e 6630 break;
9c2149c8 6631 case 3:
f31b035a 6632 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6633 gen_helper_mfc0_mvpconf1(arg, cpu_env);
9c2149c8 6634 rn = "MVPConf1";
ead9360e 6635 break;
01bc435b
YK
6636 case 4:
6637 CP0_CHECK(ctx->vp);
6638 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl));
6639 rn = "VPControl";
6640 break;
9c2149c8 6641 default:
f31b035a 6642 goto cp0_unimplemented;
9c2149c8
TS
6643 }
6644 break;
6645 case 1:
6646 switch (sel) {
6647 case 0:
f31b035a 6648 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
895c2d04 6649 gen_helper_mfc0_random(arg, cpu_env);
9c2149c8 6650 rn = "Random";
2423f660 6651 break;
9c2149c8 6652 case 1:
f31b035a 6653 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6654 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
9c2149c8 6655 rn = "VPEControl";
ead9360e 6656 break;
9c2149c8 6657 case 2:
f31b035a 6658 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6659 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
9c2149c8 6660 rn = "VPEConf0";
ead9360e 6661 break;
9c2149c8 6662 case 3:
f31b035a 6663 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6664 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
9c2149c8 6665 rn = "VPEConf1";
ead9360e 6666 break;
9c2149c8 6667 case 4:
f31b035a 6668 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6669 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_YQMask));
9c2149c8 6670 rn = "YQMask";
ead9360e 6671 break;
9c2149c8 6672 case 5:
f31b035a 6673 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6674 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
9c2149c8 6675 rn = "VPESchedule";
ead9360e 6676 break;
9c2149c8 6677 case 6:
f31b035a 6678 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6679 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
9c2149c8 6680 rn = "VPEScheFBack";
ead9360e 6681 break;
9c2149c8 6682 case 7:
f31b035a 6683 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6684 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
9c2149c8 6685 rn = "VPEOpt";
ead9360e 6686 break;
9c2149c8 6687 default:
f31b035a 6688 goto cp0_unimplemented;
9c2149c8
TS
6689 }
6690 break;
6691 case 2:
6692 switch (sel) {
6693 case 0:
7db13fae 6694 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
2423f660
TS
6695 rn = "EntryLo0";
6696 break;
9c2149c8 6697 case 1:
f31b035a 6698 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6699 gen_helper_mfc0_tcstatus(arg, cpu_env);
2423f660 6700 rn = "TCStatus";
ead9360e 6701 break;
9c2149c8 6702 case 2:
f31b035a 6703 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6704 gen_helper_mfc0_tcbind(arg, cpu_env);
2423f660 6705 rn = "TCBind";
ead9360e 6706 break;
9c2149c8 6707 case 3:
f31b035a 6708 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6709 gen_helper_dmfc0_tcrestart(arg, cpu_env);
2423f660 6710 rn = "TCRestart";
ead9360e 6711 break;
9c2149c8 6712 case 4:
f31b035a 6713 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6714 gen_helper_dmfc0_tchalt(arg, cpu_env);
2423f660 6715 rn = "TCHalt";
ead9360e 6716 break;
9c2149c8 6717 case 5:
f31b035a 6718 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6719 gen_helper_dmfc0_tccontext(arg, cpu_env);
2423f660 6720 rn = "TCContext";
ead9360e 6721 break;
9c2149c8 6722 case 6:
f31b035a 6723 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6724 gen_helper_dmfc0_tcschedule(arg, cpu_env);
2423f660 6725 rn = "TCSchedule";
ead9360e 6726 break;
9c2149c8 6727 case 7:
f31b035a 6728 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6729 gen_helper_dmfc0_tcschefback(arg, cpu_env);
2423f660 6730 rn = "TCScheFBack";
ead9360e 6731 break;
9c2149c8 6732 default:
f31b035a 6733 goto cp0_unimplemented;
9c2149c8
TS
6734 }
6735 break;
6736 case 3:
6737 switch (sel) {
6738 case 0:
7db13fae 6739 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
2423f660
TS
6740 rn = "EntryLo1";
6741 break;
01bc435b
YK
6742 case 1:
6743 CP0_CHECK(ctx->vp);
6744 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber));
6745 rn = "GlobalNumber";
6746 break;
9c2149c8 6747 default:
f31b035a 6748 goto cp0_unimplemented;
1579a72e 6749 }
9c2149c8
TS
6750 break;
6751 case 4:
6752 switch (sel) {
6753 case 0:
7db13fae 6754 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
2423f660
TS
6755 rn = "Context";
6756 break;
9c2149c8 6757 case 1:
d9bea114 6758// gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
2423f660 6759 rn = "ContextConfig";
f31b035a 6760 goto cp0_unimplemented;
d279279e 6761 case 2:
f31b035a
LA
6762 CP0_CHECK(ctx->ulri);
6763 tcg_gen_ld_tl(arg, cpu_env,
6764 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
6765 rn = "UserLocal";
d279279e 6766 break;
9c2149c8 6767 default:
f31b035a 6768 goto cp0_unimplemented;
876d4b07 6769 }
9c2149c8
TS
6770 break;
6771 case 5:
6772 switch (sel) {
6773 case 0:
7db13fae 6774 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
2423f660
TS
6775 rn = "PageMask";
6776 break;
9c2149c8 6777 case 1:
d75c135e 6778 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6779 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
2423f660
TS
6780 rn = "PageGrain";
6781 break;
cec56a73
JH
6782 case 2:
6783 CP0_CHECK(ctx->sc);
6784 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl0));
6785 rn = "SegCtl0";
6786 break;
6787 case 3:
6788 CP0_CHECK(ctx->sc);
6789 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl1));
6790 rn = "SegCtl1";
6791 break;
6792 case 4:
6793 CP0_CHECK(ctx->sc);
6794 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl2));
6795 rn = "SegCtl2";
6796 break;
9c2149c8 6797 default:
f31b035a 6798 goto cp0_unimplemented;
876d4b07 6799 }
9c2149c8
TS
6800 break;
6801 case 6:
6802 switch (sel) {
6803 case 0:
7db13fae 6804 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
2423f660
TS
6805 rn = "Wired";
6806 break;
9c2149c8 6807 case 1:
d75c135e 6808 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6809 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
2423f660 6810 rn = "SRSConf0";
ead9360e 6811 break;
9c2149c8 6812 case 2:
d75c135e 6813 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6814 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
2423f660 6815 rn = "SRSConf1";
ead9360e 6816 break;
9c2149c8 6817 case 3:
d75c135e 6818 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6819 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
2423f660 6820 rn = "SRSConf2";
ead9360e 6821 break;
9c2149c8 6822 case 4:
d75c135e 6823 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6824 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
2423f660 6825 rn = "SRSConf3";
ead9360e 6826 break;
9c2149c8 6827 case 5:
d75c135e 6828 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6829 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
2423f660 6830 rn = "SRSConf4";
ead9360e 6831 break;
9c2149c8 6832 default:
f31b035a 6833 goto cp0_unimplemented;
876d4b07 6834 }
9c2149c8
TS
6835 break;
6836 case 7:
6837 switch (sel) {
6838 case 0:
d75c135e 6839 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6840 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
2423f660
TS
6841 rn = "HWREna";
6842 break;
9c2149c8 6843 default:
f31b035a 6844 goto cp0_unimplemented;
876d4b07 6845 }
9c2149c8
TS
6846 break;
6847 case 8:
6848 switch (sel) {
6849 case 0:
7db13fae 6850 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
f0b3f3ae 6851 rn = "BadVAddr";
2423f660 6852 break;
aea14095 6853 case 1:
f31b035a
LA
6854 CP0_CHECK(ctx->bi);
6855 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
6856 rn = "BadInstr";
aea14095
LA
6857 break;
6858 case 2:
f31b035a
LA
6859 CP0_CHECK(ctx->bp);
6860 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
6861 rn = "BadInstrP";
aea14095 6862 break;
25beba9b
SM
6863 case 3:
6864 CP0_CHECK(ctx->bi);
6865 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrX));
6866 tcg_gen_andi_tl(arg, arg, ~0xffff);
6867 rn = "BadInstrX";
6868 break;
9c2149c8 6869 default:
f31b035a 6870 goto cp0_unimplemented;
876d4b07 6871 }
9c2149c8
TS
6872 break;
6873 case 9:
6874 switch (sel) {
6875 case 0:
2e70f6ef 6876 /* Mark as an IO operation because we read the time. */
eeb3bba8 6877 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
2e70f6ef 6878 gen_io_start();
bd79255d 6879 }
895c2d04 6880 gen_helper_mfc0_count(arg, cpu_env);
eeb3bba8 6881 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
2e70f6ef 6882 gen_io_end();
2e70f6ef 6883 }
55807224 6884 /* Break the TB to be able to take timer interrupts immediately
b28425ba
EC
6885 after reading count. DISAS_STOP isn't sufficient, we need to
6886 ensure we break completely out of translated code. */
eeb3bba8
EC
6887 gen_save_pc(ctx->base.pc_next + 4);
6888 ctx->base.is_jmp = DISAS_EXIT;
2423f660
TS
6889 rn = "Count";
6890 break;
6891 /* 6,7 are implementation dependent */
9c2149c8 6892 default:
f31b035a 6893 goto cp0_unimplemented;
876d4b07 6894 }
9c2149c8
TS
6895 break;
6896 case 10:
6897 switch (sel) {
6898 case 0:
7db13fae 6899 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
2423f660
TS
6900 rn = "EntryHi";
6901 break;
9c2149c8 6902 default:
f31b035a 6903 goto cp0_unimplemented;
876d4b07 6904 }
9c2149c8
TS
6905 break;
6906 case 11:
6907 switch (sel) {
6908 case 0:
7db13fae 6909 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
2423f660
TS
6910 rn = "Compare";
6911 break;
876d4b07 6912 /* 6,7 are implementation dependent */
9c2149c8 6913 default:
f31b035a 6914 goto cp0_unimplemented;
876d4b07 6915 }
9c2149c8
TS
6916 break;
6917 case 12:
6918 switch (sel) {
6919 case 0:
7db13fae 6920 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
2423f660
TS
6921 rn = "Status";
6922 break;
9c2149c8 6923 case 1:
d75c135e 6924 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6925 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
2423f660
TS
6926 rn = "IntCtl";
6927 break;
9c2149c8 6928 case 2:
d75c135e 6929 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6930 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
2423f660
TS
6931 rn = "SRSCtl";
6932 break;
9c2149c8 6933 case 3:
d75c135e 6934 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6935 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
2423f660
TS
6936 rn = "SRSMap";
6937 break;
9c2149c8 6938 default:
f31b035a 6939 goto cp0_unimplemented;
876d4b07 6940 }
9c2149c8
TS
6941 break;
6942 case 13:
6943 switch (sel) {
6944 case 0:
7db13fae 6945 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
2423f660
TS
6946 rn = "Cause";
6947 break;
9c2149c8 6948 default:
f31b035a 6949 goto cp0_unimplemented;
876d4b07 6950 }
9c2149c8
TS
6951 break;
6952 case 14:
6953 switch (sel) {
6954 case 0:
7db13fae 6955 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
2423f660
TS
6956 rn = "EPC";
6957 break;
9c2149c8 6958 default:
f31b035a 6959 goto cp0_unimplemented;
876d4b07 6960 }
9c2149c8
TS
6961 break;
6962 case 15:
6963 switch (sel) {
6964 case 0:
7db13fae 6965 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
2423f660
TS
6966 rn = "PRid";
6967 break;
9c2149c8 6968 case 1:
d75c135e 6969 check_insn(ctx, ISA_MIPS32R2);
74dbf824 6970 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EBase));
2423f660
TS
6971 rn = "EBase";
6972 break;
c870e3f5
YK
6973 case 3:
6974 check_insn(ctx, ISA_MIPS32R2);
6975 CP0_CHECK(ctx->cmgcr);
6976 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase));
6977 rn = "CMGCRBase";
6978 break;
9c2149c8 6979 default:
f31b035a 6980 goto cp0_unimplemented;
876d4b07 6981 }
9c2149c8
TS
6982 break;
6983 case 16:
6984 switch (sel) {
6985 case 0:
7db13fae 6986 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
9c2149c8
TS
6987 rn = "Config";
6988 break;
6989 case 1:
7db13fae 6990 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
9c2149c8
TS
6991 rn = "Config1";
6992 break;
6993 case 2:
7db13fae 6994 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
9c2149c8
TS
6995 rn = "Config2";
6996 break;
6997 case 3:
7db13fae 6998 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
9c2149c8
TS
6999 rn = "Config3";
7000 break;
faf1f68b
LA
7001 case 4:
7002 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
7003 rn = "Config4";
7004 break;
7005 case 5:
7006 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
7007 rn = "Config5";
7008 break;
9c2149c8 7009 /* 6,7 are implementation dependent */
f0b3f3ae 7010 case 6:
7db13fae 7011 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
f0b3f3ae
TS
7012 rn = "Config6";
7013 break;
7014 case 7:
7db13fae 7015 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
f0b3f3ae
TS
7016 rn = "Config7";
7017 break;
9c2149c8 7018 default:
f31b035a 7019 goto cp0_unimplemented;
9c2149c8
TS
7020 }
7021 break;
7022 case 17:
7023 switch (sel) {
7024 case 0:
895c2d04 7025 gen_helper_dmfc0_lladdr(arg, cpu_env);
2423f660
TS
7026 rn = "LLAddr";
7027 break;
f6d4dd81
YK
7028 case 1:
7029 CP0_CHECK(ctx->mrp);
7030 gen_helper_dmfc0_maar(arg, cpu_env);
7031 rn = "MAAR";
7032 break;
7033 case 2:
7034 CP0_CHECK(ctx->mrp);
7035 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI));
7036 rn = "MAARI";
7037 break;
9c2149c8 7038 default:
f31b035a 7039 goto cp0_unimplemented;
9c2149c8
TS
7040 }
7041 break;
7042 case 18:
7043 switch (sel) {
c2e19f3c
AM
7044 case 0:
7045 case 1:
7046 case 2:
7047 case 3:
7048 case 4:
7049 case 5:
7050 case 6:
7051 case 7:
fa192d49 7052 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
895c2d04 7053 gen_helper_1e0i(dmfc0_watchlo, arg, sel);
2423f660
TS
7054 rn = "WatchLo";
7055 break;
9c2149c8 7056 default:
f31b035a 7057 goto cp0_unimplemented;
9c2149c8
TS
7058 }
7059 break;
7060 case 19:
7061 switch (sel) {
c2e19f3c
AM
7062 case 0:
7063 case 1:
7064 case 2:
7065 case 3:
7066 case 4:
7067 case 5:
7068 case 6:
7069 case 7:
fa192d49 7070 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
895c2d04 7071 gen_helper_1e0i(mfc0_watchhi, arg, sel);
2423f660
TS
7072 rn = "WatchHi";
7073 break;
9c2149c8 7074 default:
f31b035a 7075 goto cp0_unimplemented;
9c2149c8
TS
7076 }
7077 break;
7078 case 20:
7079 switch (sel) {
7080 case 0:
d75c135e 7081 check_insn(ctx, ISA_MIPS3);
7db13fae 7082 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
2423f660
TS
7083 rn = "XContext";
7084 break;
9c2149c8 7085 default:
f31b035a 7086 goto cp0_unimplemented;
9c2149c8
TS
7087 }
7088 break;
7089 case 21:
7090 /* Officially reserved, but sel 0 is used for R1x000 framemask */
f31b035a 7091 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
9c2149c8
TS
7092 switch (sel) {
7093 case 0:
7db13fae 7094 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
2423f660
TS
7095 rn = "Framemask";
7096 break;
9c2149c8 7097 default:
f31b035a 7098 goto cp0_unimplemented;
9c2149c8
TS
7099 }
7100 break;
7101 case 22:
d9bea114 7102 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
7103 rn = "'Diagnostic"; /* implementation dependent */
7104 break;
9c2149c8
TS
7105 case 23:
7106 switch (sel) {
7107 case 0:
895c2d04 7108 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
2423f660
TS
7109 rn = "Debug";
7110 break;
9c2149c8 7111 case 1:
895c2d04 7112// gen_helper_dmfc0_tracecontrol(arg, cpu_env); /* PDtrace support */
2423f660 7113 rn = "TraceControl";
3570d7f6 7114 goto cp0_unimplemented;
9c2149c8 7115 case 2:
895c2d04 7116// gen_helper_dmfc0_tracecontrol2(arg, cpu_env); /* PDtrace support */
2423f660 7117 rn = "TraceControl2";
3570d7f6 7118 goto cp0_unimplemented;
9c2149c8 7119 case 3:
895c2d04 7120// gen_helper_dmfc0_usertracedata(arg, cpu_env); /* PDtrace support */
2423f660 7121 rn = "UserTraceData";
3570d7f6 7122 goto cp0_unimplemented;
9c2149c8 7123 case 4:
895c2d04 7124// gen_helper_dmfc0_tracebpc(arg, cpu_env); /* PDtrace support */
2423f660 7125 rn = "TraceBPC";
3570d7f6 7126 goto cp0_unimplemented;
9c2149c8 7127 default:
f31b035a 7128 goto cp0_unimplemented;
9c2149c8
TS
7129 }
7130 break;
7131 case 24:
7132 switch (sel) {
7133 case 0:
f0b3f3ae 7134 /* EJTAG support */
7db13fae 7135 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
2423f660
TS
7136 rn = "DEPC";
7137 break;
9c2149c8 7138 default:
f31b035a 7139 goto cp0_unimplemented;
9c2149c8
TS
7140 }
7141 break;
7142 case 25:
7143 switch (sel) {
7144 case 0:
7db13fae 7145 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
2423f660 7146 rn = "Performance0";
9c2149c8
TS
7147 break;
7148 case 1:
d9bea114 7149// gen_helper_dmfc0_performance1(arg);
2423f660 7150 rn = "Performance1";
3570d7f6 7151 goto cp0_unimplemented;
9c2149c8 7152 case 2:
d9bea114 7153// gen_helper_dmfc0_performance2(arg);
2423f660 7154 rn = "Performance2";
3570d7f6 7155 goto cp0_unimplemented;
9c2149c8 7156 case 3:
d9bea114 7157// gen_helper_dmfc0_performance3(arg);
2423f660 7158 rn = "Performance3";
3570d7f6 7159 goto cp0_unimplemented;
9c2149c8 7160 case 4:
d9bea114 7161// gen_helper_dmfc0_performance4(arg);
2423f660 7162 rn = "Performance4";
3570d7f6 7163 goto cp0_unimplemented;
9c2149c8 7164 case 5:
d9bea114 7165// gen_helper_dmfc0_performance5(arg);
2423f660 7166 rn = "Performance5";
3570d7f6 7167 goto cp0_unimplemented;
9c2149c8 7168 case 6:
d9bea114 7169// gen_helper_dmfc0_performance6(arg);
2423f660 7170 rn = "Performance6";
3570d7f6 7171 goto cp0_unimplemented;
9c2149c8 7172 case 7:
d9bea114 7173// gen_helper_dmfc0_performance7(arg);
2423f660 7174 rn = "Performance7";
3570d7f6 7175 goto cp0_unimplemented;
9c2149c8 7176 default:
f31b035a 7177 goto cp0_unimplemented;
9c2149c8
TS
7178 }
7179 break;
7180 case 26:
0d74a222
LA
7181 switch (sel) {
7182 case 0:
7183 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl));
7184 rn = "ErrCtl";
7185 break;
7186 default:
7187 goto cp0_unimplemented;
7188 }
da80682b 7189 break;
9c2149c8
TS
7190 case 27:
7191 switch (sel) {
7192 /* ignored */
c2e19f3c
AM
7193 case 0:
7194 case 1:
7195 case 2:
7196 case 3:
d9bea114 7197 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
7198 rn = "CacheErr";
7199 break;
9c2149c8 7200 default:
f31b035a 7201 goto cp0_unimplemented;
9c2149c8
TS
7202 }
7203 break;
7204 case 28:
7205 switch (sel) {
7206 case 0:
7207 case 2:
7208 case 4:
7209 case 6:
7db13fae 7210 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
9c2149c8
TS
7211 rn = "TagLo";
7212 break;
7213 case 1:
7214 case 3:
7215 case 5:
7216 case 7:
7db13fae 7217 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
9c2149c8
TS
7218 rn = "DataLo";
7219 break;
7220 default:
f31b035a 7221 goto cp0_unimplemented;
9c2149c8
TS
7222 }
7223 break;
7224 case 29:
7225 switch (sel) {
7226 case 0:
7227 case 2:
7228 case 4:
7229 case 6:
7db13fae 7230 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
9c2149c8
TS
7231 rn = "TagHi";
7232 break;
7233 case 1:
7234 case 3:
7235 case 5:
7236 case 7:
7db13fae 7237 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
9c2149c8
TS
7238 rn = "DataHi";
7239 break;
7240 default:
f31b035a 7241 goto cp0_unimplemented;
9c2149c8
TS
7242 }
7243 break;
7244 case 30:
7245 switch (sel) {
7246 case 0:
7db13fae 7247 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
2423f660
TS
7248 rn = "ErrorEPC";
7249 break;
9c2149c8 7250 default:
f31b035a 7251 goto cp0_unimplemented;
9c2149c8
TS
7252 }
7253 break;
7254 case 31:
7255 switch (sel) {
7256 case 0:
f0b3f3ae 7257 /* EJTAG support */
7db13fae 7258 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
7259 rn = "DESAVE";
7260 break;
c2e19f3c
AM
7261 case 2:
7262 case 3:
7263 case 4:
7264 case 5:
7265 case 6:
7266 case 7:
f31b035a
LA
7267 CP0_CHECK(ctx->kscrexist & (1 << sel));
7268 tcg_gen_ld_tl(arg, cpu_env,
7269 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
7270 rn = "KScratch";
e98c0d17 7271 break;
9c2149c8 7272 default:
f31b035a 7273 goto cp0_unimplemented;
9c2149c8
TS
7274 }
7275 break;
7276 default:
f31b035a 7277 goto cp0_unimplemented;
9c2149c8 7278 }
b44a7fb1 7279 trace_mips_translate_c0("dmfc0", rn, reg, sel);
9c2149c8
TS
7280 return;
7281
f31b035a 7282cp0_unimplemented:
965447ee 7283 qemu_log_mask(LOG_UNIMP, "dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
f31b035a 7284 gen_mfc0_unimplemented(ctx, arg);
9c2149c8
TS
7285}
7286
d75c135e 7287static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
9c2149c8
TS
7288{
7289 const char *rn = "invalid";
7290
e189e748 7291 if (sel != 0)
d75c135e 7292 check_insn(ctx, ISA_MIPS64);
e189e748 7293
eeb3bba8 7294 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
2e70f6ef 7295 gen_io_start();
bd79255d 7296 }
2e70f6ef 7297
9c2149c8
TS
7298 switch (reg) {
7299 case 0:
7300 switch (sel) {
7301 case 0:
895c2d04 7302 gen_helper_mtc0_index(cpu_env, arg);
9c2149c8
TS
7303 rn = "Index";
7304 break;
7305 case 1:
f31b035a 7306 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7307 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
9c2149c8 7308 rn = "MVPControl";
ead9360e 7309 break;
9c2149c8 7310 case 2:
f31b035a 7311 CP0_CHECK(ctx->insn_flags & ASE_MT);
ead9360e 7312 /* ignored */
9c2149c8 7313 rn = "MVPConf0";
ead9360e 7314 break;
9c2149c8 7315 case 3:
f31b035a 7316 CP0_CHECK(ctx->insn_flags & ASE_MT);
ead9360e 7317 /* ignored */
9c2149c8 7318 rn = "MVPConf1";
ead9360e 7319 break;
01bc435b
YK
7320 case 4:
7321 CP0_CHECK(ctx->vp);
7322 /* ignored */
7323 rn = "VPControl";
7324 break;
9c2149c8 7325 default:
f31b035a 7326 goto cp0_unimplemented;
9c2149c8
TS
7327 }
7328 break;
7329 case 1:
7330 switch (sel) {
7331 case 0:
2423f660 7332 /* ignored */
9c2149c8 7333 rn = "Random";
2423f660 7334 break;
9c2149c8 7335 case 1:
f31b035a 7336 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7337 gen_helper_mtc0_vpecontrol(cpu_env, arg);
9c2149c8 7338 rn = "VPEControl";
ead9360e 7339 break;
9c2149c8 7340 case 2:
f31b035a 7341 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7342 gen_helper_mtc0_vpeconf0(cpu_env, arg);
9c2149c8 7343 rn = "VPEConf0";
ead9360e 7344 break;
9c2149c8 7345 case 3:
f31b035a 7346 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7347 gen_helper_mtc0_vpeconf1(cpu_env, arg);
9c2149c8 7348 rn = "VPEConf1";
ead9360e 7349 break;
9c2149c8 7350 case 4:
f31b035a 7351 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7352 gen_helper_mtc0_yqmask(cpu_env, arg);
9c2149c8 7353 rn = "YQMask";
ead9360e 7354 break;
9c2149c8 7355 case 5:
f31b035a 7356 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 7357 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
9c2149c8 7358 rn = "VPESchedule";
ead9360e 7359 break;
9c2149c8 7360 case 6:
f31b035a 7361 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 7362 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
9c2149c8 7363 rn = "VPEScheFBack";
ead9360e 7364 break;
9c2149c8 7365 case 7:
f31b035a 7366 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7367 gen_helper_mtc0_vpeopt(cpu_env, arg);
9c2149c8 7368 rn = "VPEOpt";
ead9360e 7369 break;
9c2149c8 7370 default:
f31b035a 7371 goto cp0_unimplemented;
9c2149c8
TS
7372 }
7373 break;
7374 case 2:
7375 switch (sel) {
7376 case 0:
7207c7f9 7377 gen_helper_dmtc0_entrylo0(cpu_env, arg);
2423f660
TS
7378 rn = "EntryLo0";
7379 break;
9c2149c8 7380 case 1:
f31b035a 7381 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7382 gen_helper_mtc0_tcstatus(cpu_env, arg);
2423f660 7383 rn = "TCStatus";
ead9360e 7384 break;
9c2149c8 7385 case 2:
f31b035a 7386 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7387 gen_helper_mtc0_tcbind(cpu_env, arg);
2423f660 7388 rn = "TCBind";
ead9360e 7389 break;
9c2149c8 7390 case 3:
f31b035a 7391 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7392 gen_helper_mtc0_tcrestart(cpu_env, arg);
2423f660 7393 rn = "TCRestart";
ead9360e 7394 break;
9c2149c8 7395 case 4:
f31b035a 7396 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7397 gen_helper_mtc0_tchalt(cpu_env, arg);
2423f660 7398 rn = "TCHalt";
ead9360e 7399 break;
9c2149c8 7400 case 5:
f31b035a 7401 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7402 gen_helper_mtc0_tccontext(cpu_env, arg);
2423f660 7403 rn = "TCContext";
ead9360e 7404 break;
9c2149c8 7405 case 6:
f31b035a 7406 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7407 gen_helper_mtc0_tcschedule(cpu_env, arg);
2423f660 7408 rn = "TCSchedule";
ead9360e 7409 break;
9c2149c8 7410 case 7:
f31b035a 7411 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7412 gen_helper_mtc0_tcschefback(cpu_env, arg);
2423f660 7413 rn = "TCScheFBack";
ead9360e 7414 break;
9c2149c8 7415 default:
f31b035a 7416 goto cp0_unimplemented;
9c2149c8
TS
7417 }
7418 break;
7419 case 3:
7420 switch (sel) {
7421 case 0:
7207c7f9 7422 gen_helper_dmtc0_entrylo1(cpu_env, arg);
2423f660
TS
7423 rn = "EntryLo1";
7424 break;
01bc435b
YK
7425 case 1:
7426 CP0_CHECK(ctx->vp);
7427 /* ignored */
7428 rn = "GlobalNumber";
7429 break;
9c2149c8 7430 default:
f31b035a 7431 goto cp0_unimplemented;
876d4b07 7432 }
9c2149c8
TS
7433 break;
7434 case 4:
7435 switch (sel) {
7436 case 0:
895c2d04 7437 gen_helper_mtc0_context(cpu_env, arg);
2423f660
TS
7438 rn = "Context";
7439 break;
9c2149c8 7440 case 1:
895c2d04 7441// gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
2423f660 7442 rn = "ContextConfig";
f31b035a 7443 goto cp0_unimplemented;
d279279e 7444 case 2:
f31b035a
LA
7445 CP0_CHECK(ctx->ulri);
7446 tcg_gen_st_tl(arg, cpu_env,
7447 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
7448 rn = "UserLocal";
d279279e 7449 break;
9c2149c8 7450 default:
f31b035a 7451 goto cp0_unimplemented;
876d4b07 7452 }
9c2149c8
TS
7453 break;
7454 case 5:
7455 switch (sel) {
7456 case 0:
895c2d04 7457 gen_helper_mtc0_pagemask(cpu_env, arg);
2423f660
TS
7458 rn = "PageMask";
7459 break;
9c2149c8 7460 case 1:
d75c135e 7461 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7462 gen_helper_mtc0_pagegrain(cpu_env, arg);
2423f660
TS
7463 rn = "PageGrain";
7464 break;
cec56a73
JH
7465 case 2:
7466 CP0_CHECK(ctx->sc);
7467 gen_helper_mtc0_segctl0(cpu_env, arg);
7468 rn = "SegCtl0";
7469 break;
7470 case 3:
7471 CP0_CHECK(ctx->sc);
7472 gen_helper_mtc0_segctl1(cpu_env, arg);
7473 rn = "SegCtl1";
7474 break;
7475 case 4:
7476 CP0_CHECK(ctx->sc);
7477 gen_helper_mtc0_segctl2(cpu_env, arg);
7478 rn = "SegCtl2";
7479 break;
9c2149c8 7480 default:
f31b035a 7481 goto cp0_unimplemented;
876d4b07 7482 }
9c2149c8
TS
7483 break;
7484 case 6:
7485 switch (sel) {
7486 case 0:
895c2d04 7487 gen_helper_mtc0_wired(cpu_env, arg);
2423f660
TS
7488 rn = "Wired";
7489 break;
9c2149c8 7490 case 1:
d75c135e 7491 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7492 gen_helper_mtc0_srsconf0(cpu_env, arg);
2423f660 7493 rn = "SRSConf0";
ead9360e 7494 break;
9c2149c8 7495 case 2:
d75c135e 7496 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7497 gen_helper_mtc0_srsconf1(cpu_env, arg);
2423f660 7498 rn = "SRSConf1";
ead9360e 7499 break;
9c2149c8 7500 case 3:
d75c135e 7501 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7502 gen_helper_mtc0_srsconf2(cpu_env, arg);
2423f660 7503 rn = "SRSConf2";
ead9360e 7504 break;
9c2149c8 7505 case 4:
d75c135e 7506 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7507 gen_helper_mtc0_srsconf3(cpu_env, arg);
2423f660 7508 rn = "SRSConf3";
ead9360e 7509 break;
9c2149c8 7510 case 5:
d75c135e 7511 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7512 gen_helper_mtc0_srsconf4(cpu_env, arg);
2423f660 7513 rn = "SRSConf4";
ead9360e 7514 break;
9c2149c8 7515 default:
f31b035a 7516 goto cp0_unimplemented;
876d4b07 7517 }
9c2149c8
TS
7518 break;
7519 case 7:
7520 switch (sel) {
7521 case 0:
d75c135e 7522 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7523 gen_helper_mtc0_hwrena(cpu_env, arg);
eeb3bba8 7524 ctx->base.is_jmp = DISAS_STOP;
2423f660
TS
7525 rn = "HWREna";
7526 break;
9c2149c8 7527 default:
f31b035a 7528 goto cp0_unimplemented;
876d4b07 7529 }
9c2149c8
TS
7530 break;
7531 case 8:
aea14095
LA
7532 switch (sel) {
7533 case 0:
7534 /* ignored */
7535 rn = "BadVAddr";
7536 break;
7537 case 1:
7538 /* ignored */
7539 rn = "BadInstr";
7540 break;
7541 case 2:
7542 /* ignored */
7543 rn = "BadInstrP";
7544 break;
25beba9b
SM
7545 case 3:
7546 /* ignored */
7547 rn = "BadInstrX";
7548 break;
aea14095 7549 default:
f31b035a 7550 goto cp0_unimplemented;
aea14095 7551 }
9c2149c8
TS
7552 break;
7553 case 9:
7554 switch (sel) {
7555 case 0:
895c2d04 7556 gen_helper_mtc0_count(cpu_env, arg);
2423f660
TS
7557 rn = "Count";
7558 break;
876d4b07 7559 /* 6,7 are implementation dependent */
9c2149c8 7560 default:
f31b035a 7561 goto cp0_unimplemented;
876d4b07
TS
7562 }
7563 /* Stop translation as we may have switched the execution mode */
eeb3bba8 7564 ctx->base.is_jmp = DISAS_STOP;
9c2149c8
TS
7565 break;
7566 case 10:
7567 switch (sel) {
7568 case 0:
895c2d04 7569 gen_helper_mtc0_entryhi(cpu_env, arg);
2423f660
TS
7570 rn = "EntryHi";
7571 break;
9c2149c8 7572 default:
f31b035a 7573 goto cp0_unimplemented;
876d4b07 7574 }
9c2149c8
TS
7575 break;
7576 case 11:
7577 switch (sel) {
7578 case 0:
895c2d04 7579 gen_helper_mtc0_compare(cpu_env, arg);
2423f660
TS
7580 rn = "Compare";
7581 break;
876d4b07 7582 /* 6,7 are implementation dependent */
9c2149c8 7583 default:
f31b035a 7584 goto cp0_unimplemented;
876d4b07 7585 }
de9a95f0 7586 /* Stop translation as we may have switched the execution mode */
eeb3bba8 7587 ctx->base.is_jmp = DISAS_STOP;
9c2149c8
TS
7588 break;
7589 case 12:
7590 switch (sel) {
7591 case 0:
867abc7e 7592 save_cpu_state(ctx, 1);
895c2d04 7593 gen_helper_mtc0_status(cpu_env, arg);
b28425ba 7594 /* DISAS_STOP isn't good enough here, hflags may have changed. */
eeb3bba8
EC
7595 gen_save_pc(ctx->base.pc_next + 4);
7596 ctx->base.is_jmp = DISAS_EXIT;
2423f660
TS
7597 rn = "Status";
7598 break;
9c2149c8 7599 case 1:
d75c135e 7600 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7601 gen_helper_mtc0_intctl(cpu_env, arg);
8487327a 7602 /* Stop translation as we may have switched the execution mode */
eeb3bba8 7603 ctx->base.is_jmp = DISAS_STOP;
2423f660
TS
7604 rn = "IntCtl";
7605 break;
9c2149c8 7606 case 2:
d75c135e 7607 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7608 gen_helper_mtc0_srsctl(cpu_env, arg);
8487327a 7609 /* Stop translation as we may have switched the execution mode */
eeb3bba8 7610 ctx->base.is_jmp = DISAS_STOP;
2423f660
TS
7611 rn = "SRSCtl";
7612 break;
9c2149c8 7613 case 3:
d75c135e 7614 check_insn(ctx, ISA_MIPS32R2);
7db13fae 7615 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
8487327a 7616 /* Stop translation as we may have switched the execution mode */
eeb3bba8 7617 ctx->base.is_jmp = DISAS_STOP;
2423f660
TS
7618 rn = "SRSMap";
7619 break;
7620 default:
f31b035a 7621 goto cp0_unimplemented;
876d4b07 7622 }
9c2149c8
TS
7623 break;
7624 case 13:
7625 switch (sel) {
7626 case 0:
867abc7e 7627 save_cpu_state(ctx, 1);
895c2d04 7628 gen_helper_mtc0_cause(cpu_env, arg);
b28425ba
EC
7629 /* Stop translation as we may have triggered an interrupt.
7630 * DISAS_STOP isn't sufficient, we need to ensure we break out of
7631 * translated code to check for pending interrupts. */
eeb3bba8
EC
7632 gen_save_pc(ctx->base.pc_next + 4);
7633 ctx->base.is_jmp = DISAS_EXIT;
2423f660
TS
7634 rn = "Cause";
7635 break;
9c2149c8 7636 default:
f31b035a 7637 goto cp0_unimplemented;
876d4b07 7638 }
9c2149c8
TS
7639 break;
7640 case 14:
7641 switch (sel) {
7642 case 0:
7db13fae 7643 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
2423f660
TS
7644 rn = "EPC";
7645 break;
9c2149c8 7646 default:
f31b035a 7647 goto cp0_unimplemented;
876d4b07 7648 }
9c2149c8
TS
7649 break;
7650 case 15:
7651 switch (sel) {
7652 case 0:
2423f660
TS
7653 /* ignored */
7654 rn = "PRid";
7655 break;
9c2149c8 7656 case 1:
d75c135e 7657 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7658 gen_helper_mtc0_ebase(cpu_env, arg);
2423f660
TS
7659 rn = "EBase";
7660 break;
9c2149c8 7661 default:
f31b035a 7662 goto cp0_unimplemented;
876d4b07 7663 }
9c2149c8
TS
7664 break;
7665 case 16:
7666 switch (sel) {
7667 case 0:
895c2d04 7668 gen_helper_mtc0_config0(cpu_env, arg);
9c2149c8 7669 rn = "Config";
2423f660 7670 /* Stop translation as we may have switched the execution mode */
eeb3bba8 7671 ctx->base.is_jmp = DISAS_STOP;
9c2149c8
TS
7672 break;
7673 case 1:
1fc7bf6e 7674 /* ignored, read only */
9c2149c8
TS
7675 rn = "Config1";
7676 break;
7677 case 2:
895c2d04 7678 gen_helper_mtc0_config2(cpu_env, arg);
9c2149c8 7679 rn = "Config2";
2423f660 7680 /* Stop translation as we may have switched the execution mode */
eeb3bba8 7681 ctx->base.is_jmp = DISAS_STOP;
9c2149c8
TS
7682 break;
7683 case 3:
90f12d73 7684 gen_helper_mtc0_config3(cpu_env, arg);
9c2149c8 7685 rn = "Config3";
90f12d73 7686 /* Stop translation as we may have switched the execution mode */
eeb3bba8 7687 ctx->base.is_jmp = DISAS_STOP;
9c2149c8 7688 break;
faf1f68b
LA
7689 case 4:
7690 /* currently ignored */
7691 rn = "Config4";
7692 break;
7693 case 5:
7694 gen_helper_mtc0_config5(cpu_env, arg);
7695 rn = "Config5";
7696 /* Stop translation as we may have switched the execution mode */
eeb3bba8 7697 ctx->base.is_jmp = DISAS_STOP;
faf1f68b 7698 break;
9c2149c8
TS
7699 /* 6,7 are implementation dependent */
7700 default:
7701 rn = "Invalid config selector";
f31b035a 7702 goto cp0_unimplemented;
9c2149c8 7703 }
9c2149c8
TS
7704 break;
7705 case 17:
7706 switch (sel) {
7707 case 0:
895c2d04 7708 gen_helper_mtc0_lladdr(cpu_env, arg);
2423f660
TS
7709 rn = "LLAddr";
7710 break;
f6d4dd81
YK
7711 case 1:
7712 CP0_CHECK(ctx->mrp);
7713 gen_helper_mtc0_maar(cpu_env, arg);
7714 rn = "MAAR";
7715 break;
7716 case 2:
7717 CP0_CHECK(ctx->mrp);
7718 gen_helper_mtc0_maari(cpu_env, arg);
7719 rn = "MAARI";
7720 break;
9c2149c8 7721 default:
f31b035a 7722 goto cp0_unimplemented;
9c2149c8
TS
7723 }
7724 break;
7725 case 18:
7726 switch (sel) {
c2e19f3c
AM
7727 case 0:
7728 case 1:
7729 case 2:
7730 case 3:
7731 case 4:
7732 case 5:
7733 case 6:
7734 case 7:
fa192d49 7735 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
895c2d04 7736 gen_helper_0e1i(mtc0_watchlo, arg, sel);
2423f660
TS
7737 rn = "WatchLo";
7738 break;
9c2149c8 7739 default:
f31b035a 7740 goto cp0_unimplemented;
9c2149c8
TS
7741 }
7742 break;
7743 case 19:
7744 switch (sel) {
c2e19f3c
AM
7745 case 0:
7746 case 1:
7747 case 2:
7748 case 3:
7749 case 4:
7750 case 5:
7751 case 6:
7752 case 7:
fa192d49 7753 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
895c2d04 7754 gen_helper_0e1i(mtc0_watchhi, arg, sel);
2423f660
TS
7755 rn = "WatchHi";
7756 break;
9c2149c8 7757 default:
f31b035a 7758 goto cp0_unimplemented;
9c2149c8
TS
7759 }
7760 break;
7761 case 20:
7762 switch (sel) {
7763 case 0:
d75c135e 7764 check_insn(ctx, ISA_MIPS3);
895c2d04 7765 gen_helper_mtc0_xcontext(cpu_env, arg);
2423f660
TS
7766 rn = "XContext";
7767 break;
9c2149c8 7768 default:
f31b035a 7769 goto cp0_unimplemented;
9c2149c8
TS
7770 }
7771 break;
7772 case 21:
7773 /* Officially reserved, but sel 0 is used for R1x000 framemask */
f31b035a 7774 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
9c2149c8
TS
7775 switch (sel) {
7776 case 0:
895c2d04 7777 gen_helper_mtc0_framemask(cpu_env, arg);
2423f660
TS
7778 rn = "Framemask";
7779 break;
9c2149c8 7780 default:
f31b035a 7781 goto cp0_unimplemented;
9c2149c8
TS
7782 }
7783 break;
7784 case 22:
7785 /* ignored */
7786 rn = "Diagnostic"; /* implementation dependent */
876d4b07 7787 break;
9c2149c8
TS
7788 case 23:
7789 switch (sel) {
7790 case 0:
895c2d04 7791 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
b28425ba 7792 /* DISAS_STOP isn't good enough here, hflags may have changed. */
eeb3bba8
EC
7793 gen_save_pc(ctx->base.pc_next + 4);
7794 ctx->base.is_jmp = DISAS_EXIT;
2423f660
TS
7795 rn = "Debug";
7796 break;
9c2149c8 7797 case 1:
895c2d04 7798// gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
8487327a 7799 /* Stop translation as we may have switched the execution mode */
eeb3bba8 7800 ctx->base.is_jmp = DISAS_STOP;
2423f660 7801 rn = "TraceControl";
3570d7f6 7802 goto cp0_unimplemented;
9c2149c8 7803 case 2:
895c2d04 7804// gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
8487327a 7805 /* Stop translation as we may have switched the execution mode */
eeb3bba8 7806 ctx->base.is_jmp = DISAS_STOP;
2423f660 7807 rn = "TraceControl2";
3570d7f6 7808 goto cp0_unimplemented;
9c2149c8 7809 case 3:
895c2d04 7810// gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
8487327a 7811 /* Stop translation as we may have switched the execution mode */
eeb3bba8 7812 ctx->base.is_jmp = DISAS_STOP;
2423f660 7813 rn = "UserTraceData";
3570d7f6 7814 goto cp0_unimplemented;
9c2149c8 7815 case 4:
895c2d04 7816// gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
8487327a 7817 /* Stop translation as we may have switched the execution mode */
eeb3bba8 7818 ctx->base.is_jmp = DISAS_STOP;
2423f660 7819 rn = "TraceBPC";
3570d7f6 7820 goto cp0_unimplemented;
9c2149c8 7821 default:
f31b035a 7822 goto cp0_unimplemented;
9c2149c8 7823 }
9c2149c8
TS
7824 break;
7825 case 24:
7826 switch (sel) {
7827 case 0:
f1aa6320 7828 /* EJTAG support */
7db13fae 7829 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
2423f660
TS
7830 rn = "DEPC";
7831 break;
9c2149c8 7832 default:
f31b035a 7833 goto cp0_unimplemented;
9c2149c8
TS
7834 }
7835 break;
7836 case 25:
7837 switch (sel) {
7838 case 0:
895c2d04 7839 gen_helper_mtc0_performance0(cpu_env, arg);
2423f660
TS
7840 rn = "Performance0";
7841 break;
9c2149c8 7842 case 1:
895c2d04 7843// gen_helper_mtc0_performance1(cpu_env, arg);
2423f660 7844 rn = "Performance1";
3570d7f6 7845 goto cp0_unimplemented;
9c2149c8 7846 case 2:
895c2d04 7847// gen_helper_mtc0_performance2(cpu_env, arg);
2423f660 7848 rn = "Performance2";
3570d7f6 7849 goto cp0_unimplemented;
9c2149c8 7850 case 3:
895c2d04 7851// gen_helper_mtc0_performance3(cpu_env, arg);
2423f660 7852 rn = "Performance3";
3570d7f6 7853 goto cp0_unimplemented;
9c2149c8 7854 case 4:
895c2d04 7855// gen_helper_mtc0_performance4(cpu_env, arg);
2423f660 7856 rn = "Performance4";
3570d7f6 7857 goto cp0_unimplemented;
9c2149c8 7858 case 5:
895c2d04 7859// gen_helper_mtc0_performance5(cpu_env, arg);
2423f660 7860 rn = "Performance5";
3570d7f6 7861 goto cp0_unimplemented;
9c2149c8 7862 case 6:
895c2d04 7863// gen_helper_mtc0_performance6(cpu_env, arg);
2423f660 7864 rn = "Performance6";
3570d7f6 7865 goto cp0_unimplemented;
9c2149c8 7866 case 7:
895c2d04 7867// gen_helper_mtc0_performance7(cpu_env, arg);
2423f660 7868 rn = "Performance7";
3570d7f6 7869 goto cp0_unimplemented;
9c2149c8 7870 default:
f31b035a 7871 goto cp0_unimplemented;
9c2149c8 7872 }
876d4b07 7873 break;
9c2149c8 7874 case 26:
0d74a222
LA
7875 switch (sel) {
7876 case 0:
7877 gen_helper_mtc0_errctl(cpu_env, arg);
eeb3bba8 7878 ctx->base.is_jmp = DISAS_STOP;
0d74a222
LA
7879 rn = "ErrCtl";
7880 break;
7881 default:
7882 goto cp0_unimplemented;
7883 }
876d4b07 7884 break;
9c2149c8
TS
7885 case 27:
7886 switch (sel) {
c2e19f3c
AM
7887 case 0:
7888 case 1:
7889 case 2:
7890 case 3:
2423f660
TS
7891 /* ignored */
7892 rn = "CacheErr";
7893 break;
9c2149c8 7894 default:
f31b035a 7895 goto cp0_unimplemented;
9c2149c8 7896 }
876d4b07 7897 break;
9c2149c8
TS
7898 case 28:
7899 switch (sel) {
7900 case 0:
7901 case 2:
7902 case 4:
7903 case 6:
895c2d04 7904 gen_helper_mtc0_taglo(cpu_env, arg);
9c2149c8
TS
7905 rn = "TagLo";
7906 break;
7907 case 1:
7908 case 3:
7909 case 5:
7910 case 7:
895c2d04 7911 gen_helper_mtc0_datalo(cpu_env, arg);
9c2149c8
TS
7912 rn = "DataLo";
7913 break;
7914 default:
f31b035a 7915 goto cp0_unimplemented;
9c2149c8
TS
7916 }
7917 break;
7918 case 29:
7919 switch (sel) {
7920 case 0:
7921 case 2:
7922 case 4:
7923 case 6:
895c2d04 7924 gen_helper_mtc0_taghi(cpu_env, arg);
9c2149c8
TS
7925 rn = "TagHi";
7926 break;
7927 case 1:
7928 case 3:
7929 case 5:
7930 case 7:
895c2d04 7931 gen_helper_mtc0_datahi(cpu_env, arg);
9c2149c8
TS
7932 rn = "DataHi";
7933 break;
7934 default:
7935 rn = "invalid sel";
f31b035a 7936 goto cp0_unimplemented;
9c2149c8 7937 }
876d4b07 7938 break;
9c2149c8
TS
7939 case 30:
7940 switch (sel) {
7941 case 0:
7db13fae 7942 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
2423f660
TS
7943 rn = "ErrorEPC";
7944 break;
9c2149c8 7945 default:
f31b035a 7946 goto cp0_unimplemented;
9c2149c8
TS
7947 }
7948 break;
7949 case 31:
7950 switch (sel) {
7951 case 0:
f1aa6320 7952 /* EJTAG support */
7db13fae 7953 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
7954 rn = "DESAVE";
7955 break;
c2e19f3c
AM
7956 case 2:
7957 case 3:
7958 case 4:
7959 case 5:
7960 case 6:
7961 case 7:
f31b035a
LA
7962 CP0_CHECK(ctx->kscrexist & (1 << sel));
7963 tcg_gen_st_tl(arg, cpu_env,
7964 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
7965 rn = "KScratch";
e98c0d17 7966 break;
9c2149c8 7967 default:
f31b035a 7968 goto cp0_unimplemented;
9c2149c8 7969 }
9c2149c8
TS
7970 break;
7971 default:
f31b035a 7972 goto cp0_unimplemented;
9c2149c8 7973 }
b44a7fb1
PMD
7974 trace_mips_translate_c0("dmtc0", rn, reg, sel);
7975
bf20dc07 7976 /* For simplicity assume that all writes can cause interrupts. */
eeb3bba8 7977 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
2e70f6ef 7978 gen_io_end();
b28425ba 7979 /* DISAS_STOP isn't sufficient, we need to ensure we break out of
b74cddcb 7980 * translated code to check for pending interrupts. */
eeb3bba8
EC
7981 gen_save_pc(ctx->base.pc_next + 4);
7982 ctx->base.is_jmp = DISAS_EXIT;
2e70f6ef 7983 }
9c2149c8
TS
7984 return;
7985
f31b035a 7986cp0_unimplemented:
965447ee 7987 qemu_log_mask(LOG_UNIMP, "dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
9c2149c8 7988}
d26bc211 7989#endif /* TARGET_MIPS64 */
9c2149c8 7990
7db13fae 7991static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
ead9360e
TS
7992 int u, int sel, int h)
7993{
7994 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
a7812ae4 7995 TCGv t0 = tcg_temp_local_new();
ead9360e
TS
7996
7997 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
b5dc7732
TS
7998 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
7999 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
1a3fd9c3 8000 tcg_gen_movi_tl(t0, -1);
ead9360e
TS
8001 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
8002 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
1a3fd9c3 8003 tcg_gen_movi_tl(t0, -1);
ead9360e
TS
8004 else if (u == 0) {
8005 switch (rt) {
5a25ce94
EI
8006 case 1:
8007 switch (sel) {
8008 case 1:
895c2d04 8009 gen_helper_mftc0_vpecontrol(t0, cpu_env);
5a25ce94
EI
8010 break;
8011 case 2:
895c2d04 8012 gen_helper_mftc0_vpeconf0(t0, cpu_env);
5a25ce94
EI
8013 break;
8014 default:
8015 goto die;
8016 break;
8017 }
8018 break;
ead9360e
TS
8019 case 2:
8020 switch (sel) {
8021 case 1:
895c2d04 8022 gen_helper_mftc0_tcstatus(t0, cpu_env);
ead9360e
TS
8023 break;
8024 case 2:
895c2d04 8025 gen_helper_mftc0_tcbind(t0, cpu_env);
ead9360e
TS
8026 break;
8027 case 3:
895c2d04 8028 gen_helper_mftc0_tcrestart(t0, cpu_env);
ead9360e
TS
8029 break;
8030 case 4:
895c2d04 8031 gen_helper_mftc0_tchalt(t0, cpu_env);
ead9360e
TS
8032 break;
8033 case 5:
895c2d04 8034 gen_helper_mftc0_tccontext(t0, cpu_env);
ead9360e
TS
8035 break;
8036 case 6:
895c2d04 8037 gen_helper_mftc0_tcschedule(t0, cpu_env);
ead9360e
TS
8038 break;
8039 case 7:
895c2d04 8040 gen_helper_mftc0_tcschefback(t0, cpu_env);
ead9360e
TS
8041 break;
8042 default:
d75c135e 8043 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
8044 break;
8045 }
8046 break;
8047 case 10:
8048 switch (sel) {
8049 case 0:
895c2d04 8050 gen_helper_mftc0_entryhi(t0, cpu_env);
ead9360e
TS
8051 break;
8052 default:
d75c135e 8053 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
8054 break;
8055 }
8056 case 12:
8057 switch (sel) {
8058 case 0:
895c2d04 8059 gen_helper_mftc0_status(t0, cpu_env);
ead9360e
TS
8060 break;
8061 default:
d75c135e 8062 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
8063 break;
8064 }
5a25ce94
EI
8065 case 13:
8066 switch (sel) {
8067 case 0:
895c2d04 8068 gen_helper_mftc0_cause(t0, cpu_env);
5a25ce94
EI
8069 break;
8070 default:
8071 goto die;
8072 break;
8073 }
8074 break;
8075 case 14:
8076 switch (sel) {
8077 case 0:
895c2d04 8078 gen_helper_mftc0_epc(t0, cpu_env);
5a25ce94
EI
8079 break;
8080 default:
8081 goto die;
8082 break;
8083 }
8084 break;
8085 case 15:
8086 switch (sel) {
8087 case 1:
895c2d04 8088 gen_helper_mftc0_ebase(t0, cpu_env);
5a25ce94
EI
8089 break;
8090 default:
8091 goto die;
8092 break;
8093 }
8094 break;
8095 case 16:
8096 switch (sel) {
c2e19f3c
AM
8097 case 0:
8098 case 1:
8099 case 2:
8100 case 3:
8101 case 4:
8102 case 5:
8103 case 6:
8104 case 7:
895c2d04 8105 gen_helper_mftc0_configx(t0, cpu_env, tcg_const_tl(sel));
5a25ce94
EI
8106 break;
8107 default:
8108 goto die;
8109 break;
8110 }
8111 break;
ead9360e
TS
8112 case 23:
8113 switch (sel) {
8114 case 0:
895c2d04 8115 gen_helper_mftc0_debug(t0, cpu_env);
ead9360e
TS
8116 break;
8117 default:
d75c135e 8118 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
8119 break;
8120 }
8121 break;
8122 default:
d75c135e 8123 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
8124 }
8125 } else switch (sel) {
8126 /* GPR registers. */
8127 case 0:
895c2d04 8128 gen_helper_1e0i(mftgpr, t0, rt);
ead9360e
TS
8129 break;
8130 /* Auxiliary CPU registers */
8131 case 1:
8132 switch (rt) {
8133 case 0:
895c2d04 8134 gen_helper_1e0i(mftlo, t0, 0);
ead9360e
TS
8135 break;
8136 case 1:
895c2d04 8137 gen_helper_1e0i(mfthi, t0, 0);
ead9360e
TS
8138 break;
8139 case 2:
895c2d04 8140 gen_helper_1e0i(mftacx, t0, 0);
ead9360e
TS
8141 break;
8142 case 4:
895c2d04 8143 gen_helper_1e0i(mftlo, t0, 1);
ead9360e
TS
8144 break;
8145 case 5:
895c2d04 8146 gen_helper_1e0i(mfthi, t0, 1);
ead9360e
TS
8147 break;
8148 case 6:
895c2d04 8149 gen_helper_1e0i(mftacx, t0, 1);
ead9360e
TS
8150 break;
8151 case 8:
895c2d04 8152 gen_helper_1e0i(mftlo, t0, 2);
ead9360e
TS
8153 break;
8154 case 9:
895c2d04 8155 gen_helper_1e0i(mfthi, t0, 2);
ead9360e
TS
8156 break;
8157 case 10:
895c2d04 8158 gen_helper_1e0i(mftacx, t0, 2);
ead9360e
TS
8159 break;
8160 case 12:
895c2d04 8161 gen_helper_1e0i(mftlo, t0, 3);
ead9360e
TS
8162 break;
8163 case 13:
895c2d04 8164 gen_helper_1e0i(mfthi, t0, 3);
ead9360e
TS
8165 break;
8166 case 14:
895c2d04 8167 gen_helper_1e0i(mftacx, t0, 3);
ead9360e
TS
8168 break;
8169 case 16:
895c2d04 8170 gen_helper_mftdsp(t0, cpu_env);
ead9360e
TS
8171 break;
8172 default:
8173 goto die;
8174 }
8175 break;
8176 /* Floating point (COP1). */
8177 case 2:
8178 /* XXX: For now we support only a single FPU context. */
8179 if (h == 0) {
a7812ae4 8180 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8181
7c979afd 8182 gen_load_fpr32(ctx, fp0, rt);
b6d96bed 8183 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 8184 tcg_temp_free_i32(fp0);
ead9360e 8185 } else {
a7812ae4 8186 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8187
7f6613ce 8188 gen_load_fpr32h(ctx, fp0, rt);
b6d96bed 8189 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 8190 tcg_temp_free_i32(fp0);
ead9360e
TS
8191 }
8192 break;
8193 case 3:
8194 /* XXX: For now we support only a single FPU context. */
895c2d04 8195 gen_helper_1e0i(cfc1, t0, rt);
ead9360e
TS
8196 break;
8197 /* COP2: Not implemented. */
8198 case 4:
8199 case 5:
8200 /* fall through */
8201 default:
8202 goto die;
8203 }
b44a7fb1 8204 trace_mips_translate_tr("mftr", rt, u, sel, h);
1a3fd9c3
TS
8205 gen_store_gpr(t0, rd);
8206 tcg_temp_free(t0);
ead9360e
TS
8207 return;
8208
8209die:
1a3fd9c3 8210 tcg_temp_free(t0);
d12d51d5 8211 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
9c708c7f 8212 generate_exception_end(ctx, EXCP_RI);
ead9360e
TS
8213}
8214
7db13fae 8215static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
ead9360e
TS
8216 int u, int sel, int h)
8217{
8218 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
a7812ae4 8219 TCGv t0 = tcg_temp_local_new();
ead9360e 8220
1a3fd9c3 8221 gen_load_gpr(t0, rt);
ead9360e 8222 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
b5dc7732
TS
8223 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
8224 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
ead9360e
TS
8225 /* NOP */ ;
8226 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
8227 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
8228 /* NOP */ ;
8229 else if (u == 0) {
8230 switch (rd) {
5a25ce94
EI
8231 case 1:
8232 switch (sel) {
8233 case 1:
895c2d04 8234 gen_helper_mttc0_vpecontrol(cpu_env, t0);
5a25ce94
EI
8235 break;
8236 case 2:
895c2d04 8237 gen_helper_mttc0_vpeconf0(cpu_env, t0);
5a25ce94
EI
8238 break;
8239 default:
8240 goto die;
8241 break;
8242 }
8243 break;
ead9360e
TS
8244 case 2:
8245 switch (sel) {
8246 case 1:
895c2d04 8247 gen_helper_mttc0_tcstatus(cpu_env, t0);
ead9360e
TS
8248 break;
8249 case 2:
895c2d04 8250 gen_helper_mttc0_tcbind(cpu_env, t0);
ead9360e
TS
8251 break;
8252 case 3:
895c2d04 8253 gen_helper_mttc0_tcrestart(cpu_env, t0);
ead9360e
TS
8254 break;
8255 case 4:
895c2d04 8256 gen_helper_mttc0_tchalt(cpu_env, t0);
ead9360e
TS
8257 break;
8258 case 5:
895c2d04 8259 gen_helper_mttc0_tccontext(cpu_env, t0);
ead9360e
TS
8260 break;
8261 case 6:
895c2d04 8262 gen_helper_mttc0_tcschedule(cpu_env, t0);
ead9360e
TS
8263 break;
8264 case 7:
895c2d04 8265 gen_helper_mttc0_tcschefback(cpu_env, t0);
ead9360e
TS
8266 break;
8267 default:
d75c135e 8268 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
8269 break;
8270 }
8271 break;
8272 case 10:
8273 switch (sel) {
8274 case 0:
895c2d04 8275 gen_helper_mttc0_entryhi(cpu_env, t0);
ead9360e
TS
8276 break;
8277 default:
d75c135e 8278 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
8279 break;
8280 }
8281 case 12:
8282 switch (sel) {
8283 case 0:
895c2d04 8284 gen_helper_mttc0_status(cpu_env, t0);
ead9360e
TS
8285 break;
8286 default:
d75c135e 8287 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
8288 break;
8289 }
5a25ce94
EI
8290 case 13:
8291 switch (sel) {
8292 case 0:
895c2d04 8293 gen_helper_mttc0_cause(cpu_env, t0);
5a25ce94
EI
8294 break;
8295 default:
8296 goto die;
8297 break;
8298 }
8299 break;
8300 case 15:
8301 switch (sel) {
8302 case 1:
895c2d04 8303 gen_helper_mttc0_ebase(cpu_env, t0);
5a25ce94
EI
8304 break;
8305 default:
8306 goto die;
8307 break;
8308 }
8309 break;
ead9360e
TS
8310 case 23:
8311 switch (sel) {
8312 case 0:
895c2d04 8313 gen_helper_mttc0_debug(cpu_env, t0);
ead9360e
TS
8314 break;
8315 default:
d75c135e 8316 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
8317 break;
8318 }
8319 break;
8320 default:
d75c135e 8321 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
8322 }
8323 } else switch (sel) {
8324 /* GPR registers. */
8325 case 0:
895c2d04 8326 gen_helper_0e1i(mttgpr, t0, rd);
ead9360e
TS
8327 break;
8328 /* Auxiliary CPU registers */
8329 case 1:
8330 switch (rd) {
8331 case 0:
895c2d04 8332 gen_helper_0e1i(mttlo, t0, 0);
ead9360e
TS
8333 break;
8334 case 1:
895c2d04 8335 gen_helper_0e1i(mtthi, t0, 0);
ead9360e
TS
8336 break;
8337 case 2:
895c2d04 8338 gen_helper_0e1i(mttacx, t0, 0);
ead9360e
TS
8339 break;
8340 case 4:
895c2d04 8341 gen_helper_0e1i(mttlo, t0, 1);
ead9360e
TS
8342 break;
8343 case 5:
895c2d04 8344 gen_helper_0e1i(mtthi, t0, 1);
ead9360e
TS
8345 break;
8346 case 6:
895c2d04 8347 gen_helper_0e1i(mttacx, t0, 1);
ead9360e
TS
8348 break;
8349 case 8:
895c2d04 8350 gen_helper_0e1i(mttlo, t0, 2);
ead9360e
TS
8351 break;
8352 case 9:
895c2d04 8353 gen_helper_0e1i(mtthi, t0, 2);
ead9360e
TS
8354 break;
8355 case 10:
895c2d04 8356 gen_helper_0e1i(mttacx, t0, 2);
ead9360e
TS
8357 break;
8358 case 12:
895c2d04 8359 gen_helper_0e1i(mttlo, t0, 3);
ead9360e
TS
8360 break;
8361 case 13:
895c2d04 8362 gen_helper_0e1i(mtthi, t0, 3);
ead9360e
TS
8363 break;
8364 case 14:
895c2d04 8365 gen_helper_0e1i(mttacx, t0, 3);
ead9360e
TS
8366 break;
8367 case 16:
895c2d04 8368 gen_helper_mttdsp(cpu_env, t0);
ead9360e
TS
8369 break;
8370 default:
8371 goto die;
8372 }
8373 break;
8374 /* Floating point (COP1). */
8375 case 2:
8376 /* XXX: For now we support only a single FPU context. */
8377 if (h == 0) {
a7812ae4 8378 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8379
8380 tcg_gen_trunc_tl_i32(fp0, t0);
7c979afd 8381 gen_store_fpr32(ctx, fp0, rd);
a7812ae4 8382 tcg_temp_free_i32(fp0);
ead9360e 8383 } else {
a7812ae4 8384 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8385
8386 tcg_gen_trunc_tl_i32(fp0, t0);
7f6613ce 8387 gen_store_fpr32h(ctx, fp0, rd);
a7812ae4 8388 tcg_temp_free_i32(fp0);
ead9360e
TS
8389 }
8390 break;
8391 case 3:
8392 /* XXX: For now we support only a single FPU context. */
736d120a
PJ
8393 {
8394 TCGv_i32 fs_tmp = tcg_const_i32(rd);
8395
8396 gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
8397 tcg_temp_free_i32(fs_tmp);
8398 }
4cf8a45f 8399 /* Stop translation as we may have changed hflags */
eeb3bba8 8400 ctx->base.is_jmp = DISAS_STOP;
ead9360e
TS
8401 break;
8402 /* COP2: Not implemented. */
8403 case 4:
8404 case 5:
8405 /* fall through */
8406 default:
8407 goto die;
8408 }
b44a7fb1 8409 trace_mips_translate_tr("mttr", rd, u, sel, h);
1a3fd9c3 8410 tcg_temp_free(t0);
ead9360e
TS
8411 return;
8412
8413die:
1a3fd9c3 8414 tcg_temp_free(t0);
d12d51d5 8415 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
9c708c7f 8416 generate_exception_end(ctx, EXCP_RI);
ead9360e
TS
8417}
8418
7db13fae 8419static void gen_cp0 (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
6af0bf9c 8420{
287c4b84 8421 const char *opn = "ldst";
6af0bf9c 8422
2e15497c 8423 check_cp0_enabled(ctx);
6af0bf9c
FB
8424 switch (opc) {
8425 case OPC_MFC0:
8426 if (rt == 0) {
ead9360e 8427 /* Treat as NOP. */
6af0bf9c
FB
8428 return;
8429 }
d75c135e 8430 gen_mfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
6af0bf9c
FB
8431 opn = "mfc0";
8432 break;
8433 case OPC_MTC0:
1a3fd9c3 8434 {
1fc7bf6e 8435 TCGv t0 = tcg_temp_new();
1a3fd9c3
TS
8436
8437 gen_load_gpr(t0, rt);
d75c135e 8438 gen_mtc0(ctx, t0, rd, ctx->opcode & 0x7);
1a3fd9c3
TS
8439 tcg_temp_free(t0);
8440 }
6af0bf9c
FB
8441 opn = "mtc0";
8442 break;
d26bc211 8443#if defined(TARGET_MIPS64)
9c2149c8 8444 case OPC_DMFC0:
d75c135e 8445 check_insn(ctx, ISA_MIPS3);
9c2149c8 8446 if (rt == 0) {
ead9360e 8447 /* Treat as NOP. */
9c2149c8
TS
8448 return;
8449 }
d75c135e 8450 gen_dmfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
9c2149c8
TS
8451 opn = "dmfc0";
8452 break;
8453 case OPC_DMTC0:
d75c135e 8454 check_insn(ctx, ISA_MIPS3);
1a3fd9c3 8455 {
1fc7bf6e 8456 TCGv t0 = tcg_temp_new();
1a3fd9c3
TS
8457
8458 gen_load_gpr(t0, rt);
d75c135e 8459 gen_dmtc0(ctx, t0, rd, ctx->opcode & 0x7);
1a3fd9c3
TS
8460 tcg_temp_free(t0);
8461 }
9c2149c8
TS
8462 opn = "dmtc0";
8463 break;
534ce69f 8464#endif
5204ea79
LA
8465 case OPC_MFHC0:
8466 check_mvh(ctx);
8467 if (rt == 0) {
8468 /* Treat as NOP. */
8469 return;
8470 }
8471 gen_mfhc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
8472 opn = "mfhc0";
8473 break;
8474 case OPC_MTHC0:
8475 check_mvh(ctx);
8476 {
8477 TCGv t0 = tcg_temp_new();
8478 gen_load_gpr(t0, rt);
8479 gen_mthc0(ctx, t0, rd, ctx->opcode & 0x7);
8480 tcg_temp_free(t0);
8481 }
8482 opn = "mthc0";
8483 break;
ead9360e 8484 case OPC_MFTR:
d75c135e 8485 check_insn(ctx, ASE_MT);
ead9360e
TS
8486 if (rd == 0) {
8487 /* Treat as NOP. */
8488 return;
8489 }
6c5c1e20 8490 gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
ead9360e 8491 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
ead9360e
TS
8492 opn = "mftr";
8493 break;
8494 case OPC_MTTR:
d75c135e 8495 check_insn(ctx, ASE_MT);
6c5c1e20 8496 gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
ead9360e
TS
8497 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
8498 opn = "mttr";
8499 break;
6af0bf9c 8500 case OPC_TLBWI:
6af0bf9c 8501 opn = "tlbwi";
c01fccd2 8502 if (!env->tlb->helper_tlbwi)
29929e34 8503 goto die;
895c2d04 8504 gen_helper_tlbwi(cpu_env);
6af0bf9c 8505 break;
9456c2fb
LA
8506 case OPC_TLBINV:
8507 opn = "tlbinv";
8508 if (ctx->ie >= 2) {
8509 if (!env->tlb->helper_tlbinv) {
8510 goto die;
8511 }
8512 gen_helper_tlbinv(cpu_env);
8513 } /* treat as nop if TLBINV not supported */
8514 break;
8515 case OPC_TLBINVF:
8516 opn = "tlbinvf";
8517 if (ctx->ie >= 2) {
8518 if (!env->tlb->helper_tlbinvf) {
8519 goto die;
8520 }
8521 gen_helper_tlbinvf(cpu_env);
8522 } /* treat as nop if TLBINV not supported */
8523 break;
6af0bf9c 8524 case OPC_TLBWR:
6af0bf9c 8525 opn = "tlbwr";
c01fccd2 8526 if (!env->tlb->helper_tlbwr)
29929e34 8527 goto die;
895c2d04 8528 gen_helper_tlbwr(cpu_env);
6af0bf9c
FB
8529 break;
8530 case OPC_TLBP:
6af0bf9c 8531 opn = "tlbp";
c01fccd2 8532 if (!env->tlb->helper_tlbp)
29929e34 8533 goto die;
895c2d04 8534 gen_helper_tlbp(cpu_env);
6af0bf9c
FB
8535 break;
8536 case OPC_TLBR:
6af0bf9c 8537 opn = "tlbr";
c01fccd2 8538 if (!env->tlb->helper_tlbr)
29929e34 8539 goto die;
895c2d04 8540 gen_helper_tlbr(cpu_env);
6af0bf9c 8541 break;
ce9782f4 8542 case OPC_ERET: /* OPC_ERETNC */
339cd2a8
LA
8543 if ((ctx->insn_flags & ISA_MIPS32R6) &&
8544 (ctx->hflags & MIPS_HFLAG_BMASK)) {
339cd2a8 8545 goto die;
ce9782f4
LA
8546 } else {
8547 int bit_shift = (ctx->hflags & MIPS_HFLAG_M16) ? 16 : 6;
8548 if (ctx->opcode & (1 << bit_shift)) {
8549 /* OPC_ERETNC */
8550 opn = "eretnc";
8551 check_insn(ctx, ISA_MIPS32R5);
8552 gen_helper_eretnc(cpu_env);
8553 } else {
8554 /* OPC_ERET */
8555 opn = "eret";
8556 check_insn(ctx, ISA_MIPS2);
8557 gen_helper_eret(cpu_env);
8558 }
eeb3bba8 8559 ctx->base.is_jmp = DISAS_EXIT;
339cd2a8 8560 }
6af0bf9c
FB
8561 break;
8562 case OPC_DERET:
8563 opn = "deret";
d75c135e 8564 check_insn(ctx, ISA_MIPS32);
339cd2a8
LA
8565 if ((ctx->insn_flags & ISA_MIPS32R6) &&
8566 (ctx->hflags & MIPS_HFLAG_BMASK)) {
339cd2a8
LA
8567 goto die;
8568 }
6af0bf9c 8569 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
923617a3 8570 MIPS_INVAL(opn);
9c708c7f 8571 generate_exception_end(ctx, EXCP_RI);
6af0bf9c 8572 } else {
895c2d04 8573 gen_helper_deret(cpu_env);
eeb3bba8 8574 ctx->base.is_jmp = DISAS_EXIT;
6af0bf9c
FB
8575 }
8576 break;
4ad40f36
FB
8577 case OPC_WAIT:
8578 opn = "wait";
d75c135e 8579 check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
339cd2a8
LA
8580 if ((ctx->insn_flags & ISA_MIPS32R6) &&
8581 (ctx->hflags & MIPS_HFLAG_BMASK)) {
339cd2a8
LA
8582 goto die;
8583 }
4ad40f36 8584 /* If we get an exception, we want to restart at next instruction */
eeb3bba8 8585 ctx->base.pc_next += 4;
4ad40f36 8586 save_cpu_state(ctx, 1);
eeb3bba8 8587 ctx->base.pc_next -= 4;
895c2d04 8588 gen_helper_wait(cpu_env);
eeb3bba8 8589 ctx->base.is_jmp = DISAS_NORETURN;
4ad40f36 8590 break;
6af0bf9c 8591 default:
29929e34 8592 die:
923617a3 8593 MIPS_INVAL(opn);
9c708c7f 8594 generate_exception_end(ctx, EXCP_RI);
6af0bf9c
FB
8595 return;
8596 }
2abf314d 8597 (void)opn; /* avoid a compiler warning */
6af0bf9c 8598}
f1aa6320 8599#endif /* !CONFIG_USER_ONLY */
6af0bf9c 8600
6ea83fed 8601/* CP1 Branches (before delay slot) */
d75c135e
AJ
8602static void gen_compute_branch1(DisasContext *ctx, uint32_t op,
8603 int32_t cc, int32_t offset)
6ea83fed
FB
8604{
8605 target_ulong btarget;
a7812ae4 8606 TCGv_i32 t0 = tcg_temp_new_i32();
6ea83fed 8607
339cd2a8 8608 if ((ctx->insn_flags & ISA_MIPS32R6) && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9c708c7f 8609 generate_exception_end(ctx, EXCP_RI);
339cd2a8
LA
8610 goto out;
8611 }
8612
e189e748 8613 if (cc != 0)
d75c135e 8614 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
e189e748 8615
eeb3bba8 8616 btarget = ctx->base.pc_next + 4 + offset;
6ea83fed 8617
7a387fff
TS
8618 switch (op) {
8619 case OPC_BC1F:
d94536f4
AJ
8620 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8621 tcg_gen_not_i32(t0, t0);
8622 tcg_gen_andi_i32(t0, t0, 1);
8623 tcg_gen_extu_i32_tl(bcond, t0);
6ea83fed 8624 goto not_likely;
7a387fff 8625 case OPC_BC1FL:
d94536f4
AJ
8626 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8627 tcg_gen_not_i32(t0, t0);
8628 tcg_gen_andi_i32(t0, t0, 1);
8629 tcg_gen_extu_i32_tl(bcond, t0);
6ea83fed 8630 goto likely;
7a387fff 8631 case OPC_BC1T:
d94536f4
AJ
8632 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8633 tcg_gen_andi_i32(t0, t0, 1);
8634 tcg_gen_extu_i32_tl(bcond, t0);
5a5012ec 8635 goto not_likely;
7a387fff 8636 case OPC_BC1TL:
d94536f4
AJ
8637 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8638 tcg_gen_andi_i32(t0, t0, 1);
8639 tcg_gen_extu_i32_tl(bcond, t0);
6ea83fed
FB
8640 likely:
8641 ctx->hflags |= MIPS_HFLAG_BL;
8642 break;
5a5012ec 8643 case OPC_BC1FANY2:
a16336e4 8644 {
d94536f4
AJ
8645 TCGv_i32 t1 = tcg_temp_new_i32();
8646 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8647 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
d7f66b52 8648 tcg_gen_nand_i32(t0, t0, t1);
d94536f4 8649 tcg_temp_free_i32(t1);
d94536f4
AJ
8650 tcg_gen_andi_i32(t0, t0, 1);
8651 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 8652 }
5a5012ec
TS
8653 goto not_likely;
8654 case OPC_BC1TANY2:
a16336e4 8655 {
d94536f4
AJ
8656 TCGv_i32 t1 = tcg_temp_new_i32();
8657 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8658 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
8659 tcg_gen_or_i32(t0, t0, t1);
8660 tcg_temp_free_i32(t1);
8661 tcg_gen_andi_i32(t0, t0, 1);
8662 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 8663 }
5a5012ec
TS
8664 goto not_likely;
8665 case OPC_BC1FANY4:
a16336e4 8666 {
d94536f4
AJ
8667 TCGv_i32 t1 = tcg_temp_new_i32();
8668 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8669 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
d7f66b52 8670 tcg_gen_and_i32(t0, t0, t1);
d94536f4 8671 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
d7f66b52 8672 tcg_gen_and_i32(t0, t0, t1);
d94536f4 8673 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
d7f66b52 8674 tcg_gen_nand_i32(t0, t0, t1);
d94536f4 8675 tcg_temp_free_i32(t1);
d94536f4
AJ
8676 tcg_gen_andi_i32(t0, t0, 1);
8677 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 8678 }
5a5012ec
TS
8679 goto not_likely;
8680 case OPC_BC1TANY4:
a16336e4 8681 {
d94536f4
AJ
8682 TCGv_i32 t1 = tcg_temp_new_i32();
8683 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8684 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
8685 tcg_gen_or_i32(t0, t0, t1);
8686 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
8687 tcg_gen_or_i32(t0, t0, t1);
8688 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
8689 tcg_gen_or_i32(t0, t0, t1);
8690 tcg_temp_free_i32(t1);
8691 tcg_gen_andi_i32(t0, t0, 1);
8692 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 8693 }
5a5012ec
TS
8694 not_likely:
8695 ctx->hflags |= MIPS_HFLAG_BC;
5a5012ec
TS
8696 break;
8697 default:
9d68ac14 8698 MIPS_INVAL("cp1 cond branch");
9c708c7f 8699 generate_exception_end(ctx, EXCP_RI);
6c5c1e20 8700 goto out;
6ea83fed 8701 }
6ea83fed 8702 ctx->btarget = btarget;
b231c103 8703 ctx->hflags |= MIPS_HFLAG_BDS32;
6c5c1e20 8704 out:
a7812ae4 8705 tcg_temp_free_i32(t0);
6ea83fed
FB
8706}
8707
31837be3
YK
8708/* R6 CP1 Branches */
8709static void gen_compute_branch1_r6(DisasContext *ctx, uint32_t op,
65935f07
YK
8710 int32_t ft, int32_t offset,
8711 int delayslot_size)
31837be3
YK
8712{
8713 target_ulong btarget;
31837be3
YK
8714 TCGv_i64 t0 = tcg_temp_new_i64();
8715
8716 if (ctx->hflags & MIPS_HFLAG_BMASK) {
8717#ifdef MIPS_DEBUG_DISAS
339cd2a8 8718 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
eeb3bba8 8719 "\n", ctx->base.pc_next);
31837be3 8720#endif
9c708c7f 8721 generate_exception_end(ctx, EXCP_RI);
31837be3
YK
8722 goto out;
8723 }
8724
8725 gen_load_fpr64(ctx, t0, ft);
8726 tcg_gen_andi_i64(t0, t0, 1);
8727
eeb3bba8 8728 btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
31837be3
YK
8729
8730 switch (op) {
8731 case OPC_BC1EQZ:
8732 tcg_gen_xori_i64(t0, t0, 1);
31837be3
YK
8733 ctx->hflags |= MIPS_HFLAG_BC;
8734 break;
8735 case OPC_BC1NEZ:
8736 /* t0 already set */
31837be3
YK
8737 ctx->hflags |= MIPS_HFLAG_BC;
8738 break;
8739 default:
9d68ac14 8740 MIPS_INVAL("cp1 cond branch");
9c708c7f 8741 generate_exception_end(ctx, EXCP_RI);
31837be3
YK
8742 goto out;
8743 }
8744
8745 tcg_gen_trunc_i64_tl(bcond, t0);
8746
31837be3 8747 ctx->btarget = btarget;
65935f07
YK
8748
8749 switch (delayslot_size) {
8750 case 2:
8751 ctx->hflags |= MIPS_HFLAG_BDS16;
8752 break;
8753 case 4:
8754 ctx->hflags |= MIPS_HFLAG_BDS32;
8755 break;
8756 }
31837be3
YK
8757
8758out:
8759 tcg_temp_free_i64(t0);
8760}
8761
6af0bf9c 8762/* Coprocessor 1 (FPU) */
5a5012ec 8763
5a5012ec
TS
8764#define FOP(func, fmt) (((fmt) << 21) | (func))
8765
bf4120ad
NF
8766enum fopcode {
8767 OPC_ADD_S = FOP(0, FMT_S),
8768 OPC_SUB_S = FOP(1, FMT_S),
8769 OPC_MUL_S = FOP(2, FMT_S),
8770 OPC_DIV_S = FOP(3, FMT_S),
8771 OPC_SQRT_S = FOP(4, FMT_S),
8772 OPC_ABS_S = FOP(5, FMT_S),
8773 OPC_MOV_S = FOP(6, FMT_S),
8774 OPC_NEG_S = FOP(7, FMT_S),
8775 OPC_ROUND_L_S = FOP(8, FMT_S),
8776 OPC_TRUNC_L_S = FOP(9, FMT_S),
8777 OPC_CEIL_L_S = FOP(10, FMT_S),
8778 OPC_FLOOR_L_S = FOP(11, FMT_S),
8779 OPC_ROUND_W_S = FOP(12, FMT_S),
8780 OPC_TRUNC_W_S = FOP(13, FMT_S),
8781 OPC_CEIL_W_S = FOP(14, FMT_S),
8782 OPC_FLOOR_W_S = FOP(15, FMT_S),
e7f16abb 8783 OPC_SEL_S = FOP(16, FMT_S),
bf4120ad
NF
8784 OPC_MOVCF_S = FOP(17, FMT_S),
8785 OPC_MOVZ_S = FOP(18, FMT_S),
8786 OPC_MOVN_S = FOP(19, FMT_S),
e7f16abb 8787 OPC_SELEQZ_S = FOP(20, FMT_S),
bf4120ad
NF
8788 OPC_RECIP_S = FOP(21, FMT_S),
8789 OPC_RSQRT_S = FOP(22, FMT_S),
e7f16abb
LA
8790 OPC_SELNEZ_S = FOP(23, FMT_S),
8791 OPC_MADDF_S = FOP(24, FMT_S),
8792 OPC_MSUBF_S = FOP(25, FMT_S),
8793 OPC_RINT_S = FOP(26, FMT_S),
8794 OPC_CLASS_S = FOP(27, FMT_S),
8795 OPC_MIN_S = FOP(28, FMT_S),
bf4120ad 8796 OPC_RECIP2_S = FOP(28, FMT_S),
e7f16abb 8797 OPC_MINA_S = FOP(29, FMT_S),
bf4120ad 8798 OPC_RECIP1_S = FOP(29, FMT_S),
e7f16abb 8799 OPC_MAX_S = FOP(30, FMT_S),
bf4120ad 8800 OPC_RSQRT1_S = FOP(30, FMT_S),
e7f16abb 8801 OPC_MAXA_S = FOP(31, FMT_S),
bf4120ad
NF
8802 OPC_RSQRT2_S = FOP(31, FMT_S),
8803 OPC_CVT_D_S = FOP(33, FMT_S),
8804 OPC_CVT_W_S = FOP(36, FMT_S),
8805 OPC_CVT_L_S = FOP(37, FMT_S),
8806 OPC_CVT_PS_S = FOP(38, FMT_S),
8807 OPC_CMP_F_S = FOP (48, FMT_S),
8808 OPC_CMP_UN_S = FOP (49, FMT_S),
8809 OPC_CMP_EQ_S = FOP (50, FMT_S),
8810 OPC_CMP_UEQ_S = FOP (51, FMT_S),
8811 OPC_CMP_OLT_S = FOP (52, FMT_S),
8812 OPC_CMP_ULT_S = FOP (53, FMT_S),
8813 OPC_CMP_OLE_S = FOP (54, FMT_S),
8814 OPC_CMP_ULE_S = FOP (55, FMT_S),
8815 OPC_CMP_SF_S = FOP (56, FMT_S),
8816 OPC_CMP_NGLE_S = FOP (57, FMT_S),
8817 OPC_CMP_SEQ_S = FOP (58, FMT_S),
8818 OPC_CMP_NGL_S = FOP (59, FMT_S),
8819 OPC_CMP_LT_S = FOP (60, FMT_S),
8820 OPC_CMP_NGE_S = FOP (61, FMT_S),
8821 OPC_CMP_LE_S = FOP (62, FMT_S),
8822 OPC_CMP_NGT_S = FOP (63, FMT_S),
8823
8824 OPC_ADD_D = FOP(0, FMT_D),
8825 OPC_SUB_D = FOP(1, FMT_D),
8826 OPC_MUL_D = FOP(2, FMT_D),
8827 OPC_DIV_D = FOP(3, FMT_D),
8828 OPC_SQRT_D = FOP(4, FMT_D),
8829 OPC_ABS_D = FOP(5, FMT_D),
8830 OPC_MOV_D = FOP(6, FMT_D),
8831 OPC_NEG_D = FOP(7, FMT_D),
8832 OPC_ROUND_L_D = FOP(8, FMT_D),
8833 OPC_TRUNC_L_D = FOP(9, FMT_D),
8834 OPC_CEIL_L_D = FOP(10, FMT_D),
8835 OPC_FLOOR_L_D = FOP(11, FMT_D),
8836 OPC_ROUND_W_D = FOP(12, FMT_D),
8837 OPC_TRUNC_W_D = FOP(13, FMT_D),
8838 OPC_CEIL_W_D = FOP(14, FMT_D),
8839 OPC_FLOOR_W_D = FOP(15, FMT_D),
e7f16abb 8840 OPC_SEL_D = FOP(16, FMT_D),
bf4120ad
NF
8841 OPC_MOVCF_D = FOP(17, FMT_D),
8842 OPC_MOVZ_D = FOP(18, FMT_D),
8843 OPC_MOVN_D = FOP(19, FMT_D),
e7f16abb 8844 OPC_SELEQZ_D = FOP(20, FMT_D),
bf4120ad
NF
8845 OPC_RECIP_D = FOP(21, FMT_D),
8846 OPC_RSQRT_D = FOP(22, FMT_D),
e7f16abb
LA
8847 OPC_SELNEZ_D = FOP(23, FMT_D),
8848 OPC_MADDF_D = FOP(24, FMT_D),
8849 OPC_MSUBF_D = FOP(25, FMT_D),
8850 OPC_RINT_D = FOP(26, FMT_D),
8851 OPC_CLASS_D = FOP(27, FMT_D),
8852 OPC_MIN_D = FOP(28, FMT_D),
bf4120ad 8853 OPC_RECIP2_D = FOP(28, FMT_D),
e7f16abb 8854 OPC_MINA_D = FOP(29, FMT_D),
bf4120ad 8855 OPC_RECIP1_D = FOP(29, FMT_D),
e7f16abb 8856 OPC_MAX_D = FOP(30, FMT_D),
bf4120ad 8857 OPC_RSQRT1_D = FOP(30, FMT_D),
e7f16abb 8858 OPC_MAXA_D = FOP(31, FMT_D),
bf4120ad
NF
8859 OPC_RSQRT2_D = FOP(31, FMT_D),
8860 OPC_CVT_S_D = FOP(32, FMT_D),
8861 OPC_CVT_W_D = FOP(36, FMT_D),
8862 OPC_CVT_L_D = FOP(37, FMT_D),
8863 OPC_CMP_F_D = FOP (48, FMT_D),
8864 OPC_CMP_UN_D = FOP (49, FMT_D),
8865 OPC_CMP_EQ_D = FOP (50, FMT_D),
8866 OPC_CMP_UEQ_D = FOP (51, FMT_D),
8867 OPC_CMP_OLT_D = FOP (52, FMT_D),
8868 OPC_CMP_ULT_D = FOP (53, FMT_D),
8869 OPC_CMP_OLE_D = FOP (54, FMT_D),
8870 OPC_CMP_ULE_D = FOP (55, FMT_D),
8871 OPC_CMP_SF_D = FOP (56, FMT_D),
8872 OPC_CMP_NGLE_D = FOP (57, FMT_D),
8873 OPC_CMP_SEQ_D = FOP (58, FMT_D),
8874 OPC_CMP_NGL_D = FOP (59, FMT_D),
8875 OPC_CMP_LT_D = FOP (60, FMT_D),
8876 OPC_CMP_NGE_D = FOP (61, FMT_D),
8877 OPC_CMP_LE_D = FOP (62, FMT_D),
8878 OPC_CMP_NGT_D = FOP (63, FMT_D),
8879
8880 OPC_CVT_S_W = FOP(32, FMT_W),
8881 OPC_CVT_D_W = FOP(33, FMT_W),
8882 OPC_CVT_S_L = FOP(32, FMT_L),
8883 OPC_CVT_D_L = FOP(33, FMT_L),
8884 OPC_CVT_PS_PW = FOP(38, FMT_W),
8885
8886 OPC_ADD_PS = FOP(0, FMT_PS),
8887 OPC_SUB_PS = FOP(1, FMT_PS),
8888 OPC_MUL_PS = FOP(2, FMT_PS),
8889 OPC_DIV_PS = FOP(3, FMT_PS),
8890 OPC_ABS_PS = FOP(5, FMT_PS),
8891 OPC_MOV_PS = FOP(6, FMT_PS),
8892 OPC_NEG_PS = FOP(7, FMT_PS),
8893 OPC_MOVCF_PS = FOP(17, FMT_PS),
8894 OPC_MOVZ_PS = FOP(18, FMT_PS),
8895 OPC_MOVN_PS = FOP(19, FMT_PS),
8896 OPC_ADDR_PS = FOP(24, FMT_PS),
8897 OPC_MULR_PS = FOP(26, FMT_PS),
8898 OPC_RECIP2_PS = FOP(28, FMT_PS),
8899 OPC_RECIP1_PS = FOP(29, FMT_PS),
8900 OPC_RSQRT1_PS = FOP(30, FMT_PS),
8901 OPC_RSQRT2_PS = FOP(31, FMT_PS),
8902
8903 OPC_CVT_S_PU = FOP(32, FMT_PS),
8904 OPC_CVT_PW_PS = FOP(36, FMT_PS),
8905 OPC_CVT_S_PL = FOP(40, FMT_PS),
8906 OPC_PLL_PS = FOP(44, FMT_PS),
8907 OPC_PLU_PS = FOP(45, FMT_PS),
8908 OPC_PUL_PS = FOP(46, FMT_PS),
8909 OPC_PUU_PS = FOP(47, FMT_PS),
8910 OPC_CMP_F_PS = FOP (48, FMT_PS),
8911 OPC_CMP_UN_PS = FOP (49, FMT_PS),
8912 OPC_CMP_EQ_PS = FOP (50, FMT_PS),
8913 OPC_CMP_UEQ_PS = FOP (51, FMT_PS),
8914 OPC_CMP_OLT_PS = FOP (52, FMT_PS),
8915 OPC_CMP_ULT_PS = FOP (53, FMT_PS),
8916 OPC_CMP_OLE_PS = FOP (54, FMT_PS),
8917 OPC_CMP_ULE_PS = FOP (55, FMT_PS),
8918 OPC_CMP_SF_PS = FOP (56, FMT_PS),
8919 OPC_CMP_NGLE_PS = FOP (57, FMT_PS),
8920 OPC_CMP_SEQ_PS = FOP (58, FMT_PS),
8921 OPC_CMP_NGL_PS = FOP (59, FMT_PS),
8922 OPC_CMP_LT_PS = FOP (60, FMT_PS),
8923 OPC_CMP_NGE_PS = FOP (61, FMT_PS),
8924 OPC_CMP_LE_PS = FOP (62, FMT_PS),
8925 OPC_CMP_NGT_PS = FOP (63, FMT_PS),
8926};
8927
3f493883
YK
8928enum r6_f_cmp_op {
8929 R6_OPC_CMP_AF_S = FOP(0, FMT_W),
8930 R6_OPC_CMP_UN_S = FOP(1, FMT_W),
8931 R6_OPC_CMP_EQ_S = FOP(2, FMT_W),
8932 R6_OPC_CMP_UEQ_S = FOP(3, FMT_W),
8933 R6_OPC_CMP_LT_S = FOP(4, FMT_W),
8934 R6_OPC_CMP_ULT_S = FOP(5, FMT_W),
8935 R6_OPC_CMP_LE_S = FOP(6, FMT_W),
8936 R6_OPC_CMP_ULE_S = FOP(7, FMT_W),
8937 R6_OPC_CMP_SAF_S = FOP(8, FMT_W),
8938 R6_OPC_CMP_SUN_S = FOP(9, FMT_W),
8939 R6_OPC_CMP_SEQ_S = FOP(10, FMT_W),
8940 R6_OPC_CMP_SEUQ_S = FOP(11, FMT_W),
8941 R6_OPC_CMP_SLT_S = FOP(12, FMT_W),
8942 R6_OPC_CMP_SULT_S = FOP(13, FMT_W),
8943 R6_OPC_CMP_SLE_S = FOP(14, FMT_W),
8944 R6_OPC_CMP_SULE_S = FOP(15, FMT_W),
8945 R6_OPC_CMP_OR_S = FOP(17, FMT_W),
8946 R6_OPC_CMP_UNE_S = FOP(18, FMT_W),
8947 R6_OPC_CMP_NE_S = FOP(19, FMT_W),
8948 R6_OPC_CMP_SOR_S = FOP(25, FMT_W),
8949 R6_OPC_CMP_SUNE_S = FOP(26, FMT_W),
8950 R6_OPC_CMP_SNE_S = FOP(27, FMT_W),
8951
8952 R6_OPC_CMP_AF_D = FOP(0, FMT_L),
8953 R6_OPC_CMP_UN_D = FOP(1, FMT_L),
8954 R6_OPC_CMP_EQ_D = FOP(2, FMT_L),
8955 R6_OPC_CMP_UEQ_D = FOP(3, FMT_L),
8956 R6_OPC_CMP_LT_D = FOP(4, FMT_L),
8957 R6_OPC_CMP_ULT_D = FOP(5, FMT_L),
8958 R6_OPC_CMP_LE_D = FOP(6, FMT_L),
8959 R6_OPC_CMP_ULE_D = FOP(7, FMT_L),
8960 R6_OPC_CMP_SAF_D = FOP(8, FMT_L),
8961 R6_OPC_CMP_SUN_D = FOP(9, FMT_L),
8962 R6_OPC_CMP_SEQ_D = FOP(10, FMT_L),
8963 R6_OPC_CMP_SEUQ_D = FOP(11, FMT_L),
8964 R6_OPC_CMP_SLT_D = FOP(12, FMT_L),
8965 R6_OPC_CMP_SULT_D = FOP(13, FMT_L),
8966 R6_OPC_CMP_SLE_D = FOP(14, FMT_L),
8967 R6_OPC_CMP_SULE_D = FOP(15, FMT_L),
8968 R6_OPC_CMP_OR_D = FOP(17, FMT_L),
8969 R6_OPC_CMP_UNE_D = FOP(18, FMT_L),
8970 R6_OPC_CMP_NE_D = FOP(19, FMT_L),
8971 R6_OPC_CMP_SOR_D = FOP(25, FMT_L),
8972 R6_OPC_CMP_SUNE_D = FOP(26, FMT_L),
8973 R6_OPC_CMP_SNE_D = FOP(27, FMT_L),
8974};
7a387fff 8975static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
6ea83fed 8976{
72c3a3ee 8977 TCGv t0 = tcg_temp_new();
6ea83fed
FB
8978
8979 switch (opc) {
8980 case OPC_MFC1:
b6d96bed 8981 {
a7812ae4 8982 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8983
7c979afd 8984 gen_load_fpr32(ctx, fp0, fs);
b6d96bed 8985 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 8986 tcg_temp_free_i32(fp0);
6958549d 8987 }
6c5c1e20 8988 gen_store_gpr(t0, rt);
6ea83fed
FB
8989 break;
8990 case OPC_MTC1:
6c5c1e20 8991 gen_load_gpr(t0, rt);
b6d96bed 8992 {
a7812ae4 8993 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8994
8995 tcg_gen_trunc_tl_i32(fp0, t0);
7c979afd 8996 gen_store_fpr32(ctx, fp0, fs);
a7812ae4 8997 tcg_temp_free_i32(fp0);
6958549d 8998 }
6ea83fed
FB
8999 break;
9000 case OPC_CFC1:
895c2d04 9001 gen_helper_1e0i(cfc1, t0, fs);
6c5c1e20 9002 gen_store_gpr(t0, rt);
6ea83fed
FB
9003 break;
9004 case OPC_CTC1:
6c5c1e20 9005 gen_load_gpr(t0, rt);
9c708c7f 9006 save_cpu_state(ctx, 0);
736d120a
PJ
9007 {
9008 TCGv_i32 fs_tmp = tcg_const_i32(fs);
9009
9010 gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
9011 tcg_temp_free_i32(fs_tmp);
9012 }
4cf8a45f 9013 /* Stop translation as we may have changed hflags */
eeb3bba8 9014 ctx->base.is_jmp = DISAS_STOP;
6ea83fed 9015 break;
72c3a3ee 9016#if defined(TARGET_MIPS64)
9c2149c8 9017 case OPC_DMFC1:
72c3a3ee 9018 gen_load_fpr64(ctx, t0, fs);
6c5c1e20 9019 gen_store_gpr(t0, rt);
5a5012ec 9020 break;
9c2149c8 9021 case OPC_DMTC1:
6c5c1e20 9022 gen_load_gpr(t0, rt);
72c3a3ee 9023 gen_store_fpr64(ctx, t0, fs);
5a5012ec 9024 break;
72c3a3ee 9025#endif
5a5012ec 9026 case OPC_MFHC1:
b6d96bed 9027 {
a7812ae4 9028 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9029
7f6613ce 9030 gen_load_fpr32h(ctx, fp0, fs);
b6d96bed 9031 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 9032 tcg_temp_free_i32(fp0);
6958549d 9033 }
6c5c1e20 9034 gen_store_gpr(t0, rt);
5a5012ec
TS
9035 break;
9036 case OPC_MTHC1:
6c5c1e20 9037 gen_load_gpr(t0, rt);
b6d96bed 9038 {
a7812ae4 9039 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
9040
9041 tcg_gen_trunc_tl_i32(fp0, t0);
7f6613ce 9042 gen_store_fpr32h(ctx, fp0, fs);
a7812ae4 9043 tcg_temp_free_i32(fp0);
6958549d 9044 }
5a5012ec 9045 break;
6ea83fed 9046 default:
9d68ac14 9047 MIPS_INVAL("cp1 move");
9c708c7f 9048 generate_exception_end(ctx, EXCP_RI);
6c5c1e20 9049 goto out;
6ea83fed 9050 }
6c5c1e20
TS
9051
9052 out:
9053 tcg_temp_free(t0);
6ea83fed
FB
9054}
9055
5a5012ec
TS
9056static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
9057{
42a268c2 9058 TCGLabel *l1;
e214b9bb 9059 TCGCond cond;
af58f9ca
AJ
9060 TCGv_i32 t0;
9061
9062 if (rd == 0) {
9063 /* Treat as NOP. */
9064 return;
9065 }
6ea83fed 9066
e214b9bb 9067 if (tf)
e214b9bb 9068 cond = TCG_COND_EQ;
27848470
TS
9069 else
9070 cond = TCG_COND_NE;
9071
af58f9ca
AJ
9072 l1 = gen_new_label();
9073 t0 = tcg_temp_new_i32();
fa31af0e 9074 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
af58f9ca 9075 tcg_gen_brcondi_i32(cond, t0, 0, l1);
a4e8338d 9076 tcg_temp_free_i32(t0);
af58f9ca
AJ
9077 if (rs == 0) {
9078 tcg_gen_movi_tl(cpu_gpr[rd], 0);
9079 } else {
9080 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
9081 }
e214b9bb 9082 gen_set_label(l1);
5a5012ec
TS
9083}
9084
7c979afd
LA
9085static inline void gen_movcf_s(DisasContext *ctx, int fs, int fd, int cc,
9086 int tf)
a16336e4 9087{
a16336e4 9088 int cond;
cbc37b28 9089 TCGv_i32 t0 = tcg_temp_new_i32();
42a268c2 9090 TCGLabel *l1 = gen_new_label();
a16336e4 9091
a16336e4
TS
9092 if (tf)
9093 cond = TCG_COND_EQ;
9094 else
9095 cond = TCG_COND_NE;
9096
fa31af0e 9097 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
cbc37b28 9098 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7c979afd
LA
9099 gen_load_fpr32(ctx, t0, fs);
9100 gen_store_fpr32(ctx, t0, fd);
a16336e4 9101 gen_set_label(l1);
cbc37b28 9102 tcg_temp_free_i32(t0);
5a5012ec 9103}
a16336e4 9104
b6d96bed 9105static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
a16336e4 9106{
a16336e4 9107 int cond;
cbc37b28
AJ
9108 TCGv_i32 t0 = tcg_temp_new_i32();
9109 TCGv_i64 fp0;
42a268c2 9110 TCGLabel *l1 = gen_new_label();
a16336e4 9111
a16336e4
TS
9112 if (tf)
9113 cond = TCG_COND_EQ;
9114 else
9115 cond = TCG_COND_NE;
9116
fa31af0e 9117 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
cbc37b28 9118 tcg_gen_brcondi_i32(cond, t0, 0, l1);
a4e8338d 9119 tcg_temp_free_i32(t0);
11f94258 9120 fp0 = tcg_temp_new_i64();
9bf3eb2c 9121 gen_load_fpr64(ctx, fp0, fs);
9bf3eb2c 9122 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9123 tcg_temp_free_i64(fp0);
cbc37b28 9124 gen_set_label(l1);
a16336e4
TS
9125}
9126
7f6613ce
PJ
9127static inline void gen_movcf_ps(DisasContext *ctx, int fs, int fd,
9128 int cc, int tf)
a16336e4
TS
9129{
9130 int cond;
cbc37b28 9131 TCGv_i32 t0 = tcg_temp_new_i32();
42a268c2
RH
9132 TCGLabel *l1 = gen_new_label();
9133 TCGLabel *l2 = gen_new_label();
a16336e4
TS
9134
9135 if (tf)
9136 cond = TCG_COND_EQ;
9137 else
9138 cond = TCG_COND_NE;
9139
fa31af0e 9140 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
cbc37b28 9141 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7c979afd
LA
9142 gen_load_fpr32(ctx, t0, fs);
9143 gen_store_fpr32(ctx, t0, fd);
a16336e4 9144 gen_set_label(l1);
9bf3eb2c 9145
fa31af0e 9146 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc+1));
cbc37b28 9147 tcg_gen_brcondi_i32(cond, t0, 0, l2);
7f6613ce
PJ
9148 gen_load_fpr32h(ctx, t0, fs);
9149 gen_store_fpr32h(ctx, t0, fd);
52a0e9eb 9150 tcg_temp_free_i32(t0);
a16336e4 9151 gen_set_label(l2);
a16336e4
TS
9152}
9153
e7f16abb
LA
9154static void gen_sel_s(DisasContext *ctx, enum fopcode op1, int fd, int ft,
9155 int fs)
9156{
9157 TCGv_i32 t1 = tcg_const_i32(0);
9158 TCGv_i32 fp0 = tcg_temp_new_i32();
9159 TCGv_i32 fp1 = tcg_temp_new_i32();
9160 TCGv_i32 fp2 = tcg_temp_new_i32();
7c979afd
LA
9161 gen_load_fpr32(ctx, fp0, fd);
9162 gen_load_fpr32(ctx, fp1, ft);
9163 gen_load_fpr32(ctx, fp2, fs);
e7f16abb
LA
9164
9165 switch (op1) {
9166 case OPC_SEL_S:
9167 tcg_gen_andi_i32(fp0, fp0, 1);
9168 tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
9169 break;
9170 case OPC_SELEQZ_S:
9171 tcg_gen_andi_i32(fp1, fp1, 1);
9172 tcg_gen_movcond_i32(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
9173 break;
9174 case OPC_SELNEZ_S:
9175 tcg_gen_andi_i32(fp1, fp1, 1);
9176 tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
9177 break;
9178 default:
9179 MIPS_INVAL("gen_sel_s");
9c708c7f 9180 generate_exception_end(ctx, EXCP_RI);
e7f16abb
LA
9181 break;
9182 }
9183
7c979afd 9184 gen_store_fpr32(ctx, fp0, fd);
e7f16abb
LA
9185 tcg_temp_free_i32(fp2);
9186 tcg_temp_free_i32(fp1);
9187 tcg_temp_free_i32(fp0);
9188 tcg_temp_free_i32(t1);
9189}
9190
9191static void gen_sel_d(DisasContext *ctx, enum fopcode op1, int fd, int ft,
9192 int fs)
9193{
9194 TCGv_i64 t1 = tcg_const_i64(0);
9195 TCGv_i64 fp0 = tcg_temp_new_i64();
9196 TCGv_i64 fp1 = tcg_temp_new_i64();
9197 TCGv_i64 fp2 = tcg_temp_new_i64();
9198 gen_load_fpr64(ctx, fp0, fd);
9199 gen_load_fpr64(ctx, fp1, ft);
9200 gen_load_fpr64(ctx, fp2, fs);
9201
9202 switch (op1) {
9203 case OPC_SEL_D:
9204 tcg_gen_andi_i64(fp0, fp0, 1);
9205 tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
9206 break;
9207 case OPC_SELEQZ_D:
9208 tcg_gen_andi_i64(fp1, fp1, 1);
9209 tcg_gen_movcond_i64(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
9210 break;
9211 case OPC_SELNEZ_D:
9212 tcg_gen_andi_i64(fp1, fp1, 1);
9213 tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
9214 break;
9215 default:
9216 MIPS_INVAL("gen_sel_d");
9c708c7f 9217 generate_exception_end(ctx, EXCP_RI);
e7f16abb
LA
9218 break;
9219 }
9220
9221 gen_store_fpr64(ctx, fp0, fd);
9222 tcg_temp_free_i64(fp2);
9223 tcg_temp_free_i64(fp1);
9224 tcg_temp_free_i64(fp0);
9225 tcg_temp_free_i64(t1);
9226}
6ea83fed 9227
bf4120ad 9228static void gen_farith (DisasContext *ctx, enum fopcode op1,
5e755519 9229 int ft, int fs, int fd, int cc)
6ea83fed 9230{
7a387fff 9231 uint32_t func = ctx->opcode & 0x3f;
bf4120ad
NF
9232 switch (op1) {
9233 case OPC_ADD_S:
b6d96bed 9234 {
a7812ae4
PB
9235 TCGv_i32 fp0 = tcg_temp_new_i32();
9236 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 9237
7c979afd
LA
9238 gen_load_fpr32(ctx, fp0, fs);
9239 gen_load_fpr32(ctx, fp1, ft);
895c2d04 9240 gen_helper_float_add_s(fp0, cpu_env, fp0, fp1);
a7812ae4 9241 tcg_temp_free_i32(fp1);
7c979afd 9242 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9243 tcg_temp_free_i32(fp0);
b6d96bed 9244 }
5a5012ec 9245 break;
bf4120ad 9246 case OPC_SUB_S:
b6d96bed 9247 {
a7812ae4
PB
9248 TCGv_i32 fp0 = tcg_temp_new_i32();
9249 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 9250
7c979afd
LA
9251 gen_load_fpr32(ctx, fp0, fs);
9252 gen_load_fpr32(ctx, fp1, ft);
895c2d04 9253 gen_helper_float_sub_s(fp0, cpu_env, fp0, fp1);
a7812ae4 9254 tcg_temp_free_i32(fp1);
7c979afd 9255 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9256 tcg_temp_free_i32(fp0);
b6d96bed 9257 }
5a5012ec 9258 break;
bf4120ad 9259 case OPC_MUL_S:
b6d96bed 9260 {
a7812ae4
PB
9261 TCGv_i32 fp0 = tcg_temp_new_i32();
9262 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 9263
7c979afd
LA
9264 gen_load_fpr32(ctx, fp0, fs);
9265 gen_load_fpr32(ctx, fp1, ft);
895c2d04 9266 gen_helper_float_mul_s(fp0, cpu_env, fp0, fp1);
a7812ae4 9267 tcg_temp_free_i32(fp1);
7c979afd 9268 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9269 tcg_temp_free_i32(fp0);
b6d96bed 9270 }
5a5012ec 9271 break;
bf4120ad 9272 case OPC_DIV_S:
b6d96bed 9273 {
a7812ae4
PB
9274 TCGv_i32 fp0 = tcg_temp_new_i32();
9275 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 9276
7c979afd
LA
9277 gen_load_fpr32(ctx, fp0, fs);
9278 gen_load_fpr32(ctx, fp1, ft);
895c2d04 9279 gen_helper_float_div_s(fp0, cpu_env, fp0, fp1);
a7812ae4 9280 tcg_temp_free_i32(fp1);
7c979afd 9281 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9282 tcg_temp_free_i32(fp0);
b6d96bed 9283 }
5a5012ec 9284 break;
bf4120ad 9285 case OPC_SQRT_S:
b6d96bed 9286 {
a7812ae4 9287 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9288
7c979afd 9289 gen_load_fpr32(ctx, fp0, fs);
895c2d04 9290 gen_helper_float_sqrt_s(fp0, cpu_env, fp0);
7c979afd 9291 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9292 tcg_temp_free_i32(fp0);
b6d96bed 9293 }
5a5012ec 9294 break;
bf4120ad 9295 case OPC_ABS_S:
b6d96bed 9296 {
a7812ae4 9297 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9298
7c979afd 9299 gen_load_fpr32(ctx, fp0, fs);
6be77480
AM
9300 if (ctx->abs2008) {
9301 tcg_gen_andi_i32(fp0, fp0, 0x7fffffffUL);
9302 } else {
9303 gen_helper_float_abs_s(fp0, fp0);
9304 }
7c979afd 9305 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9306 tcg_temp_free_i32(fp0);
b6d96bed 9307 }
5a5012ec 9308 break;
bf4120ad 9309 case OPC_MOV_S:
b6d96bed 9310 {
a7812ae4 9311 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9312
7c979afd
LA
9313 gen_load_fpr32(ctx, fp0, fs);
9314 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9315 tcg_temp_free_i32(fp0);
b6d96bed 9316 }
5a5012ec 9317 break;
bf4120ad 9318 case OPC_NEG_S:
b6d96bed 9319 {
a7812ae4 9320 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9321
7c979afd 9322 gen_load_fpr32(ctx, fp0, fs);
6be77480
AM
9323 if (ctx->abs2008) {
9324 tcg_gen_xori_i32(fp0, fp0, 1UL << 31);
9325 } else {
9326 gen_helper_float_chs_s(fp0, fp0);
9327 }
7c979afd 9328 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9329 tcg_temp_free_i32(fp0);
b6d96bed 9330 }
5a5012ec 9331 break;
bf4120ad 9332 case OPC_ROUND_L_S:
5e755519 9333 check_cp1_64bitmode(ctx);
b6d96bed 9334 {
a7812ae4
PB
9335 TCGv_i32 fp32 = tcg_temp_new_i32();
9336 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 9337
7c979afd 9338 gen_load_fpr32(ctx, fp32, fs);
87552089
AM
9339 if (ctx->nan2008) {
9340 gen_helper_float_round_2008_l_s(fp64, cpu_env, fp32);
9341 } else {
9342 gen_helper_float_round_l_s(fp64, cpu_env, fp32);
9343 }
a7812ae4 9344 tcg_temp_free_i32(fp32);
b6d96bed 9345 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 9346 tcg_temp_free_i64(fp64);
b6d96bed 9347 }
5a5012ec 9348 break;
bf4120ad 9349 case OPC_TRUNC_L_S:
5e755519 9350 check_cp1_64bitmode(ctx);
b6d96bed 9351 {
a7812ae4
PB
9352 TCGv_i32 fp32 = tcg_temp_new_i32();
9353 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 9354
7c979afd 9355 gen_load_fpr32(ctx, fp32, fs);
87552089
AM
9356 if (ctx->nan2008) {
9357 gen_helper_float_trunc_2008_l_s(fp64, cpu_env, fp32);
9358 } else {
9359 gen_helper_float_trunc_l_s(fp64, cpu_env, fp32);
9360 }
a7812ae4 9361 tcg_temp_free_i32(fp32);
b6d96bed 9362 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 9363 tcg_temp_free_i64(fp64);
b6d96bed 9364 }
5a5012ec 9365 break;
bf4120ad 9366 case OPC_CEIL_L_S:
5e755519 9367 check_cp1_64bitmode(ctx);
b6d96bed 9368 {
a7812ae4
PB
9369 TCGv_i32 fp32 = tcg_temp_new_i32();
9370 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 9371
7c979afd 9372 gen_load_fpr32(ctx, fp32, fs);
87552089
AM
9373 if (ctx->nan2008) {
9374 gen_helper_float_ceil_2008_l_s(fp64, cpu_env, fp32);
9375 } else {
9376 gen_helper_float_ceil_l_s(fp64, cpu_env, fp32);
9377 }
a7812ae4 9378 tcg_temp_free_i32(fp32);
b6d96bed 9379 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 9380 tcg_temp_free_i64(fp64);
b6d96bed 9381 }
5a5012ec 9382 break;
bf4120ad 9383 case OPC_FLOOR_L_S:
5e755519 9384 check_cp1_64bitmode(ctx);
b6d96bed 9385 {
a7812ae4
PB
9386 TCGv_i32 fp32 = tcg_temp_new_i32();
9387 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 9388
7c979afd 9389 gen_load_fpr32(ctx, fp32, fs);
87552089
AM
9390 if (ctx->nan2008) {
9391 gen_helper_float_floor_2008_l_s(fp64, cpu_env, fp32);
9392 } else {
9393 gen_helper_float_floor_l_s(fp64, cpu_env, fp32);
9394 }
a7812ae4 9395 tcg_temp_free_i32(fp32);
b6d96bed 9396 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 9397 tcg_temp_free_i64(fp64);
b6d96bed 9398 }
5a5012ec 9399 break;
bf4120ad 9400 case OPC_ROUND_W_S:
b6d96bed 9401 {
a7812ae4 9402 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9403
7c979afd 9404 gen_load_fpr32(ctx, fp0, fs);
87552089
AM
9405 if (ctx->nan2008) {
9406 gen_helper_float_round_2008_w_s(fp0, cpu_env, fp0);
9407 } else {
9408 gen_helper_float_round_w_s(fp0, cpu_env, fp0);
9409 }
7c979afd 9410 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9411 tcg_temp_free_i32(fp0);
b6d96bed 9412 }
5a5012ec 9413 break;
bf4120ad 9414 case OPC_TRUNC_W_S:
b6d96bed 9415 {
a7812ae4 9416 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9417
7c979afd 9418 gen_load_fpr32(ctx, fp0, fs);
87552089
AM
9419 if (ctx->nan2008) {
9420 gen_helper_float_trunc_2008_w_s(fp0, cpu_env, fp0);
9421 } else {
9422 gen_helper_float_trunc_w_s(fp0, cpu_env, fp0);
9423 }
7c979afd 9424 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9425 tcg_temp_free_i32(fp0);
b6d96bed 9426 }
5a5012ec 9427 break;
bf4120ad 9428 case OPC_CEIL_W_S:
b6d96bed 9429 {
a7812ae4 9430 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9431
7c979afd 9432 gen_load_fpr32(ctx, fp0, fs);
87552089
AM
9433 if (ctx->nan2008) {
9434 gen_helper_float_ceil_2008_w_s(fp0, cpu_env, fp0);
9435 } else {
9436 gen_helper_float_ceil_w_s(fp0, cpu_env, fp0);
9437 }
7c979afd 9438 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9439 tcg_temp_free_i32(fp0);
b6d96bed 9440 }
5a5012ec 9441 break;
bf4120ad 9442 case OPC_FLOOR_W_S:
b6d96bed 9443 {
a7812ae4 9444 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9445
7c979afd 9446 gen_load_fpr32(ctx, fp0, fs);
87552089
AM
9447 if (ctx->nan2008) {
9448 gen_helper_float_floor_2008_w_s(fp0, cpu_env, fp0);
9449 } else {
9450 gen_helper_float_floor_w_s(fp0, cpu_env, fp0);
9451 }
7c979afd 9452 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9453 tcg_temp_free_i32(fp0);
b6d96bed 9454 }
5a5012ec 9455 break;
e7f16abb
LA
9456 case OPC_SEL_S:
9457 check_insn(ctx, ISA_MIPS32R6);
9458 gen_sel_s(ctx, op1, fd, ft, fs);
e7f16abb
LA
9459 break;
9460 case OPC_SELEQZ_S:
9461 check_insn(ctx, ISA_MIPS32R6);
9462 gen_sel_s(ctx, op1, fd, ft, fs);
e7f16abb
LA
9463 break;
9464 case OPC_SELNEZ_S:
9465 check_insn(ctx, ISA_MIPS32R6);
9466 gen_sel_s(ctx, op1, fd, ft, fs);
e7f16abb 9467 break;
bf4120ad 9468 case OPC_MOVCF_S:
fecd2646 9469 check_insn_opc_removed(ctx, ISA_MIPS32R6);
7c979afd 9470 gen_movcf_s(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
5a5012ec 9471 break;
bf4120ad 9472 case OPC_MOVZ_S:
fecd2646 9473 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a16336e4 9474 {
42a268c2 9475 TCGLabel *l1 = gen_new_label();
c9297f4d 9476 TCGv_i32 fp0;
a16336e4 9477
c9297f4d
AJ
9478 if (ft != 0) {
9479 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
9480 }
9481 fp0 = tcg_temp_new_i32();
7c979afd
LA
9482 gen_load_fpr32(ctx, fp0, fs);
9483 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9484 tcg_temp_free_i32(fp0);
a16336e4
TS
9485 gen_set_label(l1);
9486 }
5a5012ec 9487 break;
bf4120ad 9488 case OPC_MOVN_S:
fecd2646 9489 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a16336e4 9490 {
42a268c2 9491 TCGLabel *l1 = gen_new_label();
c9297f4d
AJ
9492 TCGv_i32 fp0;
9493
9494 if (ft != 0) {
9495 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
9496 fp0 = tcg_temp_new_i32();
7c979afd
LA
9497 gen_load_fpr32(ctx, fp0, fs);
9498 gen_store_fpr32(ctx, fp0, fd);
c9297f4d
AJ
9499 tcg_temp_free_i32(fp0);
9500 gen_set_label(l1);
9501 }
a16336e4 9502 }
5a5012ec 9503 break;
bf4120ad 9504 case OPC_RECIP_S:
b6d96bed 9505 {
a7812ae4 9506 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9507
7c979afd 9508 gen_load_fpr32(ctx, fp0, fs);
895c2d04 9509 gen_helper_float_recip_s(fp0, cpu_env, fp0);
7c979afd 9510 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9511 tcg_temp_free_i32(fp0);
b6d96bed 9512 }
57fa1fb3 9513 break;
bf4120ad 9514 case OPC_RSQRT_S:
b6d96bed 9515 {
a7812ae4 9516 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9517
7c979afd 9518 gen_load_fpr32(ctx, fp0, fs);
895c2d04 9519 gen_helper_float_rsqrt_s(fp0, cpu_env, fp0);
7c979afd 9520 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9521 tcg_temp_free_i32(fp0);
b6d96bed 9522 }
57fa1fb3 9523 break;
e7f16abb
LA
9524 case OPC_MADDF_S:
9525 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 9526 {
a7812ae4
PB
9527 TCGv_i32 fp0 = tcg_temp_new_i32();
9528 TCGv_i32 fp1 = tcg_temp_new_i32();
e7f16abb 9529 TCGv_i32 fp2 = tcg_temp_new_i32();
7c979afd
LA
9530 gen_load_fpr32(ctx, fp0, fs);
9531 gen_load_fpr32(ctx, fp1, ft);
9532 gen_load_fpr32(ctx, fp2, fd);
e7f16abb 9533 gen_helper_float_maddf_s(fp2, cpu_env, fp0, fp1, fp2);
7c979afd 9534 gen_store_fpr32(ctx, fp2, fd);
e7f16abb 9535 tcg_temp_free_i32(fp2);
a7812ae4 9536 tcg_temp_free_i32(fp1);
a7812ae4 9537 tcg_temp_free_i32(fp0);
b6d96bed 9538 }
57fa1fb3 9539 break;
e7f16abb
LA
9540 case OPC_MSUBF_S:
9541 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 9542 {
a7812ae4 9543 TCGv_i32 fp0 = tcg_temp_new_i32();
e7f16abb
LA
9544 TCGv_i32 fp1 = tcg_temp_new_i32();
9545 TCGv_i32 fp2 = tcg_temp_new_i32();
7c979afd
LA
9546 gen_load_fpr32(ctx, fp0, fs);
9547 gen_load_fpr32(ctx, fp1, ft);
9548 gen_load_fpr32(ctx, fp2, fd);
e7f16abb 9549 gen_helper_float_msubf_s(fp2, cpu_env, fp0, fp1, fp2);
7c979afd 9550 gen_store_fpr32(ctx, fp2, fd);
e7f16abb
LA
9551 tcg_temp_free_i32(fp2);
9552 tcg_temp_free_i32(fp1);
a7812ae4 9553 tcg_temp_free_i32(fp0);
b6d96bed 9554 }
57fa1fb3 9555 break;
e7f16abb
LA
9556 case OPC_RINT_S:
9557 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 9558 {
a7812ae4 9559 TCGv_i32 fp0 = tcg_temp_new_i32();
7c979afd 9560 gen_load_fpr32(ctx, fp0, fs);
e7f16abb 9561 gen_helper_float_rint_s(fp0, cpu_env, fp0);
7c979afd 9562 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9563 tcg_temp_free_i32(fp0);
b6d96bed 9564 }
57fa1fb3 9565 break;
e7f16abb
LA
9566 case OPC_CLASS_S:
9567 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 9568 {
e7f16abb 9569 TCGv_i32 fp0 = tcg_temp_new_i32();
7c979afd 9570 gen_load_fpr32(ctx, fp0, fs);
af39bc8c 9571 gen_helper_float_class_s(fp0, cpu_env, fp0);
7c979afd 9572 gen_store_fpr32(ctx, fp0, fd);
e7f16abb 9573 tcg_temp_free_i32(fp0);
e7f16abb
LA
9574 }
9575 break;
9576 case OPC_MIN_S: /* OPC_RECIP2_S */
9577 if (ctx->insn_flags & ISA_MIPS32R6) {
9578 /* OPC_MIN_S */
a7812ae4
PB
9579 TCGv_i32 fp0 = tcg_temp_new_i32();
9580 TCGv_i32 fp1 = tcg_temp_new_i32();
e7f16abb 9581 TCGv_i32 fp2 = tcg_temp_new_i32();
7c979afd
LA
9582 gen_load_fpr32(ctx, fp0, fs);
9583 gen_load_fpr32(ctx, fp1, ft);
e7f16abb 9584 gen_helper_float_min_s(fp2, cpu_env, fp0, fp1);
7c979afd 9585 gen_store_fpr32(ctx, fp2, fd);
e7f16abb
LA
9586 tcg_temp_free_i32(fp2);
9587 tcg_temp_free_i32(fp1);
9588 tcg_temp_free_i32(fp0);
e7f16abb
LA
9589 } else {
9590 /* OPC_RECIP2_S */
9591 check_cp1_64bitmode(ctx);
9592 {
9593 TCGv_i32 fp0 = tcg_temp_new_i32();
9594 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 9595
7c979afd
LA
9596 gen_load_fpr32(ctx, fp0, fs);
9597 gen_load_fpr32(ctx, fp1, ft);
e7f16abb
LA
9598 gen_helper_float_recip2_s(fp0, cpu_env, fp0, fp1);
9599 tcg_temp_free_i32(fp1);
7c979afd 9600 gen_store_fpr32(ctx, fp0, fd);
e7f16abb
LA
9601 tcg_temp_free_i32(fp0);
9602 }
e7f16abb
LA
9603 }
9604 break;
9605 case OPC_MINA_S: /* OPC_RECIP1_S */
9606 if (ctx->insn_flags & ISA_MIPS32R6) {
9607 /* OPC_MINA_S */
9608 TCGv_i32 fp0 = tcg_temp_new_i32();
9609 TCGv_i32 fp1 = tcg_temp_new_i32();
9610 TCGv_i32 fp2 = tcg_temp_new_i32();
7c979afd
LA
9611 gen_load_fpr32(ctx, fp0, fs);
9612 gen_load_fpr32(ctx, fp1, ft);
e7f16abb 9613 gen_helper_float_mina_s(fp2, cpu_env, fp0, fp1);
7c979afd 9614 gen_store_fpr32(ctx, fp2, fd);
e7f16abb
LA
9615 tcg_temp_free_i32(fp2);
9616 tcg_temp_free_i32(fp1);
9617 tcg_temp_free_i32(fp0);
e7f16abb
LA
9618 } else {
9619 /* OPC_RECIP1_S */
9620 check_cp1_64bitmode(ctx);
9621 {
9622 TCGv_i32 fp0 = tcg_temp_new_i32();
9623
7c979afd 9624 gen_load_fpr32(ctx, fp0, fs);
e7f16abb 9625 gen_helper_float_recip1_s(fp0, cpu_env, fp0);
7c979afd 9626 gen_store_fpr32(ctx, fp0, fd);
e7f16abb
LA
9627 tcg_temp_free_i32(fp0);
9628 }
e7f16abb
LA
9629 }
9630 break;
9631 case OPC_MAX_S: /* OPC_RSQRT1_S */
9632 if (ctx->insn_flags & ISA_MIPS32R6) {
9633 /* OPC_MAX_S */
9634 TCGv_i32 fp0 = tcg_temp_new_i32();
9635 TCGv_i32 fp1 = tcg_temp_new_i32();
7c979afd
LA
9636 gen_load_fpr32(ctx, fp0, fs);
9637 gen_load_fpr32(ctx, fp1, ft);
e7f16abb 9638 gen_helper_float_max_s(fp1, cpu_env, fp0, fp1);
7c979afd 9639 gen_store_fpr32(ctx, fp1, fd);
e7f16abb
LA
9640 tcg_temp_free_i32(fp1);
9641 tcg_temp_free_i32(fp0);
e7f16abb
LA
9642 } else {
9643 /* OPC_RSQRT1_S */
9644 check_cp1_64bitmode(ctx);
9645 {
9646 TCGv_i32 fp0 = tcg_temp_new_i32();
9647
7c979afd 9648 gen_load_fpr32(ctx, fp0, fs);
e7f16abb 9649 gen_helper_float_rsqrt1_s(fp0, cpu_env, fp0);
7c979afd 9650 gen_store_fpr32(ctx, fp0, fd);
e7f16abb
LA
9651 tcg_temp_free_i32(fp0);
9652 }
e7f16abb
LA
9653 }
9654 break;
9655 case OPC_MAXA_S: /* OPC_RSQRT2_S */
9656 if (ctx->insn_flags & ISA_MIPS32R6) {
9657 /* OPC_MAXA_S */
9658 TCGv_i32 fp0 = tcg_temp_new_i32();
9659 TCGv_i32 fp1 = tcg_temp_new_i32();
7c979afd
LA
9660 gen_load_fpr32(ctx, fp0, fs);
9661 gen_load_fpr32(ctx, fp1, ft);
e7f16abb 9662 gen_helper_float_maxa_s(fp1, cpu_env, fp0, fp1);
7c979afd 9663 gen_store_fpr32(ctx, fp1, fd);
a7812ae4 9664 tcg_temp_free_i32(fp1);
a7812ae4 9665 tcg_temp_free_i32(fp0);
e7f16abb
LA
9666 } else {
9667 /* OPC_RSQRT2_S */
9668 check_cp1_64bitmode(ctx);
9669 {
9670 TCGv_i32 fp0 = tcg_temp_new_i32();
9671 TCGv_i32 fp1 = tcg_temp_new_i32();
9672
7c979afd
LA
9673 gen_load_fpr32(ctx, fp0, fs);
9674 gen_load_fpr32(ctx, fp1, ft);
e7f16abb
LA
9675 gen_helper_float_rsqrt2_s(fp0, cpu_env, fp0, fp1);
9676 tcg_temp_free_i32(fp1);
7c979afd 9677 gen_store_fpr32(ctx, fp0, fd);
e7f16abb
LA
9678 tcg_temp_free_i32(fp0);
9679 }
b6d96bed 9680 }
57fa1fb3 9681 break;
bf4120ad 9682 case OPC_CVT_D_S:
5e755519 9683 check_cp1_registers(ctx, fd);
b6d96bed 9684 {
a7812ae4
PB
9685 TCGv_i32 fp32 = tcg_temp_new_i32();
9686 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 9687
7c979afd 9688 gen_load_fpr32(ctx, fp32, fs);
895c2d04 9689 gen_helper_float_cvtd_s(fp64, cpu_env, fp32);
a7812ae4 9690 tcg_temp_free_i32(fp32);
b6d96bed 9691 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 9692 tcg_temp_free_i64(fp64);
b6d96bed 9693 }
5a5012ec 9694 break;
bf4120ad 9695 case OPC_CVT_W_S:
b6d96bed 9696 {
a7812ae4 9697 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9698
7c979afd 9699 gen_load_fpr32(ctx, fp0, fs);
87552089
AM
9700 if (ctx->nan2008) {
9701 gen_helper_float_cvt_2008_w_s(fp0, cpu_env, fp0);
9702 } else {
9703 gen_helper_float_cvt_w_s(fp0, cpu_env, fp0);
9704 }
7c979afd 9705 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9706 tcg_temp_free_i32(fp0);
b6d96bed 9707 }
5a5012ec 9708 break;
bf4120ad 9709 case OPC_CVT_L_S:
5e755519 9710 check_cp1_64bitmode(ctx);
b6d96bed 9711 {
a7812ae4
PB
9712 TCGv_i32 fp32 = tcg_temp_new_i32();
9713 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 9714
7c979afd 9715 gen_load_fpr32(ctx, fp32, fs);
87552089
AM
9716 if (ctx->nan2008) {
9717 gen_helper_float_cvt_2008_l_s(fp64, cpu_env, fp32);
9718 } else {
9719 gen_helper_float_cvt_l_s(fp64, cpu_env, fp32);
9720 }
a7812ae4 9721 tcg_temp_free_i32(fp32);
b6d96bed 9722 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 9723 tcg_temp_free_i64(fp64);
b6d96bed 9724 }
5a5012ec 9725 break;
bf4120ad 9726 case OPC_CVT_PS_S:
e29c9628 9727 check_ps(ctx);
b6d96bed 9728 {
a7812ae4
PB
9729 TCGv_i64 fp64 = tcg_temp_new_i64();
9730 TCGv_i32 fp32_0 = tcg_temp_new_i32();
9731 TCGv_i32 fp32_1 = tcg_temp_new_i32();
b6d96bed 9732
7c979afd
LA
9733 gen_load_fpr32(ctx, fp32_0, fs);
9734 gen_load_fpr32(ctx, fp32_1, ft);
13d24f49 9735 tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0);
a7812ae4
PB
9736 tcg_temp_free_i32(fp32_1);
9737 tcg_temp_free_i32(fp32_0);
36aa55dc 9738 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 9739 tcg_temp_free_i64(fp64);
b6d96bed 9740 }
5a5012ec 9741 break;
bf4120ad
NF
9742 case OPC_CMP_F_S:
9743 case OPC_CMP_UN_S:
9744 case OPC_CMP_EQ_S:
9745 case OPC_CMP_UEQ_S:
9746 case OPC_CMP_OLT_S:
9747 case OPC_CMP_ULT_S:
9748 case OPC_CMP_OLE_S:
9749 case OPC_CMP_ULE_S:
9750 case OPC_CMP_SF_S:
9751 case OPC_CMP_NGLE_S:
9752 case OPC_CMP_SEQ_S:
9753 case OPC_CMP_NGL_S:
9754 case OPC_CMP_LT_S:
9755 case OPC_CMP_NGE_S:
9756 case OPC_CMP_LE_S:
9757 case OPC_CMP_NGT_S:
fecd2646 9758 check_insn_opc_removed(ctx, ISA_MIPS32R6);
8153667c
NF
9759 if (ctx->opcode & (1 << 6)) {
9760 gen_cmpabs_s(ctx, func-48, ft, fs, cc);
8153667c
NF
9761 } else {
9762 gen_cmp_s(ctx, func-48, ft, fs, cc);
5a1e8ffb 9763 }
5a5012ec 9764 break;
bf4120ad 9765 case OPC_ADD_D:
5e755519 9766 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 9767 {
a7812ae4
PB
9768 TCGv_i64 fp0 = tcg_temp_new_i64();
9769 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9770
9771 gen_load_fpr64(ctx, fp0, fs);
9772 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9773 gen_helper_float_add_d(fp0, cpu_env, fp0, fp1);
a7812ae4 9774 tcg_temp_free_i64(fp1);
b6d96bed 9775 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9776 tcg_temp_free_i64(fp0);
b6d96bed 9777 }
6ea83fed 9778 break;
bf4120ad 9779 case OPC_SUB_D:
5e755519 9780 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 9781 {
a7812ae4
PB
9782 TCGv_i64 fp0 = tcg_temp_new_i64();
9783 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9784
9785 gen_load_fpr64(ctx, fp0, fs);
9786 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9787 gen_helper_float_sub_d(fp0, cpu_env, fp0, fp1);
a7812ae4 9788 tcg_temp_free_i64(fp1);
b6d96bed 9789 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9790 tcg_temp_free_i64(fp0);
b6d96bed 9791 }
6ea83fed 9792 break;
bf4120ad 9793 case OPC_MUL_D:
5e755519 9794 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 9795 {
a7812ae4
PB
9796 TCGv_i64 fp0 = tcg_temp_new_i64();
9797 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9798
9799 gen_load_fpr64(ctx, fp0, fs);
9800 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9801 gen_helper_float_mul_d(fp0, cpu_env, fp0, fp1);
a7812ae4 9802 tcg_temp_free_i64(fp1);
b6d96bed 9803 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9804 tcg_temp_free_i64(fp0);
b6d96bed 9805 }
6ea83fed 9806 break;
bf4120ad 9807 case OPC_DIV_D:
5e755519 9808 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 9809 {
a7812ae4
PB
9810 TCGv_i64 fp0 = tcg_temp_new_i64();
9811 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9812
9813 gen_load_fpr64(ctx, fp0, fs);
9814 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9815 gen_helper_float_div_d(fp0, cpu_env, fp0, fp1);
a7812ae4 9816 tcg_temp_free_i64(fp1);
b6d96bed 9817 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9818 tcg_temp_free_i64(fp0);
b6d96bed 9819 }
6ea83fed 9820 break;
bf4120ad 9821 case OPC_SQRT_D:
5e755519 9822 check_cp1_registers(ctx, fs | fd);
b6d96bed 9823 {
a7812ae4 9824 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9825
9826 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9827 gen_helper_float_sqrt_d(fp0, cpu_env, fp0);
b6d96bed 9828 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9829 tcg_temp_free_i64(fp0);
b6d96bed 9830 }
6ea83fed 9831 break;
bf4120ad 9832 case OPC_ABS_D:
5e755519 9833 check_cp1_registers(ctx, fs | fd);
b6d96bed 9834 {
a7812ae4 9835 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9836
9837 gen_load_fpr64(ctx, fp0, fs);
6be77480
AM
9838 if (ctx->abs2008) {
9839 tcg_gen_andi_i64(fp0, fp0, 0x7fffffffffffffffULL);
9840 } else {
9841 gen_helper_float_abs_d(fp0, fp0);
9842 }
b6d96bed 9843 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9844 tcg_temp_free_i64(fp0);
b6d96bed 9845 }
6ea83fed 9846 break;
bf4120ad 9847 case OPC_MOV_D:
5e755519 9848 check_cp1_registers(ctx, fs | fd);
b6d96bed 9849 {
a7812ae4 9850 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9851
9852 gen_load_fpr64(ctx, fp0, fs);
9853 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9854 tcg_temp_free_i64(fp0);
b6d96bed 9855 }
6ea83fed 9856 break;
bf4120ad 9857 case OPC_NEG_D:
5e755519 9858 check_cp1_registers(ctx, fs | fd);
b6d96bed 9859 {
a7812ae4 9860 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9861
9862 gen_load_fpr64(ctx, fp0, fs);
6be77480
AM
9863 if (ctx->abs2008) {
9864 tcg_gen_xori_i64(fp0, fp0, 1ULL << 63);
9865 } else {
9866 gen_helper_float_chs_d(fp0, fp0);
9867 }
b6d96bed 9868 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9869 tcg_temp_free_i64(fp0);
b6d96bed 9870 }
6ea83fed 9871 break;
bf4120ad 9872 case OPC_ROUND_L_D:
5e755519 9873 check_cp1_64bitmode(ctx);
b6d96bed 9874 {
a7812ae4 9875 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9876
9877 gen_load_fpr64(ctx, fp0, fs);
87552089
AM
9878 if (ctx->nan2008) {
9879 gen_helper_float_round_2008_l_d(fp0, cpu_env, fp0);
9880 } else {
9881 gen_helper_float_round_l_d(fp0, cpu_env, fp0);
9882 }
b6d96bed 9883 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9884 tcg_temp_free_i64(fp0);
b6d96bed 9885 }
5a5012ec 9886 break;
bf4120ad 9887 case OPC_TRUNC_L_D:
5e755519 9888 check_cp1_64bitmode(ctx);
b6d96bed 9889 {
a7812ae4 9890 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9891
9892 gen_load_fpr64(ctx, fp0, fs);
87552089
AM
9893 if (ctx->nan2008) {
9894 gen_helper_float_trunc_2008_l_d(fp0, cpu_env, fp0);
9895 } else {
9896 gen_helper_float_trunc_l_d(fp0, cpu_env, fp0);
9897 }
b6d96bed 9898 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9899 tcg_temp_free_i64(fp0);
b6d96bed 9900 }
5a5012ec 9901 break;
bf4120ad 9902 case OPC_CEIL_L_D:
5e755519 9903 check_cp1_64bitmode(ctx);
b6d96bed 9904 {
a7812ae4 9905 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9906
9907 gen_load_fpr64(ctx, fp0, fs);
87552089
AM
9908 if (ctx->nan2008) {
9909 gen_helper_float_ceil_2008_l_d(fp0, cpu_env, fp0);
9910 } else {
9911 gen_helper_float_ceil_l_d(fp0, cpu_env, fp0);
9912 }
b6d96bed 9913 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9914 tcg_temp_free_i64(fp0);
b6d96bed 9915 }
5a5012ec 9916 break;
bf4120ad 9917 case OPC_FLOOR_L_D:
5e755519 9918 check_cp1_64bitmode(ctx);
b6d96bed 9919 {
a7812ae4 9920 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9921
9922 gen_load_fpr64(ctx, fp0, fs);
87552089
AM
9923 if (ctx->nan2008) {
9924 gen_helper_float_floor_2008_l_d(fp0, cpu_env, fp0);
9925 } else {
9926 gen_helper_float_floor_l_d(fp0, cpu_env, fp0);
9927 }
b6d96bed 9928 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9929 tcg_temp_free_i64(fp0);
b6d96bed 9930 }
5a5012ec 9931 break;
bf4120ad 9932 case OPC_ROUND_W_D:
5e755519 9933 check_cp1_registers(ctx, fs);
b6d96bed 9934 {
a7812ae4
PB
9935 TCGv_i32 fp32 = tcg_temp_new_i32();
9936 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
9937
9938 gen_load_fpr64(ctx, fp64, fs);
87552089
AM
9939 if (ctx->nan2008) {
9940 gen_helper_float_round_2008_w_d(fp32, cpu_env, fp64);
9941 } else {
9942 gen_helper_float_round_w_d(fp32, cpu_env, fp64);
9943 }
a7812ae4 9944 tcg_temp_free_i64(fp64);
7c979afd 9945 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 9946 tcg_temp_free_i32(fp32);
b6d96bed 9947 }
6ea83fed 9948 break;
bf4120ad 9949 case OPC_TRUNC_W_D:
5e755519 9950 check_cp1_registers(ctx, fs);
b6d96bed 9951 {
a7812ae4
PB
9952 TCGv_i32 fp32 = tcg_temp_new_i32();
9953 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
9954
9955 gen_load_fpr64(ctx, fp64, fs);
87552089
AM
9956 if (ctx->nan2008) {
9957 gen_helper_float_trunc_2008_w_d(fp32, cpu_env, fp64);
9958 } else {
9959 gen_helper_float_trunc_w_d(fp32, cpu_env, fp64);
9960 }
a7812ae4 9961 tcg_temp_free_i64(fp64);
7c979afd 9962 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 9963 tcg_temp_free_i32(fp32);
b6d96bed 9964 }
6ea83fed 9965 break;
bf4120ad 9966 case OPC_CEIL_W_D:
5e755519 9967 check_cp1_registers(ctx, fs);
b6d96bed 9968 {
a7812ae4
PB
9969 TCGv_i32 fp32 = tcg_temp_new_i32();
9970 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
9971
9972 gen_load_fpr64(ctx, fp64, fs);
87552089
AM
9973 if (ctx->nan2008) {
9974 gen_helper_float_ceil_2008_w_d(fp32, cpu_env, fp64);
9975 } else {
9976 gen_helper_float_ceil_w_d(fp32, cpu_env, fp64);
9977 }
a7812ae4 9978 tcg_temp_free_i64(fp64);
7c979afd 9979 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 9980 tcg_temp_free_i32(fp32);
b6d96bed 9981 }
6ea83fed 9982 break;
bf4120ad 9983 case OPC_FLOOR_W_D:
5e755519 9984 check_cp1_registers(ctx, fs);
b6d96bed 9985 {
a7812ae4
PB
9986 TCGv_i32 fp32 = tcg_temp_new_i32();
9987 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
9988
9989 gen_load_fpr64(ctx, fp64, fs);
87552089
AM
9990 if (ctx->nan2008) {
9991 gen_helper_float_floor_2008_w_d(fp32, cpu_env, fp64);
9992 } else {
9993 gen_helper_float_floor_w_d(fp32, cpu_env, fp64);
9994 }
a7812ae4 9995 tcg_temp_free_i64(fp64);
7c979afd 9996 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 9997 tcg_temp_free_i32(fp32);
b6d96bed 9998 }
6ea83fed 9999 break;
e7f16abb
LA
10000 case OPC_SEL_D:
10001 check_insn(ctx, ISA_MIPS32R6);
10002 gen_sel_d(ctx, op1, fd, ft, fs);
e7f16abb
LA
10003 break;
10004 case OPC_SELEQZ_D:
10005 check_insn(ctx, ISA_MIPS32R6);
10006 gen_sel_d(ctx, op1, fd, ft, fs);
e7f16abb
LA
10007 break;
10008 case OPC_SELNEZ_D:
10009 check_insn(ctx, ISA_MIPS32R6);
10010 gen_sel_d(ctx, op1, fd, ft, fs);
e7f16abb 10011 break;
bf4120ad 10012 case OPC_MOVCF_D:
fecd2646 10013 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b6d96bed 10014 gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
dd016883 10015 break;
bf4120ad 10016 case OPC_MOVZ_D:
fecd2646 10017 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a16336e4 10018 {
42a268c2 10019 TCGLabel *l1 = gen_new_label();
c9297f4d 10020 TCGv_i64 fp0;
a16336e4 10021
c9297f4d
AJ
10022 if (ft != 0) {
10023 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
10024 }
10025 fp0 = tcg_temp_new_i64();
b6d96bed
TS
10026 gen_load_fpr64(ctx, fp0, fs);
10027 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10028 tcg_temp_free_i64(fp0);
a16336e4
TS
10029 gen_set_label(l1);
10030 }
5a5012ec 10031 break;
bf4120ad 10032 case OPC_MOVN_D:
fecd2646 10033 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a16336e4 10034 {
42a268c2 10035 TCGLabel *l1 = gen_new_label();
c9297f4d
AJ
10036 TCGv_i64 fp0;
10037
10038 if (ft != 0) {
10039 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
10040 fp0 = tcg_temp_new_i64();
10041 gen_load_fpr64(ctx, fp0, fs);
10042 gen_store_fpr64(ctx, fp0, fd);
10043 tcg_temp_free_i64(fp0);
10044 gen_set_label(l1);
10045 }
a16336e4 10046 }
6ea83fed 10047 break;
bf4120ad 10048 case OPC_RECIP_D:
ca6c7803 10049 check_cp1_registers(ctx, fs | fd);
b6d96bed 10050 {
a7812ae4 10051 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
10052
10053 gen_load_fpr64(ctx, fp0, fs);
895c2d04 10054 gen_helper_float_recip_d(fp0, cpu_env, fp0);
b6d96bed 10055 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10056 tcg_temp_free_i64(fp0);
b6d96bed 10057 }
57fa1fb3 10058 break;
bf4120ad 10059 case OPC_RSQRT_D:
ca6c7803 10060 check_cp1_registers(ctx, fs | fd);
b6d96bed 10061 {
a7812ae4 10062 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
10063
10064 gen_load_fpr64(ctx, fp0, fs);
895c2d04 10065 gen_helper_float_rsqrt_d(fp0, cpu_env, fp0);
b6d96bed 10066 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10067 tcg_temp_free_i64(fp0);
b6d96bed 10068 }
57fa1fb3 10069 break;
e7f16abb
LA
10070 case OPC_MADDF_D:
10071 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 10072 {
a7812ae4
PB
10073 TCGv_i64 fp0 = tcg_temp_new_i64();
10074 TCGv_i64 fp1 = tcg_temp_new_i64();
e7f16abb 10075 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10076 gen_load_fpr64(ctx, fp0, fs);
10077 gen_load_fpr64(ctx, fp1, ft);
e7f16abb
LA
10078 gen_load_fpr64(ctx, fp2, fd);
10079 gen_helper_float_maddf_d(fp2, cpu_env, fp0, fp1, fp2);
10080 gen_store_fpr64(ctx, fp2, fd);
10081 tcg_temp_free_i64(fp2);
a7812ae4 10082 tcg_temp_free_i64(fp1);
a7812ae4 10083 tcg_temp_free_i64(fp0);
b6d96bed 10084 }
57fa1fb3 10085 break;
e7f16abb
LA
10086 case OPC_MSUBF_D:
10087 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 10088 {
a7812ae4 10089 TCGv_i64 fp0 = tcg_temp_new_i64();
e7f16abb
LA
10090 TCGv_i64 fp1 = tcg_temp_new_i64();
10091 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed 10092 gen_load_fpr64(ctx, fp0, fs);
e7f16abb
LA
10093 gen_load_fpr64(ctx, fp1, ft);
10094 gen_load_fpr64(ctx, fp2, fd);
10095 gen_helper_float_msubf_d(fp2, cpu_env, fp0, fp1, fp2);
10096 gen_store_fpr64(ctx, fp2, fd);
10097 tcg_temp_free_i64(fp2);
10098 tcg_temp_free_i64(fp1);
a7812ae4 10099 tcg_temp_free_i64(fp0);
b6d96bed 10100 }
57fa1fb3 10101 break;
e7f16abb
LA
10102 case OPC_RINT_D:
10103 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 10104 {
a7812ae4 10105 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 10106 gen_load_fpr64(ctx, fp0, fs);
e7f16abb 10107 gen_helper_float_rint_d(fp0, cpu_env, fp0);
b6d96bed 10108 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10109 tcg_temp_free_i64(fp0);
b6d96bed 10110 }
57fa1fb3 10111 break;
e7f16abb
LA
10112 case OPC_CLASS_D:
10113 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 10114 {
e7f16abb
LA
10115 TCGv_i64 fp0 = tcg_temp_new_i64();
10116 gen_load_fpr64(ctx, fp0, fs);
af39bc8c 10117 gen_helper_float_class_d(fp0, cpu_env, fp0);
e7f16abb
LA
10118 gen_store_fpr64(ctx, fp0, fd);
10119 tcg_temp_free_i64(fp0);
e7f16abb
LA
10120 }
10121 break;
10122 case OPC_MIN_D: /* OPC_RECIP2_D */
10123 if (ctx->insn_flags & ISA_MIPS32R6) {
10124 /* OPC_MIN_D */
a7812ae4
PB
10125 TCGv_i64 fp0 = tcg_temp_new_i64();
10126 TCGv_i64 fp1 = tcg_temp_new_i64();
e7f16abb
LA
10127 gen_load_fpr64(ctx, fp0, fs);
10128 gen_load_fpr64(ctx, fp1, ft);
10129 gen_helper_float_min_d(fp1, cpu_env, fp0, fp1);
10130 gen_store_fpr64(ctx, fp1, fd);
10131 tcg_temp_free_i64(fp1);
10132 tcg_temp_free_i64(fp0);
e7f16abb
LA
10133 } else {
10134 /* OPC_RECIP2_D */
10135 check_cp1_64bitmode(ctx);
10136 {
10137 TCGv_i64 fp0 = tcg_temp_new_i64();
10138 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed 10139
e7f16abb
LA
10140 gen_load_fpr64(ctx, fp0, fs);
10141 gen_load_fpr64(ctx, fp1, ft);
10142 gen_helper_float_recip2_d(fp0, cpu_env, fp0, fp1);
10143 tcg_temp_free_i64(fp1);
10144 gen_store_fpr64(ctx, fp0, fd);
10145 tcg_temp_free_i64(fp0);
10146 }
e7f16abb
LA
10147 }
10148 break;
10149 case OPC_MINA_D: /* OPC_RECIP1_D */
10150 if (ctx->insn_flags & ISA_MIPS32R6) {
10151 /* OPC_MINA_D */
10152 TCGv_i64 fp0 = tcg_temp_new_i64();
10153 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
10154 gen_load_fpr64(ctx, fp0, fs);
10155 gen_load_fpr64(ctx, fp1, ft);
e7f16abb
LA
10156 gen_helper_float_mina_d(fp1, cpu_env, fp0, fp1);
10157 gen_store_fpr64(ctx, fp1, fd);
10158 tcg_temp_free_i64(fp1);
10159 tcg_temp_free_i64(fp0);
e7f16abb
LA
10160 } else {
10161 /* OPC_RECIP1_D */
10162 check_cp1_64bitmode(ctx);
10163 {
10164 TCGv_i64 fp0 = tcg_temp_new_i64();
10165
10166 gen_load_fpr64(ctx, fp0, fs);
10167 gen_helper_float_recip1_d(fp0, cpu_env, fp0);
10168 gen_store_fpr64(ctx, fp0, fd);
10169 tcg_temp_free_i64(fp0);
10170 }
e7f16abb
LA
10171 }
10172 break;
10173 case OPC_MAX_D: /* OPC_RSQRT1_D */
10174 if (ctx->insn_flags & ISA_MIPS32R6) {
10175 /* OPC_MAX_D */
10176 TCGv_i64 fp0 = tcg_temp_new_i64();
10177 TCGv_i64 fp1 = tcg_temp_new_i64();
10178 gen_load_fpr64(ctx, fp0, fs);
10179 gen_load_fpr64(ctx, fp1, ft);
10180 gen_helper_float_max_d(fp1, cpu_env, fp0, fp1);
10181 gen_store_fpr64(ctx, fp1, fd);
a7812ae4 10182 tcg_temp_free_i64(fp1);
a7812ae4 10183 tcg_temp_free_i64(fp0);
e7f16abb
LA
10184 } else {
10185 /* OPC_RSQRT1_D */
10186 check_cp1_64bitmode(ctx);
10187 {
10188 TCGv_i64 fp0 = tcg_temp_new_i64();
10189
10190 gen_load_fpr64(ctx, fp0, fs);
10191 gen_helper_float_rsqrt1_d(fp0, cpu_env, fp0);
10192 gen_store_fpr64(ctx, fp0, fd);
10193 tcg_temp_free_i64(fp0);
10194 }
e7f16abb
LA
10195 }
10196 break;
10197 case OPC_MAXA_D: /* OPC_RSQRT2_D */
10198 if (ctx->insn_flags & ISA_MIPS32R6) {
10199 /* OPC_MAXA_D */
10200 TCGv_i64 fp0 = tcg_temp_new_i64();
10201 TCGv_i64 fp1 = tcg_temp_new_i64();
10202 gen_load_fpr64(ctx, fp0, fs);
10203 gen_load_fpr64(ctx, fp1, ft);
10204 gen_helper_float_maxa_d(fp1, cpu_env, fp0, fp1);
10205 gen_store_fpr64(ctx, fp1, fd);
10206 tcg_temp_free_i64(fp1);
10207 tcg_temp_free_i64(fp0);
e7f16abb
LA
10208 } else {
10209 /* OPC_RSQRT2_D */
10210 check_cp1_64bitmode(ctx);
10211 {
10212 TCGv_i64 fp0 = tcg_temp_new_i64();
10213 TCGv_i64 fp1 = tcg_temp_new_i64();
10214
10215 gen_load_fpr64(ctx, fp0, fs);
10216 gen_load_fpr64(ctx, fp1, ft);
10217 gen_helper_float_rsqrt2_d(fp0, cpu_env, fp0, fp1);
10218 tcg_temp_free_i64(fp1);
10219 gen_store_fpr64(ctx, fp0, fd);
10220 tcg_temp_free_i64(fp0);
10221 }
b6d96bed 10222 }
57fa1fb3 10223 break;
bf4120ad
NF
10224 case OPC_CMP_F_D:
10225 case OPC_CMP_UN_D:
10226 case OPC_CMP_EQ_D:
10227 case OPC_CMP_UEQ_D:
10228 case OPC_CMP_OLT_D:
10229 case OPC_CMP_ULT_D:
10230 case OPC_CMP_OLE_D:
10231 case OPC_CMP_ULE_D:
10232 case OPC_CMP_SF_D:
10233 case OPC_CMP_NGLE_D:
10234 case OPC_CMP_SEQ_D:
10235 case OPC_CMP_NGL_D:
10236 case OPC_CMP_LT_D:
10237 case OPC_CMP_NGE_D:
10238 case OPC_CMP_LE_D:
10239 case OPC_CMP_NGT_D:
fecd2646 10240 check_insn_opc_removed(ctx, ISA_MIPS32R6);
8153667c
NF
10241 if (ctx->opcode & (1 << 6)) {
10242 gen_cmpabs_d(ctx, func-48, ft, fs, cc);
8153667c
NF
10243 } else {
10244 gen_cmp_d(ctx, func-48, ft, fs, cc);
5a1e8ffb 10245 }
6ea83fed 10246 break;
bf4120ad 10247 case OPC_CVT_S_D:
5e755519 10248 check_cp1_registers(ctx, fs);
b6d96bed 10249 {
a7812ae4
PB
10250 TCGv_i32 fp32 = tcg_temp_new_i32();
10251 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
10252
10253 gen_load_fpr64(ctx, fp64, fs);
895c2d04 10254 gen_helper_float_cvts_d(fp32, cpu_env, fp64);
a7812ae4 10255 tcg_temp_free_i64(fp64);
7c979afd 10256 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 10257 tcg_temp_free_i32(fp32);
b6d96bed 10258 }
5a5012ec 10259 break;
bf4120ad 10260 case OPC_CVT_W_D:
5e755519 10261 check_cp1_registers(ctx, fs);
b6d96bed 10262 {
a7812ae4
PB
10263 TCGv_i32 fp32 = tcg_temp_new_i32();
10264 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
10265
10266 gen_load_fpr64(ctx, fp64, fs);
87552089
AM
10267 if (ctx->nan2008) {
10268 gen_helper_float_cvt_2008_w_d(fp32, cpu_env, fp64);
10269 } else {
10270 gen_helper_float_cvt_w_d(fp32, cpu_env, fp64);
10271 }
a7812ae4 10272 tcg_temp_free_i64(fp64);
7c979afd 10273 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 10274 tcg_temp_free_i32(fp32);
b6d96bed 10275 }
5a5012ec 10276 break;
bf4120ad 10277 case OPC_CVT_L_D:
5e755519 10278 check_cp1_64bitmode(ctx);
b6d96bed 10279 {
a7812ae4 10280 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
10281
10282 gen_load_fpr64(ctx, fp0, fs);
87552089
AM
10283 if (ctx->nan2008) {
10284 gen_helper_float_cvt_2008_l_d(fp0, cpu_env, fp0);
10285 } else {
10286 gen_helper_float_cvt_l_d(fp0, cpu_env, fp0);
10287 }
b6d96bed 10288 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10289 tcg_temp_free_i64(fp0);
b6d96bed 10290 }
5a5012ec 10291 break;
bf4120ad 10292 case OPC_CVT_S_W:
b6d96bed 10293 {
a7812ae4 10294 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 10295
7c979afd 10296 gen_load_fpr32(ctx, fp0, fs);
895c2d04 10297 gen_helper_float_cvts_w(fp0, cpu_env, fp0);
7c979afd 10298 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 10299 tcg_temp_free_i32(fp0);
b6d96bed 10300 }
6ea83fed 10301 break;
bf4120ad 10302 case OPC_CVT_D_W:
5e755519 10303 check_cp1_registers(ctx, fd);
b6d96bed 10304 {
a7812ae4
PB
10305 TCGv_i32 fp32 = tcg_temp_new_i32();
10306 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 10307
7c979afd 10308 gen_load_fpr32(ctx, fp32, fs);
895c2d04 10309 gen_helper_float_cvtd_w(fp64, cpu_env, fp32);
a7812ae4 10310 tcg_temp_free_i32(fp32);
b6d96bed 10311 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 10312 tcg_temp_free_i64(fp64);
b6d96bed 10313 }
5a5012ec 10314 break;
bf4120ad 10315 case OPC_CVT_S_L:
5e755519 10316 check_cp1_64bitmode(ctx);
b6d96bed 10317 {
a7812ae4
PB
10318 TCGv_i32 fp32 = tcg_temp_new_i32();
10319 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
10320
10321 gen_load_fpr64(ctx, fp64, fs);
895c2d04 10322 gen_helper_float_cvts_l(fp32, cpu_env, fp64);
a7812ae4 10323 tcg_temp_free_i64(fp64);
7c979afd 10324 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 10325 tcg_temp_free_i32(fp32);
b6d96bed 10326 }
5a5012ec 10327 break;
bf4120ad 10328 case OPC_CVT_D_L:
5e755519 10329 check_cp1_64bitmode(ctx);
b6d96bed 10330 {
a7812ae4 10331 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
10332
10333 gen_load_fpr64(ctx, fp0, fs);
895c2d04 10334 gen_helper_float_cvtd_l(fp0, cpu_env, fp0);
b6d96bed 10335 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10336 tcg_temp_free_i64(fp0);
b6d96bed 10337 }
5a5012ec 10338 break;
bf4120ad 10339 case OPC_CVT_PS_PW:
e29c9628 10340 check_ps(ctx);
b6d96bed 10341 {
a7812ae4 10342 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
10343
10344 gen_load_fpr64(ctx, fp0, fs);
895c2d04 10345 gen_helper_float_cvtps_pw(fp0, cpu_env, fp0);
b6d96bed 10346 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10347 tcg_temp_free_i64(fp0);
b6d96bed 10348 }
5a5012ec 10349 break;
bf4120ad 10350 case OPC_ADD_PS:
e29c9628 10351 check_ps(ctx);
b6d96bed 10352 {
a7812ae4
PB
10353 TCGv_i64 fp0 = tcg_temp_new_i64();
10354 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
10355
10356 gen_load_fpr64(ctx, fp0, fs);
10357 gen_load_fpr64(ctx, fp1, ft);
895c2d04 10358 gen_helper_float_add_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 10359 tcg_temp_free_i64(fp1);
b6d96bed 10360 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10361 tcg_temp_free_i64(fp0);
b6d96bed 10362 }
6ea83fed 10363 break;
bf4120ad 10364 case OPC_SUB_PS:
e29c9628 10365 check_ps(ctx);
b6d96bed 10366 {
a7812ae4
PB
10367 TCGv_i64 fp0 = tcg_temp_new_i64();
10368 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
10369
10370 gen_load_fpr64(ctx, fp0, fs);
10371 gen_load_fpr64(ctx, fp1, ft);
895c2d04 10372 gen_helper_float_sub_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 10373 tcg_temp_free_i64(fp1);
b6d96bed 10374 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10375 tcg_temp_free_i64(fp0);
b6d96bed 10376 }
6ea83fed 10377 break;
bf4120ad 10378 case OPC_MUL_PS:
e29c9628 10379 check_ps(ctx);
b6d96bed 10380 {
a7812ae4
PB
10381 TCGv_i64 fp0 = tcg_temp_new_i64();
10382 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
10383
10384 gen_load_fpr64(ctx, fp0, fs);
10385 gen_load_fpr64(ctx, fp1, ft);
895c2d04 10386 gen_helper_float_mul_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 10387 tcg_temp_free_i64(fp1);
b6d96bed 10388 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10389 tcg_temp_free_i64(fp0);
b6d96bed 10390 }
6ea83fed 10391 break;
bf4120ad 10392 case OPC_ABS_PS:
e29c9628 10393 check_ps(ctx);
b6d96bed 10394 {
a7812ae4 10395 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
10396
10397 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 10398 gen_helper_float_abs_ps(fp0, fp0);
b6d96bed 10399 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10400 tcg_temp_free_i64(fp0);
b6d96bed 10401 }
6ea83fed 10402 break;
bf4120ad 10403 case OPC_MOV_PS:
e29c9628 10404 check_ps(ctx);
b6d96bed 10405 {
a7812ae4 10406 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
10407
10408 gen_load_fpr64(ctx, fp0, fs);
10409 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10410 tcg_temp_free_i64(fp0);
b6d96bed 10411 }
6ea83fed 10412 break;
bf4120ad 10413 case OPC_NEG_PS:
e29c9628 10414 check_ps(ctx);
b6d96bed 10415 {
a7812ae4 10416 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
10417
10418 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 10419 gen_helper_float_chs_ps(fp0, fp0);
b6d96bed 10420 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10421 tcg_temp_free_i64(fp0);
b6d96bed 10422 }
6ea83fed 10423 break;
bf4120ad 10424 case OPC_MOVCF_PS:
e29c9628 10425 check_ps(ctx);
7f6613ce 10426 gen_movcf_ps(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
6ea83fed 10427 break;
bf4120ad 10428 case OPC_MOVZ_PS:
e29c9628 10429 check_ps(ctx);
a16336e4 10430 {
42a268c2 10431 TCGLabel *l1 = gen_new_label();
30a3848b 10432 TCGv_i64 fp0;
a16336e4 10433
c9297f4d
AJ
10434 if (ft != 0)
10435 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
10436 fp0 = tcg_temp_new_i64();
10437 gen_load_fpr64(ctx, fp0, fs);
10438 gen_store_fpr64(ctx, fp0, fd);
10439 tcg_temp_free_i64(fp0);
a16336e4
TS
10440 gen_set_label(l1);
10441 }
6ea83fed 10442 break;
bf4120ad 10443 case OPC_MOVN_PS:
e29c9628 10444 check_ps(ctx);
a16336e4 10445 {
42a268c2 10446 TCGLabel *l1 = gen_new_label();
30a3848b 10447 TCGv_i64 fp0;
c9297f4d
AJ
10448
10449 if (ft != 0) {
10450 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
10451 fp0 = tcg_temp_new_i64();
10452 gen_load_fpr64(ctx, fp0, fs);
10453 gen_store_fpr64(ctx, fp0, fd);
10454 tcg_temp_free_i64(fp0);
10455 gen_set_label(l1);
10456 }
a16336e4 10457 }
6ea83fed 10458 break;
bf4120ad 10459 case OPC_ADDR_PS:
e29c9628 10460 check_ps(ctx);
b6d96bed 10461 {
a7812ae4
PB
10462 TCGv_i64 fp0 = tcg_temp_new_i64();
10463 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
10464
10465 gen_load_fpr64(ctx, fp0, ft);
10466 gen_load_fpr64(ctx, fp1, fs);
895c2d04 10467 gen_helper_float_addr_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 10468 tcg_temp_free_i64(fp1);
b6d96bed 10469 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10470 tcg_temp_free_i64(fp0);
b6d96bed 10471 }
fbcc6828 10472 break;
bf4120ad 10473 case OPC_MULR_PS:
e29c9628 10474 check_ps(ctx);
b6d96bed 10475 {
a7812ae4
PB
10476 TCGv_i64 fp0 = tcg_temp_new_i64();
10477 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
10478
10479 gen_load_fpr64(ctx, fp0, ft);
10480 gen_load_fpr64(ctx, fp1, fs);
895c2d04 10481 gen_helper_float_mulr_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 10482 tcg_temp_free_i64(fp1);
b6d96bed 10483 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10484 tcg_temp_free_i64(fp0);
b6d96bed 10485 }
57fa1fb3 10486 break;
bf4120ad 10487 case OPC_RECIP2_PS:
e29c9628 10488 check_ps(ctx);
b6d96bed 10489 {
a7812ae4
PB
10490 TCGv_i64 fp0 = tcg_temp_new_i64();
10491 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
10492
10493 gen_load_fpr64(ctx, fp0, fs);
d22d7289 10494 gen_load_fpr64(ctx, fp1, ft);
895c2d04 10495 gen_helper_float_recip2_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 10496 tcg_temp_free_i64(fp1);
b6d96bed 10497 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10498 tcg_temp_free_i64(fp0);
b6d96bed 10499 }
57fa1fb3 10500 break;
bf4120ad 10501 case OPC_RECIP1_PS:
e29c9628 10502 check_ps(ctx);
b6d96bed 10503 {
a7812ae4 10504 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
10505
10506 gen_load_fpr64(ctx, fp0, fs);
895c2d04 10507 gen_helper_float_recip1_ps(fp0, cpu_env, fp0);
b6d96bed 10508 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10509 tcg_temp_free_i64(fp0);
b6d96bed 10510 }
57fa1fb3 10511 break;
bf4120ad 10512 case OPC_RSQRT1_PS:
e29c9628 10513 check_ps(ctx);
b6d96bed 10514 {
a7812ae4 10515 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
10516
10517 gen_load_fpr64(ctx, fp0, fs);
895c2d04 10518 gen_helper_float_rsqrt1_ps(fp0, cpu_env, fp0);
b6d96bed 10519 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10520 tcg_temp_free_i64(fp0);
b6d96bed 10521 }
57fa1fb3 10522 break;
bf4120ad 10523 case OPC_RSQRT2_PS:
e29c9628 10524 check_ps(ctx);
b6d96bed 10525 {
a7812ae4
PB
10526 TCGv_i64 fp0 = tcg_temp_new_i64();
10527 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
10528
10529 gen_load_fpr64(ctx, fp0, fs);
10530 gen_load_fpr64(ctx, fp1, ft);
895c2d04 10531 gen_helper_float_rsqrt2_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 10532 tcg_temp_free_i64(fp1);
b6d96bed 10533 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10534 tcg_temp_free_i64(fp0);
b6d96bed 10535 }
57fa1fb3 10536 break;
bf4120ad 10537 case OPC_CVT_S_PU:
5e755519 10538 check_cp1_64bitmode(ctx);
b6d96bed 10539 {
a7812ae4 10540 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 10541
7f6613ce 10542 gen_load_fpr32h(ctx, fp0, fs);
895c2d04 10543 gen_helper_float_cvts_pu(fp0, cpu_env, fp0);
7c979afd 10544 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 10545 tcg_temp_free_i32(fp0);
b6d96bed 10546 }
dd016883 10547 break;
bf4120ad 10548 case OPC_CVT_PW_PS:
e29c9628 10549 check_ps(ctx);
b6d96bed 10550 {
a7812ae4 10551 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
10552
10553 gen_load_fpr64(ctx, fp0, fs);
895c2d04 10554 gen_helper_float_cvtpw_ps(fp0, cpu_env, fp0);
b6d96bed 10555 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10556 tcg_temp_free_i64(fp0);
b6d96bed 10557 }
6ea83fed 10558 break;
bf4120ad 10559 case OPC_CVT_S_PL:
5e755519 10560 check_cp1_64bitmode(ctx);
b6d96bed 10561 {
a7812ae4 10562 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 10563
7c979afd 10564 gen_load_fpr32(ctx, fp0, fs);
895c2d04 10565 gen_helper_float_cvts_pl(fp0, cpu_env, fp0);
7c979afd 10566 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 10567 tcg_temp_free_i32(fp0);
b6d96bed 10568 }
6ea83fed 10569 break;
bf4120ad 10570 case OPC_PLL_PS:
e29c9628 10571 check_ps(ctx);
b6d96bed 10572 {
a7812ae4
PB
10573 TCGv_i32 fp0 = tcg_temp_new_i32();
10574 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 10575
7c979afd
LA
10576 gen_load_fpr32(ctx, fp0, fs);
10577 gen_load_fpr32(ctx, fp1, ft);
7f6613ce 10578 gen_store_fpr32h(ctx, fp0, fd);
7c979afd 10579 gen_store_fpr32(ctx, fp1, fd);
a7812ae4
PB
10580 tcg_temp_free_i32(fp0);
10581 tcg_temp_free_i32(fp1);
b6d96bed 10582 }
6ea83fed 10583 break;
bf4120ad 10584 case OPC_PLU_PS:
e29c9628 10585 check_ps(ctx);
b6d96bed 10586 {
a7812ae4
PB
10587 TCGv_i32 fp0 = tcg_temp_new_i32();
10588 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 10589
7c979afd 10590 gen_load_fpr32(ctx, fp0, fs);
7f6613ce 10591 gen_load_fpr32h(ctx, fp1, ft);
7c979afd 10592 gen_store_fpr32(ctx, fp1, fd);
7f6613ce 10593 gen_store_fpr32h(ctx, fp0, fd);
a7812ae4
PB
10594 tcg_temp_free_i32(fp0);
10595 tcg_temp_free_i32(fp1);
b6d96bed 10596 }
5a5012ec 10597 break;
bf4120ad 10598 case OPC_PUL_PS:
e29c9628 10599 check_ps(ctx);
b6d96bed 10600 {
a7812ae4
PB
10601 TCGv_i32 fp0 = tcg_temp_new_i32();
10602 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 10603
7f6613ce 10604 gen_load_fpr32h(ctx, fp0, fs);
7c979afd
LA
10605 gen_load_fpr32(ctx, fp1, ft);
10606 gen_store_fpr32(ctx, fp1, fd);
7f6613ce 10607 gen_store_fpr32h(ctx, fp0, fd);
a7812ae4
PB
10608 tcg_temp_free_i32(fp0);
10609 tcg_temp_free_i32(fp1);
b6d96bed 10610 }
5a5012ec 10611 break;
bf4120ad 10612 case OPC_PUU_PS:
e29c9628 10613 check_ps(ctx);
b6d96bed 10614 {
a7812ae4
PB
10615 TCGv_i32 fp0 = tcg_temp_new_i32();
10616 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 10617
7f6613ce
PJ
10618 gen_load_fpr32h(ctx, fp0, fs);
10619 gen_load_fpr32h(ctx, fp1, ft);
7c979afd 10620 gen_store_fpr32(ctx, fp1, fd);
7f6613ce 10621 gen_store_fpr32h(ctx, fp0, fd);
a7812ae4
PB
10622 tcg_temp_free_i32(fp0);
10623 tcg_temp_free_i32(fp1);
b6d96bed 10624 }
5a5012ec 10625 break;
bf4120ad
NF
10626 case OPC_CMP_F_PS:
10627 case OPC_CMP_UN_PS:
10628 case OPC_CMP_EQ_PS:
10629 case OPC_CMP_UEQ_PS:
10630 case OPC_CMP_OLT_PS:
10631 case OPC_CMP_ULT_PS:
10632 case OPC_CMP_OLE_PS:
10633 case OPC_CMP_ULE_PS:
10634 case OPC_CMP_SF_PS:
10635 case OPC_CMP_NGLE_PS:
10636 case OPC_CMP_SEQ_PS:
10637 case OPC_CMP_NGL_PS:
10638 case OPC_CMP_LT_PS:
10639 case OPC_CMP_NGE_PS:
10640 case OPC_CMP_LE_PS:
10641 case OPC_CMP_NGT_PS:
8153667c
NF
10642 if (ctx->opcode & (1 << 6)) {
10643 gen_cmpabs_ps(ctx, func-48, ft, fs, cc);
8153667c
NF
10644 } else {
10645 gen_cmp_ps(ctx, func-48, ft, fs, cc);
5a1e8ffb 10646 }
6ea83fed 10647 break;
5a5012ec 10648 default:
9d68ac14 10649 MIPS_INVAL("farith");
9c708c7f 10650 generate_exception_end(ctx, EXCP_RI);
6ea83fed
FB
10651 return;
10652 }
6ea83fed 10653}
6af0bf9c 10654
5a5012ec 10655/* Coprocessor 3 (FPU) */
5e755519
TS
10656static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
10657 int fd, int fs, int base, int index)
7a387fff 10658{
4e2474d6 10659 TCGv t0 = tcg_temp_new();
7a387fff 10660
93b12ccc 10661 if (base == 0) {
6c5c1e20 10662 gen_load_gpr(t0, index);
93b12ccc 10663 } else if (index == 0) {
6c5c1e20 10664 gen_load_gpr(t0, base);
93b12ccc 10665 } else {
05168674 10666 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]);
93b12ccc 10667 }
5a5012ec 10668 /* Don't do NOP if destination is zero: we must perform the actual
ead9360e 10669 memory access. */
5a5012ec
TS
10670 switch (opc) {
10671 case OPC_LWXC1:
8c0ab41f 10672 check_cop1x(ctx);
b6d96bed 10673 {
a7812ae4 10674 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 10675
5f68f5ae 10676 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
585c88d5 10677 tcg_gen_trunc_tl_i32(fp0, t0);
7c979afd 10678 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 10679 tcg_temp_free_i32(fp0);
b6d96bed 10680 }
5a5012ec
TS
10681 break;
10682 case OPC_LDXC1:
8c0ab41f
AJ
10683 check_cop1x(ctx);
10684 check_cp1_registers(ctx, fd);
b6d96bed 10685 {
a7812ae4 10686 TCGv_i64 fp0 = tcg_temp_new_i64();
5f68f5ae 10687 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
b6d96bed 10688 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10689 tcg_temp_free_i64(fp0);
b6d96bed 10690 }
5a5012ec
TS
10691 break;
10692 case OPC_LUXC1:
8c0ab41f 10693 check_cp1_64bitmode(ctx);
6c5c1e20 10694 tcg_gen_andi_tl(t0, t0, ~0x7);
b6d96bed 10695 {
a7812ae4 10696 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 10697
5f68f5ae 10698 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
b6d96bed 10699 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10700 tcg_temp_free_i64(fp0);
b6d96bed 10701 }
5a5012ec
TS
10702 break;
10703 case OPC_SWXC1:
8c0ab41f 10704 check_cop1x(ctx);
b6d96bed 10705 {
a7812ae4 10706 TCGv_i32 fp0 = tcg_temp_new_i32();
7c979afd 10707 gen_load_fpr32(ctx, fp0, fs);
5f68f5ae 10708 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL);
a7812ae4 10709 tcg_temp_free_i32(fp0);
b6d96bed 10710 }
5a5012ec
TS
10711 break;
10712 case OPC_SDXC1:
8c0ab41f
AJ
10713 check_cop1x(ctx);
10714 check_cp1_registers(ctx, fs);
b6d96bed 10715 {
a7812ae4 10716 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 10717 gen_load_fpr64(ctx, fp0, fs);
5f68f5ae 10718 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
a7812ae4 10719 tcg_temp_free_i64(fp0);
b6d96bed 10720 }
5a5012ec
TS
10721 break;
10722 case OPC_SUXC1:
8c0ab41f 10723 check_cp1_64bitmode(ctx);
6c5c1e20 10724 tcg_gen_andi_tl(t0, t0, ~0x7);
b6d96bed 10725 {
a7812ae4 10726 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 10727 gen_load_fpr64(ctx, fp0, fs);
5f68f5ae 10728 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
a7812ae4 10729 tcg_temp_free_i64(fp0);
b6d96bed 10730 }
5a5012ec 10731 break;
5a5012ec 10732 }
6c5c1e20 10733 tcg_temp_free(t0);
5a5012ec
TS
10734}
10735
5e755519
TS
10736static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
10737 int fd, int fr, int fs, int ft)
5a5012ec 10738{
5a5012ec
TS
10739 switch (opc) {
10740 case OPC_ALNV_PS:
e29c9628 10741 check_ps(ctx);
a16336e4 10742 {
a7812ae4 10743 TCGv t0 = tcg_temp_local_new();
c905fdac
AJ
10744 TCGv_i32 fp = tcg_temp_new_i32();
10745 TCGv_i32 fph = tcg_temp_new_i32();
42a268c2
RH
10746 TCGLabel *l1 = gen_new_label();
10747 TCGLabel *l2 = gen_new_label();
a16336e4 10748
6c5c1e20
TS
10749 gen_load_gpr(t0, fr);
10750 tcg_gen_andi_tl(t0, t0, 0x7);
6c5c1e20
TS
10751
10752 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
7c979afd 10753 gen_load_fpr32(ctx, fp, fs);
7f6613ce 10754 gen_load_fpr32h(ctx, fph, fs);
7c979afd 10755 gen_store_fpr32(ctx, fp, fd);
7f6613ce 10756 gen_store_fpr32h(ctx, fph, fd);
a16336e4
TS
10757 tcg_gen_br(l2);
10758 gen_set_label(l1);
6c5c1e20
TS
10759 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
10760 tcg_temp_free(t0);
a16336e4 10761#ifdef TARGET_WORDS_BIGENDIAN
7c979afd 10762 gen_load_fpr32(ctx, fp, fs);
7f6613ce
PJ
10763 gen_load_fpr32h(ctx, fph, ft);
10764 gen_store_fpr32h(ctx, fp, fd);
7c979afd 10765 gen_store_fpr32(ctx, fph, fd);
a16336e4 10766#else
7f6613ce 10767 gen_load_fpr32h(ctx, fph, fs);
7c979afd
LA
10768 gen_load_fpr32(ctx, fp, ft);
10769 gen_store_fpr32(ctx, fph, fd);
7f6613ce 10770 gen_store_fpr32h(ctx, fp, fd);
a16336e4
TS
10771#endif
10772 gen_set_label(l2);
c905fdac
AJ
10773 tcg_temp_free_i32(fp);
10774 tcg_temp_free_i32(fph);
a16336e4 10775 }
5a5012ec
TS
10776 break;
10777 case OPC_MADD_S:
b8aa4598 10778 check_cop1x(ctx);
b6d96bed 10779 {
a7812ae4
PB
10780 TCGv_i32 fp0 = tcg_temp_new_i32();
10781 TCGv_i32 fp1 = tcg_temp_new_i32();
10782 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed 10783
7c979afd
LA
10784 gen_load_fpr32(ctx, fp0, fs);
10785 gen_load_fpr32(ctx, fp1, ft);
10786 gen_load_fpr32(ctx, fp2, fr);
b3d6cd44 10787 gen_helper_float_madd_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10788 tcg_temp_free_i32(fp0);
10789 tcg_temp_free_i32(fp1);
7c979afd 10790 gen_store_fpr32(ctx, fp2, fd);
a7812ae4 10791 tcg_temp_free_i32(fp2);
b6d96bed 10792 }
5a5012ec
TS
10793 break;
10794 case OPC_MADD_D:
b8aa4598
TS
10795 check_cop1x(ctx);
10796 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 10797 {
a7812ae4
PB
10798 TCGv_i64 fp0 = tcg_temp_new_i64();
10799 TCGv_i64 fp1 = tcg_temp_new_i64();
10800 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10801
10802 gen_load_fpr64(ctx, fp0, fs);
10803 gen_load_fpr64(ctx, fp1, ft);
10804 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10805 gen_helper_float_madd_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10806 tcg_temp_free_i64(fp0);
10807 tcg_temp_free_i64(fp1);
b6d96bed 10808 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10809 tcg_temp_free_i64(fp2);
b6d96bed 10810 }
5a5012ec
TS
10811 break;
10812 case OPC_MADD_PS:
e29c9628 10813 check_ps(ctx);
b6d96bed 10814 {
a7812ae4
PB
10815 TCGv_i64 fp0 = tcg_temp_new_i64();
10816 TCGv_i64 fp1 = tcg_temp_new_i64();
10817 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10818
10819 gen_load_fpr64(ctx, fp0, fs);
10820 gen_load_fpr64(ctx, fp1, ft);
10821 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10822 gen_helper_float_madd_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10823 tcg_temp_free_i64(fp0);
10824 tcg_temp_free_i64(fp1);
b6d96bed 10825 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10826 tcg_temp_free_i64(fp2);
b6d96bed 10827 }
5a5012ec
TS
10828 break;
10829 case OPC_MSUB_S:
b8aa4598 10830 check_cop1x(ctx);
b6d96bed 10831 {
a7812ae4
PB
10832 TCGv_i32 fp0 = tcg_temp_new_i32();
10833 TCGv_i32 fp1 = tcg_temp_new_i32();
10834 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed 10835
7c979afd
LA
10836 gen_load_fpr32(ctx, fp0, fs);
10837 gen_load_fpr32(ctx, fp1, ft);
10838 gen_load_fpr32(ctx, fp2, fr);
b3d6cd44 10839 gen_helper_float_msub_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10840 tcg_temp_free_i32(fp0);
10841 tcg_temp_free_i32(fp1);
7c979afd 10842 gen_store_fpr32(ctx, fp2, fd);
a7812ae4 10843 tcg_temp_free_i32(fp2);
b6d96bed 10844 }
5a5012ec
TS
10845 break;
10846 case OPC_MSUB_D:
b8aa4598
TS
10847 check_cop1x(ctx);
10848 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 10849 {
a7812ae4
PB
10850 TCGv_i64 fp0 = tcg_temp_new_i64();
10851 TCGv_i64 fp1 = tcg_temp_new_i64();
10852 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10853
10854 gen_load_fpr64(ctx, fp0, fs);
10855 gen_load_fpr64(ctx, fp1, ft);
10856 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10857 gen_helper_float_msub_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10858 tcg_temp_free_i64(fp0);
10859 tcg_temp_free_i64(fp1);
b6d96bed 10860 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10861 tcg_temp_free_i64(fp2);
b6d96bed 10862 }
5a5012ec
TS
10863 break;
10864 case OPC_MSUB_PS:
e29c9628 10865 check_ps(ctx);
b6d96bed 10866 {
a7812ae4
PB
10867 TCGv_i64 fp0 = tcg_temp_new_i64();
10868 TCGv_i64 fp1 = tcg_temp_new_i64();
10869 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10870
10871 gen_load_fpr64(ctx, fp0, fs);
10872 gen_load_fpr64(ctx, fp1, ft);
10873 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10874 gen_helper_float_msub_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10875 tcg_temp_free_i64(fp0);
10876 tcg_temp_free_i64(fp1);
b6d96bed 10877 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10878 tcg_temp_free_i64(fp2);
b6d96bed 10879 }
5a5012ec
TS
10880 break;
10881 case OPC_NMADD_S:
b8aa4598 10882 check_cop1x(ctx);
b6d96bed 10883 {
a7812ae4
PB
10884 TCGv_i32 fp0 = tcg_temp_new_i32();
10885 TCGv_i32 fp1 = tcg_temp_new_i32();
10886 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed 10887
7c979afd
LA
10888 gen_load_fpr32(ctx, fp0, fs);
10889 gen_load_fpr32(ctx, fp1, ft);
10890 gen_load_fpr32(ctx, fp2, fr);
b3d6cd44 10891 gen_helper_float_nmadd_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10892 tcg_temp_free_i32(fp0);
10893 tcg_temp_free_i32(fp1);
7c979afd 10894 gen_store_fpr32(ctx, fp2, fd);
a7812ae4 10895 tcg_temp_free_i32(fp2);
b6d96bed 10896 }
5a5012ec
TS
10897 break;
10898 case OPC_NMADD_D:
b8aa4598
TS
10899 check_cop1x(ctx);
10900 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 10901 {
a7812ae4
PB
10902 TCGv_i64 fp0 = tcg_temp_new_i64();
10903 TCGv_i64 fp1 = tcg_temp_new_i64();
10904 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10905
10906 gen_load_fpr64(ctx, fp0, fs);
10907 gen_load_fpr64(ctx, fp1, ft);
10908 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10909 gen_helper_float_nmadd_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10910 tcg_temp_free_i64(fp0);
10911 tcg_temp_free_i64(fp1);
b6d96bed 10912 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10913 tcg_temp_free_i64(fp2);
b6d96bed 10914 }
5a5012ec
TS
10915 break;
10916 case OPC_NMADD_PS:
e29c9628 10917 check_ps(ctx);
b6d96bed 10918 {
a7812ae4
PB
10919 TCGv_i64 fp0 = tcg_temp_new_i64();
10920 TCGv_i64 fp1 = tcg_temp_new_i64();
10921 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10922
10923 gen_load_fpr64(ctx, fp0, fs);
10924 gen_load_fpr64(ctx, fp1, ft);
10925 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10926 gen_helper_float_nmadd_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10927 tcg_temp_free_i64(fp0);
10928 tcg_temp_free_i64(fp1);
b6d96bed 10929 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10930 tcg_temp_free_i64(fp2);
b6d96bed 10931 }
5a5012ec
TS
10932 break;
10933 case OPC_NMSUB_S:
b8aa4598 10934 check_cop1x(ctx);
b6d96bed 10935 {
a7812ae4
PB
10936 TCGv_i32 fp0 = tcg_temp_new_i32();
10937 TCGv_i32 fp1 = tcg_temp_new_i32();
10938 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed 10939
7c979afd
LA
10940 gen_load_fpr32(ctx, fp0, fs);
10941 gen_load_fpr32(ctx, fp1, ft);
10942 gen_load_fpr32(ctx, fp2, fr);
b3d6cd44 10943 gen_helper_float_nmsub_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10944 tcg_temp_free_i32(fp0);
10945 tcg_temp_free_i32(fp1);
7c979afd 10946 gen_store_fpr32(ctx, fp2, fd);
a7812ae4 10947 tcg_temp_free_i32(fp2);
b6d96bed 10948 }
5a5012ec
TS
10949 break;
10950 case OPC_NMSUB_D:
b8aa4598
TS
10951 check_cop1x(ctx);
10952 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 10953 {
a7812ae4
PB
10954 TCGv_i64 fp0 = tcg_temp_new_i64();
10955 TCGv_i64 fp1 = tcg_temp_new_i64();
10956 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10957
10958 gen_load_fpr64(ctx, fp0, fs);
10959 gen_load_fpr64(ctx, fp1, ft);
10960 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10961 gen_helper_float_nmsub_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10962 tcg_temp_free_i64(fp0);
10963 tcg_temp_free_i64(fp1);
b6d96bed 10964 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10965 tcg_temp_free_i64(fp2);
b6d96bed 10966 }
5a5012ec
TS
10967 break;
10968 case OPC_NMSUB_PS:
e29c9628 10969 check_ps(ctx);
b6d96bed 10970 {
a7812ae4
PB
10971 TCGv_i64 fp0 = tcg_temp_new_i64();
10972 TCGv_i64 fp1 = tcg_temp_new_i64();
10973 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10974
10975 gen_load_fpr64(ctx, fp0, fs);
10976 gen_load_fpr64(ctx, fp1, ft);
10977 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10978 gen_helper_float_nmsub_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10979 tcg_temp_free_i64(fp0);
10980 tcg_temp_free_i64(fp1);
b6d96bed 10981 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10982 tcg_temp_free_i64(fp2);
b6d96bed 10983 }
5a5012ec 10984 break;
923617a3 10985 default:
9d68ac14 10986 MIPS_INVAL("flt3_arith");
9c708c7f 10987 generate_exception_end(ctx, EXCP_RI);
5a5012ec
TS
10988 return;
10989 }
7a387fff
TS
10990}
10991
b00c7218 10992static void gen_rdhwr(DisasContext *ctx, int rt, int rd, int sel)
26ebe468
NF
10993{
10994 TCGv t0;
10995
b3167288
RH
10996#if !defined(CONFIG_USER_ONLY)
10997 /* The Linux kernel will emulate rdhwr if it's not supported natively.
10998 Therefore only check the ISA in system mode. */
d75c135e 10999 check_insn(ctx, ISA_MIPS32R2);
b3167288 11000#endif
26ebe468
NF
11001 t0 = tcg_temp_new();
11002
11003 switch (rd) {
11004 case 0:
895c2d04 11005 gen_helper_rdhwr_cpunum(t0, cpu_env);
26ebe468
NF
11006 gen_store_gpr(t0, rt);
11007 break;
11008 case 1:
895c2d04 11009 gen_helper_rdhwr_synci_step(t0, cpu_env);
26ebe468
NF
11010 gen_store_gpr(t0, rt);
11011 break;
11012 case 2:
eeb3bba8 11013 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
d673a68d
JH
11014 gen_io_start();
11015 }
895c2d04 11016 gen_helper_rdhwr_cc(t0, cpu_env);
eeb3bba8 11017 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
d673a68d
JH
11018 gen_io_end();
11019 }
26ebe468 11020 gen_store_gpr(t0, rt);
d673a68d 11021 /* Break the TB to be able to take timer interrupts immediately
b28425ba 11022 after reading count. DISAS_STOP isn't sufficient, we need to ensure
d673a68d 11023 we break completely out of translated code. */
eeb3bba8
EC
11024 gen_save_pc(ctx->base.pc_next + 4);
11025 ctx->base.is_jmp = DISAS_EXIT;
26ebe468
NF
11026 break;
11027 case 3:
895c2d04 11028 gen_helper_rdhwr_ccres(t0, cpu_env);
26ebe468
NF
11029 gen_store_gpr(t0, rt);
11030 break;
b00c7218
YK
11031 case 4:
11032 check_insn(ctx, ISA_MIPS32R6);
11033 if (sel != 0) {
11034 /* Performance counter registers are not implemented other than
11035 * control register 0.
11036 */
11037 generate_exception(ctx, EXCP_RI);
11038 }
11039 gen_helper_rdhwr_performance(t0, cpu_env);
11040 gen_store_gpr(t0, rt);
11041 break;
11042 case 5:
11043 check_insn(ctx, ISA_MIPS32R6);
11044 gen_helper_rdhwr_xnp(t0, cpu_env);
11045 gen_store_gpr(t0, rt);
11046 break;
26ebe468
NF
11047 case 29:
11048#if defined(CONFIG_USER_ONLY)
d279279e
PJ
11049 tcg_gen_ld_tl(t0, cpu_env,
11050 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
26ebe468
NF
11051 gen_store_gpr(t0, rt);
11052 break;
11053#else
d279279e
PJ
11054 if ((ctx->hflags & MIPS_HFLAG_CP0) ||
11055 (ctx->hflags & MIPS_HFLAG_HWRENA_ULR)) {
11056 tcg_gen_ld_tl(t0, cpu_env,
11057 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
11058 gen_store_gpr(t0, rt);
11059 } else {
9c708c7f 11060 generate_exception_end(ctx, EXCP_RI);
d279279e
PJ
11061 }
11062 break;
26ebe468
NF
11063#endif
11064 default: /* Invalid */
11065 MIPS_INVAL("rdhwr");
9c708c7f 11066 generate_exception_end(ctx, EXCP_RI);
26ebe468
NF
11067 break;
11068 }
11069 tcg_temp_free(t0);
11070}
11071
a5f53390
LA
11072static inline void clear_branch_hflags(DisasContext *ctx)
11073{
11074 ctx->hflags &= ~MIPS_HFLAG_BMASK;
eeb3bba8 11075 if (ctx->base.is_jmp == DISAS_NEXT) {
a5f53390
LA
11076 save_cpu_state(ctx, 0);
11077 } else {
11078 /* it is not safe to save ctx->hflags as hflags may be changed
11079 in execution time by the instruction in delay / forbidden slot. */
11080 tcg_gen_andi_i32(hflags, hflags, ~MIPS_HFLAG_BMASK);
11081 }
11082}
11083
31837be3 11084static void gen_branch(DisasContext *ctx, int insn_bytes)
c9602061
NF
11085{
11086 if (ctx->hflags & MIPS_HFLAG_BMASK) {
364d4831 11087 int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
c9602061 11088 /* Branches completion */
a5f53390 11089 clear_branch_hflags(ctx);
eeb3bba8 11090 ctx->base.is_jmp = DISAS_NORETURN;
c9602061 11091 /* FIXME: Need to clear can_do_io. */
364d4831 11092 switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
339cd2a8 11093 case MIPS_HFLAG_FBNSLOT:
eeb3bba8 11094 gen_goto_tb(ctx, 0, ctx->base.pc_next + insn_bytes);
339cd2a8 11095 break;
c9602061
NF
11096 case MIPS_HFLAG_B:
11097 /* unconditional branch */
364d4831
NF
11098 if (proc_hflags & MIPS_HFLAG_BX) {
11099 tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
11100 }
c9602061
NF
11101 gen_goto_tb(ctx, 0, ctx->btarget);
11102 break;
11103 case MIPS_HFLAG_BL:
11104 /* blikely taken case */
c9602061
NF
11105 gen_goto_tb(ctx, 0, ctx->btarget);
11106 break;
11107 case MIPS_HFLAG_BC:
11108 /* Conditional branch */
c9602061 11109 {
42a268c2 11110 TCGLabel *l1 = gen_new_label();
c9602061
NF
11111
11112 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
eeb3bba8 11113 gen_goto_tb(ctx, 1, ctx->base.pc_next + insn_bytes);
c9602061
NF
11114 gen_set_label(l1);
11115 gen_goto_tb(ctx, 0, ctx->btarget);
11116 }
11117 break;
11118 case MIPS_HFLAG_BR:
11119 /* unconditional branch to register */
d75c135e 11120 if (ctx->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
364d4831
NF
11121 TCGv t0 = tcg_temp_new();
11122 TCGv_i32 t1 = tcg_temp_new_i32();
11123
11124 tcg_gen_andi_tl(t0, btarget, 0x1);
11125 tcg_gen_trunc_tl_i32(t1, t0);
11126 tcg_temp_free(t0);
11127 tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
11128 tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
11129 tcg_gen_or_i32(hflags, hflags, t1);
11130 tcg_temp_free_i32(t1);
11131
11132 tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
11133 } else {
11134 tcg_gen_mov_tl(cpu_PC, btarget);
11135 }
eeb3bba8 11136 if (ctx->base.singlestep_enabled) {
c9602061 11137 save_cpu_state(ctx, 0);
9c708c7f 11138 gen_helper_raise_exception_debug(cpu_env);
c9602061 11139 }
7f11636d 11140 tcg_gen_lookup_and_goto_ptr();
c9602061
NF
11141 break;
11142 default:
a5f53390
LA
11143 fprintf(stderr, "unknown branch 0x%x\n", proc_hflags);
11144 abort();
c9602061
NF
11145 }
11146 }
11147}
11148
6893f074
YK
11149/* Compact Branches */
11150static void gen_compute_compact_branch(DisasContext *ctx, uint32_t opc,
11151 int rs, int rt, int32_t offset)
11152{
11153 int bcond_compute = 0;
11154 TCGv t0 = tcg_temp_new();
11155 TCGv t1 = tcg_temp_new();
65935f07 11156 int m16_lowbit = (ctx->hflags & MIPS_HFLAG_M16) != 0;
6893f074
YK
11157
11158 if (ctx->hflags & MIPS_HFLAG_BMASK) {
11159#ifdef MIPS_DEBUG_DISAS
11160 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
eeb3bba8 11161 "\n", ctx->base.pc_next);
6893f074 11162#endif
9c708c7f 11163 generate_exception_end(ctx, EXCP_RI);
6893f074
YK
11164 goto out;
11165 }
11166
11167 /* Load needed operands and calculate btarget */
11168 switch (opc) {
11169 /* compact branch */
11170 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
11171 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
11172 gen_load_gpr(t0, rs);
11173 gen_load_gpr(t1, rt);
11174 bcond_compute = 1;
eeb3bba8 11175 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
6893f074
YK
11176 if (rs <= rt && rs == 0) {
11177 /* OPC_BEQZALC, OPC_BNEZALC */
eeb3bba8 11178 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
6893f074
YK
11179 }
11180 break;
11181 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
11182 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
11183 gen_load_gpr(t0, rs);
11184 gen_load_gpr(t1, rt);
11185 bcond_compute = 1;
eeb3bba8 11186 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
6893f074
YK
11187 break;
11188 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
11189 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
11190 if (rs == 0 || rs == rt) {
11191 /* OPC_BLEZALC, OPC_BGEZALC */
11192 /* OPC_BGTZALC, OPC_BLTZALC */
eeb3bba8 11193 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
6893f074
YK
11194 }
11195 gen_load_gpr(t0, rs);
11196 gen_load_gpr(t1, rt);
11197 bcond_compute = 1;
eeb3bba8 11198 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
6893f074
YK
11199 break;
11200 case OPC_BC:
11201 case OPC_BALC:
eeb3bba8 11202 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
6893f074
YK
11203 break;
11204 case OPC_BEQZC:
11205 case OPC_BNEZC:
11206 if (rs != 0) {
11207 /* OPC_BEQZC, OPC_BNEZC */
11208 gen_load_gpr(t0, rs);
11209 bcond_compute = 1;
eeb3bba8 11210 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
6893f074
YK
11211 } else {
11212 /* OPC_JIC, OPC_JIALC */
11213 TCGv tbase = tcg_temp_new();
11214 TCGv toffset = tcg_temp_new();
11215
11216 gen_load_gpr(tbase, rt);
11217 tcg_gen_movi_tl(toffset, offset);
11218 gen_op_addr_add(ctx, btarget, tbase, toffset);
11219 tcg_temp_free(tbase);
11220 tcg_temp_free(toffset);
11221 }
11222 break;
11223 default:
11224 MIPS_INVAL("Compact branch/jump");
9c708c7f 11225 generate_exception_end(ctx, EXCP_RI);
6893f074
YK
11226 goto out;
11227 }
11228
11229 if (bcond_compute == 0) {
11230 /* Uncoditional compact branch */
11231 switch (opc) {
11232 case OPC_JIALC:
eeb3bba8 11233 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
6893f074
YK
11234 /* Fallthrough */
11235 case OPC_JIC:
11236 ctx->hflags |= MIPS_HFLAG_BR;
11237 break;
11238 case OPC_BALC:
eeb3bba8 11239 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
6893f074
YK
11240 /* Fallthrough */
11241 case OPC_BC:
11242 ctx->hflags |= MIPS_HFLAG_B;
11243 break;
11244 default:
11245 MIPS_INVAL("Compact branch/jump");
9c708c7f 11246 generate_exception_end(ctx, EXCP_RI);
6893f074
YK
11247 goto out;
11248 }
11249
11250 /* Generating branch here as compact branches don't have delay slot */
11251 gen_branch(ctx, 4);
11252 } else {
11253 /* Conditional compact branch */
11254 TCGLabel *fs = gen_new_label();
11255 save_cpu_state(ctx, 0);
11256
11257 switch (opc) {
11258 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
11259 if (rs == 0 && rt != 0) {
11260 /* OPC_BLEZALC */
11261 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
11262 } else if (rs != 0 && rt != 0 && rs == rt) {
11263 /* OPC_BGEZALC */
11264 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
11265 } else {
11266 /* OPC_BGEUC */
11267 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU), t0, t1, fs);
11268 }
11269 break;
11270 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
11271 if (rs == 0 && rt != 0) {
11272 /* OPC_BGTZALC */
11273 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
11274 } else if (rs != 0 && rt != 0 && rs == rt) {
11275 /* OPC_BLTZALC */
11276 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
11277 } else {
11278 /* OPC_BLTUC */
11279 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU), t0, t1, fs);
11280 }
11281 break;
11282 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
11283 if (rs == 0 && rt != 0) {
11284 /* OPC_BLEZC */
11285 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
11286 } else if (rs != 0 && rt != 0 && rs == rt) {
11287 /* OPC_BGEZC */
11288 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
11289 } else {
11290 /* OPC_BGEC */
11291 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE), t0, t1, fs);
11292 }
11293 break;
11294 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
11295 if (rs == 0 && rt != 0) {
11296 /* OPC_BGTZC */
11297 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
11298 } else if (rs != 0 && rt != 0 && rs == rt) {
11299 /* OPC_BLTZC */
11300 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
11301 } else {
11302 /* OPC_BLTC */
11303 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT), t0, t1, fs);
11304 }
11305 break;
11306 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
11307 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
11308 if (rs >= rt) {
11309 /* OPC_BOVC, OPC_BNVC */
11310 TCGv t2 = tcg_temp_new();
11311 TCGv t3 = tcg_temp_new();
11312 TCGv t4 = tcg_temp_new();
11313 TCGv input_overflow = tcg_temp_new();
11314
11315 gen_load_gpr(t0, rs);
11316 gen_load_gpr(t1, rt);
11317 tcg_gen_ext32s_tl(t2, t0);
11318 tcg_gen_setcond_tl(TCG_COND_NE, input_overflow, t2, t0);
11319 tcg_gen_ext32s_tl(t3, t1);
11320 tcg_gen_setcond_tl(TCG_COND_NE, t4, t3, t1);
11321 tcg_gen_or_tl(input_overflow, input_overflow, t4);
11322
11323 tcg_gen_add_tl(t4, t2, t3);
11324 tcg_gen_ext32s_tl(t4, t4);
11325 tcg_gen_xor_tl(t2, t2, t3);
11326 tcg_gen_xor_tl(t3, t4, t3);
11327 tcg_gen_andc_tl(t2, t3, t2);
11328 tcg_gen_setcondi_tl(TCG_COND_LT, t4, t2, 0);
11329 tcg_gen_or_tl(t4, t4, input_overflow);
11330 if (opc == OPC_BOVC) {
11331 /* OPC_BOVC */
11332 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t4, 0, fs);
11333 } else {
11334 /* OPC_BNVC */
11335 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t4, 0, fs);
11336 }
11337 tcg_temp_free(input_overflow);
11338 tcg_temp_free(t4);
11339 tcg_temp_free(t3);
11340 tcg_temp_free(t2);
11341 } else if (rs < rt && rs == 0) {
11342 /* OPC_BEQZALC, OPC_BNEZALC */
11343 if (opc == OPC_BEQZALC) {
11344 /* OPC_BEQZALC */
11345 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t1, 0, fs);
11346 } else {
11347 /* OPC_BNEZALC */
11348 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t1, 0, fs);
11349 }
11350 } else {
11351 /* OPC_BEQC, OPC_BNEC */
11352 if (opc == OPC_BEQC) {
11353 /* OPC_BEQC */
11354 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_EQ), t0, t1, fs);
11355 } else {
11356 /* OPC_BNEC */
11357 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_NE), t0, t1, fs);
11358 }
11359 }
11360 break;
11361 case OPC_BEQZC:
11362 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t0, 0, fs);
11363 break;
11364 case OPC_BNEZC:
11365 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t0, 0, fs);
11366 break;
11367 default:
11368 MIPS_INVAL("Compact conditional branch/jump");
9c708c7f 11369 generate_exception_end(ctx, EXCP_RI);
6893f074
YK
11370 goto out;
11371 }
11372
11373 /* Generating branch here as compact branches don't have delay slot */
11374 gen_goto_tb(ctx, 1, ctx->btarget);
11375 gen_set_label(fs);
11376
11377 ctx->hflags |= MIPS_HFLAG_FBNSLOT;
6893f074
YK
11378 }
11379
11380out:
11381 tcg_temp_free(t0);
11382 tcg_temp_free(t1);
11383}
11384
7a387fff 11385/* ISA extensions (ASEs) */
6af0bf9c 11386/* MIPS16 extension to MIPS32 */
6ea219d0
NF
11387
11388/* MIPS16 major opcodes */
11389enum {
11390 M16_OPC_ADDIUSP = 0x00,
11391 M16_OPC_ADDIUPC = 0x01,
11392 M16_OPC_B = 0x02,
11393 M16_OPC_JAL = 0x03,
11394 M16_OPC_BEQZ = 0x04,
11395 M16_OPC_BNEQZ = 0x05,
11396 M16_OPC_SHIFT = 0x06,
11397 M16_OPC_LD = 0x07,
11398 M16_OPC_RRIA = 0x08,
11399 M16_OPC_ADDIU8 = 0x09,
11400 M16_OPC_SLTI = 0x0a,
11401 M16_OPC_SLTIU = 0x0b,
11402 M16_OPC_I8 = 0x0c,
11403 M16_OPC_LI = 0x0d,
11404 M16_OPC_CMPI = 0x0e,
11405 M16_OPC_SD = 0x0f,
11406 M16_OPC_LB = 0x10,
11407 M16_OPC_LH = 0x11,
11408 M16_OPC_LWSP = 0x12,
11409 M16_OPC_LW = 0x13,
11410 M16_OPC_LBU = 0x14,
11411 M16_OPC_LHU = 0x15,
11412 M16_OPC_LWPC = 0x16,
11413 M16_OPC_LWU = 0x17,
11414 M16_OPC_SB = 0x18,
11415 M16_OPC_SH = 0x19,
11416 M16_OPC_SWSP = 0x1a,
11417 M16_OPC_SW = 0x1b,
11418 M16_OPC_RRR = 0x1c,
11419 M16_OPC_RR = 0x1d,
11420 M16_OPC_EXTEND = 0x1e,
11421 M16_OPC_I64 = 0x1f
11422};
11423
11424/* I8 funct field */
11425enum {
11426 I8_BTEQZ = 0x0,
11427 I8_BTNEZ = 0x1,
11428 I8_SWRASP = 0x2,
11429 I8_ADJSP = 0x3,
11430 I8_SVRS = 0x4,
11431 I8_MOV32R = 0x5,
11432 I8_MOVR32 = 0x7
11433};
11434
11435/* RRR f field */
11436enum {
11437 RRR_DADDU = 0x0,
11438 RRR_ADDU = 0x1,
11439 RRR_DSUBU = 0x2,
11440 RRR_SUBU = 0x3
11441};
11442
11443/* RR funct field */
11444enum {
11445 RR_JR = 0x00,
11446 RR_SDBBP = 0x01,
11447 RR_SLT = 0x02,
11448 RR_SLTU = 0x03,
11449 RR_SLLV = 0x04,
11450 RR_BREAK = 0x05,
11451 RR_SRLV = 0x06,
11452 RR_SRAV = 0x07,
11453 RR_DSRL = 0x08,
11454 RR_CMP = 0x0a,
11455 RR_NEG = 0x0b,
11456 RR_AND = 0x0c,
11457 RR_OR = 0x0d,
11458 RR_XOR = 0x0e,
11459 RR_NOT = 0x0f,
11460 RR_MFHI = 0x10,
11461 RR_CNVT = 0x11,
11462 RR_MFLO = 0x12,
11463 RR_DSRA = 0x13,
11464 RR_DSLLV = 0x14,
11465 RR_DSRLV = 0x16,
11466 RR_DSRAV = 0x17,
11467 RR_MULT = 0x18,
11468 RR_MULTU = 0x19,
11469 RR_DIV = 0x1a,
11470 RR_DIVU = 0x1b,
11471 RR_DMULT = 0x1c,
11472 RR_DMULTU = 0x1d,
11473 RR_DDIV = 0x1e,
11474 RR_DDIVU = 0x1f
11475};
11476
11477/* I64 funct field */
11478enum {
11479 I64_LDSP = 0x0,
11480 I64_SDSP = 0x1,
11481 I64_SDRASP = 0x2,
11482 I64_DADJSP = 0x3,
11483 I64_LDPC = 0x4,
364d4831 11484 I64_DADDIU5 = 0x5,
6ea219d0
NF
11485 I64_DADDIUPC = 0x6,
11486 I64_DADDIUSP = 0x7
11487};
11488
11489/* RR ry field for CNVT */
11490enum {
11491 RR_RY_CNVT_ZEB = 0x0,
11492 RR_RY_CNVT_ZEH = 0x1,
11493 RR_RY_CNVT_ZEW = 0x2,
11494 RR_RY_CNVT_SEB = 0x4,
11495 RR_RY_CNVT_SEH = 0x5,
11496 RR_RY_CNVT_SEW = 0x6,
11497};
11498
364d4831
NF
11499static int xlat (int r)
11500{
11501 static int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
11502
11503 return map[r];
11504}
11505
11506static void gen_mips16_save (DisasContext *ctx,
11507 int xsregs, int aregs,
11508 int do_ra, int do_s0, int do_s1,
11509 int framesize)
11510{
11511 TCGv t0 = tcg_temp_new();
11512 TCGv t1 = tcg_temp_new();
c48245f0 11513 TCGv t2 = tcg_temp_new();
364d4831
NF
11514 int args, astatic;
11515
11516 switch (aregs) {
11517 case 0:
11518 case 1:
11519 case 2:
11520 case 3:
11521 case 11:
11522 args = 0;
11523 break;
11524 case 4:
11525 case 5:
11526 case 6:
11527 case 7:
11528 args = 1;
11529 break;
11530 case 8:
11531 case 9:
11532 case 10:
11533 args = 2;
11534 break;
11535 case 12:
11536 case 13:
11537 args = 3;
11538 break;
11539 case 14:
11540 args = 4;
11541 break;
11542 default:
9c708c7f 11543 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
11544 return;
11545 }
11546
11547 switch (args) {
11548 case 4:
11549 gen_base_offset_addr(ctx, t0, 29, 12);
11550 gen_load_gpr(t1, 7);
5f68f5ae 11551 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
364d4831
NF
11552 /* Fall through */
11553 case 3:
11554 gen_base_offset_addr(ctx, t0, 29, 8);
11555 gen_load_gpr(t1, 6);
5f68f5ae 11556 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
364d4831
NF
11557 /* Fall through */
11558 case 2:
11559 gen_base_offset_addr(ctx, t0, 29, 4);
11560 gen_load_gpr(t1, 5);
5f68f5ae 11561 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
364d4831
NF
11562 /* Fall through */
11563 case 1:
11564 gen_base_offset_addr(ctx, t0, 29, 0);
11565 gen_load_gpr(t1, 4);
5f68f5ae 11566 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
364d4831
NF
11567 }
11568
11569 gen_load_gpr(t0, 29);
11570
5f68f5ae 11571#define DECR_AND_STORE(reg) do { \
c48245f0
MR
11572 tcg_gen_movi_tl(t2, -4); \
11573 gen_op_addr_add(ctx, t0, t0, t2); \
5f68f5ae
AJ
11574 gen_load_gpr(t1, reg); \
11575 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); \
364d4831
NF
11576 } while (0)
11577
11578 if (do_ra) {
11579 DECR_AND_STORE(31);
11580 }
11581
11582 switch (xsregs) {
11583 case 7:
11584 DECR_AND_STORE(30);
11585 /* Fall through */
11586 case 6:
11587 DECR_AND_STORE(23);
11588 /* Fall through */
11589 case 5:
11590 DECR_AND_STORE(22);
11591 /* Fall through */
11592 case 4:
11593 DECR_AND_STORE(21);
11594 /* Fall through */
11595 case 3:
11596 DECR_AND_STORE(20);
11597 /* Fall through */
11598 case 2:
11599 DECR_AND_STORE(19);
11600 /* Fall through */
11601 case 1:
11602 DECR_AND_STORE(18);
11603 }
11604
11605 if (do_s1) {
11606 DECR_AND_STORE(17);
11607 }
11608 if (do_s0) {
11609 DECR_AND_STORE(16);
11610 }
11611
11612 switch (aregs) {
11613 case 0:
11614 case 4:
11615 case 8:
11616 case 12:
11617 case 14:
11618 astatic = 0;
11619 break;
11620 case 1:
11621 case 5:
11622 case 9:
11623 case 13:
11624 astatic = 1;
11625 break;
11626 case 2:
11627 case 6:
11628 case 10:
11629 astatic = 2;
11630 break;
11631 case 3:
11632 case 7:
11633 astatic = 3;
11634 break;
11635 case 11:
11636 astatic = 4;
11637 break;
11638 default:
9c708c7f 11639 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
11640 return;
11641 }
11642
11643 if (astatic > 0) {
11644 DECR_AND_STORE(7);
11645 if (astatic > 1) {
11646 DECR_AND_STORE(6);
11647 if (astatic > 2) {
11648 DECR_AND_STORE(5);
11649 if (astatic > 3) {
11650 DECR_AND_STORE(4);
11651 }
11652 }
11653 }
11654 }
11655#undef DECR_AND_STORE
11656
c48245f0
MR
11657 tcg_gen_movi_tl(t2, -framesize);
11658 gen_op_addr_add(ctx, cpu_gpr[29], cpu_gpr[29], t2);
364d4831
NF
11659 tcg_temp_free(t0);
11660 tcg_temp_free(t1);
c48245f0 11661 tcg_temp_free(t2);
364d4831
NF
11662}
11663
11664static void gen_mips16_restore (DisasContext *ctx,
11665 int xsregs, int aregs,
11666 int do_ra, int do_s0, int do_s1,
11667 int framesize)
11668{
11669 int astatic;
11670 TCGv t0 = tcg_temp_new();
11671 TCGv t1 = tcg_temp_new();
c48245f0 11672 TCGv t2 = tcg_temp_new();
364d4831 11673
c48245f0
MR
11674 tcg_gen_movi_tl(t2, framesize);
11675 gen_op_addr_add(ctx, t0, cpu_gpr[29], t2);
364d4831 11676
5f68f5ae 11677#define DECR_AND_LOAD(reg) do { \
c48245f0
MR
11678 tcg_gen_movi_tl(t2, -4); \
11679 gen_op_addr_add(ctx, t0, t0, t2); \
5f68f5ae
AJ
11680 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL); \
11681 gen_store_gpr(t1, reg); \
364d4831
NF
11682 } while (0)
11683
11684 if (do_ra) {
11685 DECR_AND_LOAD(31);
11686 }
11687
11688 switch (xsregs) {
11689 case 7:
11690 DECR_AND_LOAD(30);
11691 /* Fall through */
11692 case 6:
11693 DECR_AND_LOAD(23);
11694 /* Fall through */
11695 case 5:
11696 DECR_AND_LOAD(22);
11697 /* Fall through */
11698 case 4:
11699 DECR_AND_LOAD(21);
11700 /* Fall through */
11701 case 3:
11702 DECR_AND_LOAD(20);
11703 /* Fall through */
11704 case 2:
11705 DECR_AND_LOAD(19);
11706 /* Fall through */
11707 case 1:
11708 DECR_AND_LOAD(18);
11709 }
11710
11711 if (do_s1) {
11712 DECR_AND_LOAD(17);
11713 }
11714 if (do_s0) {
11715 DECR_AND_LOAD(16);
11716 }
11717
11718 switch (aregs) {
11719 case 0:
11720 case 4:
11721 case 8:
11722 case 12:
11723 case 14:
11724 astatic = 0;
11725 break;
11726 case 1:
11727 case 5:
11728 case 9:
11729 case 13:
11730 astatic = 1;
11731 break;
11732 case 2:
11733 case 6:
11734 case 10:
11735 astatic = 2;
11736 break;
11737 case 3:
11738 case 7:
11739 astatic = 3;
11740 break;
11741 case 11:
11742 astatic = 4;
11743 break;
11744 default:
9c708c7f 11745 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
11746 return;
11747 }
11748
11749 if (astatic > 0) {
11750 DECR_AND_LOAD(7);
11751 if (astatic > 1) {
11752 DECR_AND_LOAD(6);
11753 if (astatic > 2) {
11754 DECR_AND_LOAD(5);
11755 if (astatic > 3) {
11756 DECR_AND_LOAD(4);
11757 }
11758 }
11759 }
11760 }
11761#undef DECR_AND_LOAD
11762
c48245f0
MR
11763 tcg_gen_movi_tl(t2, framesize);
11764 gen_op_addr_add(ctx, cpu_gpr[29], cpu_gpr[29], t2);
364d4831
NF
11765 tcg_temp_free(t0);
11766 tcg_temp_free(t1);
c48245f0 11767 tcg_temp_free(t2);
364d4831
NF
11768}
11769
11770static void gen_addiupc (DisasContext *ctx, int rx, int imm,
11771 int is_64_bit, int extended)
11772{
11773 TCGv t0;
11774
11775 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9c708c7f 11776 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
11777 return;
11778 }
11779
11780 t0 = tcg_temp_new();
11781
11782 tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
11783 tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
11784 if (!is_64_bit) {
11785 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
11786 }
11787
11788 tcg_temp_free(t0);
11789}
11790
0d74a222
LA
11791static void gen_cache_operation(DisasContext *ctx, uint32_t op, int base,
11792 int16_t offset)
11793{
11794 TCGv_i32 t0 = tcg_const_i32(op);
11795 TCGv t1 = tcg_temp_new();
11796 gen_base_offset_addr(ctx, t1, base, offset);
11797 gen_helper_cache(cpu_env, t1, t0);
11798}
11799
364d4831 11800#if defined(TARGET_MIPS64)
d75c135e 11801static void decode_i64_mips16 (DisasContext *ctx,
364d4831
NF
11802 int ry, int funct, int16_t offset,
11803 int extended)
11804{
11805 switch (funct) {
11806 case I64_LDSP:
d9224450 11807 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11808 check_mips_64(ctx);
11809 offset = extended ? offset : offset << 3;
d75c135e 11810 gen_ld(ctx, OPC_LD, ry, 29, offset);
364d4831
NF
11811 break;
11812 case I64_SDSP:
d9224450 11813 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11814 check_mips_64(ctx);
11815 offset = extended ? offset : offset << 3;
5c13fdfd 11816 gen_st(ctx, OPC_SD, ry, 29, offset);
364d4831
NF
11817 break;
11818 case I64_SDRASP:
d9224450 11819 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11820 check_mips_64(ctx);
11821 offset = extended ? offset : (ctx->opcode & 0xff) << 3;
5c13fdfd 11822 gen_st(ctx, OPC_SD, 31, 29, offset);
364d4831
NF
11823 break;
11824 case I64_DADJSP:
d9224450 11825 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11826 check_mips_64(ctx);
11827 offset = extended ? offset : ((int8_t)ctx->opcode) << 3;
d75c135e 11828 gen_arith_imm(ctx, OPC_DADDIU, 29, 29, offset);
364d4831
NF
11829 break;
11830 case I64_LDPC:
d9224450
MR
11831 check_insn(ctx, ISA_MIPS3);
11832 check_mips_64(ctx);
364d4831 11833 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9c708c7f 11834 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
11835 } else {
11836 offset = extended ? offset : offset << 3;
d75c135e 11837 gen_ld(ctx, OPC_LDPC, ry, 0, offset);
364d4831
NF
11838 }
11839 break;
11840 case I64_DADDIU5:
d9224450 11841 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11842 check_mips_64(ctx);
11843 offset = extended ? offset : ((int8_t)(offset << 3)) >> 3;
d75c135e 11844 gen_arith_imm(ctx, OPC_DADDIU, ry, ry, offset);
364d4831
NF
11845 break;
11846 case I64_DADDIUPC:
d9224450 11847 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11848 check_mips_64(ctx);
11849 offset = extended ? offset : offset << 2;
11850 gen_addiupc(ctx, ry, offset, 1, extended);
11851 break;
11852 case I64_DADDIUSP:
d9224450 11853 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11854 check_mips_64(ctx);
11855 offset = extended ? offset : offset << 2;
d75c135e 11856 gen_arith_imm(ctx, OPC_DADDIU, ry, 29, offset);
364d4831
NF
11857 break;
11858 }
11859}
11860#endif
11861
240ce26a 11862static int decode_extended_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
364d4831 11863{
eeb3bba8 11864 int extend = cpu_lduw_code(env, ctx->base.pc_next + 2);
364d4831
NF
11865 int op, rx, ry, funct, sa;
11866 int16_t imm, offset;
11867
11868 ctx->opcode = (ctx->opcode << 16) | extend;
11869 op = (ctx->opcode >> 11) & 0x1f;
11870 sa = (ctx->opcode >> 22) & 0x1f;
11871 funct = (ctx->opcode >> 8) & 0x7;
11872 rx = xlat((ctx->opcode >> 8) & 0x7);
11873 ry = xlat((ctx->opcode >> 5) & 0x7);
11874 offset = imm = (int16_t) (((ctx->opcode >> 16) & 0x1f) << 11
11875 | ((ctx->opcode >> 21) & 0x3f) << 5
11876 | (ctx->opcode & 0x1f));
11877
11878 /* The extended opcodes cleverly reuse the opcodes from their 16-bit
11879 counterparts. */
11880 switch (op) {
11881 case M16_OPC_ADDIUSP:
d75c135e 11882 gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
364d4831
NF
11883 break;
11884 case M16_OPC_ADDIUPC:
11885 gen_addiupc(ctx, rx, imm, 0, 1);
11886 break;
11887 case M16_OPC_B:
b231c103 11888 gen_compute_branch(ctx, OPC_BEQ, 4, 0, 0, offset << 1, 0);
364d4831
NF
11889 /* No delay slot, so just process as a normal instruction */
11890 break;
11891 case M16_OPC_BEQZ:
b231c103 11892 gen_compute_branch(ctx, OPC_BEQ, 4, rx, 0, offset << 1, 0);
364d4831
NF
11893 /* No delay slot, so just process as a normal instruction */
11894 break;
11895 case M16_OPC_BNEQZ:
b231c103 11896 gen_compute_branch(ctx, OPC_BNE, 4, rx, 0, offset << 1, 0);
364d4831
NF
11897 /* No delay slot, so just process as a normal instruction */
11898 break;
11899 case M16_OPC_SHIFT:
11900 switch (ctx->opcode & 0x3) {
11901 case 0x0:
d75c135e 11902 gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
364d4831
NF
11903 break;
11904 case 0x1:
11905#if defined(TARGET_MIPS64)
11906 check_mips_64(ctx);
d75c135e 11907 gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
364d4831 11908#else
9c708c7f 11909 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
11910#endif
11911 break;
11912 case 0x2:
d75c135e 11913 gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
364d4831
NF
11914 break;
11915 case 0x3:
d75c135e 11916 gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
364d4831
NF
11917 break;
11918 }
11919 break;
11920#if defined(TARGET_MIPS64)
11921 case M16_OPC_LD:
d9224450 11922 check_insn(ctx, ISA_MIPS3);
d75de749 11923 check_mips_64(ctx);
d75c135e 11924 gen_ld(ctx, OPC_LD, ry, rx, offset);
364d4831
NF
11925 break;
11926#endif
11927 case M16_OPC_RRIA:
11928 imm = ctx->opcode & 0xf;
11929 imm = imm | ((ctx->opcode >> 20) & 0x7f) << 4;
11930 imm = imm | ((ctx->opcode >> 16) & 0xf) << 11;
11931 imm = (int16_t) (imm << 1) >> 1;
11932 if ((ctx->opcode >> 4) & 0x1) {
11933#if defined(TARGET_MIPS64)
11934 check_mips_64(ctx);
d75c135e 11935 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
364d4831 11936#else
9c708c7f 11937 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
11938#endif
11939 } else {
d75c135e 11940 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
364d4831
NF
11941 }
11942 break;
11943 case M16_OPC_ADDIU8:
d75c135e 11944 gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
364d4831
NF
11945 break;
11946 case M16_OPC_SLTI:
d75c135e 11947 gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
364d4831
NF
11948 break;
11949 case M16_OPC_SLTIU:
d75c135e 11950 gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
364d4831
NF
11951 break;
11952 case M16_OPC_I8:
11953 switch (funct) {
11954 case I8_BTEQZ:
b231c103 11955 gen_compute_branch(ctx, OPC_BEQ, 4, 24, 0, offset << 1, 0);
364d4831
NF
11956 break;
11957 case I8_BTNEZ:
b231c103 11958 gen_compute_branch(ctx, OPC_BNE, 4, 24, 0, offset << 1, 0);
364d4831
NF
11959 break;
11960 case I8_SWRASP:
5c13fdfd 11961 gen_st(ctx, OPC_SW, 31, 29, imm);
364d4831
NF
11962 break;
11963 case I8_ADJSP:
d75c135e 11964 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm);
364d4831
NF
11965 break;
11966 case I8_SVRS:
d9224450 11967 check_insn(ctx, ISA_MIPS32);
364d4831
NF
11968 {
11969 int xsregs = (ctx->opcode >> 24) & 0x7;
11970 int aregs = (ctx->opcode >> 16) & 0xf;
11971 int do_ra = (ctx->opcode >> 6) & 0x1;
11972 int do_s0 = (ctx->opcode >> 5) & 0x1;
11973 int do_s1 = (ctx->opcode >> 4) & 0x1;
11974 int framesize = (((ctx->opcode >> 20) & 0xf) << 4
11975 | (ctx->opcode & 0xf)) << 3;
11976
11977 if (ctx->opcode & (1 << 7)) {
11978 gen_mips16_save(ctx, xsregs, aregs,
11979 do_ra, do_s0, do_s1,
11980 framesize);
11981 } else {
11982 gen_mips16_restore(ctx, xsregs, aregs,
11983 do_ra, do_s0, do_s1,
11984 framesize);
11985 }
11986 }
11987 break;
11988 default:
9c708c7f 11989 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
11990 break;
11991 }
11992 break;
11993 case M16_OPC_LI:
11994 tcg_gen_movi_tl(cpu_gpr[rx], (uint16_t) imm);
11995 break;
11996 case M16_OPC_CMPI:
11997 tcg_gen_xori_tl(cpu_gpr[24], cpu_gpr[rx], (uint16_t) imm);
11998 break;
11999#if defined(TARGET_MIPS64)
12000 case M16_OPC_SD:
d9224450
MR
12001 check_insn(ctx, ISA_MIPS3);
12002 check_mips_64(ctx);
5c13fdfd 12003 gen_st(ctx, OPC_SD, ry, rx, offset);
364d4831
NF
12004 break;
12005#endif
12006 case M16_OPC_LB:
d75c135e 12007 gen_ld(ctx, OPC_LB, ry, rx, offset);
364d4831
NF
12008 break;
12009 case M16_OPC_LH:
d75c135e 12010 gen_ld(ctx, OPC_LH, ry, rx, offset);
364d4831
NF
12011 break;
12012 case M16_OPC_LWSP:
d75c135e 12013 gen_ld(ctx, OPC_LW, rx, 29, offset);
364d4831
NF
12014 break;
12015 case M16_OPC_LW:
d75c135e 12016 gen_ld(ctx, OPC_LW, ry, rx, offset);
364d4831
NF
12017 break;
12018 case M16_OPC_LBU:
d75c135e 12019 gen_ld(ctx, OPC_LBU, ry, rx, offset);
364d4831
NF
12020 break;
12021 case M16_OPC_LHU:
d75c135e 12022 gen_ld(ctx, OPC_LHU, ry, rx, offset);
364d4831
NF
12023 break;
12024 case M16_OPC_LWPC:
d75c135e 12025 gen_ld(ctx, OPC_LWPC, rx, 0, offset);
364d4831
NF
12026 break;
12027#if defined(TARGET_MIPS64)
12028 case M16_OPC_LWU:
d9224450
MR
12029 check_insn(ctx, ISA_MIPS3);
12030 check_mips_64(ctx);
d75c135e 12031 gen_ld(ctx, OPC_LWU, ry, rx, offset);
364d4831
NF
12032 break;
12033#endif
12034 case M16_OPC_SB:
5c13fdfd 12035 gen_st(ctx, OPC_SB, ry, rx, offset);
364d4831
NF
12036 break;
12037 case M16_OPC_SH:
5c13fdfd 12038 gen_st(ctx, OPC_SH, ry, rx, offset);
364d4831
NF
12039 break;
12040 case M16_OPC_SWSP:
5c13fdfd 12041 gen_st(ctx, OPC_SW, rx, 29, offset);
364d4831
NF
12042 break;
12043 case M16_OPC_SW:
5c13fdfd 12044 gen_st(ctx, OPC_SW, ry, rx, offset);
364d4831
NF
12045 break;
12046#if defined(TARGET_MIPS64)
12047 case M16_OPC_I64:
d75c135e 12048 decode_i64_mips16(ctx, ry, funct, offset, 1);
364d4831
NF
12049 break;
12050#endif
12051 default:
9c708c7f 12052 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
12053 break;
12054 }
12055
12056 return 4;
12057}
12058
3b3c1694
LA
12059static inline bool is_uhi(int sdbbp_code)
12060{
12061#ifdef CONFIG_USER_ONLY
12062 return false;
12063#else
12064 return semihosting_enabled() && sdbbp_code == 1;
12065#endif
12066}
12067
240ce26a 12068static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
364d4831
NF
12069{
12070 int rx, ry;
12071 int sa;
12072 int op, cnvt_op, op1, offset;
12073 int funct;
12074 int n_bytes;
12075
12076 op = (ctx->opcode >> 11) & 0x1f;
12077 sa = (ctx->opcode >> 2) & 0x7;
12078 sa = sa == 0 ? 8 : sa;
12079 rx = xlat((ctx->opcode >> 8) & 0x7);
12080 cnvt_op = (ctx->opcode >> 5) & 0x7;
12081 ry = xlat((ctx->opcode >> 5) & 0x7);
12082 op1 = offset = ctx->opcode & 0x1f;
12083
12084 n_bytes = 2;
12085
12086 switch (op) {
12087 case M16_OPC_ADDIUSP:
12088 {
12089 int16_t imm = ((uint8_t) ctx->opcode) << 2;
12090
d75c135e 12091 gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
364d4831
NF
12092 }
12093 break;
12094 case M16_OPC_ADDIUPC:
12095 gen_addiupc(ctx, rx, ((uint8_t) ctx->opcode) << 2, 0, 0);
12096 break;
12097 case M16_OPC_B:
12098 offset = (ctx->opcode & 0x7ff) << 1;
12099 offset = (int16_t)(offset << 4) >> 4;
b231c103 12100 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, offset, 0);
364d4831
NF
12101 /* No delay slot, so just process as a normal instruction */
12102 break;
12103 case M16_OPC_JAL:
eeb3bba8 12104 offset = cpu_lduw_code(env, ctx->base.pc_next + 2);
364d4831
NF
12105 offset = (((ctx->opcode & 0x1f) << 21)
12106 | ((ctx->opcode >> 5) & 0x1f) << 16
12107 | offset) << 2;
b231c103
YK
12108 op = ((ctx->opcode >> 10) & 0x1) ? OPC_JALX : OPC_JAL;
12109 gen_compute_branch(ctx, op, 4, rx, ry, offset, 2);
364d4831 12110 n_bytes = 4;
364d4831
NF
12111 break;
12112 case M16_OPC_BEQZ:
b231c103
YK
12113 gen_compute_branch(ctx, OPC_BEQ, 2, rx, 0,
12114 ((int8_t)ctx->opcode) << 1, 0);
364d4831
NF
12115 /* No delay slot, so just process as a normal instruction */
12116 break;
12117 case M16_OPC_BNEQZ:
b231c103
YK
12118 gen_compute_branch(ctx, OPC_BNE, 2, rx, 0,
12119 ((int8_t)ctx->opcode) << 1, 0);
364d4831
NF
12120 /* No delay slot, so just process as a normal instruction */
12121 break;
12122 case M16_OPC_SHIFT:
12123 switch (ctx->opcode & 0x3) {
12124 case 0x0:
d75c135e 12125 gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
364d4831
NF
12126 break;
12127 case 0x1:
12128#if defined(TARGET_MIPS64)
d9224450 12129 check_insn(ctx, ISA_MIPS3);
364d4831 12130 check_mips_64(ctx);
d75c135e 12131 gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
364d4831 12132#else
9c708c7f 12133 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
12134#endif
12135 break;
12136 case 0x2:
d75c135e 12137 gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
364d4831
NF
12138 break;
12139 case 0x3:
d75c135e 12140 gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
364d4831
NF
12141 break;
12142 }
12143 break;
12144#if defined(TARGET_MIPS64)
12145 case M16_OPC_LD:
d9224450 12146 check_insn(ctx, ISA_MIPS3);
364d4831 12147 check_mips_64(ctx);
d75c135e 12148 gen_ld(ctx, OPC_LD, ry, rx, offset << 3);
364d4831
NF
12149 break;
12150#endif
12151 case M16_OPC_RRIA:
12152 {
12153 int16_t imm = (int8_t)((ctx->opcode & 0xf) << 4) >> 4;
12154
12155 if ((ctx->opcode >> 4) & 1) {
12156#if defined(TARGET_MIPS64)
d9224450 12157 check_insn(ctx, ISA_MIPS3);
364d4831 12158 check_mips_64(ctx);
d75c135e 12159 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
364d4831 12160#else
9c708c7f 12161 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
12162#endif
12163 } else {
d75c135e 12164 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
364d4831
NF
12165 }
12166 }
12167 break;
12168 case M16_OPC_ADDIU8:
12169 {
12170 int16_t imm = (int8_t) ctx->opcode;
12171
d75c135e 12172 gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
364d4831
NF
12173 }
12174 break;
12175 case M16_OPC_SLTI:
12176 {
12177 int16_t imm = (uint8_t) ctx->opcode;
d75c135e 12178 gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
364d4831
NF
12179 }
12180 break;
12181 case M16_OPC_SLTIU:
12182 {
12183 int16_t imm = (uint8_t) ctx->opcode;
d75c135e 12184 gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
364d4831
NF
12185 }
12186 break;
12187 case M16_OPC_I8:
12188 {
12189 int reg32;
12190
12191 funct = (ctx->opcode >> 8) & 0x7;
12192 switch (funct) {
12193 case I8_BTEQZ:
12194 gen_compute_branch(ctx, OPC_BEQ, 2, 24, 0,
b231c103 12195 ((int8_t)ctx->opcode) << 1, 0);
364d4831
NF
12196 break;
12197 case I8_BTNEZ:
12198 gen_compute_branch(ctx, OPC_BNE, 2, 24, 0,
b231c103 12199 ((int8_t)ctx->opcode) << 1, 0);
364d4831
NF
12200 break;
12201 case I8_SWRASP:
5c13fdfd 12202 gen_st(ctx, OPC_SW, 31, 29, (ctx->opcode & 0xff) << 2);
364d4831
NF
12203 break;
12204 case I8_ADJSP:
d75c135e 12205 gen_arith_imm(ctx, OPC_ADDIU, 29, 29,
364d4831
NF
12206 ((int8_t)ctx->opcode) << 3);
12207 break;
12208 case I8_SVRS:
d9224450 12209 check_insn(ctx, ISA_MIPS32);
364d4831
NF
12210 {
12211 int do_ra = ctx->opcode & (1 << 6);
12212 int do_s0 = ctx->opcode & (1 << 5);
12213 int do_s1 = ctx->opcode & (1 << 4);
12214 int framesize = ctx->opcode & 0xf;
12215
12216 if (framesize == 0) {
12217 framesize = 128;
12218 } else {
12219 framesize = framesize << 3;
12220 }
12221
12222 if (ctx->opcode & (1 << 7)) {
12223 gen_mips16_save(ctx, 0, 0,
12224 do_ra, do_s0, do_s1, framesize);
12225 } else {
12226 gen_mips16_restore(ctx, 0, 0,
12227 do_ra, do_s0, do_s1, framesize);
12228 }
12229 }
12230 break;
12231 case I8_MOV32R:
12232 {
12233 int rz = xlat(ctx->opcode & 0x7);
12234
12235 reg32 = (((ctx->opcode >> 3) & 0x3) << 3) |
12236 ((ctx->opcode >> 5) & 0x7);
d75c135e 12237 gen_arith(ctx, OPC_ADDU, reg32, rz, 0);
364d4831
NF
12238 }
12239 break;
12240 case I8_MOVR32:
12241 reg32 = ctx->opcode & 0x1f;
d75c135e 12242 gen_arith(ctx, OPC_ADDU, ry, reg32, 0);
364d4831
NF
12243 break;
12244 default:
9c708c7f 12245 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
12246 break;
12247 }
12248 }
12249 break;
12250 case M16_OPC_LI:
12251 {
12252 int16_t imm = (uint8_t) ctx->opcode;
12253
d75c135e 12254 gen_arith_imm(ctx, OPC_ADDIU, rx, 0, imm);
364d4831
NF
12255 }
12256 break;
12257 case M16_OPC_CMPI:
12258 {
12259 int16_t imm = (uint8_t) ctx->opcode;
d75c135e 12260 gen_logic_imm(ctx, OPC_XORI, 24, rx, imm);
364d4831
NF
12261 }
12262 break;
12263#if defined(TARGET_MIPS64)
12264 case M16_OPC_SD:
d9224450 12265 check_insn(ctx, ISA_MIPS3);
364d4831 12266 check_mips_64(ctx);
5c13fdfd 12267 gen_st(ctx, OPC_SD, ry, rx, offset << 3);
364d4831
NF
12268 break;
12269#endif
12270 case M16_OPC_LB:
d75c135e 12271 gen_ld(ctx, OPC_LB, ry, rx, offset);
364d4831
NF
12272 break;
12273 case M16_OPC_LH:
d75c135e 12274 gen_ld(ctx, OPC_LH, ry, rx, offset << 1);
364d4831
NF
12275 break;
12276 case M16_OPC_LWSP:
d75c135e 12277 gen_ld(ctx, OPC_LW, rx, 29, ((uint8_t)ctx->opcode) << 2);
364d4831
NF
12278 break;
12279 case M16_OPC_LW:
d75c135e 12280 gen_ld(ctx, OPC_LW, ry, rx, offset << 2);
364d4831
NF
12281 break;
12282 case M16_OPC_LBU:
d75c135e 12283 gen_ld(ctx, OPC_LBU, ry, rx, offset);
364d4831
NF
12284 break;
12285 case M16_OPC_LHU:
d75c135e 12286 gen_ld(ctx, OPC_LHU, ry, rx, offset << 1);
364d4831
NF
12287 break;
12288 case M16_OPC_LWPC:
d75c135e 12289 gen_ld(ctx, OPC_LWPC, rx, 0, ((uint8_t)ctx->opcode) << 2);
364d4831
NF
12290 break;
12291#if defined (TARGET_MIPS64)
12292 case M16_OPC_LWU:
d9224450 12293 check_insn(ctx, ISA_MIPS3);
364d4831 12294 check_mips_64(ctx);
d75c135e 12295 gen_ld(ctx, OPC_LWU, ry, rx, offset << 2);
364d4831
NF
12296 break;
12297#endif
12298 case M16_OPC_SB:
5c13fdfd 12299 gen_st(ctx, OPC_SB, ry, rx, offset);
364d4831
NF
12300 break;
12301 case M16_OPC_SH:
5c13fdfd 12302 gen_st(ctx, OPC_SH, ry, rx, offset << 1);
364d4831
NF
12303 break;
12304 case M16_OPC_SWSP:
5c13fdfd 12305 gen_st(ctx, OPC_SW, rx, 29, ((uint8_t)ctx->opcode) << 2);
364d4831
NF
12306 break;
12307 case M16_OPC_SW:
5c13fdfd 12308 gen_st(ctx, OPC_SW, ry, rx, offset << 2);
364d4831
NF
12309 break;
12310 case M16_OPC_RRR:
12311 {
12312 int rz = xlat((ctx->opcode >> 2) & 0x7);
12313 int mips32_op;
12314
12315 switch (ctx->opcode & 0x3) {
12316 case RRR_ADDU:
12317 mips32_op = OPC_ADDU;
12318 break;
12319 case RRR_SUBU:
12320 mips32_op = OPC_SUBU;
12321 break;
12322#if defined(TARGET_MIPS64)
12323 case RRR_DADDU:
12324 mips32_op = OPC_DADDU;
d9224450 12325 check_insn(ctx, ISA_MIPS3);
364d4831
NF
12326 check_mips_64(ctx);
12327 break;
12328 case RRR_DSUBU:
12329 mips32_op = OPC_DSUBU;
d9224450 12330 check_insn(ctx, ISA_MIPS3);
364d4831
NF
12331 check_mips_64(ctx);
12332 break;
12333#endif
12334 default:
9c708c7f 12335 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
12336 goto done;
12337 }
12338
d75c135e 12339 gen_arith(ctx, mips32_op, rz, rx, ry);
364d4831
NF
12340 done:
12341 ;
12342 }
12343 break;
12344 case M16_OPC_RR:
12345 switch (op1) {
12346 case RR_JR:
12347 {
12348 int nd = (ctx->opcode >> 7) & 0x1;
12349 int link = (ctx->opcode >> 6) & 0x1;
12350 int ra = (ctx->opcode >> 5) & 0x1;
12351
d9224450
MR
12352 if (nd) {
12353 check_insn(ctx, ISA_MIPS32);
12354 }
12355
364d4831 12356 if (link) {
b231c103 12357 op = OPC_JALR;
364d4831
NF
12358 } else {
12359 op = OPC_JR;
12360 }
12361
b231c103
YK
12362 gen_compute_branch(ctx, op, 2, ra ? 31 : rx, 31, 0,
12363 (nd ? 0 : 2));
364d4831
NF
12364 }
12365 break;
12366 case RR_SDBBP:
3b3c1694
LA
12367 if (is_uhi(extract32(ctx->opcode, 5, 6))) {
12368 gen_helper_do_semihosting(cpu_env);
12369 } else {
12370 /* XXX: not clear which exception should be raised
12371 * when in debug mode...
12372 */
12373 check_insn(ctx, ISA_MIPS32);
9c708c7f 12374 generate_exception_end(ctx, EXCP_DBp);
3b3c1694 12375 }
364d4831
NF
12376 break;
12377 case RR_SLT:
d75c135e 12378 gen_slt(ctx, OPC_SLT, 24, rx, ry);
364d4831
NF
12379 break;
12380 case RR_SLTU:
d75c135e 12381 gen_slt(ctx, OPC_SLTU, 24, rx, ry);
364d4831
NF
12382 break;
12383 case RR_BREAK:
9c708c7f 12384 generate_exception_end(ctx, EXCP_BREAK);
364d4831
NF
12385 break;
12386 case RR_SLLV:
d75c135e 12387 gen_shift(ctx, OPC_SLLV, ry, rx, ry);
364d4831
NF
12388 break;
12389 case RR_SRLV:
d75c135e 12390 gen_shift(ctx, OPC_SRLV, ry, rx, ry);
364d4831
NF
12391 break;
12392 case RR_SRAV:
d75c135e 12393 gen_shift(ctx, OPC_SRAV, ry, rx, ry);
364d4831
NF
12394 break;
12395#if defined (TARGET_MIPS64)
12396 case RR_DSRL:
d9224450 12397 check_insn(ctx, ISA_MIPS3);
364d4831 12398 check_mips_64(ctx);
d75c135e 12399 gen_shift_imm(ctx, OPC_DSRL, ry, ry, sa);
364d4831
NF
12400 break;
12401#endif
12402 case RR_CMP:
d75c135e 12403 gen_logic(ctx, OPC_XOR, 24, rx, ry);
364d4831
NF
12404 break;
12405 case RR_NEG:
d75c135e 12406 gen_arith(ctx, OPC_SUBU, rx, 0, ry);
364d4831
NF
12407 break;
12408 case RR_AND:
d75c135e 12409 gen_logic(ctx, OPC_AND, rx, rx, ry);
364d4831
NF
12410 break;
12411 case RR_OR:
d75c135e 12412 gen_logic(ctx, OPC_OR, rx, rx, ry);
364d4831
NF
12413 break;
12414 case RR_XOR:
d75c135e 12415 gen_logic(ctx, OPC_XOR, rx, rx, ry);
364d4831
NF
12416 break;
12417 case RR_NOT:
d75c135e 12418 gen_logic(ctx, OPC_NOR, rx, ry, 0);
364d4831
NF
12419 break;
12420 case RR_MFHI:
26135ead 12421 gen_HILO(ctx, OPC_MFHI, 0, rx);
364d4831
NF
12422 break;
12423 case RR_CNVT:
d9224450 12424 check_insn(ctx, ISA_MIPS32);
364d4831
NF
12425 switch (cnvt_op) {
12426 case RR_RY_CNVT_ZEB:
12427 tcg_gen_ext8u_tl(cpu_gpr[rx], cpu_gpr[rx]);
12428 break;
12429 case RR_RY_CNVT_ZEH:
12430 tcg_gen_ext16u_tl(cpu_gpr[rx], cpu_gpr[rx]);
12431 break;
12432 case RR_RY_CNVT_SEB:
12433 tcg_gen_ext8s_tl(cpu_gpr[rx], cpu_gpr[rx]);
12434 break;
12435 case RR_RY_CNVT_SEH:
12436 tcg_gen_ext16s_tl(cpu_gpr[rx], cpu_gpr[rx]);
12437 break;
12438#if defined (TARGET_MIPS64)
12439 case RR_RY_CNVT_ZEW:
d9224450 12440 check_insn(ctx, ISA_MIPS64);
364d4831
NF
12441 check_mips_64(ctx);
12442 tcg_gen_ext32u_tl(cpu_gpr[rx], cpu_gpr[rx]);
12443 break;
12444 case RR_RY_CNVT_SEW:
d9224450 12445 check_insn(ctx, ISA_MIPS64);
364d4831
NF
12446 check_mips_64(ctx);
12447 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
12448 break;
12449#endif
12450 default:
9c708c7f 12451 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
12452 break;
12453 }
12454 break;
12455 case RR_MFLO:
26135ead 12456 gen_HILO(ctx, OPC_MFLO, 0, rx);
364d4831
NF
12457 break;
12458#if defined (TARGET_MIPS64)
12459 case RR_DSRA:
d9224450 12460 check_insn(ctx, ISA_MIPS3);
364d4831 12461 check_mips_64(ctx);
d75c135e 12462 gen_shift_imm(ctx, OPC_DSRA, ry, ry, sa);
364d4831
NF
12463 break;
12464 case RR_DSLLV:
d9224450 12465 check_insn(ctx, ISA_MIPS3);
364d4831 12466 check_mips_64(ctx);
d75c135e 12467 gen_shift(ctx, OPC_DSLLV, ry, rx, ry);
364d4831
NF
12468 break;
12469 case RR_DSRLV:
d9224450 12470 check_insn(ctx, ISA_MIPS3);
364d4831 12471 check_mips_64(ctx);
d75c135e 12472 gen_shift(ctx, OPC_DSRLV, ry, rx, ry);
364d4831
NF
12473 break;
12474 case RR_DSRAV:
d9224450 12475 check_insn(ctx, ISA_MIPS3);
364d4831 12476 check_mips_64(ctx);
d75c135e 12477 gen_shift(ctx, OPC_DSRAV, ry, rx, ry);
364d4831
NF
12478 break;
12479#endif
12480 case RR_MULT:
26135ead 12481 gen_muldiv(ctx, OPC_MULT, 0, rx, ry);
364d4831
NF
12482 break;
12483 case RR_MULTU:
26135ead 12484 gen_muldiv(ctx, OPC_MULTU, 0, rx, ry);
364d4831
NF
12485 break;
12486 case RR_DIV:
26135ead 12487 gen_muldiv(ctx, OPC_DIV, 0, rx, ry);
364d4831
NF
12488 break;
12489 case RR_DIVU:
26135ead 12490 gen_muldiv(ctx, OPC_DIVU, 0, rx, ry);
364d4831
NF
12491 break;
12492#if defined (TARGET_MIPS64)
12493 case RR_DMULT:
d9224450 12494 check_insn(ctx, ISA_MIPS3);
364d4831 12495 check_mips_64(ctx);
26135ead 12496 gen_muldiv(ctx, OPC_DMULT, 0, rx, ry);
364d4831
NF
12497 break;
12498 case RR_DMULTU:
d9224450 12499 check_insn(ctx, ISA_MIPS3);
364d4831 12500 check_mips_64(ctx);
26135ead 12501 gen_muldiv(ctx, OPC_DMULTU, 0, rx, ry);
364d4831
NF
12502 break;
12503 case RR_DDIV:
d9224450 12504 check_insn(ctx, ISA_MIPS3);
364d4831 12505 check_mips_64(ctx);
26135ead 12506 gen_muldiv(ctx, OPC_DDIV, 0, rx, ry);
364d4831
NF
12507 break;
12508 case RR_DDIVU:
d9224450 12509 check_insn(ctx, ISA_MIPS3);
364d4831 12510 check_mips_64(ctx);
26135ead 12511 gen_muldiv(ctx, OPC_DDIVU, 0, rx, ry);
364d4831
NF
12512 break;
12513#endif
12514 default:
9c708c7f 12515 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
12516 break;
12517 }
12518 break;
12519 case M16_OPC_EXTEND:
240ce26a 12520 decode_extended_mips16_opc(env, ctx);
364d4831
NF
12521 n_bytes = 4;
12522 break;
12523#if defined(TARGET_MIPS64)
12524 case M16_OPC_I64:
12525 funct = (ctx->opcode >> 8) & 0x7;
d75c135e 12526 decode_i64_mips16(ctx, ry, funct, offset, 0);
364d4831
NF
12527 break;
12528#endif
12529 default:
9c708c7f 12530 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
12531 break;
12532 }
12533
12534 return n_bytes;
12535}
12536
211da992 12537/* microMIPS extension to MIPS32/MIPS64 */
6af0bf9c 12538
211da992
CWR
12539/*
12540 * microMIPS32/microMIPS64 major opcodes
12541 *
12542 * 1. MIPS Architecture for Programmers Volume II-B:
12543 * The microMIPS32 Instruction Set (Revision 3.05)
12544 *
12545 * Table 6.2 microMIPS32 Encoding of Major Opcode Field
12546 *
12547 * 2. MIPS Architecture For Programmers Volume II-A:
12548 * The MIPS64 Instruction Set (Revision 3.51)
12549 */
6af0bf9c 12550
3c824109
NF
12551enum {
12552 POOL32A = 0x00,
12553 POOL16A = 0x01,
12554 LBU16 = 0x02,
12555 MOVE16 = 0x03,
12556 ADDI32 = 0x04,
3a1f4268
YK
12557 R6_LUI = 0x04,
12558 AUI = 0x04,
3c824109
NF
12559 LBU32 = 0x05,
12560 SB32 = 0x06,
12561 LB32 = 0x07,
12562
12563 POOL32B = 0x08,
12564 POOL16B = 0x09,
12565 LHU16 = 0x0a,
12566 ANDI16 = 0x0b,
12567 ADDIU32 = 0x0c,
12568 LHU32 = 0x0d,
12569 SH32 = 0x0e,
12570 LH32 = 0x0f,
12571
12572 POOL32I = 0x10,
12573 POOL16C = 0x11,
12574 LWSP16 = 0x12,
12575 POOL16D = 0x13,
12576 ORI32 = 0x14,
12577 POOL32F = 0x15,
211da992
CWR
12578 POOL32S = 0x16, /* MIPS64 */
12579 DADDIU32 = 0x17, /* MIPS64 */
3c824109
NF
12580
12581 POOL32C = 0x18,
12582 LWGP16 = 0x19,
12583 LW16 = 0x1a,
12584 POOL16E = 0x1b,
12585 XORI32 = 0x1c,
12586 JALS32 = 0x1d,
3a1f4268
YK
12587 BOVC = 0x1d,
12588 BEQC = 0x1d,
12589 BEQZALC = 0x1d,
3c824109 12590 ADDIUPC = 0x1e,
3a1f4268
YK
12591 PCREL = 0x1e,
12592 BNVC = 0x1f,
12593 BNEC = 0x1f,
12594 BNEZALC = 0x1f,
3c824109 12595
3a1f4268
YK
12596 R6_BEQZC = 0x20,
12597 JIC = 0x20,
3c824109
NF
12598 POOL16F = 0x21,
12599 SB16 = 0x22,
12600 BEQZ16 = 0x23,
3a1f4268 12601 BEQZC16 = 0x23,
3c824109
NF
12602 SLTI32 = 0x24,
12603 BEQ32 = 0x25,
3a1f4268 12604 BC = 0x25,
3c824109
NF
12605 SWC132 = 0x26,
12606 LWC132 = 0x27,
12607
3a1f4268 12608 /* 0x29 is reserved */
3c824109 12609 RES_29 = 0x29,
3a1f4268
YK
12610 R6_BNEZC = 0x28,
12611 JIALC = 0x28,
3c824109
NF
12612 SH16 = 0x2a,
12613 BNEZ16 = 0x2b,
3a1f4268 12614 BNEZC16 = 0x2b,
3c824109
NF
12615 SLTIU32 = 0x2c,
12616 BNE32 = 0x2d,
3a1f4268 12617 BALC = 0x2d,
3c824109
NF
12618 SDC132 = 0x2e,
12619 LDC132 = 0x2f,
12620
3a1f4268 12621 /* 0x31 is reserved */
3c824109 12622 RES_31 = 0x31,
3a1f4268
YK
12623 BLEZALC = 0x30,
12624 BGEZALC = 0x30,
12625 BGEUC = 0x30,
3c824109
NF
12626 SWSP16 = 0x32,
12627 B16 = 0x33,
3a1f4268 12628 BC16 = 0x33,
3c824109
NF
12629 ANDI32 = 0x34,
12630 J32 = 0x35,
3a1f4268
YK
12631 BGTZC = 0x35,
12632 BLTZC = 0x35,
12633 BLTC = 0x35,
211da992
CWR
12634 SD32 = 0x36, /* MIPS64 */
12635 LD32 = 0x37, /* MIPS64 */
3c824109 12636
3a1f4268 12637 /* 0x39 is reserved */
3c824109 12638 RES_39 = 0x39,
3a1f4268
YK
12639 BGTZALC = 0x38,
12640 BLTZALC = 0x38,
12641 BLTUC = 0x38,
3c824109
NF
12642 SW16 = 0x3a,
12643 LI16 = 0x3b,
12644 JALX32 = 0x3c,
12645 JAL32 = 0x3d,
3a1f4268
YK
12646 BLEZC = 0x3d,
12647 BGEZC = 0x3d,
12648 BGEC = 0x3d,
3c824109
NF
12649 SW32 = 0x3e,
12650 LW32 = 0x3f
12651};
12652
3a1f4268
YK
12653/* PCREL Instructions perform PC-Relative address calculation. bits 20..16 */
12654enum {
12655 ADDIUPC_00 = 0x00,
c38a1d52
AR
12656 ADDIUPC_01 = 0x01,
12657 ADDIUPC_02 = 0x02,
12658 ADDIUPC_03 = 0x03,
12659 ADDIUPC_04 = 0x04,
12660 ADDIUPC_05 = 0x05,
12661 ADDIUPC_06 = 0x06,
3a1f4268
YK
12662 ADDIUPC_07 = 0x07,
12663 AUIPC = 0x1e,
12664 ALUIPC = 0x1f,
12665 LWPC_08 = 0x08,
c38a1d52
AR
12666 LWPC_09 = 0x09,
12667 LWPC_0A = 0x0A,
12668 LWPC_0B = 0x0B,
12669 LWPC_0C = 0x0C,
12670 LWPC_0D = 0x0D,
12671 LWPC_0E = 0x0E,
3a1f4268
YK
12672 LWPC_0F = 0x0F,
12673};
12674
3c824109
NF
12675/* POOL32A encoding of minor opcode field */
12676
12677enum {
12678 /* These opcodes are distinguished only by bits 9..6; those bits are
12679 * what are recorded below. */
12680 SLL32 = 0x0,
12681 SRL32 = 0x1,
12682 SRA = 0x2,
12683 ROTR = 0x3,
3a1f4268
YK
12684 SELEQZ = 0x5,
12685 SELNEZ = 0x6,
b00c7218 12686 R6_RDHWR = 0x7,
3c824109
NF
12687
12688 SLLV = 0x0,
12689 SRLV = 0x1,
12690 SRAV = 0x2,
12691 ROTRV = 0x3,
12692 ADD = 0x4,
12693 ADDU32 = 0x5,
12694 SUB = 0x6,
12695 SUBU32 = 0x7,
12696 MUL = 0x8,
12697 AND = 0x9,
12698 OR32 = 0xa,
12699 NOR = 0xb,
12700 XOR32 = 0xc,
12701 SLT = 0xd,
12702 SLTU = 0xe,
12703
12704 MOVN = 0x0,
3a1f4268 12705 R6_MUL = 0x0,
3c824109 12706 MOVZ = 0x1,
3a1f4268
YK
12707 MUH = 0x1,
12708 MULU = 0x2,
12709 MUHU = 0x3,
3c824109 12710 LWXS = 0x4,
3a1f4268
YK
12711 R6_DIV = 0x4,
12712 MOD = 0x5,
12713 R6_DIVU = 0x6,
12714 MODU = 0x7,
3c824109
NF
12715
12716 /* The following can be distinguished by their lower 6 bits. */
dbd8af98 12717 BREAK32 = 0x07,
3c824109 12718 INS = 0x0c,
3a1f4268
YK
12719 LSA = 0x0f,
12720 ALIGN = 0x1f,
3c824109 12721 EXT = 0x2c,
bb238210
YK
12722 POOL32AXF = 0x3c,
12723 SIGRIE = 0x3f
3c824109
NF
12724};
12725
12726/* POOL32AXF encoding of minor opcode field extension */
12727
d132c79f
CWR
12728/*
12729 * 1. MIPS Architecture for Programmers Volume II-B:
12730 * The microMIPS32 Instruction Set (Revision 3.05)
12731 *
12732 * Table 6.5 POOL32Axf Encoding of Minor Opcode Extension Field
12733 *
12734 * 2. MIPS Architecture for Programmers VolumeIV-e:
12735 * The MIPS DSP Application-Specific Extension
12736 * to the microMIPS32 Architecture (Revision 2.34)
12737 *
12738 * Table 5.5 POOL32Axf Encoding of Minor Opcode Extension Field
12739 */
12740
3c824109
NF
12741enum {
12742 /* bits 11..6 */
12743 TEQ = 0x00,
12744 TGE = 0x08,
12745 TGEU = 0x10,
12746 TLT = 0x20,
12747 TLTU = 0x28,
12748 TNE = 0x30,
12749
12750 MFC0 = 0x03,
12751 MTC0 = 0x0b,
12752
d132c79f
CWR
12753 /* begin of microMIPS32 DSP */
12754
3c824109
NF
12755 /* bits 13..12 for 0x01 */
12756 MFHI_ACC = 0x0,
12757 MFLO_ACC = 0x1,
12758 MTHI_ACC = 0x2,
12759 MTLO_ACC = 0x3,
12760
12761 /* bits 13..12 for 0x2a */
12762 MADD_ACC = 0x0,
12763 MADDU_ACC = 0x1,
12764 MSUB_ACC = 0x2,
12765 MSUBU_ACC = 0x3,
12766
12767 /* bits 13..12 for 0x32 */
12768 MULT_ACC = 0x0,
6801038b 12769 MULTU_ACC = 0x1,
3c824109 12770
d132c79f
CWR
12771 /* end of microMIPS32 DSP */
12772
3c824109 12773 /* bits 15..12 for 0x2c */
3a1f4268 12774 BITSWAP = 0x0,
3c824109
NF
12775 SEB = 0x2,
12776 SEH = 0x3,
12777 CLO = 0x4,
12778 CLZ = 0x5,
12779 RDHWR = 0x6,
12780 WSBH = 0x7,
12781 MULT = 0x8,
12782 MULTU = 0x9,
12783 DIV = 0xa,
12784 DIVU = 0xb,
12785 MADD = 0xc,
12786 MADDU = 0xd,
12787 MSUB = 0xe,
12788 MSUBU = 0xf,
12789
12790 /* bits 15..12 for 0x34 */
12791 MFC2 = 0x4,
12792 MTC2 = 0x5,
12793 MFHC2 = 0x8,
12794 MTHC2 = 0x9,
12795 CFC2 = 0xc,
12796 CTC2 = 0xd,
12797
12798 /* bits 15..12 for 0x3c */
12799 JALR = 0x0,
12800 JR = 0x0, /* alias */
3a1f4268
YK
12801 JALRC = 0x0,
12802 JRC = 0x0,
3c824109 12803 JALR_HB = 0x1,
3a1f4268 12804 JALRC_HB = 0x1,
3c824109
NF
12805 JALRS = 0x4,
12806 JALRS_HB = 0x5,
12807
12808 /* bits 15..12 for 0x05 */
12809 RDPGPR = 0xe,
12810 WRPGPR = 0xf,
12811
12812 /* bits 15..12 for 0x0d */
12813 TLBP = 0x0,
12814 TLBR = 0x1,
12815 TLBWI = 0x2,
12816 TLBWR = 0x3,
e60ec063
YK
12817 TLBINV = 0x4,
12818 TLBINVF = 0x5,
3c824109
NF
12819 WAIT = 0x9,
12820 IRET = 0xd,
12821 DERET = 0xe,
12822 ERET = 0xf,
12823
12824 /* bits 15..12 for 0x15 */
12825 DMT = 0x0,
12826 DVPE = 0x1,
12827 EMT = 0x2,
12828 EVPE = 0x3,
12829
12830 /* bits 15..12 for 0x1d */
12831 DI = 0x4,
12832 EI = 0x5,
12833
12834 /* bits 15..12 for 0x2d */
12835 SYNC = 0x6,
12836 SYSCALL = 0x8,
12837 SDBBP = 0xd,
12838
12839 /* bits 15..12 for 0x35 */
12840 MFHI32 = 0x0,
12841 MFLO32 = 0x1,
12842 MTHI32 = 0x2,
12843 MTLO32 = 0x3,
12844};
12845
12846/* POOL32B encoding of minor opcode field (bits 15..12) */
12847
12848enum {
12849 LWC2 = 0x0,
12850 LWP = 0x1,
12851 LDP = 0x4,
12852 LWM32 = 0x5,
12853 CACHE = 0x6,
12854 LDM = 0x7,
12855 SWC2 = 0x8,
12856 SWP = 0x9,
12857 SDP = 0xc,
12858 SWM32 = 0xd,
12859 SDM = 0xf
12860};
12861
12862/* POOL32C encoding of minor opcode field (bits 15..12) */
12863
12864enum {
12865 LWL = 0x0,
12866 SWL = 0x8,
12867 LWR = 0x1,
12868 SWR = 0x9,
12869 PREF = 0x2,
8fffc646 12870 ST_EVA = 0xa,
3c824109
NF
12871 LL = 0x3,
12872 SC = 0xb,
12873 LDL = 0x4,
12874 SDL = 0xc,
12875 LDR = 0x5,
12876 SDR = 0xd,
8fffc646 12877 LD_EVA = 0x6,
3c824109
NF
12878 LWU = 0xe,
12879 LLD = 0x7,
12880 SCD = 0xf
12881};
12882
8fffc646
JH
12883/* POOL32C LD-EVA encoding of minor opcode field (bits 11..9) */
12884
12885enum {
12886 LBUE = 0x0,
12887 LHUE = 0x1,
12888 LWLE = 0x2,
12889 LWRE = 0x3,
12890 LBE = 0x4,
12891 LHE = 0x5,
12892 LLE = 0x6,
12893 LWE = 0x7,
12894};
12895
12896/* POOL32C ST-EVA encoding of minor opcode field (bits 11..9) */
12897
12898enum {
12899 SWLE = 0x0,
12900 SWRE = 0x1,
12901 PREFE = 0x2,
12902 CACHEE = 0x3,
12903 SBE = 0x4,
12904 SHE = 0x5,
12905 SCE = 0x6,
12906 SWE = 0x7,
12907};
12908
3c824109
NF
12909/* POOL32F encoding of minor opcode field (bits 5..0) */
12910
12911enum {
12912 /* These are the bit 7..6 values */
12913 ADD_FMT = 0x0,
3c824109
NF
12914
12915 SUB_FMT = 0x1,
3c824109
NF
12916
12917 MUL_FMT = 0x2,
12918
12919 DIV_FMT = 0x3,
12920
12921 /* These are the bit 8..6 values */
3a1f4268 12922 MOVN_FMT = 0x0,
3c824109
NF
12923 RSQRT2_FMT = 0x0,
12924 MOVF_FMT = 0x0,
3a1f4268
YK
12925 RINT_FMT = 0x0,
12926 SELNEZ_FMT = 0x0,
3c824109 12927
3a1f4268 12928 MOVZ_FMT = 0x1,
3c824109
NF
12929 LWXC1 = 0x1,
12930 MOVT_FMT = 0x1,
3a1f4268
YK
12931 CLASS_FMT = 0x1,
12932 SELEQZ_FMT = 0x1,
3c824109
NF
12933
12934 PLL_PS = 0x2,
12935 SWXC1 = 0x2,
3a1f4268 12936 SEL_FMT = 0x2,
3c824109
NF
12937
12938 PLU_PS = 0x3,
12939 LDXC1 = 0x3,
12940
3a1f4268 12941 MOVN_FMT_04 = 0x4,
3c824109
NF
12942 PUL_PS = 0x4,
12943 SDXC1 = 0x4,
12944 RECIP2_FMT = 0x4,
12945
3a1f4268 12946 MOVZ_FMT_05 = 0x05,
3c824109
NF
12947 PUU_PS = 0x5,
12948 LUXC1 = 0x5,
12949
12950 CVT_PS_S = 0x6,
12951 SUXC1 = 0x6,
12952 ADDR_PS = 0x6,
12953 PREFX = 0x6,
3a1f4268 12954 MADDF_FMT = 0x6,
3c824109
NF
12955
12956 MULR_PS = 0x7,
3a1f4268 12957 MSUBF_FMT = 0x7,
3c824109
NF
12958
12959 MADD_S = 0x01,
12960 MADD_D = 0x09,
12961 MADD_PS = 0x11,
12962 ALNV_PS = 0x19,
12963 MSUB_S = 0x21,
12964 MSUB_D = 0x29,
12965 MSUB_PS = 0x31,
12966
12967 NMADD_S = 0x02,
12968 NMADD_D = 0x0a,
12969 NMADD_PS = 0x12,
12970 NMSUB_S = 0x22,
12971 NMSUB_D = 0x2a,
12972 NMSUB_PS = 0x32,
12973
3a1f4268
YK
12974 MIN_FMT = 0x3,
12975 MAX_FMT = 0xb,
12976 MINA_FMT = 0x23,
12977 MAXA_FMT = 0x2b,
3c824109
NF
12978 POOL32FXF = 0x3b,
12979
12980 CABS_COND_FMT = 0x1c, /* MIPS3D */
3a1f4268
YK
12981 C_COND_FMT = 0x3c,
12982
12983 CMP_CONDN_S = 0x5,
12984 CMP_CONDN_D = 0x15
3c824109
NF
12985};
12986
12987/* POOL32Fxf encoding of minor opcode extension field */
12988
12989enum {
12990 CVT_L = 0x04,
12991 RSQRT_FMT = 0x08,
12992 FLOOR_L = 0x0c,
12993 CVT_PW_PS = 0x1c,
12994 CVT_W = 0x24,
12995 SQRT_FMT = 0x28,
12996 FLOOR_W = 0x2c,
12997 CVT_PS_PW = 0x3c,
12998 CFC1 = 0x40,
12999 RECIP_FMT = 0x48,
13000 CEIL_L = 0x4c,
13001 CTC1 = 0x60,
13002 CEIL_W = 0x6c,
13003 MFC1 = 0x80,
13004 CVT_S_PL = 0x84,
13005 TRUNC_L = 0x8c,
13006 MTC1 = 0xa0,
13007 CVT_S_PU = 0xa4,
13008 TRUNC_W = 0xac,
13009 MFHC1 = 0xc0,
13010 ROUND_L = 0xcc,
13011 MTHC1 = 0xe0,
13012 ROUND_W = 0xec,
13013
13014 MOV_FMT = 0x01,
13015 MOVF = 0x05,
13016 ABS_FMT = 0x0d,
13017 RSQRT1_FMT = 0x1d,
13018 MOVT = 0x25,
13019 NEG_FMT = 0x2d,
13020 CVT_D = 0x4d,
13021 RECIP1_FMT = 0x5d,
13022 CVT_S = 0x6d
13023};
13024
13025/* POOL32I encoding of minor opcode field (bits 25..21) */
13026
13027enum {
13028 BLTZ = 0x00,
13029 BLTZAL = 0x01,
13030 BGEZ = 0x02,
13031 BGEZAL = 0x03,
13032 BLEZ = 0x04,
13033 BNEZC = 0x05,
13034 BGTZ = 0x06,
13035 BEQZC = 0x07,
13036 TLTI = 0x08,
3a1f4268 13037 BC1EQZC = 0x08,
3c824109 13038 TGEI = 0x09,
3a1f4268 13039 BC1NEZC = 0x09,
3c824109 13040 TLTIU = 0x0a,
3a1f4268 13041 BC2EQZC = 0x0a,
3c824109 13042 TGEIU = 0x0b,
3a1f4268 13043 BC2NEZC = 0x0a,
3c824109 13044 TNEI = 0x0c,
3a1f4268 13045 R6_SYNCI = 0x0c,
3c824109
NF
13046 LUI = 0x0d,
13047 TEQI = 0x0e,
13048 SYNCI = 0x10,
13049 BLTZALS = 0x11,
13050 BGEZALS = 0x13,
13051 BC2F = 0x14,
13052 BC2T = 0x15,
13053 BPOSGE64 = 0x1a,
13054 BPOSGE32 = 0x1b,
13055 /* These overlap and are distinguished by bit16 of the instruction */
13056 BC1F = 0x1c,
13057 BC1T = 0x1d,
13058 BC1ANY2F = 0x1c,
13059 BC1ANY2T = 0x1d,
13060 BC1ANY4F = 0x1e,
13061 BC1ANY4T = 0x1f
13062};
13063
13064/* POOL16A encoding of minor opcode field */
13065
13066enum {
13067 ADDU16 = 0x0,
13068 SUBU16 = 0x1
13069};
13070
13071/* POOL16B encoding of minor opcode field */
13072
13073enum {
13074 SLL16 = 0x0,
13075 SRL16 = 0x1
13076};
13077
13078/* POOL16C encoding of minor opcode field */
13079
13080enum {
13081 NOT16 = 0x00,
13082 XOR16 = 0x04,
13083 AND16 = 0x08,
13084 OR16 = 0x0c,
13085 LWM16 = 0x10,
13086 SWM16 = 0x14,
13087 JR16 = 0x18,
13088 JRC16 = 0x1a,
13089 JALR16 = 0x1c,
13090 JALR16S = 0x1e,
13091 MFHI16 = 0x20,
13092 MFLO16 = 0x24,
13093 BREAK16 = 0x28,
13094 SDBBP16 = 0x2c,
13095 JRADDIUSP = 0x30
13096};
13097
3a1f4268
YK
13098/* R6 POOL16C encoding of minor opcode field (bits 0..5) */
13099
13100enum {
13101 R6_NOT16 = 0x00,
13102 R6_AND16 = 0x01,
13103 R6_LWM16 = 0x02,
13104 R6_JRC16 = 0x03,
13105 MOVEP = 0x04,
c38a1d52
AR
13106 MOVEP_05 = 0x05,
13107 MOVEP_06 = 0x06,
3a1f4268
YK
13108 MOVEP_07 = 0x07,
13109 R6_XOR16 = 0x08,
13110 R6_OR16 = 0x09,
13111 R6_SWM16 = 0x0a,
13112 JALRC16 = 0x0b,
13113 MOVEP_0C = 0x0c,
c38a1d52
AR
13114 MOVEP_0D = 0x0d,
13115 MOVEP_0E = 0x0e,
3a1f4268
YK
13116 MOVEP_0F = 0x0f,
13117 JRCADDIUSP = 0x13,
13118 R6_BREAK16 = 0x1b,
13119 R6_SDBBP16 = 0x3b
13120};
13121
3c824109
NF
13122/* POOL16D encoding of minor opcode field */
13123
13124enum {
13125 ADDIUS5 = 0x0,
13126 ADDIUSP = 0x1
13127};
13128
13129/* POOL16E encoding of minor opcode field */
13130
13131enum {
13132 ADDIUR2 = 0x0,
13133 ADDIUR1SP = 0x1
13134};
13135
13136static int mmreg (int r)
13137{
13138 static const int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
13139
13140 return map[r];
13141}
13142
13143/* Used for 16-bit store instructions. */
13144static int mmreg2 (int r)
13145{
13146 static const int map[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
13147
13148 return map[r];
13149}
13150
13151#define uMIPS_RD(op) ((op >> 7) & 0x7)
13152#define uMIPS_RS(op) ((op >> 4) & 0x7)
13153#define uMIPS_RS2(op) uMIPS_RS(op)
13154#define uMIPS_RS1(op) ((op >> 1) & 0x7)
13155#define uMIPS_RD5(op) ((op >> 5) & 0x1f)
13156#define uMIPS_RS5(op) (op & 0x1f)
13157
13158/* Signed immediate */
13159#define SIMM(op, start, width) \
13160 ((int32_t)(((op >> start) & ((~0U) >> (32-width))) \
13161 << (32-width)) \
13162 >> (32-width))
13163/* Zero-extended immediate */
13164#define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
13165
d75c135e 13166static void gen_addiur1sp(DisasContext *ctx)
3c824109
NF
13167{
13168 int rd = mmreg(uMIPS_RD(ctx->opcode));
13169
d75c135e 13170 gen_arith_imm(ctx, OPC_ADDIU, rd, 29, ((ctx->opcode >> 1) & 0x3f) << 2);
3c824109
NF
13171}
13172
d75c135e 13173static void gen_addiur2(DisasContext *ctx)
3c824109
NF
13174{
13175 static const int decoded_imm[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
13176 int rd = mmreg(uMIPS_RD(ctx->opcode));
13177 int rs = mmreg(uMIPS_RS(ctx->opcode));
13178
d75c135e 13179 gen_arith_imm(ctx, OPC_ADDIU, rd, rs, decoded_imm[ZIMM(ctx->opcode, 1, 3)]);
3c824109
NF
13180}
13181
d75c135e 13182static void gen_addiusp(DisasContext *ctx)
3c824109
NF
13183{
13184 int encoded = ZIMM(ctx->opcode, 1, 9);
13185 int decoded;
13186
13187 if (encoded <= 1) {
13188 decoded = 256 + encoded;
13189 } else if (encoded <= 255) {
13190 decoded = encoded;
13191 } else if (encoded <= 509) {
13192 decoded = encoded - 512;
13193 } else {
13194 decoded = encoded - 768;
13195 }
13196
d75c135e 13197 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, decoded << 2);
3c824109
NF
13198}
13199
d75c135e 13200static void gen_addius5(DisasContext *ctx)
3c824109
NF
13201{
13202 int imm = SIMM(ctx->opcode, 1, 4);
13203 int rd = (ctx->opcode >> 5) & 0x1f;
13204
d75c135e 13205 gen_arith_imm(ctx, OPC_ADDIU, rd, rd, imm);
3c824109
NF
13206}
13207
d75c135e 13208static void gen_andi16(DisasContext *ctx)
3c824109
NF
13209{
13210 static const int decoded_imm[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
13211 31, 32, 63, 64, 255, 32768, 65535 };
13212 int rd = mmreg(uMIPS_RD(ctx->opcode));
13213 int rs = mmreg(uMIPS_RS(ctx->opcode));
13214 int encoded = ZIMM(ctx->opcode, 0, 4);
13215
d75c135e 13216 gen_logic_imm(ctx, OPC_ANDI, rd, rs, decoded_imm[encoded]);
3c824109
NF
13217}
13218
13219static void gen_ldst_multiple (DisasContext *ctx, uint32_t opc, int reglist,
13220 int base, int16_t offset)
13221{
13222 TCGv t0, t1;
13223 TCGv_i32 t2;
13224
13225 if (ctx->hflags & MIPS_HFLAG_BMASK) {
9c708c7f 13226 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
13227 return;
13228 }
13229
13230 t0 = tcg_temp_new();
13231
13232 gen_base_offset_addr(ctx, t0, base, offset);
13233
13234 t1 = tcg_const_tl(reglist);
13235 t2 = tcg_const_i32(ctx->mem_idx);
6af0bf9c 13236
3c824109
NF
13237 save_cpu_state(ctx, 1);
13238 switch (opc) {
13239 case LWM32:
895c2d04 13240 gen_helper_lwm(cpu_env, t0, t1, t2);
3c824109
NF
13241 break;
13242 case SWM32:
895c2d04 13243 gen_helper_swm(cpu_env, t0, t1, t2);
3c824109
NF
13244 break;
13245#ifdef TARGET_MIPS64
13246 case LDM:
895c2d04 13247 gen_helper_ldm(cpu_env, t0, t1, t2);
3c824109
NF
13248 break;
13249 case SDM:
895c2d04 13250 gen_helper_sdm(cpu_env, t0, t1, t2);
3c824109 13251 break;
6af0bf9c 13252#endif
3c824109 13253 }
3c824109 13254 tcg_temp_free(t0);
33087598 13255 tcg_temp_free(t1);
3c824109
NF
13256 tcg_temp_free_i32(t2);
13257}
6af0bf9c 13258
3c824109 13259
240ce26a 13260static void gen_pool16c_insn(DisasContext *ctx)
6af0bf9c 13261{
3c824109
NF
13262 int rd = mmreg((ctx->opcode >> 3) & 0x7);
13263 int rs = mmreg(ctx->opcode & 0x7);
6af0bf9c 13264
3c824109
NF
13265 switch (((ctx->opcode) >> 4) & 0x3f) {
13266 case NOT16 + 0:
13267 case NOT16 + 1:
13268 case NOT16 + 2:
13269 case NOT16 + 3:
d75c135e 13270 gen_logic(ctx, OPC_NOR, rd, rs, 0);
3c824109
NF
13271 break;
13272 case XOR16 + 0:
13273 case XOR16 + 1:
13274 case XOR16 + 2:
13275 case XOR16 + 3:
d75c135e 13276 gen_logic(ctx, OPC_XOR, rd, rd, rs);
3c824109
NF
13277 break;
13278 case AND16 + 0:
13279 case AND16 + 1:
13280 case AND16 + 2:
13281 case AND16 + 3:
d75c135e 13282 gen_logic(ctx, OPC_AND, rd, rd, rs);
3c824109
NF
13283 break;
13284 case OR16 + 0:
13285 case OR16 + 1:
13286 case OR16 + 2:
13287 case OR16 + 3:
d75c135e 13288 gen_logic(ctx, OPC_OR, rd, rd, rs);
3c824109
NF
13289 break;
13290 case LWM16 + 0:
13291 case LWM16 + 1:
13292 case LWM16 + 2:
13293 case LWM16 + 3:
13294 {
13295 static const int lwm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
13296 int offset = ZIMM(ctx->opcode, 0, 4);
13297
13298 gen_ldst_multiple(ctx, LWM32, lwm_convert[(ctx->opcode >> 4) & 0x3],
13299 29, offset << 2);
13300 }
13301 break;
13302 case SWM16 + 0:
13303 case SWM16 + 1:
13304 case SWM16 + 2:
13305 case SWM16 + 3:
13306 {
13307 static const int swm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
13308 int offset = ZIMM(ctx->opcode, 0, 4);
13309
13310 gen_ldst_multiple(ctx, SWM32, swm_convert[(ctx->opcode >> 4) & 0x3],
13311 29, offset << 2);
13312 }
13313 break;
13314 case JR16 + 0:
13315 case JR16 + 1:
13316 {
13317 int reg = ctx->opcode & 0x1f;
13318
b231c103 13319 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 4);
3c824109 13320 }
3c824109
NF
13321 break;
13322 case JRC16 + 0:
13323 case JRC16 + 1:
13324 {
13325 int reg = ctx->opcode & 0x1f;
b231c103 13326 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 0);
3c824109
NF
13327 /* Let normal delay slot handling in our caller take us
13328 to the branch target. */
13329 }
13330 break;
13331 case JALR16 + 0:
13332 case JALR16 + 1:
b231c103
YK
13333 gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 4);
13334 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
13335 break;
3c824109
NF
13336 case JALR16S + 0:
13337 case JALR16S + 1:
b231c103
YK
13338 gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 2);
13339 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
3c824109
NF
13340 break;
13341 case MFHI16 + 0:
13342 case MFHI16 + 1:
26135ead 13343 gen_HILO(ctx, OPC_MFHI, 0, uMIPS_RS5(ctx->opcode));
3c824109
NF
13344 break;
13345 case MFLO16 + 0:
13346 case MFLO16 + 1:
26135ead 13347 gen_HILO(ctx, OPC_MFLO, 0, uMIPS_RS5(ctx->opcode));
3c824109
NF
13348 break;
13349 case BREAK16:
9c708c7f 13350 generate_exception_end(ctx, EXCP_BREAK);
3c824109
NF
13351 break;
13352 case SDBBP16:
3b3c1694
LA
13353 if (is_uhi(extract32(ctx->opcode, 0, 4))) {
13354 gen_helper_do_semihosting(cpu_env);
13355 } else {
13356 /* XXX: not clear which exception should be raised
13357 * when in debug mode...
13358 */
13359 check_insn(ctx, ISA_MIPS32);
9c708c7f 13360 generate_exception_end(ctx, EXCP_DBp);
3b3c1694 13361 }
3c824109
NF
13362 break;
13363 case JRADDIUSP + 0:
13364 case JRADDIUSP + 1:
13365 {
13366 int imm = ZIMM(ctx->opcode, 0, 5);
b231c103 13367 gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0, 0);
d75c135e 13368 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
3c824109
NF
13369 /* Let normal delay slot handling in our caller take us
13370 to the branch target. */
13371 }
13372 break;
13373 default:
9c708c7f 13374 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
13375 break;
13376 }
13377}
13378
ed7ce6c0
YK
13379static inline void gen_movep(DisasContext *ctx, int enc_dest, int enc_rt,
13380 int enc_rs)
13381{
13382 int rd, rs, re, rt;
13383 static const int rd_enc[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
13384 static const int re_enc[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
13385 static const int rs_rt_enc[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
13386 rd = rd_enc[enc_dest];
13387 re = re_enc[enc_dest];
13388 rs = rs_rt_enc[enc_rs];
13389 rt = rs_rt_enc[enc_rt];
13390 if (rs) {
13391 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
13392 } else {
13393 tcg_gen_movi_tl(cpu_gpr[rd], 0);
13394 }
13395 if (rt) {
13396 tcg_gen_mov_tl(cpu_gpr[re], cpu_gpr[rt]);
13397 } else {
13398 tcg_gen_movi_tl(cpu_gpr[re], 0);
13399 }
13400}
13401
13402static void gen_pool16c_r6_insn(DisasContext *ctx)
13403{
13404 int rt = mmreg((ctx->opcode >> 7) & 0x7);
13405 int rs = mmreg((ctx->opcode >> 4) & 0x7);
13406
13407 switch (ctx->opcode & 0xf) {
13408 case R6_NOT16:
13409 gen_logic(ctx, OPC_NOR, rt, rs, 0);
13410 break;
13411 case R6_AND16:
13412 gen_logic(ctx, OPC_AND, rt, rt, rs);
13413 break;
13414 case R6_LWM16:
13415 {
13416 int lwm_converted = 0x11 + extract32(ctx->opcode, 8, 2);
13417 int offset = extract32(ctx->opcode, 4, 4);
13418 gen_ldst_multiple(ctx, LWM32, lwm_converted, 29, offset << 2);
13419 }
13420 break;
13421 case R6_JRC16: /* JRCADDIUSP */
13422 if ((ctx->opcode >> 4) & 1) {
13423 /* JRCADDIUSP */
13424 int imm = extract32(ctx->opcode, 5, 5);
13425 gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0, 0);
13426 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
13427 } else {
13428 /* JRC16 */
e1555d7d 13429 rs = extract32(ctx->opcode, 5, 5);
ed7ce6c0
YK
13430 gen_compute_branch(ctx, OPC_JR, 2, rs, 0, 0, 0);
13431 }
13432 break;
c38a1d52
AR
13433 case MOVEP:
13434 case MOVEP_05:
13435 case MOVEP_06:
13436 case MOVEP_07:
13437 case MOVEP_0C:
13438 case MOVEP_0D:
13439 case MOVEP_0E:
13440 case MOVEP_0F:
ed7ce6c0
YK
13441 {
13442 int enc_dest = uMIPS_RD(ctx->opcode);
13443 int enc_rt = uMIPS_RS2(ctx->opcode);
13444 int enc_rs = (ctx->opcode & 3) | ((ctx->opcode >> 1) & 4);
13445 gen_movep(ctx, enc_dest, enc_rt, enc_rs);
13446 }
13447 break;
13448 case R6_XOR16:
13449 gen_logic(ctx, OPC_XOR, rt, rt, rs);
13450 break;
13451 case R6_OR16:
13452 gen_logic(ctx, OPC_OR, rt, rt, rs);
13453 break;
13454 case R6_SWM16:
13455 {
13456 int swm_converted = 0x11 + extract32(ctx->opcode, 8, 2);
13457 int offset = extract32(ctx->opcode, 4, 4);
13458 gen_ldst_multiple(ctx, SWM32, swm_converted, 29, offset << 2);
13459 }
13460 break;
13461 case JALRC16: /* BREAK16, SDBBP16 */
13462 switch (ctx->opcode & 0x3f) {
13463 case JALRC16:
13464 case JALRC16 + 0x20:
13465 /* JALRC16 */
13466 gen_compute_branch(ctx, OPC_JALR, 2, (ctx->opcode >> 5) & 0x1f,
13467 31, 0, 0);
13468 break;
13469 case R6_BREAK16:
13470 /* BREAK16 */
13471 generate_exception(ctx, EXCP_BREAK);
13472 break;
13473 case R6_SDBBP16:
13474 /* SDBBP16 */
060ebfef
LA
13475 if (is_uhi(extract32(ctx->opcode, 6, 4))) {
13476 gen_helper_do_semihosting(cpu_env);
ed7ce6c0 13477 } else {
060ebfef
LA
13478 if (ctx->hflags & MIPS_HFLAG_SBRI) {
13479 generate_exception(ctx, EXCP_RI);
13480 } else {
13481 generate_exception(ctx, EXCP_DBp);
13482 }
ed7ce6c0
YK
13483 }
13484 break;
13485 }
13486 break;
13487 default:
13488 generate_exception(ctx, EXCP_RI);
13489 break;
13490 }
13491}
13492
3c824109
NF
13493static void gen_ldxs (DisasContext *ctx, int base, int index, int rd)
13494{
13495 TCGv t0 = tcg_temp_new();
13496 TCGv t1 = tcg_temp_new();
13497
13498 gen_load_gpr(t0, base);
13499
13500 if (index != 0) {
13501 gen_load_gpr(t1, index);
13502 tcg_gen_shli_tl(t1, t1, 2);
13503 gen_op_addr_add(ctx, t0, t1, t0);
13504 }
13505
5f68f5ae 13506 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
3c824109
NF
13507 gen_store_gpr(t1, rd);
13508
13509 tcg_temp_free(t0);
13510 tcg_temp_free(t1);
13511}
13512
13513static void gen_ldst_pair (DisasContext *ctx, uint32_t opc, int rd,
13514 int base, int16_t offset)
13515{
3c824109
NF
13516 TCGv t0, t1;
13517
36c6711b 13518 if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31) {
9c708c7f 13519 generate_exception_end(ctx, EXCP_RI);
d796321b
FB
13520 return;
13521 }
13522
3c824109
NF
13523 t0 = tcg_temp_new();
13524 t1 = tcg_temp_new();
8e9ade68 13525
3c824109
NF
13526 gen_base_offset_addr(ctx, t0, base, offset);
13527
13528 switch (opc) {
13529 case LWP:
36c6711b 13530 if (rd == base) {
9c708c7f 13531 generate_exception_end(ctx, EXCP_RI);
36c6711b
EJ
13532 return;
13533 }
5f68f5ae 13534 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
3c824109
NF
13535 gen_store_gpr(t1, rd);
13536 tcg_gen_movi_tl(t1, 4);
13537 gen_op_addr_add(ctx, t0, t0, t1);
5f68f5ae 13538 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
3c824109 13539 gen_store_gpr(t1, rd+1);
3c824109
NF
13540 break;
13541 case SWP:
3c824109 13542 gen_load_gpr(t1, rd);
5f68f5ae 13543 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
3c824109
NF
13544 tcg_gen_movi_tl(t1, 4);
13545 gen_op_addr_add(ctx, t0, t0, t1);
13546 gen_load_gpr(t1, rd+1);
5f68f5ae 13547 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
3c824109
NF
13548 break;
13549#ifdef TARGET_MIPS64
13550 case LDP:
36c6711b 13551 if (rd == base) {
9c708c7f 13552 generate_exception_end(ctx, EXCP_RI);
36c6711b
EJ
13553 return;
13554 }
5f68f5ae 13555 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
3c824109
NF
13556 gen_store_gpr(t1, rd);
13557 tcg_gen_movi_tl(t1, 8);
13558 gen_op_addr_add(ctx, t0, t0, t1);
5f68f5ae 13559 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
3c824109 13560 gen_store_gpr(t1, rd+1);
3c824109
NF
13561 break;
13562 case SDP:
3c824109 13563 gen_load_gpr(t1, rd);
5f68f5ae 13564 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
3c824109
NF
13565 tcg_gen_movi_tl(t1, 8);
13566 gen_op_addr_add(ctx, t0, t0, t1);
13567 gen_load_gpr(t1, rd+1);
5f68f5ae 13568 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
3c824109
NF
13569 break;
13570#endif
6af0bf9c 13571 }
3c824109
NF
13572 tcg_temp_free(t0);
13573 tcg_temp_free(t1);
13574}
618b0fe9 13575
d208ac0c
LA
13576static void gen_sync(int stype)
13577{
13578 TCGBar tcg_mo = TCG_BAR_SC;
13579
13580 switch (stype) {
13581 case 0x4: /* SYNC_WMB */
13582 tcg_mo |= TCG_MO_ST_ST;
13583 break;
13584 case 0x10: /* SYNC_MB */
13585 tcg_mo |= TCG_MO_ALL;
13586 break;
13587 case 0x11: /* SYNC_ACQUIRE */
13588 tcg_mo |= TCG_MO_LD_LD | TCG_MO_LD_ST;
13589 break;
13590 case 0x12: /* SYNC_RELEASE */
13591 tcg_mo |= TCG_MO_ST_ST | TCG_MO_LD_ST;
13592 break;
13593 case 0x13: /* SYNC_RMB */
13594 tcg_mo |= TCG_MO_LD_LD;
13595 break;
13596 default:
13597 tcg_mo |= TCG_MO_ALL;
13598 break;
13599 }
13600
13601 tcg_gen_mb(tcg_mo);
13602}
13603
240ce26a 13604static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
3c824109
NF
13605{
13606 int extension = (ctx->opcode >> 6) & 0x3f;
13607 int minor = (ctx->opcode >> 12) & 0xf;
13608 uint32_t mips32_op;
13609
13610 switch (extension) {
13611 case TEQ:
13612 mips32_op = OPC_TEQ;
13613 goto do_trap;
13614 case TGE:
13615 mips32_op = OPC_TGE;
13616 goto do_trap;
13617 case TGEU:
13618 mips32_op = OPC_TGEU;
13619 goto do_trap;
13620 case TLT:
13621 mips32_op = OPC_TLT;
13622 goto do_trap;
13623 case TLTU:
13624 mips32_op = OPC_TLTU;
13625 goto do_trap;
13626 case TNE:
13627 mips32_op = OPC_TNE;
13628 do_trap:
13629 gen_trap(ctx, mips32_op, rs, rt, -1);
13630 break;
13631#ifndef CONFIG_USER_ONLY
13632 case MFC0:
13633 case MFC0 + 32:
2e15497c 13634 check_cp0_enabled(ctx);
3c824109
NF
13635 if (rt == 0) {
13636 /* Treat as NOP. */
13637 break;
13638 }
d75c135e 13639 gen_mfc0(ctx, cpu_gpr[rt], rs, (ctx->opcode >> 11) & 0x7);
3c824109
NF
13640 break;
13641 case MTC0:
13642 case MTC0 + 32:
2e15497c 13643 check_cp0_enabled(ctx);
3c824109
NF
13644 {
13645 TCGv t0 = tcg_temp_new();
618b0fe9 13646
3c824109 13647 gen_load_gpr(t0, rt);
d75c135e 13648 gen_mtc0(ctx, t0, rs, (ctx->opcode >> 11) & 0x7);
3c824109
NF
13649 tcg_temp_free(t0);
13650 }
13651 break;
13652#endif
a1fc6246
LA
13653 case 0x2a:
13654 switch (minor & 3) {
13655 case MADD_ACC:
13656 gen_muldiv(ctx, OPC_MADD, (ctx->opcode >> 14) & 3, rs, rt);
13657 break;
13658 case MADDU_ACC:
13659 gen_muldiv(ctx, OPC_MADDU, (ctx->opcode >> 14) & 3, rs, rt);
13660 break;
13661 case MSUB_ACC:
13662 gen_muldiv(ctx, OPC_MSUB, (ctx->opcode >> 14) & 3, rs, rt);
13663 break;
13664 case MSUBU_ACC:
13665 gen_muldiv(ctx, OPC_MSUBU, (ctx->opcode >> 14) & 3, rs, rt);
13666 break;
13667 default:
13668 goto pool32axf_invalid;
13669 }
13670 break;
13671 case 0x32:
13672 switch (minor & 3) {
13673 case MULT_ACC:
13674 gen_muldiv(ctx, OPC_MULT, (ctx->opcode >> 14) & 3, rs, rt);
13675 break;
13676 case MULTU_ACC:
13677 gen_muldiv(ctx, OPC_MULTU, (ctx->opcode >> 14) & 3, rs, rt);
13678 break;
13679 default:
13680 goto pool32axf_invalid;
13681 }
13682 break;
3c824109
NF
13683 case 0x2c:
13684 switch (minor) {
e0332095
YK
13685 case BITSWAP:
13686 check_insn(ctx, ISA_MIPS32R6);
13687 gen_bitswap(ctx, OPC_BITSWAP, rs, rt);
13688 break;
3c824109
NF
13689 case SEB:
13690 gen_bshfl(ctx, OPC_SEB, rs, rt);
13691 break;
13692 case SEH:
13693 gen_bshfl(ctx, OPC_SEH, rs, rt);
13694 break;
13695 case CLO:
13696 mips32_op = OPC_CLO;
13697 goto do_cl;
13698 case CLZ:
13699 mips32_op = OPC_CLZ;
13700 do_cl:
d75c135e 13701 check_insn(ctx, ISA_MIPS32);
3c824109
NF
13702 gen_cl(ctx, mips32_op, rt, rs);
13703 break;
13704 case RDHWR:
b00c7218
YK
13705 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13706 gen_rdhwr(ctx, rt, rs, 0);
3c824109
NF
13707 break;
13708 case WSBH:
13709 gen_bshfl(ctx, OPC_WSBH, rs, rt);
13710 break;
13711 case MULT:
9e8f441a 13712 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 13713 mips32_op = OPC_MULT;
26135ead 13714 goto do_mul;
3c824109 13715 case MULTU:
9e8f441a 13716 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 13717 mips32_op = OPC_MULTU;
26135ead 13718 goto do_mul;
3c824109 13719 case DIV:
9e8f441a 13720 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 13721 mips32_op = OPC_DIV;
26135ead 13722 goto do_div;
3c824109 13723 case DIVU:
9e8f441a 13724 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 13725 mips32_op = OPC_DIVU;
26135ead
RS
13726 goto do_div;
13727 do_div:
13728 check_insn(ctx, ISA_MIPS32);
13729 gen_muldiv(ctx, mips32_op, 0, rs, rt);
13730 break;
3c824109 13731 case MADD:
9e8f441a 13732 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 13733 mips32_op = OPC_MADD;
26135ead 13734 goto do_mul;
3c824109 13735 case MADDU:
9e8f441a 13736 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 13737 mips32_op = OPC_MADDU;
26135ead 13738 goto do_mul;
3c824109 13739 case MSUB:
9e8f441a 13740 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 13741 mips32_op = OPC_MSUB;
26135ead 13742 goto do_mul;
3c824109 13743 case MSUBU:
9e8f441a 13744 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 13745 mips32_op = OPC_MSUBU;
26135ead 13746 do_mul:
d75c135e 13747 check_insn(ctx, ISA_MIPS32);
a1fc6246 13748 gen_muldiv(ctx, mips32_op, 0, rs, rt);
3c824109
NF
13749 break;
13750 default:
13751 goto pool32axf_invalid;
13752 }
13753 break;
13754 case 0x34:
13755 switch (minor) {
13756 case MFC2:
13757 case MTC2:
13758 case MFHC2:
13759 case MTHC2:
13760 case CFC2:
13761 case CTC2:
13762 generate_exception_err(ctx, EXCP_CpU, 2);
13763 break;
13764 default:
13765 goto pool32axf_invalid;
13766 }
13767 break;
13768 case 0x3c:
13769 switch (minor) {
65935f07
YK
13770 case JALR: /* JALRC */
13771 case JALR_HB: /* JALRC_HB */
13772 if (ctx->insn_flags & ISA_MIPS32R6) {
13773 /* JALRC, JALRC_HB */
13774 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 0);
13775 } else {
13776 /* JALR, JALR_HB */
13777 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 4);
13778 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
13779 }
3c824109
NF
13780 break;
13781 case JALRS:
13782 case JALRS_HB:
9e8f441a 13783 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
13784 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 2);
13785 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
3c824109
NF
13786 break;
13787 default:
13788 goto pool32axf_invalid;
13789 }
13790 break;
13791 case 0x05:
13792 switch (minor) {
13793 case RDPGPR:
2e15497c 13794 check_cp0_enabled(ctx);
d75c135e 13795 check_insn(ctx, ISA_MIPS32R2);
1bf5902d 13796 gen_load_srsgpr(rs, rt);
3c824109
NF
13797 break;
13798 case WRPGPR:
2e15497c 13799 check_cp0_enabled(ctx);
d75c135e 13800 check_insn(ctx, ISA_MIPS32R2);
1bf5902d 13801 gen_store_srsgpr(rs, rt);
3c824109
NF
13802 break;
13803 default:
13804 goto pool32axf_invalid;
13805 }
13806 break;
13807#ifndef CONFIG_USER_ONLY
13808 case 0x0d:
13809 switch (minor) {
13810 case TLBP:
13811 mips32_op = OPC_TLBP;
13812 goto do_cp0;
13813 case TLBR:
13814 mips32_op = OPC_TLBR;
13815 goto do_cp0;
13816 case TLBWI:
13817 mips32_op = OPC_TLBWI;
13818 goto do_cp0;
13819 case TLBWR:
13820 mips32_op = OPC_TLBWR;
13821 goto do_cp0;
e60ec063
YK
13822 case TLBINV:
13823 mips32_op = OPC_TLBINV;
13824 goto do_cp0;
13825 case TLBINVF:
13826 mips32_op = OPC_TLBINVF;
13827 goto do_cp0;
3c824109
NF
13828 case WAIT:
13829 mips32_op = OPC_WAIT;
13830 goto do_cp0;
13831 case DERET:
13832 mips32_op = OPC_DERET;
13833 goto do_cp0;
13834 case ERET:
13835 mips32_op = OPC_ERET;
13836 do_cp0:
13837 gen_cp0(env, ctx, mips32_op, rt, rs);
13838 break;
13839 default:
13840 goto pool32axf_invalid;
13841 }
13842 break;
13843 case 0x1d:
13844 switch (minor) {
13845 case DI:
2e15497c 13846 check_cp0_enabled(ctx);
3c824109
NF
13847 {
13848 TCGv t0 = tcg_temp_new();
13849
13850 save_cpu_state(ctx, 1);
895c2d04 13851 gen_helper_di(t0, cpu_env);
3c824109
NF
13852 gen_store_gpr(t0, rs);
13853 /* Stop translation as we may have switched the execution mode */
eeb3bba8 13854 ctx->base.is_jmp = DISAS_STOP;
3c824109
NF
13855 tcg_temp_free(t0);
13856 }
13857 break;
13858 case EI:
2e15497c 13859 check_cp0_enabled(ctx);
3c824109
NF
13860 {
13861 TCGv t0 = tcg_temp_new();
13862
13863 save_cpu_state(ctx, 1);
895c2d04 13864 gen_helper_ei(t0, cpu_env);
3c824109 13865 gen_store_gpr(t0, rs);
b28425ba 13866 /* DISAS_STOP isn't sufficient, we need to ensure we break out
b74cddcb 13867 of translated code to check for pending interrupts. */
eeb3bba8
EC
13868 gen_save_pc(ctx->base.pc_next + 4);
13869 ctx->base.is_jmp = DISAS_EXIT;
3c824109
NF
13870 tcg_temp_free(t0);
13871 }
13872 break;
13873 default:
13874 goto pool32axf_invalid;
13875 }
13876 break;
13877#endif
13878 case 0x2d:
13879 switch (minor) {
13880 case SYNC:
d208ac0c 13881 gen_sync(extract32(ctx->opcode, 16, 5));
3c824109
NF
13882 break;
13883 case SYSCALL:
9c708c7f 13884 generate_exception_end(ctx, EXCP_SYSCALL);
3c824109
NF
13885 break;
13886 case SDBBP:
3b3c1694
LA
13887 if (is_uhi(extract32(ctx->opcode, 16, 10))) {
13888 gen_helper_do_semihosting(cpu_env);
13889 } else {
13890 check_insn(ctx, ISA_MIPS32);
e0332095 13891 if (ctx->hflags & MIPS_HFLAG_SBRI) {
9c708c7f 13892 generate_exception_end(ctx, EXCP_RI);
e0332095 13893 } else {
9c708c7f 13894 generate_exception_end(ctx, EXCP_DBp);
e0332095 13895 }
3b3c1694 13896 }
3c824109
NF
13897 break;
13898 default:
13899 goto pool32axf_invalid;
13900 }
13901 break;
a1fc6246 13902 case 0x01:
26135ead 13903 switch (minor & 3) {
a1fc6246 13904 case MFHI_ACC:
26135ead 13905 gen_HILO(ctx, OPC_MFHI, minor >> 2, rs);
3c824109 13906 break;
a1fc6246 13907 case MFLO_ACC:
26135ead 13908 gen_HILO(ctx, OPC_MFLO, minor >> 2, rs);
3c824109 13909 break;
a1fc6246 13910 case MTHI_ACC:
26135ead 13911 gen_HILO(ctx, OPC_MTHI, minor >> 2, rs);
3c824109 13912 break;
a1fc6246 13913 case MTLO_ACC:
26135ead 13914 gen_HILO(ctx, OPC_MTLO, minor >> 2, rs);
3c824109
NF
13915 break;
13916 default:
13917 goto pool32axf_invalid;
13918 }
13919 break;
a1fc6246 13920 case 0x35:
9e8f441a 13921 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a1fc6246
LA
13922 switch (minor) {
13923 case MFHI32:
13924 gen_HILO(ctx, OPC_MFHI, 0, rs);
13925 break;
13926 case MFLO32:
13927 gen_HILO(ctx, OPC_MFLO, 0, rs);
13928 break;
13929 case MTHI32:
13930 gen_HILO(ctx, OPC_MTHI, 0, rs);
13931 break;
13932 case MTLO32:
13933 gen_HILO(ctx, OPC_MTLO, 0, rs);
13934 break;
13935 default:
13936 goto pool32axf_invalid;
13937 }
13938 break;
3c824109
NF
13939 default:
13940 pool32axf_invalid:
13941 MIPS_INVAL("pool32axf");
9c708c7f 13942 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
13943 break;
13944 }
13945}
13946
13947/* Values for microMIPS fmt field. Variable-width, depending on which
13948 formats the instruction supports. */
13949
13950enum {
13951 FMT_SD_S = 0,
13952 FMT_SD_D = 1,
13953
13954 FMT_SDPS_S = 0,
13955 FMT_SDPS_D = 1,
13956 FMT_SDPS_PS = 2,
13957
13958 FMT_SWL_S = 0,
13959 FMT_SWL_W = 1,
13960 FMT_SWL_L = 2,
13961
13962 FMT_DWL_D = 0,
13963 FMT_DWL_W = 1,
13964 FMT_DWL_L = 2
13965};
13966
d75c135e 13967static void gen_pool32fxf(DisasContext *ctx, int rt, int rs)
3c824109
NF
13968{
13969 int extension = (ctx->opcode >> 6) & 0x3ff;
13970 uint32_t mips32_op;
13971
13972#define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
13973#define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
13974#define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
13975
13976 switch (extension) {
13977 case FLOAT_1BIT_FMT(CFC1, 0):
13978 mips32_op = OPC_CFC1;
13979 goto do_cp1;
13980 case FLOAT_1BIT_FMT(CTC1, 0):
13981 mips32_op = OPC_CTC1;
13982 goto do_cp1;
13983 case FLOAT_1BIT_FMT(MFC1, 0):
13984 mips32_op = OPC_MFC1;
13985 goto do_cp1;
13986 case FLOAT_1BIT_FMT(MTC1, 0):
13987 mips32_op = OPC_MTC1;
13988 goto do_cp1;
13989 case FLOAT_1BIT_FMT(MFHC1, 0):
13990 mips32_op = OPC_MFHC1;
13991 goto do_cp1;
13992 case FLOAT_1BIT_FMT(MTHC1, 0):
13993 mips32_op = OPC_MTHC1;
13994 do_cp1:
13995 gen_cp1(ctx, mips32_op, rt, rs);
13996 break;
13997
13998 /* Reciprocal square root */
13999 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_S):
14000 mips32_op = OPC_RSQRT_S;
14001 goto do_unaryfp;
14002 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_D):
14003 mips32_op = OPC_RSQRT_D;
14004 goto do_unaryfp;
14005
14006 /* Square root */
14007 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_S):
14008 mips32_op = OPC_SQRT_S;
14009 goto do_unaryfp;
14010 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_D):
14011 mips32_op = OPC_SQRT_D;
14012 goto do_unaryfp;
14013
14014 /* Reciprocal */
14015 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_S):
14016 mips32_op = OPC_RECIP_S;
14017 goto do_unaryfp;
14018 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_D):
14019 mips32_op = OPC_RECIP_D;
14020 goto do_unaryfp;
14021
14022 /* Floor */
14023 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_S):
14024 mips32_op = OPC_FLOOR_L_S;
14025 goto do_unaryfp;
14026 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_D):
14027 mips32_op = OPC_FLOOR_L_D;
14028 goto do_unaryfp;
14029 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_S):
14030 mips32_op = OPC_FLOOR_W_S;
14031 goto do_unaryfp;
14032 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_D):
14033 mips32_op = OPC_FLOOR_W_D;
14034 goto do_unaryfp;
14035
14036 /* Ceiling */
14037 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_S):
14038 mips32_op = OPC_CEIL_L_S;
14039 goto do_unaryfp;
14040 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_D):
14041 mips32_op = OPC_CEIL_L_D;
14042 goto do_unaryfp;
14043 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_S):
14044 mips32_op = OPC_CEIL_W_S;
14045 goto do_unaryfp;
14046 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_D):
14047 mips32_op = OPC_CEIL_W_D;
14048 goto do_unaryfp;
14049
14050 /* Truncation */
14051 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_S):
14052 mips32_op = OPC_TRUNC_L_S;
14053 goto do_unaryfp;
14054 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_D):
14055 mips32_op = OPC_TRUNC_L_D;
14056 goto do_unaryfp;
14057 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_S):
14058 mips32_op = OPC_TRUNC_W_S;
14059 goto do_unaryfp;
14060 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_D):
14061 mips32_op = OPC_TRUNC_W_D;
14062 goto do_unaryfp;
14063
14064 /* Round */
14065 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_S):
14066 mips32_op = OPC_ROUND_L_S;
14067 goto do_unaryfp;
14068 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_D):
14069 mips32_op = OPC_ROUND_L_D;
14070 goto do_unaryfp;
14071 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_S):
14072 mips32_op = OPC_ROUND_W_S;
14073 goto do_unaryfp;
14074 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_D):
14075 mips32_op = OPC_ROUND_W_D;
14076 goto do_unaryfp;
14077
14078 /* Integer to floating-point conversion */
14079 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_S):
14080 mips32_op = OPC_CVT_L_S;
14081 goto do_unaryfp;
14082 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_D):
14083 mips32_op = OPC_CVT_L_D;
14084 goto do_unaryfp;
14085 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_S):
14086 mips32_op = OPC_CVT_W_S;
14087 goto do_unaryfp;
14088 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_D):
14089 mips32_op = OPC_CVT_W_D;
14090 goto do_unaryfp;
14091
14092 /* Paired-foo conversions */
14093 case FLOAT_1BIT_FMT(CVT_S_PL, 0):
14094 mips32_op = OPC_CVT_S_PL;
14095 goto do_unaryfp;
14096 case FLOAT_1BIT_FMT(CVT_S_PU, 0):
14097 mips32_op = OPC_CVT_S_PU;
14098 goto do_unaryfp;
14099 case FLOAT_1BIT_FMT(CVT_PW_PS, 0):
14100 mips32_op = OPC_CVT_PW_PS;
14101 goto do_unaryfp;
14102 case FLOAT_1BIT_FMT(CVT_PS_PW, 0):
14103 mips32_op = OPC_CVT_PS_PW;
14104 goto do_unaryfp;
14105
14106 /* Floating-point moves */
14107 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_S):
14108 mips32_op = OPC_MOV_S;
14109 goto do_unaryfp;
14110 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_D):
14111 mips32_op = OPC_MOV_D;
14112 goto do_unaryfp;
14113 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_PS):
14114 mips32_op = OPC_MOV_PS;
14115 goto do_unaryfp;
14116
14117 /* Absolute value */
14118 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_S):
14119 mips32_op = OPC_ABS_S;
14120 goto do_unaryfp;
14121 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_D):
14122 mips32_op = OPC_ABS_D;
14123 goto do_unaryfp;
14124 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_PS):
14125 mips32_op = OPC_ABS_PS;
14126 goto do_unaryfp;
14127
14128 /* Negation */
14129 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_S):
14130 mips32_op = OPC_NEG_S;
14131 goto do_unaryfp;
14132 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_D):
14133 mips32_op = OPC_NEG_D;
14134 goto do_unaryfp;
14135 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_PS):
14136 mips32_op = OPC_NEG_PS;
14137 goto do_unaryfp;
14138
14139 /* Reciprocal square root step */
14140 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_S):
14141 mips32_op = OPC_RSQRT1_S;
14142 goto do_unaryfp;
14143 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_D):
14144 mips32_op = OPC_RSQRT1_D;
14145 goto do_unaryfp;
14146 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_PS):
14147 mips32_op = OPC_RSQRT1_PS;
14148 goto do_unaryfp;
14149
14150 /* Reciprocal step */
14151 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_S):
14152 mips32_op = OPC_RECIP1_S;
14153 goto do_unaryfp;
14154 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_D):
14155 mips32_op = OPC_RECIP1_S;
14156 goto do_unaryfp;
14157 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_PS):
14158 mips32_op = OPC_RECIP1_PS;
14159 goto do_unaryfp;
14160
14161 /* Conversions from double */
14162 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_S):
14163 mips32_op = OPC_CVT_D_S;
14164 goto do_unaryfp;
14165 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_W):
14166 mips32_op = OPC_CVT_D_W;
14167 goto do_unaryfp;
14168 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_L):
14169 mips32_op = OPC_CVT_D_L;
14170 goto do_unaryfp;
14171
14172 /* Conversions from single */
14173 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_D):
14174 mips32_op = OPC_CVT_S_D;
14175 goto do_unaryfp;
14176 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_W):
14177 mips32_op = OPC_CVT_S_W;
14178 goto do_unaryfp;
14179 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_L):
14180 mips32_op = OPC_CVT_S_L;
14181 do_unaryfp:
14182 gen_farith(ctx, mips32_op, -1, rs, rt, 0);
14183 break;
14184
14185 /* Conditional moves on floating-point codes */
14186 case COND_FLOAT_MOV(MOVT, 0):
14187 case COND_FLOAT_MOV(MOVT, 1):
14188 case COND_FLOAT_MOV(MOVT, 2):
14189 case COND_FLOAT_MOV(MOVT, 3):
14190 case COND_FLOAT_MOV(MOVT, 4):
14191 case COND_FLOAT_MOV(MOVT, 5):
14192 case COND_FLOAT_MOV(MOVT, 6):
14193 case COND_FLOAT_MOV(MOVT, 7):
9e8f441a 14194 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14195 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 1);
14196 break;
14197 case COND_FLOAT_MOV(MOVF, 0):
14198 case COND_FLOAT_MOV(MOVF, 1):
14199 case COND_FLOAT_MOV(MOVF, 2):
14200 case COND_FLOAT_MOV(MOVF, 3):
14201 case COND_FLOAT_MOV(MOVF, 4):
14202 case COND_FLOAT_MOV(MOVF, 5):
14203 case COND_FLOAT_MOV(MOVF, 6):
14204 case COND_FLOAT_MOV(MOVF, 7):
9e8f441a 14205 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14206 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 0);
14207 break;
14208 default:
14209 MIPS_INVAL("pool32fxf");
9c708c7f 14210 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
14211 break;
14212 }
14213}
14214
f60eeb0c 14215static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx)
3c824109
NF
14216{
14217 int32_t offset;
14218 uint16_t insn;
14219 int rt, rs, rd, rr;
14220 int16_t imm;
8fffc646 14221 uint32_t op, minor, minor2, mips32_op;
3c824109
NF
14222 uint32_t cond, fmt, cc;
14223
eeb3bba8 14224 insn = cpu_lduw_code(env, ctx->base.pc_next + 2);
3c824109
NF
14225 ctx->opcode = (ctx->opcode << 16) | insn;
14226
14227 rt = (ctx->opcode >> 21) & 0x1f;
14228 rs = (ctx->opcode >> 16) & 0x1f;
14229 rd = (ctx->opcode >> 11) & 0x1f;
14230 rr = (ctx->opcode >> 6) & 0x1f;
14231 imm = (int16_t) ctx->opcode;
14232
14233 op = (ctx->opcode >> 26) & 0x3f;
14234 switch (op) {
14235 case POOL32A:
14236 minor = ctx->opcode & 0x3f;
14237 switch (minor) {
14238 case 0x00:
14239 minor = (ctx->opcode >> 6) & 0xf;
14240 switch (minor) {
14241 case SLL32:
14242 mips32_op = OPC_SLL;
14243 goto do_shifti;
14244 case SRA:
14245 mips32_op = OPC_SRA;
14246 goto do_shifti;
14247 case SRL32:
14248 mips32_op = OPC_SRL;
14249 goto do_shifti;
14250 case ROTR:
14251 mips32_op = OPC_ROTR;
14252 do_shifti:
d75c135e 14253 gen_shift_imm(ctx, mips32_op, rt, rs, rd);
3c824109 14254 break;
e0332095
YK
14255 case SELEQZ:
14256 check_insn(ctx, ISA_MIPS32R6);
14257 gen_cond_move(ctx, OPC_SELEQZ, rd, rs, rt);
14258 break;
14259 case SELNEZ:
14260 check_insn(ctx, ISA_MIPS32R6);
14261 gen_cond_move(ctx, OPC_SELNEZ, rd, rs, rt);
14262 break;
b00c7218
YK
14263 case R6_RDHWR:
14264 check_insn(ctx, ISA_MIPS32R6);
14265 gen_rdhwr(ctx, rt, rs, extract32(ctx->opcode, 11, 3));
14266 break;
3c824109
NF
14267 default:
14268 goto pool32a_invalid;
14269 }
14270 break;
14271 case 0x10:
14272 minor = (ctx->opcode >> 6) & 0xf;
14273 switch (minor) {
14274 /* Arithmetic */
14275 case ADD:
14276 mips32_op = OPC_ADD;
14277 goto do_arith;
14278 case ADDU32:
14279 mips32_op = OPC_ADDU;
14280 goto do_arith;
14281 case SUB:
14282 mips32_op = OPC_SUB;
14283 goto do_arith;
14284 case SUBU32:
14285 mips32_op = OPC_SUBU;
14286 goto do_arith;
14287 case MUL:
9e8f441a 14288 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14289 mips32_op = OPC_MUL;
14290 do_arith:
d75c135e 14291 gen_arith(ctx, mips32_op, rd, rs, rt);
3c824109
NF
14292 break;
14293 /* Shifts */
14294 case SLLV:
14295 mips32_op = OPC_SLLV;
14296 goto do_shift;
14297 case SRLV:
14298 mips32_op = OPC_SRLV;
14299 goto do_shift;
14300 case SRAV:
14301 mips32_op = OPC_SRAV;
14302 goto do_shift;
14303 case ROTRV:
14304 mips32_op = OPC_ROTRV;
14305 do_shift:
d75c135e 14306 gen_shift(ctx, mips32_op, rd, rs, rt);
3c824109
NF
14307 break;
14308 /* Logical operations */
14309 case AND:
14310 mips32_op = OPC_AND;
14311 goto do_logic;
14312 case OR32:
14313 mips32_op = OPC_OR;
14314 goto do_logic;
14315 case NOR:
14316 mips32_op = OPC_NOR;
14317 goto do_logic;
14318 case XOR32:
14319 mips32_op = OPC_XOR;
14320 do_logic:
d75c135e 14321 gen_logic(ctx, mips32_op, rd, rs, rt);
3c824109
NF
14322 break;
14323 /* Set less than */
14324 case SLT:
14325 mips32_op = OPC_SLT;
14326 goto do_slt;
14327 case SLTU:
14328 mips32_op = OPC_SLTU;
14329 do_slt:
d75c135e 14330 gen_slt(ctx, mips32_op, rd, rs, rt);
3c824109
NF
14331 break;
14332 default:
14333 goto pool32a_invalid;
14334 }
14335 break;
14336 case 0x18:
14337 minor = (ctx->opcode >> 6) & 0xf;
14338 switch (minor) {
14339 /* Conditional moves */
e0332095
YK
14340 case MOVN: /* MUL */
14341 if (ctx->insn_flags & ISA_MIPS32R6) {
14342 /* MUL */
14343 gen_r6_muldiv(ctx, R6_OPC_MUL, rd, rs, rt);
14344 } else {
14345 /* MOVN */
14346 gen_cond_move(ctx, OPC_MOVN, rd, rs, rt);
14347 }
14348 break;
14349 case MOVZ: /* MUH */
14350 if (ctx->insn_flags & ISA_MIPS32R6) {
14351 /* MUH */
14352 gen_r6_muldiv(ctx, R6_OPC_MUH, rd, rs, rt);
14353 } else {
14354 /* MOVZ */
14355 gen_cond_move(ctx, OPC_MOVZ, rd, rs, rt);
14356 }
14357 break;
14358 case MULU:
14359 check_insn(ctx, ISA_MIPS32R6);
14360 gen_r6_muldiv(ctx, R6_OPC_MULU, rd, rs, rt);
14361 break;
14362 case MUHU:
14363 check_insn(ctx, ISA_MIPS32R6);
14364 gen_r6_muldiv(ctx, R6_OPC_MUHU, rd, rs, rt);
14365 break;
14366 case LWXS: /* DIV */
14367 if (ctx->insn_flags & ISA_MIPS32R6) {
14368 /* DIV */
14369 gen_r6_muldiv(ctx, R6_OPC_DIV, rd, rs, rt);
14370 } else {
14371 /* LWXS */
14372 gen_ldxs(ctx, rs, rt, rd);
14373 }
14374 break;
14375 case MOD:
14376 check_insn(ctx, ISA_MIPS32R6);
14377 gen_r6_muldiv(ctx, R6_OPC_MOD, rd, rs, rt);
14378 break;
14379 case R6_DIVU:
14380 check_insn(ctx, ISA_MIPS32R6);
14381 gen_r6_muldiv(ctx, R6_OPC_DIVU, rd, rs, rt);
3c824109 14382 break;
e0332095
YK
14383 case MODU:
14384 check_insn(ctx, ISA_MIPS32R6);
14385 gen_r6_muldiv(ctx, R6_OPC_MODU, rd, rs, rt);
3c824109
NF
14386 break;
14387 default:
14388 goto pool32a_invalid;
14389 }
14390 break;
14391 case INS:
14392 gen_bitops(ctx, OPC_INS, rt, rs, rr, rd);
14393 return;
e0332095
YK
14394 case LSA:
14395 check_insn(ctx, ISA_MIPS32R6);
14396 gen_lsa(ctx, OPC_LSA, rd, rs, rt,
14397 extract32(ctx->opcode, 9, 2));
14398 break;
14399 case ALIGN:
14400 check_insn(ctx, ISA_MIPS32R6);
14401 gen_align(ctx, OPC_ALIGN, rd, rs, rt,
14402 extract32(ctx->opcode, 9, 2));
14403 break;
3c824109
NF
14404 case EXT:
14405 gen_bitops(ctx, OPC_EXT, rt, rs, rr, rd);
14406 return;
14407 case POOL32AXF:
240ce26a 14408 gen_pool32axf(env, ctx, rt, rs);
3c824109 14409 break;
dbd8af98 14410 case BREAK32:
9c708c7f 14411 generate_exception_end(ctx, EXCP_BREAK);
3c824109 14412 break;
bb238210
YK
14413 case SIGRIE:
14414 check_insn(ctx, ISA_MIPS32R6);
14415 generate_exception_end(ctx, EXCP_RI);
14416 break;
3c824109
NF
14417 default:
14418 pool32a_invalid:
14419 MIPS_INVAL("pool32a");
9c708c7f 14420 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
14421 break;
14422 }
14423 break;
14424 case POOL32B:
14425 minor = (ctx->opcode >> 12) & 0xf;
14426 switch (minor) {
14427 case CACHE:
2e15497c 14428 check_cp0_enabled(ctx);
0d74a222
LA
14429 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
14430 gen_cache_operation(ctx, rt, rs, imm);
14431 }
3c824109
NF
14432 break;
14433 case LWC2:
14434 case SWC2:
14435 /* COP2: Not implemented. */
14436 generate_exception_err(ctx, EXCP_CpU, 2);
14437 break;
3c824109
NF
14438#ifdef TARGET_MIPS64
14439 case LDP:
14440 case SDP:
d9224450
MR
14441 check_insn(ctx, ISA_MIPS3);
14442 check_mips_64(ctx);
3c824109 14443#endif
146dd620 14444 /* fall through */
d9224450
MR
14445 case LWP:
14446 case SWP:
3c824109
NF
14447 gen_ldst_pair(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
14448 break;
3c824109
NF
14449#ifdef TARGET_MIPS64
14450 case LDM:
14451 case SDM:
d9224450
MR
14452 check_insn(ctx, ISA_MIPS3);
14453 check_mips_64(ctx);
3c824109 14454#endif
146dd620 14455 /* fall through */
d9224450
MR
14456 case LWM32:
14457 case SWM32:
3c824109
NF
14458 gen_ldst_multiple(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
14459 break;
14460 default:
14461 MIPS_INVAL("pool32b");
9c708c7f 14462 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
14463 break;
14464 }
14465 break;
14466 case POOL32F:
5ab5c041 14467 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
3c824109
NF
14468 minor = ctx->opcode & 0x3f;
14469 check_cp1_enabled(ctx);
14470 switch (minor) {
14471 case ALNV_PS:
9e8f441a 14472 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14473 mips32_op = OPC_ALNV_PS;
14474 goto do_madd;
14475 case MADD_S:
9e8f441a 14476 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14477 mips32_op = OPC_MADD_S;
14478 goto do_madd;
14479 case MADD_D:
9e8f441a 14480 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14481 mips32_op = OPC_MADD_D;
14482 goto do_madd;
14483 case MADD_PS:
9e8f441a 14484 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14485 mips32_op = OPC_MADD_PS;
14486 goto do_madd;
14487 case MSUB_S:
9e8f441a 14488 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14489 mips32_op = OPC_MSUB_S;
14490 goto do_madd;
14491 case MSUB_D:
9e8f441a 14492 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14493 mips32_op = OPC_MSUB_D;
14494 goto do_madd;
14495 case MSUB_PS:
9e8f441a 14496 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14497 mips32_op = OPC_MSUB_PS;
14498 goto do_madd;
14499 case NMADD_S:
9e8f441a 14500 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14501 mips32_op = OPC_NMADD_S;
14502 goto do_madd;
14503 case NMADD_D:
9e8f441a 14504 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14505 mips32_op = OPC_NMADD_D;
14506 goto do_madd;
14507 case NMADD_PS:
9e8f441a 14508 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14509 mips32_op = OPC_NMADD_PS;
14510 goto do_madd;
14511 case NMSUB_S:
9e8f441a 14512 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14513 mips32_op = OPC_NMSUB_S;
14514 goto do_madd;
14515 case NMSUB_D:
9e8f441a 14516 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14517 mips32_op = OPC_NMSUB_D;
14518 goto do_madd;
14519 case NMSUB_PS:
9e8f441a 14520 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14521 mips32_op = OPC_NMSUB_PS;
14522 do_madd:
14523 gen_flt3_arith(ctx, mips32_op, rd, rr, rs, rt);
14524 break;
14525 case CABS_COND_FMT:
9e8f441a 14526 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14527 cond = (ctx->opcode >> 6) & 0xf;
14528 cc = (ctx->opcode >> 13) & 0x7;
14529 fmt = (ctx->opcode >> 10) & 0x3;
14530 switch (fmt) {
14531 case 0x0:
14532 gen_cmpabs_s(ctx, cond, rt, rs, cc);
14533 break;
14534 case 0x1:
14535 gen_cmpabs_d(ctx, cond, rt, rs, cc);
14536 break;
14537 case 0x2:
14538 gen_cmpabs_ps(ctx, cond, rt, rs, cc);
14539 break;
14540 default:
14541 goto pool32f_invalid;
14542 }
14543 break;
14544 case C_COND_FMT:
9e8f441a 14545 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14546 cond = (ctx->opcode >> 6) & 0xf;
14547 cc = (ctx->opcode >> 13) & 0x7;
14548 fmt = (ctx->opcode >> 10) & 0x3;
14549 switch (fmt) {
14550 case 0x0:
14551 gen_cmp_s(ctx, cond, rt, rs, cc);
14552 break;
14553 case 0x1:
14554 gen_cmp_d(ctx, cond, rt, rs, cc);
14555 break;
14556 case 0x2:
14557 gen_cmp_ps(ctx, cond, rt, rs, cc);
14558 break;
14559 default:
14560 goto pool32f_invalid;
14561 }
14562 break;
2a24a7ba
YK
14563 case CMP_CONDN_S:
14564 check_insn(ctx, ISA_MIPS32R6);
14565 gen_r6_cmp_s(ctx, (ctx->opcode >> 6) & 0x1f, rt, rs, rd);
14566 break;
14567 case CMP_CONDN_D:
14568 check_insn(ctx, ISA_MIPS32R6);
14569 gen_r6_cmp_d(ctx, (ctx->opcode >> 6) & 0x1f, rt, rs, rd);
14570 break;
3c824109 14571 case POOL32FXF:
d75c135e 14572 gen_pool32fxf(ctx, rt, rs);
3c824109
NF
14573 break;
14574 case 0x00:
14575 /* PLL foo */
14576 switch ((ctx->opcode >> 6) & 0x7) {
14577 case PLL_PS:
14578 mips32_op = OPC_PLL_PS;
14579 goto do_ps;
14580 case PLU_PS:
14581 mips32_op = OPC_PLU_PS;
14582 goto do_ps;
14583 case PUL_PS:
14584 mips32_op = OPC_PUL_PS;
14585 goto do_ps;
14586 case PUU_PS:
14587 mips32_op = OPC_PUU_PS;
14588 goto do_ps;
14589 case CVT_PS_S:
9e8f441a 14590 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14591 mips32_op = OPC_CVT_PS_S;
14592 do_ps:
14593 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
14594 break;
14595 default:
14596 goto pool32f_invalid;
14597 }
14598 break;
2a24a7ba
YK
14599 case MIN_FMT:
14600 check_insn(ctx, ISA_MIPS32R6);
14601 switch ((ctx->opcode >> 9) & 0x3) {
14602 case FMT_SDPS_S:
14603 gen_farith(ctx, OPC_MIN_S, rt, rs, rd, 0);
14604 break;
14605 case FMT_SDPS_D:
14606 gen_farith(ctx, OPC_MIN_D, rt, rs, rd, 0);
14607 break;
14608 default:
14609 goto pool32f_invalid;
14610 }
14611 break;
3c824109
NF
14612 case 0x08:
14613 /* [LS][WDU]XC1 */
14614 switch ((ctx->opcode >> 6) & 0x7) {
14615 case LWXC1:
9e8f441a 14616 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14617 mips32_op = OPC_LWXC1;
14618 goto do_ldst_cp1;
14619 case SWXC1:
9e8f441a 14620 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14621 mips32_op = OPC_SWXC1;
14622 goto do_ldst_cp1;
14623 case LDXC1:
9e8f441a 14624 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14625 mips32_op = OPC_LDXC1;
14626 goto do_ldst_cp1;
14627 case SDXC1:
9e8f441a 14628 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14629 mips32_op = OPC_SDXC1;
14630 goto do_ldst_cp1;
14631 case LUXC1:
9e8f441a 14632 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14633 mips32_op = OPC_LUXC1;
14634 goto do_ldst_cp1;
14635 case SUXC1:
9e8f441a 14636 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14637 mips32_op = OPC_SUXC1;
14638 do_ldst_cp1:
14639 gen_flt3_ldst(ctx, mips32_op, rd, rd, rt, rs);
14640 break;
14641 default:
14642 goto pool32f_invalid;
14643 }
14644 break;
2a24a7ba
YK
14645 case MAX_FMT:
14646 check_insn(ctx, ISA_MIPS32R6);
14647 switch ((ctx->opcode >> 9) & 0x3) {
14648 case FMT_SDPS_S:
14649 gen_farith(ctx, OPC_MAX_S, rt, rs, rd, 0);
14650 break;
14651 case FMT_SDPS_D:
14652 gen_farith(ctx, OPC_MAX_D, rt, rs, rd, 0);
14653 break;
14654 default:
14655 goto pool32f_invalid;
14656 }
14657 break;
3c824109
NF
14658 case 0x18:
14659 /* 3D insns */
9e8f441a 14660 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14661 fmt = (ctx->opcode >> 9) & 0x3;
14662 switch ((ctx->opcode >> 6) & 0x7) {
14663 case RSQRT2_FMT:
14664 switch (fmt) {
14665 case FMT_SDPS_S:
14666 mips32_op = OPC_RSQRT2_S;
14667 goto do_3d;
14668 case FMT_SDPS_D:
14669 mips32_op = OPC_RSQRT2_D;
14670 goto do_3d;
14671 case FMT_SDPS_PS:
14672 mips32_op = OPC_RSQRT2_PS;
14673 goto do_3d;
14674 default:
14675 goto pool32f_invalid;
14676 }
14677 break;
14678 case RECIP2_FMT:
14679 switch (fmt) {
14680 case FMT_SDPS_S:
14681 mips32_op = OPC_RECIP2_S;
14682 goto do_3d;
14683 case FMT_SDPS_D:
14684 mips32_op = OPC_RECIP2_D;
14685 goto do_3d;
14686 case FMT_SDPS_PS:
14687 mips32_op = OPC_RECIP2_PS;
14688 goto do_3d;
14689 default:
14690 goto pool32f_invalid;
14691 }
14692 break;
14693 case ADDR_PS:
14694 mips32_op = OPC_ADDR_PS;
14695 goto do_3d;
14696 case MULR_PS:
14697 mips32_op = OPC_MULR_PS;
14698 do_3d:
14699 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
14700 break;
14701 default:
14702 goto pool32f_invalid;
14703 }
14704 break;
14705 case 0x20:
2a24a7ba 14706 /* MOV[FT].fmt, PREFX, RINT.fmt, CLASS.fmt*/
3c824109
NF
14707 cc = (ctx->opcode >> 13) & 0x7;
14708 fmt = (ctx->opcode >> 9) & 0x3;
14709 switch ((ctx->opcode >> 6) & 0x7) {
2a24a7ba
YK
14710 case MOVF_FMT: /* RINT_FMT */
14711 if (ctx->insn_flags & ISA_MIPS32R6) {
14712 /* RINT_FMT */
14713 switch (fmt) {
14714 case FMT_SDPS_S:
14715 gen_farith(ctx, OPC_RINT_S, 0, rt, rs, 0);
14716 break;
14717 case FMT_SDPS_D:
14718 gen_farith(ctx, OPC_RINT_D, 0, rt, rs, 0);
14719 break;
14720 default:
14721 goto pool32f_invalid;
14722 }
14723 } else {
14724 /* MOVF_FMT */
14725 switch (fmt) {
14726 case FMT_SDPS_S:
14727 gen_movcf_s(ctx, rs, rt, cc, 0);
14728 break;
14729 case FMT_SDPS_D:
14730 gen_movcf_d(ctx, rs, rt, cc, 0);
14731 break;
14732 case FMT_SDPS_PS:
14733 check_ps(ctx);
14734 gen_movcf_ps(ctx, rs, rt, cc, 0);
14735 break;
14736 default:
14737 goto pool32f_invalid;
14738 }
3c824109
NF
14739 }
14740 break;
2a24a7ba
YK
14741 case MOVT_FMT: /* CLASS_FMT */
14742 if (ctx->insn_flags & ISA_MIPS32R6) {
14743 /* CLASS_FMT */
14744 switch (fmt) {
14745 case FMT_SDPS_S:
14746 gen_farith(ctx, OPC_CLASS_S, 0, rt, rs, 0);
14747 break;
14748 case FMT_SDPS_D:
14749 gen_farith(ctx, OPC_CLASS_D, 0, rt, rs, 0);
14750 break;
14751 default:
14752 goto pool32f_invalid;
14753 }
14754 } else {
14755 /* MOVT_FMT */
14756 switch (fmt) {
14757 case FMT_SDPS_S:
14758 gen_movcf_s(ctx, rs, rt, cc, 1);
14759 break;
14760 case FMT_SDPS_D:
14761 gen_movcf_d(ctx, rs, rt, cc, 1);
14762 break;
14763 case FMT_SDPS_PS:
14764 check_ps(ctx);
14765 gen_movcf_ps(ctx, rs, rt, cc, 1);
14766 break;
14767 default:
14768 goto pool32f_invalid;
14769 }
3c824109
NF
14770 }
14771 break;
14772 case PREFX:
9e8f441a 14773 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14774 break;
14775 default:
14776 goto pool32f_invalid;
14777 }
14778 break;
14779#define FINSN_3ARG_SDPS(prfx) \
14780 switch ((ctx->opcode >> 8) & 0x3) { \
14781 case FMT_SDPS_S: \
14782 mips32_op = OPC_##prfx##_S; \
14783 goto do_fpop; \
14784 case FMT_SDPS_D: \
14785 mips32_op = OPC_##prfx##_D; \
14786 goto do_fpop; \
14787 case FMT_SDPS_PS: \
e29c9628 14788 check_ps(ctx); \
3c824109
NF
14789 mips32_op = OPC_##prfx##_PS; \
14790 goto do_fpop; \
14791 default: \
14792 goto pool32f_invalid; \
14793 }
2a24a7ba
YK
14794 case MINA_FMT:
14795 check_insn(ctx, ISA_MIPS32R6);
14796 switch ((ctx->opcode >> 9) & 0x3) {
14797 case FMT_SDPS_S:
14798 gen_farith(ctx, OPC_MINA_S, rt, rs, rd, 0);
14799 break;
14800 case FMT_SDPS_D:
14801 gen_farith(ctx, OPC_MINA_D, rt, rs, rd, 0);
14802 break;
14803 default:
14804 goto pool32f_invalid;
14805 }
14806 break;
14807 case MAXA_FMT:
14808 check_insn(ctx, ISA_MIPS32R6);
14809 switch ((ctx->opcode >> 9) & 0x3) {
14810 case FMT_SDPS_S:
14811 gen_farith(ctx, OPC_MAXA_S, rt, rs, rd, 0);
14812 break;
14813 case FMT_SDPS_D:
14814 gen_farith(ctx, OPC_MAXA_D, rt, rs, rd, 0);
14815 break;
14816 default:
14817 goto pool32f_invalid;
14818 }
14819 break;
3c824109
NF
14820 case 0x30:
14821 /* regular FP ops */
14822 switch ((ctx->opcode >> 6) & 0x3) {
14823 case ADD_FMT:
14824 FINSN_3ARG_SDPS(ADD);
14825 break;
14826 case SUB_FMT:
14827 FINSN_3ARG_SDPS(SUB);
14828 break;
14829 case MUL_FMT:
14830 FINSN_3ARG_SDPS(MUL);
14831 break;
14832 case DIV_FMT:
14833 fmt = (ctx->opcode >> 8) & 0x3;
14834 if (fmt == 1) {
14835 mips32_op = OPC_DIV_D;
14836 } else if (fmt == 0) {
14837 mips32_op = OPC_DIV_S;
14838 } else {
14839 goto pool32f_invalid;
14840 }
14841 goto do_fpop;
14842 default:
14843 goto pool32f_invalid;
14844 }
14845 break;
14846 case 0x38:
14847 /* cmovs */
2a24a7ba
YK
14848 switch ((ctx->opcode >> 6) & 0x7) {
14849 case MOVN_FMT: /* SELNEZ_FMT */
14850 if (ctx->insn_flags & ISA_MIPS32R6) {
14851 /* SELNEZ_FMT */
14852 switch ((ctx->opcode >> 9) & 0x3) {
14853 case FMT_SDPS_S:
14854 gen_sel_s(ctx, OPC_SELNEZ_S, rd, rt, rs);
14855 break;
14856 case FMT_SDPS_D:
14857 gen_sel_d(ctx, OPC_SELNEZ_D, rd, rt, rs);
14858 break;
14859 default:
14860 goto pool32f_invalid;
14861 }
14862 } else {
14863 /* MOVN_FMT */
14864 FINSN_3ARG_SDPS(MOVN);
14865 }
14866 break;
14867 case MOVN_FMT_04:
14868 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14869 FINSN_3ARG_SDPS(MOVN);
14870 break;
2a24a7ba
YK
14871 case MOVZ_FMT: /* SELEQZ_FMT */
14872 if (ctx->insn_flags & ISA_MIPS32R6) {
14873 /* SELEQZ_FMT */
14874 switch ((ctx->opcode >> 9) & 0x3) {
14875 case FMT_SDPS_S:
14876 gen_sel_s(ctx, OPC_SELEQZ_S, rd, rt, rs);
14877 break;
14878 case FMT_SDPS_D:
14879 gen_sel_d(ctx, OPC_SELEQZ_D, rd, rt, rs);
14880 break;
14881 default:
14882 goto pool32f_invalid;
14883 }
14884 } else {
14885 /* MOVZ_FMT */
14886 FINSN_3ARG_SDPS(MOVZ);
14887 }
14888 break;
14889 case MOVZ_FMT_05:
14890 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14891 FINSN_3ARG_SDPS(MOVZ);
14892 break;
2a24a7ba
YK
14893 case SEL_FMT:
14894 check_insn(ctx, ISA_MIPS32R6);
14895 switch ((ctx->opcode >> 9) & 0x3) {
14896 case FMT_SDPS_S:
14897 gen_sel_s(ctx, OPC_SEL_S, rd, rt, rs);
14898 break;
14899 case FMT_SDPS_D:
14900 gen_sel_d(ctx, OPC_SEL_D, rd, rt, rs);
14901 break;
14902 default:
14903 goto pool32f_invalid;
14904 }
14905 break;
14906 case MADDF_FMT:
14907 check_insn(ctx, ISA_MIPS32R6);
14908 switch ((ctx->opcode >> 9) & 0x3) {
14909 case FMT_SDPS_S:
14910 mips32_op = OPC_MADDF_S;
14911 goto do_fpop;
14912 case FMT_SDPS_D:
14913 mips32_op = OPC_MADDF_D;
14914 goto do_fpop;
14915 default:
14916 goto pool32f_invalid;
14917 }
14918 break;
14919 case MSUBF_FMT:
14920 check_insn(ctx, ISA_MIPS32R6);
14921 switch ((ctx->opcode >> 9) & 0x3) {
14922 case FMT_SDPS_S:
14923 mips32_op = OPC_MSUBF_S;
14924 goto do_fpop;
14925 case FMT_SDPS_D:
14926 mips32_op = OPC_MSUBF_D;
14927 goto do_fpop;
14928 default:
14929 goto pool32f_invalid;
14930 }
14931 break;
3c824109
NF
14932 default:
14933 goto pool32f_invalid;
14934 }
14935 break;
14936 do_fpop:
14937 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
14938 break;
14939 default:
14940 pool32f_invalid:
14941 MIPS_INVAL("pool32f");
9c708c7f 14942 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
14943 break;
14944 }
14945 } else {
14946 generate_exception_err(ctx, EXCP_CpU, 1);
14947 }
14948 break;
14949 case POOL32I:
14950 minor = (ctx->opcode >> 21) & 0x1f;
14951 switch (minor) {
14952 case BLTZ:
9e8f441a 14953 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
14954 gen_compute_branch(ctx, OPC_BLTZ, 4, rs, -1, imm << 1, 4);
14955 break;
3c824109 14956 case BLTZAL:
9e8f441a 14957 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
14958 gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 4);
14959 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14960 break;
3c824109 14961 case BLTZALS:
9e8f441a 14962 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
14963 gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 2);
14964 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14965 break;
3c824109 14966 case BGEZ:
9e8f441a 14967 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
14968 gen_compute_branch(ctx, OPC_BGEZ, 4, rs, -1, imm << 1, 4);
14969 break;
3c824109 14970 case BGEZAL:
9e8f441a 14971 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
14972 gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 4);
14973 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14974 break;
3c824109 14975 case BGEZALS:
9e8f441a 14976 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
14977 gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 2);
14978 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14979 break;
3c824109 14980 case BLEZ:
9e8f441a 14981 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
14982 gen_compute_branch(ctx, OPC_BLEZ, 4, rs, -1, imm << 1, 4);
14983 break;
3c824109 14984 case BGTZ:
9e8f441a 14985 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103 14986 gen_compute_branch(ctx, OPC_BGTZ, 4, rs, -1, imm << 1, 4);
3c824109
NF
14987 break;
14988
14989 /* Traps */
65935f07
YK
14990 case TLTI: /* BC1EQZC */
14991 if (ctx->insn_flags & ISA_MIPS32R6) {
14992 /* BC1EQZC */
14993 check_cp1_enabled(ctx);
14994 gen_compute_branch1_r6(ctx, OPC_BC1EQZ, rs, imm << 1, 0);
14995 } else {
14996 /* TLTI */
14997 mips32_op = OPC_TLTI;
14998 goto do_trapi;
14999 }
15000 break;
15001 case TGEI: /* BC1NEZC */
15002 if (ctx->insn_flags & ISA_MIPS32R6) {
15003 /* BC1NEZC */
15004 check_cp1_enabled(ctx);
15005 gen_compute_branch1_r6(ctx, OPC_BC1NEZ, rs, imm << 1, 0);
15006 } else {
15007 /* TGEI */
15008 mips32_op = OPC_TGEI;
15009 goto do_trapi;
15010 }
15011 break;
3c824109 15012 case TLTIU:
9e8f441a 15013 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
15014 mips32_op = OPC_TLTIU;
15015 goto do_trapi;
15016 case TGEIU:
9e8f441a 15017 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
15018 mips32_op = OPC_TGEIU;
15019 goto do_trapi;
3b4a5489
YK
15020 case TNEI: /* SYNCI */
15021 if (ctx->insn_flags & ISA_MIPS32R6) {
15022 /* SYNCI */
15023 /* Break the TB to be able to sync copied instructions
15024 immediately */
eeb3bba8 15025 ctx->base.is_jmp = DISAS_STOP;
3b4a5489
YK
15026 } else {
15027 /* TNEI */
15028 mips32_op = OPC_TNEI;
15029 goto do_trapi;
15030 }
15031 break;
3c824109 15032 case TEQI:
9e8f441a 15033 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
15034 mips32_op = OPC_TEQI;
15035 do_trapi:
15036 gen_trap(ctx, mips32_op, rs, -1, imm);
15037 break;
15038
15039 case BNEZC:
15040 case BEQZC:
9e8f441a 15041 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 15042 gen_compute_branch(ctx, minor == BNEZC ? OPC_BNE : OPC_BEQ,
b231c103 15043 4, rs, 0, imm << 1, 0);
3c824109
NF
15044 /* Compact branches don't have a delay slot, so just let
15045 the normal delay slot handling take us to the branch
15046 target. */
15047 break;
15048 case LUI:
9e8f441a 15049 check_insn_opc_removed(ctx, ISA_MIPS32R6);
5e88759a 15050 gen_logic_imm(ctx, OPC_LUI, rs, 0, imm);
3c824109
NF
15051 break;
15052 case SYNCI:
9e8f441a 15053 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a83bddd6
DZ
15054 /* Break the TB to be able to sync copied instructions
15055 immediately */
eeb3bba8 15056 ctx->base.is_jmp = DISAS_STOP;
3c824109
NF
15057 break;
15058 case BC2F:
15059 case BC2T:
9e8f441a 15060 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
15061 /* COP2: Not implemented. */
15062 generate_exception_err(ctx, EXCP_CpU, 2);
15063 break;
15064 case BC1F:
9e8f441a 15065 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
15066 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1FANY2 : OPC_BC1F;
15067 goto do_cp1branch;
15068 case BC1T:
9e8f441a 15069 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
15070 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1TANY2 : OPC_BC1T;
15071 goto do_cp1branch;
15072 case BC1ANY4F:
9e8f441a 15073 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
15074 mips32_op = OPC_BC1FANY4;
15075 goto do_cp1mips3d;
15076 case BC1ANY4T:
9e8f441a 15077 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
15078 mips32_op = OPC_BC1TANY4;
15079 do_cp1mips3d:
15080 check_cop1x(ctx);
d75c135e 15081 check_insn(ctx, ASE_MIPS3D);
3c824109
NF
15082 /* Fall through */
15083 do_cp1branch:
272f458d
MR
15084 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
15085 check_cp1_enabled(ctx);
15086 gen_compute_branch1(ctx, mips32_op,
15087 (ctx->opcode >> 18) & 0x7, imm << 1);
15088 } else {
15089 generate_exception_err(ctx, EXCP_CpU, 1);
15090 }
3c824109
NF
15091 break;
15092 case BPOSGE64:
15093 case BPOSGE32:
15094 /* MIPS DSP: not implemented */
15095 /* Fall through */
15096 default:
15097 MIPS_INVAL("pool32i");
9c708c7f 15098 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
15099 break;
15100 }
15101 break;
15102 case POOL32C:
15103 minor = (ctx->opcode >> 12) & 0xf;
3b4a5489
YK
15104 offset = sextract32(ctx->opcode, 0,
15105 (ctx->insn_flags & ISA_MIPS32R6) ? 9 : 12);
3c824109
NF
15106 switch (minor) {
15107 case LWL:
9e8f441a 15108 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 15109 mips32_op = OPC_LWL;
5c13fdfd 15110 goto do_ld_lr;
3c824109 15111 case SWL:
9e8f441a 15112 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 15113 mips32_op = OPC_SWL;
5c13fdfd 15114 goto do_st_lr;
3c824109 15115 case LWR:
9e8f441a 15116 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 15117 mips32_op = OPC_LWR;
5c13fdfd 15118 goto do_ld_lr;
3c824109 15119 case SWR:
9e8f441a 15120 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 15121 mips32_op = OPC_SWR;
5c13fdfd 15122 goto do_st_lr;
3c824109
NF
15123#if defined(TARGET_MIPS64)
15124 case LDL:
d9224450
MR
15125 check_insn(ctx, ISA_MIPS3);
15126 check_mips_64(ctx);
9e8f441a 15127 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 15128 mips32_op = OPC_LDL;
5c13fdfd 15129 goto do_ld_lr;
3c824109 15130 case SDL:
d9224450
MR
15131 check_insn(ctx, ISA_MIPS3);
15132 check_mips_64(ctx);
9e8f441a 15133 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 15134 mips32_op = OPC_SDL;
5c13fdfd 15135 goto do_st_lr;
3c824109 15136 case LDR:
d9224450
MR
15137 check_insn(ctx, ISA_MIPS3);
15138 check_mips_64(ctx);
9e8f441a 15139 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 15140 mips32_op = OPC_LDR;
5c13fdfd 15141 goto do_ld_lr;
3c824109 15142 case SDR:
d9224450
MR
15143 check_insn(ctx, ISA_MIPS3);
15144 check_mips_64(ctx);
9e8f441a 15145 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 15146 mips32_op = OPC_SDR;
5c13fdfd 15147 goto do_st_lr;
3c824109 15148 case LWU:
d9224450
MR
15149 check_insn(ctx, ISA_MIPS3);
15150 check_mips_64(ctx);
3c824109 15151 mips32_op = OPC_LWU;
5c13fdfd 15152 goto do_ld_lr;
3c824109 15153 case LLD:
d9224450
MR
15154 check_insn(ctx, ISA_MIPS3);
15155 check_mips_64(ctx);
3c824109 15156 mips32_op = OPC_LLD;
5c13fdfd 15157 goto do_ld_lr;
3c824109
NF
15158#endif
15159 case LL:
15160 mips32_op = OPC_LL;
5c13fdfd
AJ
15161 goto do_ld_lr;
15162 do_ld_lr:
3b4a5489 15163 gen_ld(ctx, mips32_op, rt, rs, offset);
5c13fdfd
AJ
15164 break;
15165 do_st_lr:
8fffc646 15166 gen_st(ctx, mips32_op, rt, rs, offset);
3c824109
NF
15167 break;
15168 case SC:
3b4a5489 15169 gen_st_cond(ctx, OPC_SC, rt, rs, offset);
3c824109
NF
15170 break;
15171#if defined(TARGET_MIPS64)
15172 case SCD:
d9224450
MR
15173 check_insn(ctx, ISA_MIPS3);
15174 check_mips_64(ctx);
3b4a5489 15175 gen_st_cond(ctx, OPC_SCD, rt, rs, offset);
3c824109
NF
15176 break;
15177#endif
8fffc646
JH
15178 case LD_EVA:
15179 if (!ctx->eva) {
15180 MIPS_INVAL("pool32c ld-eva");
15181 generate_exception_end(ctx, EXCP_RI);
15182 break;
15183 }
15184 check_cp0_enabled(ctx);
15185
15186 minor2 = (ctx->opcode >> 9) & 0x7;
15187 offset = sextract32(ctx->opcode, 0, 9);
15188 switch (minor2) {
15189 case LBUE:
15190 mips32_op = OPC_LBUE;
15191 goto do_ld_lr;
15192 case LHUE:
15193 mips32_op = OPC_LHUE;
15194 goto do_ld_lr;
15195 case LWLE:
15196 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15197 mips32_op = OPC_LWLE;
15198 goto do_ld_lr;
15199 case LWRE:
15200 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15201 mips32_op = OPC_LWRE;
15202 goto do_ld_lr;
15203 case LBE:
15204 mips32_op = OPC_LBE;
15205 goto do_ld_lr;
15206 case LHE:
15207 mips32_op = OPC_LHE;
15208 goto do_ld_lr;
15209 case LLE:
15210 mips32_op = OPC_LLE;
15211 goto do_ld_lr;
15212 case LWE:
15213 mips32_op = OPC_LWE;
15214 goto do_ld_lr;
15215 };
15216 break;
15217 case ST_EVA:
15218 if (!ctx->eva) {
15219 MIPS_INVAL("pool32c st-eva");
15220 generate_exception_end(ctx, EXCP_RI);
15221 break;
15222 }
15223 check_cp0_enabled(ctx);
15224
15225 minor2 = (ctx->opcode >> 9) & 0x7;
15226 offset = sextract32(ctx->opcode, 0, 9);
15227 switch (minor2) {
15228 case SWLE:
15229 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15230 mips32_op = OPC_SWLE;
15231 goto do_st_lr;
15232 case SWRE:
15233 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15234 mips32_op = OPC_SWRE;
15235 goto do_st_lr;
15236 case PREFE:
15237 /* Treat as no-op */
15238 if ((ctx->insn_flags & ISA_MIPS32R6) && (rt >= 24)) {
15239 /* hint codes 24-31 are reserved and signal RI */
15240 generate_exception(ctx, EXCP_RI);
15241 }
15242 break;
15243 case CACHEE:
15244 /* Treat as no-op */
15245 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
15246 gen_cache_operation(ctx, rt, rs, offset);
15247 }
15248 break;
15249 case SBE:
15250 mips32_op = OPC_SBE;
15251 goto do_st_lr;
15252 case SHE:
15253 mips32_op = OPC_SHE;
15254 goto do_st_lr;
15255 case SCE:
15256 gen_st_cond(ctx, OPC_SCE, rt, rs, offset);
15257 break;
15258 case SWE:
15259 mips32_op = OPC_SWE;
15260 goto do_st_lr;
15261 };
15262 break;
3c824109
NF
15263 case PREF:
15264 /* Treat as no-op */
3b4a5489
YK
15265 if ((ctx->insn_flags & ISA_MIPS32R6) && (rt >= 24)) {
15266 /* hint codes 24-31 are reserved and signal RI */
15267 generate_exception(ctx, EXCP_RI);
15268 }
3c824109
NF
15269 break;
15270 default:
15271 MIPS_INVAL("pool32c");
9c708c7f 15272 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
15273 break;
15274 }
15275 break;
ab39ee45
YK
15276 case ADDI32: /* AUI, LUI */
15277 if (ctx->insn_flags & ISA_MIPS32R6) {
15278 /* AUI, LUI */
15279 gen_logic_imm(ctx, OPC_LUI, rt, rs, imm);
15280 } else {
15281 /* ADDI32 */
15282 mips32_op = OPC_ADDI;
15283 goto do_addi;
15284 }
15285 break;
3c824109
NF
15286 case ADDIU32:
15287 mips32_op = OPC_ADDIU;
15288 do_addi:
d75c135e 15289 gen_arith_imm(ctx, mips32_op, rt, rs, imm);
3c824109
NF
15290 break;
15291
15292 /* Logical operations */
15293 case ORI32:
15294 mips32_op = OPC_ORI;
15295 goto do_logici;
15296 case XORI32:
15297 mips32_op = OPC_XORI;
15298 goto do_logici;
15299 case ANDI32:
15300 mips32_op = OPC_ANDI;
15301 do_logici:
d75c135e 15302 gen_logic_imm(ctx, mips32_op, rt, rs, imm);
3c824109
NF
15303 break;
15304
15305 /* Set less than immediate */
15306 case SLTI32:
15307 mips32_op = OPC_SLTI;
15308 goto do_slti;
15309 case SLTIU32:
15310 mips32_op = OPC_SLTIU;
15311 do_slti:
d75c135e 15312 gen_slt_imm(ctx, mips32_op, rt, rs, imm);
3c824109
NF
15313 break;
15314 case JALX32:
9e8f441a 15315 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 15316 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
b231c103
YK
15317 gen_compute_branch(ctx, OPC_JALX, 4, rt, rs, offset, 4);
15318 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
3c824109 15319 break;
65935f07
YK
15320 case JALS32: /* BOVC, BEQC, BEQZALC */
15321 if (ctx->insn_flags & ISA_MIPS32R6) {
15322 if (rs >= rt) {
15323 /* BOVC */
15324 mips32_op = OPC_BOVC;
15325 } else if (rs < rt && rs == 0) {
15326 /* BEQZALC */
15327 mips32_op = OPC_BEQZALC;
15328 } else {
15329 /* BEQC */
15330 mips32_op = OPC_BEQC;
15331 }
15332 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
15333 } else {
15334 /* JALS32 */
15335 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 1;
15336 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs, offset, 2);
15337 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
15338 }
3c824109 15339 break;
65935f07
YK
15340 case BEQ32: /* BC */
15341 if (ctx->insn_flags & ISA_MIPS32R6) {
15342 /* BC */
15343 gen_compute_compact_branch(ctx, OPC_BC, 0, 0,
15344 sextract32(ctx->opcode << 1, 0, 27));
15345 } else {
15346 /* BEQ32 */
15347 gen_compute_branch(ctx, OPC_BEQ, 4, rt, rs, imm << 1, 4);
15348 }
3c824109 15349 break;
65935f07
YK
15350 case BNE32: /* BALC */
15351 if (ctx->insn_flags & ISA_MIPS32R6) {
15352 /* BALC */
15353 gen_compute_compact_branch(ctx, OPC_BALC, 0, 0,
15354 sextract32(ctx->opcode << 1, 0, 27));
15355 } else {
15356 /* BNE32 */
15357 gen_compute_branch(ctx, OPC_BNE, 4, rt, rs, imm << 1, 4);
15358 }
3c824109 15359 break;
65935f07
YK
15360 case J32: /* BGTZC, BLTZC, BLTC */
15361 if (ctx->insn_flags & ISA_MIPS32R6) {
15362 if (rs == 0 && rt != 0) {
15363 /* BGTZC */
15364 mips32_op = OPC_BGTZC;
15365 } else if (rs != 0 && rt != 0 && rs == rt) {
15366 /* BLTZC */
15367 mips32_op = OPC_BLTZC;
15368 } else {
15369 /* BLTC */
15370 mips32_op = OPC_BLTC;
15371 }
15372 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
15373 } else {
15374 /* J32 */
15375 gen_compute_branch(ctx, OPC_J, 4, rt, rs,
15376 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
15377 }
3c824109 15378 break;
65935f07
YK
15379 case JAL32: /* BLEZC, BGEZC, BGEC */
15380 if (ctx->insn_flags & ISA_MIPS32R6) {
15381 if (rs == 0 && rt != 0) {
15382 /* BLEZC */
15383 mips32_op = OPC_BLEZC;
15384 } else if (rs != 0 && rt != 0 && rs == rt) {
15385 /* BGEZC */
15386 mips32_op = OPC_BGEZC;
15387 } else {
15388 /* BGEC */
15389 mips32_op = OPC_BGEC;
15390 }
15391 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
15392 } else {
15393 /* JAL32 */
15394 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs,
15395 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
15396 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
15397 }
3c824109
NF
15398 break;
15399 /* Floating point (COP1) */
15400 case LWC132:
15401 mips32_op = OPC_LWC1;
15402 goto do_cop1;
15403 case LDC132:
15404 mips32_op = OPC_LDC1;
15405 goto do_cop1;
15406 case SWC132:
15407 mips32_op = OPC_SWC1;
15408 goto do_cop1;
15409 case SDC132:
15410 mips32_op = OPC_SDC1;
15411 do_cop1:
5ab5c041 15412 gen_cop1_ldst(ctx, mips32_op, rt, rs, imm);
3c824109 15413 break;
ab39ee45
YK
15414 case ADDIUPC: /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
15415 if (ctx->insn_flags & ISA_MIPS32R6) {
15416 /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
15417 switch ((ctx->opcode >> 16) & 0x1f) {
c38a1d52
AR
15418 case ADDIUPC_00:
15419 case ADDIUPC_01:
15420 case ADDIUPC_02:
15421 case ADDIUPC_03:
15422 case ADDIUPC_04:
15423 case ADDIUPC_05:
15424 case ADDIUPC_06:
15425 case ADDIUPC_07:
eeb3bba8 15426 gen_pcrel(ctx, OPC_ADDIUPC, ctx->base.pc_next & ~0x3, rt);
ab39ee45
YK
15427 break;
15428 case AUIPC:
eeb3bba8 15429 gen_pcrel(ctx, OPC_AUIPC, ctx->base.pc_next, rt);
ab39ee45
YK
15430 break;
15431 case ALUIPC:
eeb3bba8 15432 gen_pcrel(ctx, OPC_ALUIPC, ctx->base.pc_next, rt);
ab39ee45 15433 break;
c38a1d52
AR
15434 case LWPC_08:
15435 case LWPC_09:
15436 case LWPC_0A:
15437 case LWPC_0B:
15438 case LWPC_0C:
15439 case LWPC_0D:
15440 case LWPC_0E:
15441 case LWPC_0F:
eeb3bba8 15442 gen_pcrel(ctx, R6_OPC_LWPC, ctx->base.pc_next & ~0x3, rt);
ab39ee45
YK
15443 break;
15444 default:
15445 generate_exception(ctx, EXCP_RI);
15446 break;
15447 }
15448 } else {
15449 /* ADDIUPC */
3c824109 15450 int reg = mmreg(ZIMM(ctx->opcode, 23, 3));
e1555d7d 15451 offset = SIMM(ctx->opcode, 0, 23) << 2;
3c824109
NF
15452
15453 gen_addiupc(ctx, reg, offset, 0, 0);
15454 }
15455 break;
65935f07
YK
15456 case BNVC: /* BNEC, BNEZALC */
15457 check_insn(ctx, ISA_MIPS32R6);
15458 if (rs >= rt) {
15459 /* BNVC */
15460 mips32_op = OPC_BNVC;
15461 } else if (rs < rt && rs == 0) {
15462 /* BNEZALC */
15463 mips32_op = OPC_BNEZALC;
15464 } else {
15465 /* BNEC */
15466 mips32_op = OPC_BNEC;
15467 }
15468 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
15469 break;
15470 case R6_BNEZC: /* JIALC */
15471 check_insn(ctx, ISA_MIPS32R6);
15472 if (rt != 0) {
15473 /* BNEZC */
15474 gen_compute_compact_branch(ctx, OPC_BNEZC, rt, 0,
15475 sextract32(ctx->opcode << 1, 0, 22));
15476 } else {
15477 /* JIALC */
15478 gen_compute_compact_branch(ctx, OPC_JIALC, 0, rs, imm);
15479 }
15480 break;
15481 case R6_BEQZC: /* JIC */
15482 check_insn(ctx, ISA_MIPS32R6);
15483 if (rt != 0) {
15484 /* BEQZC */
15485 gen_compute_compact_branch(ctx, OPC_BEQZC, rt, 0,
15486 sextract32(ctx->opcode << 1, 0, 22));
15487 } else {
15488 /* JIC */
15489 gen_compute_compact_branch(ctx, OPC_JIC, 0, rs, imm);
15490 }
15491 break;
15492 case BLEZALC: /* BGEZALC, BGEUC */
15493 check_insn(ctx, ISA_MIPS32R6);
15494 if (rs == 0 && rt != 0) {
15495 /* BLEZALC */
15496 mips32_op = OPC_BLEZALC;
15497 } else if (rs != 0 && rt != 0 && rs == rt) {
15498 /* BGEZALC */
15499 mips32_op = OPC_BGEZALC;
15500 } else {
15501 /* BGEUC */
15502 mips32_op = OPC_BGEUC;
15503 }
15504 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
15505 break;
15506 case BGTZALC: /* BLTZALC, BLTUC */
15507 check_insn(ctx, ISA_MIPS32R6);
15508 if (rs == 0 && rt != 0) {
15509 /* BGTZALC */
15510 mips32_op = OPC_BGTZALC;
15511 } else if (rs != 0 && rt != 0 && rs == rt) {
15512 /* BLTZALC */
15513 mips32_op = OPC_BLTZALC;
15514 } else {
15515 /* BLTUC */
15516 mips32_op = OPC_BLTUC;
15517 }
15518 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
15519 break;
3c824109
NF
15520 /* Loads and stores */
15521 case LB32:
15522 mips32_op = OPC_LB;
5c13fdfd 15523 goto do_ld;
3c824109
NF
15524 case LBU32:
15525 mips32_op = OPC_LBU;
5c13fdfd 15526 goto do_ld;
3c824109
NF
15527 case LH32:
15528 mips32_op = OPC_LH;
5c13fdfd 15529 goto do_ld;
3c824109
NF
15530 case LHU32:
15531 mips32_op = OPC_LHU;
5c13fdfd 15532 goto do_ld;
3c824109
NF
15533 case LW32:
15534 mips32_op = OPC_LW;
5c13fdfd 15535 goto do_ld;
3c824109
NF
15536#ifdef TARGET_MIPS64
15537 case LD32:
d9224450
MR
15538 check_insn(ctx, ISA_MIPS3);
15539 check_mips_64(ctx);
3c824109 15540 mips32_op = OPC_LD;
5c13fdfd 15541 goto do_ld;
3c824109 15542 case SD32:
d9224450
MR
15543 check_insn(ctx, ISA_MIPS3);
15544 check_mips_64(ctx);
3c824109 15545 mips32_op = OPC_SD;
5c13fdfd 15546 goto do_st;
3c824109
NF
15547#endif
15548 case SB32:
15549 mips32_op = OPC_SB;
5c13fdfd 15550 goto do_st;
3c824109
NF
15551 case SH32:
15552 mips32_op = OPC_SH;
5c13fdfd 15553 goto do_st;
3c824109
NF
15554 case SW32:
15555 mips32_op = OPC_SW;
5c13fdfd
AJ
15556 goto do_st;
15557 do_ld:
d75c135e 15558 gen_ld(ctx, mips32_op, rt, rs, imm);
5c13fdfd
AJ
15559 break;
15560 do_st:
15561 gen_st(ctx, mips32_op, rt, rs, imm);
3c824109
NF
15562 break;
15563 default:
9c708c7f 15564 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
15565 break;
15566 }
15567}
15568
240ce26a 15569static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx)
3c824109
NF
15570{
15571 uint32_t op;
15572
15573 /* make sure instructions are on a halfword boundary */
eeb3bba8
EC
15574 if (ctx->base.pc_next & 0x1) {
15575 env->CP0_BadVAddr = ctx->base.pc_next;
9c708c7f 15576 generate_exception_end(ctx, EXCP_AdEL);
3c824109
NF
15577 return 2;
15578 }
15579
15580 op = (ctx->opcode >> 10) & 0x3f;
15581 /* Enforce properly-sized instructions in a delay slot */
b231c103
YK
15582 if (ctx->hflags & MIPS_HFLAG_BDS_STRICT) {
15583 switch (op & 0x7) { /* MSB-3..MSB-5 */
15584 case 0:
15585 /* POOL32A, POOL32B, POOL32I, POOL32C */
15586 case 4:
15587 /* ADDI32, ADDIU32, ORI32, XORI32, SLTI32, SLTIU32, ANDI32, JALX32 */
15588 case 5:
15589 /* LBU32, LHU32, POOL32F, JALS32, BEQ32, BNE32, J32, JAL32 */
15590 case 6:
15591 /* SB32, SH32, ADDIUPC, SWC132, SDC132, SW32 */
15592 case 7:
15593 /* LB32, LH32, LWC132, LDC132, LW32 */
15594 if (ctx->hflags & MIPS_HFLAG_BDS16) {
9c708c7f 15595 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
15596 return 2;
15597 }
15598 break;
b231c103
YK
15599 case 1:
15600 /* POOL16A, POOL16B, POOL16C, LWGP16, POOL16F */
15601 case 2:
15602 /* LBU16, LHU16, LWSP16, LW16, SB16, SH16, SWSP16, SW16 */
15603 case 3:
15604 /* MOVE16, ANDI16, POOL16D, POOL16E, BEQZ16, BNEZ16, B16, LI16 */
15605 if (ctx->hflags & MIPS_HFLAG_BDS32) {
9c708c7f 15606 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
15607 return 2;
15608 }
15609 break;
3c824109
NF
15610 }
15611 }
b231c103 15612
3c824109
NF
15613 switch (op) {
15614 case POOL16A:
15615 {
15616 int rd = mmreg(uMIPS_RD(ctx->opcode));
15617 int rs1 = mmreg(uMIPS_RS1(ctx->opcode));
15618 int rs2 = mmreg(uMIPS_RS2(ctx->opcode));
15619 uint32_t opc = 0;
15620
15621 switch (ctx->opcode & 0x1) {
15622 case ADDU16:
15623 opc = OPC_ADDU;
15624 break;
15625 case SUBU16:
15626 opc = OPC_SUBU;
15627 break;
15628 }
ed7ce6c0
YK
15629 if (ctx->insn_flags & ISA_MIPS32R6) {
15630 /* In the Release 6 the register number location in
15631 * the instruction encoding has changed.
15632 */
15633 gen_arith(ctx, opc, rs1, rd, rs2);
15634 } else {
15635 gen_arith(ctx, opc, rd, rs1, rs2);
15636 }
3c824109
NF
15637 }
15638 break;
15639 case POOL16B:
15640 {
15641 int rd = mmreg(uMIPS_RD(ctx->opcode));
15642 int rs = mmreg(uMIPS_RS(ctx->opcode));
15643 int amount = (ctx->opcode >> 1) & 0x7;
15644 uint32_t opc = 0;
15645 amount = amount == 0 ? 8 : amount;
15646
15647 switch (ctx->opcode & 0x1) {
15648 case SLL16:
15649 opc = OPC_SLL;
15650 break;
15651 case SRL16:
15652 opc = OPC_SRL;
15653 break;
15654 }
15655
d75c135e 15656 gen_shift_imm(ctx, opc, rd, rs, amount);
3c824109
NF
15657 }
15658 break;
15659 case POOL16C:
ed7ce6c0
YK
15660 if (ctx->insn_flags & ISA_MIPS32R6) {
15661 gen_pool16c_r6_insn(ctx);
15662 } else {
15663 gen_pool16c_insn(ctx);
15664 }
3c824109
NF
15665 break;
15666 case LWGP16:
15667 {
15668 int rd = mmreg(uMIPS_RD(ctx->opcode));
15669 int rb = 28; /* GP */
15670 int16_t offset = SIMM(ctx->opcode, 0, 7) << 2;
15671
d75c135e 15672 gen_ld(ctx, OPC_LW, rd, rb, offset);
3c824109
NF
15673 }
15674 break;
15675 case POOL16F:
9e8f441a 15676 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 15677 if (ctx->opcode & 1) {
9c708c7f 15678 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
15679 } else {
15680 /* MOVEP */
15681 int enc_dest = uMIPS_RD(ctx->opcode);
15682 int enc_rt = uMIPS_RS2(ctx->opcode);
15683 int enc_rs = uMIPS_RS1(ctx->opcode);
ed7ce6c0 15684 gen_movep(ctx, enc_dest, enc_rt, enc_rs);
3c824109
NF
15685 }
15686 break;
15687 case LBU16:
15688 {
15689 int rd = mmreg(uMIPS_RD(ctx->opcode));
15690 int rb = mmreg(uMIPS_RS(ctx->opcode));
15691 int16_t offset = ZIMM(ctx->opcode, 0, 4);
15692 offset = (offset == 0xf ? -1 : offset);
15693
d75c135e 15694 gen_ld(ctx, OPC_LBU, rd, rb, offset);
3c824109
NF
15695 }
15696 break;
15697 case LHU16:
15698 {
15699 int rd = mmreg(uMIPS_RD(ctx->opcode));
15700 int rb = mmreg(uMIPS_RS(ctx->opcode));
15701 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
15702
d75c135e 15703 gen_ld(ctx, OPC_LHU, rd, rb, offset);
3c824109
NF
15704 }
15705 break;
15706 case LWSP16:
15707 {
15708 int rd = (ctx->opcode >> 5) & 0x1f;
15709 int rb = 29; /* SP */
15710 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
15711
d75c135e 15712 gen_ld(ctx, OPC_LW, rd, rb, offset);
3c824109
NF
15713 }
15714 break;
15715 case LW16:
15716 {
15717 int rd = mmreg(uMIPS_RD(ctx->opcode));
15718 int rb = mmreg(uMIPS_RS(ctx->opcode));
15719 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
15720
d75c135e 15721 gen_ld(ctx, OPC_LW, rd, rb, offset);
3c824109
NF
15722 }
15723 break;
15724 case SB16:
15725 {
15726 int rd = mmreg2(uMIPS_RD(ctx->opcode));
15727 int rb = mmreg(uMIPS_RS(ctx->opcode));
15728 int16_t offset = ZIMM(ctx->opcode, 0, 4);
15729
5c13fdfd 15730 gen_st(ctx, OPC_SB, rd, rb, offset);
3c824109
NF
15731 }
15732 break;
15733 case SH16:
15734 {
15735 int rd = mmreg2(uMIPS_RD(ctx->opcode));
15736 int rb = mmreg(uMIPS_RS(ctx->opcode));
15737 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
15738
5c13fdfd 15739 gen_st(ctx, OPC_SH, rd, rb, offset);
3c824109
NF
15740 }
15741 break;
15742 case SWSP16:
15743 {
15744 int rd = (ctx->opcode >> 5) & 0x1f;
15745 int rb = 29; /* SP */
15746 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
15747
5c13fdfd 15748 gen_st(ctx, OPC_SW, rd, rb, offset);
3c824109
NF
15749 }
15750 break;
15751 case SW16:
15752 {
15753 int rd = mmreg2(uMIPS_RD(ctx->opcode));
15754 int rb = mmreg(uMIPS_RS(ctx->opcode));
15755 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
15756
5c13fdfd 15757 gen_st(ctx, OPC_SW, rd, rb, offset);
3c824109
NF
15758 }
15759 break;
15760 case MOVE16:
15761 {
15762 int rd = uMIPS_RD5(ctx->opcode);
15763 int rs = uMIPS_RS5(ctx->opcode);
15764
7215d7e7 15765 gen_arith(ctx, OPC_ADDU, rd, rs, 0);
3c824109
NF
15766 }
15767 break;
15768 case ANDI16:
d75c135e 15769 gen_andi16(ctx);
3c824109
NF
15770 break;
15771 case POOL16D:
15772 switch (ctx->opcode & 0x1) {
15773 case ADDIUS5:
d75c135e 15774 gen_addius5(ctx);
3c824109
NF
15775 break;
15776 case ADDIUSP:
d75c135e 15777 gen_addiusp(ctx);
3c824109
NF
15778 break;
15779 }
15780 break;
15781 case POOL16E:
15782 switch (ctx->opcode & 0x1) {
15783 case ADDIUR2:
d75c135e 15784 gen_addiur2(ctx);
3c824109
NF
15785 break;
15786 case ADDIUR1SP:
d75c135e 15787 gen_addiur1sp(ctx);
3c824109
NF
15788 break;
15789 }
15790 break;
65935f07 15791 case B16: /* BC16 */
3c824109 15792 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0,
65935f07
YK
15793 sextract32(ctx->opcode, 0, 10) << 1,
15794 (ctx->insn_flags & ISA_MIPS32R6) ? 0 : 4);
3c824109 15795 break;
65935f07
YK
15796 case BNEZ16: /* BNEZC16 */
15797 case BEQZ16: /* BEQZC16 */
3c824109
NF
15798 gen_compute_branch(ctx, op == BNEZ16 ? OPC_BNE : OPC_BEQ, 2,
15799 mmreg(uMIPS_RD(ctx->opcode)),
65935f07
YK
15800 0, sextract32(ctx->opcode, 0, 7) << 1,
15801 (ctx->insn_flags & ISA_MIPS32R6) ? 0 : 4);
15802
3c824109
NF
15803 break;
15804 case LI16:
15805 {
15806 int reg = mmreg(uMIPS_RD(ctx->opcode));
15807 int imm = ZIMM(ctx->opcode, 0, 7);
15808
15809 imm = (imm == 0x7f ? -1 : imm);
15810 tcg_gen_movi_tl(cpu_gpr[reg], imm);
15811 }
15812 break;
3c824109 15813 case RES_29:
3c824109 15814 case RES_31:
3c824109 15815 case RES_39:
9c708c7f 15816 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
15817 break;
15818 default:
f60eeb0c 15819 decode_micromips32_opc(env, ctx);
3c824109
NF
15820 return 4;
15821 }
15822
15823 return 2;
15824}
15825
261c95a0
YK
15826/*
15827 *
15828 * nanoMIPS opcodes
15829 *
15830 */
15831
15832/* MAJOR, P16, and P32 pools opcodes */
15833enum {
15834 NM_P_ADDIU = 0x00,
15835 NM_ADDIUPC = 0x01,
15836 NM_MOVE_BALC = 0x02,
15837 NM_P16_MV = 0x04,
15838 NM_LW16 = 0x05,
15839 NM_BC16 = 0x06,
15840 NM_P16_SR = 0x07,
15841
15842 NM_POOL32A = 0x08,
15843 NM_P_BAL = 0x0a,
15844 NM_P16_SHIFT = 0x0c,
15845 NM_LWSP16 = 0x0d,
15846 NM_BALC16 = 0x0e,
15847 NM_P16_4X4 = 0x0f,
15848
15849 NM_P_GP_W = 0x10,
15850 NM_P_GP_BH = 0x11,
15851 NM_P_J = 0x12,
15852 NM_P16C = 0x14,
15853 NM_LWGP16 = 0x15,
15854 NM_P16_LB = 0x17,
15855
15856 NM_P48I = 0x18,
15857 NM_P16_A1 = 0x1c,
15858 NM_LW4X4 = 0x1d,
15859 NM_P16_LH = 0x1f,
15860
15861 NM_P_U12 = 0x20,
15862 NM_P_LS_U12 = 0x21,
15863 NM_P_BR1 = 0x22,
15864 NM_P16_A2 = 0x24,
15865 NM_SW16 = 0x25,
15866 NM_BEQZC16 = 0x26,
15867
15868 NM_POOL32F = 0x28,
15869 NM_P_LS_S9 = 0x29,
15870 NM_P_BR2 = 0x2a,
15871
15872 NM_P16_ADDU = 0x2c,
15873 NM_SWSP16 = 0x2d,
15874 NM_BNEZC16 = 0x2e,
15875 NM_MOVEP = 0x2f,
15876
15877 NM_POOL32S = 0x30,
15878 NM_P_BRI = 0x32,
15879 NM_LI16 = 0x34,
15880 NM_SWGP16 = 0x35,
15881 NM_P16_BR = 0x36,
15882
15883 NM_P_LUI = 0x38,
15884 NM_ANDI16 = 0x3c,
15885 NM_SW4X4 = 0x3d,
15886 NM_MOVEPREV = 0x3f,
15887};
15888
15889/* POOL32A instruction pool */
15890enum {
15891 NM_POOL32A0 = 0x00,
15892 NM_SPECIAL2 = 0x01,
15893 NM_COP2_1 = 0x02,
15894 NM_UDI = 0x03,
15895 NM_POOL32A5 = 0x05,
15896 NM_POOL32A7 = 0x07,
15897};
15898
15899/* P.GP.W instruction pool */
15900enum {
15901 NM_ADDIUGP_W = 0x00,
15902 NM_LWGP = 0x02,
15903 NM_SWGP = 0x03,
15904};
15905
15906/* P48I instruction pool */
15907enum {
15908 NM_LI48 = 0x00,
15909 NM_ADDIU48 = 0x01,
15910 NM_ADDIUGP48 = 0x02,
15911 NM_ADDIUPC48 = 0x03,
15912 NM_LWPC48 = 0x0b,
15913 NM_SWPC48 = 0x0f,
15914};
15915
15916/* P.U12 instruction pool */
15917enum {
15918 NM_ORI = 0x00,
15919 NM_XORI = 0x01,
15920 NM_ANDI = 0x02,
15921 NM_P_SR = 0x03,
15922 NM_SLTI = 0x04,
15923 NM_SLTIU = 0x05,
15924 NM_SEQI = 0x06,
15925 NM_ADDIUNEG = 0x08,
15926 NM_P_SHIFT = 0x0c,
15927 NM_P_ROTX = 0x0d,
15928 NM_P_INS = 0x0e,
15929 NM_P_EXT = 0x0f,
15930};
15931
15932/* POOL32F instruction pool */
15933enum {
15934 NM_POOL32F_0 = 0x00,
15935 NM_POOL32F_3 = 0x03,
15936 NM_POOL32F_5 = 0x05,
15937};
15938
15939/* POOL32S instruction pool */
15940enum {
15941 NM_POOL32S_0 = 0x00,
15942 NM_POOL32S_4 = 0x04,
15943};
15944
15945/* P.LUI instruction pool */
15946enum {
15947 NM_LUI = 0x00,
15948 NM_ALUIPC = 0x01,
15949};
15950
15951/* P.GP.BH instruction pool */
15952enum {
15953 NM_LBGP = 0x00,
15954 NM_SBGP = 0x01,
15955 NM_LBUGP = 0x02,
15956 NM_ADDIUGP_B = 0x03,
15957 NM_P_GP_LH = 0x04,
15958 NM_P_GP_SH = 0x05,
15959 NM_P_GP_CP1 = 0x06,
15960};
15961
15962/* P.LS.U12 instruction pool */
15963enum {
15964 NM_LB = 0x00,
15965 NM_SB = 0x01,
15966 NM_LBU = 0x02,
15967 NM_P_PREFU12 = 0x03,
15968 NM_LH = 0x04,
15969 NM_SH = 0x05,
15970 NM_LHU = 0x06,
15971 NM_LWU = 0x07,
15972 NM_LW = 0x08,
15973 NM_SW = 0x09,
15974 NM_LWC1 = 0x0a,
15975 NM_SWC1 = 0x0b,
15976 NM_LDC1 = 0x0e,
15977 NM_SDC1 = 0x0f,
15978};
15979
15980/* P.LS.S9 instruction pool */
15981enum {
15982 NM_P_LS_S0 = 0x00,
15983 NM_P_LS_S1 = 0x01,
15984 NM_P_LS_E0 = 0x02,
15985 NM_P_LS_WM = 0x04,
15986 NM_P_LS_UAWM = 0x05,
15987};
15988
15989/* P.BAL instruction pool */
15990enum {
15991 NM_BC = 0x00,
15992 NM_BALC = 0x01,
15993};
15994
15995/* P.J instruction pool */
15996enum {
15997 NM_JALRC = 0x00,
15998 NM_JALRC_HB = 0x01,
15999 NM_P_BALRSC = 0x08,
16000};
16001
16002/* P.BR1 instruction pool */
16003enum {
16004 NM_BEQC = 0x00,
16005 NM_P_BR3A = 0x01,
16006 NM_BGEC = 0x02,
16007 NM_BGEUC = 0x03,
16008};
16009
16010/* P.BR2 instruction pool */
16011enum {
16012 NM_BNEC = 0x00,
16013 NM_BLTC = 0x02,
16014 NM_BLTUC = 0x03,
16015};
16016
16017/* P.BRI instruction pool */
16018enum {
16019 NM_BEQIC = 0x00,
16020 NM_BBEQZC = 0x01,
16021 NM_BGEIC = 0x02,
16022 NM_BGEIUC = 0x03,
16023 NM_BNEIC = 0x04,
16024 NM_BBNEZC = 0x05,
16025 NM_BLTIC = 0x06,
16026 NM_BLTIUC = 0x07,
16027};
16028
16029/* P16.SHIFT instruction pool */
16030enum {
16031 NM_SLL16 = 0x00,
16032 NM_SRL16 = 0x01,
16033};
16034
16035/* POOL16C instruction pool */
16036enum {
16037 NM_POOL16C_0 = 0x00,
16038 NM_LWXS16 = 0x01,
16039};
16040
16041/* P16.A1 instruction pool */
16042enum {
16043 NM_ADDIUR1SP = 0x01,
16044};
16045
16046/* P16.A2 instruction pool */
16047enum {
16048 NM_ADDIUR2 = 0x00,
16049 NM_P_ADDIURS5 = 0x01,
16050};
16051
16052/* P16.ADDU instruction pool */
16053enum {
16054 NM_ADDU16 = 0x00,
16055 NM_SUBU16 = 0x01,
16056};
16057
16058/* P16.SR instruction pool */
16059enum {
16060 NM_SAVE16 = 0x00,
16061 NM_RESTORE_JRC16 = 0x01,
16062};
16063
16064/* P16.4X4 instruction pool */
16065enum {
16066 NM_ADDU4X4 = 0x00,
16067 NM_MUL4X4 = 0x01,
16068};
16069
16070/* P16.LB instruction pool */
16071enum {
16072 NM_LB16 = 0x00,
16073 NM_SB16 = 0x01,
16074 NM_LBU16 = 0x02,
16075};
16076
16077/* P16.LH instruction pool */
16078enum {
16079 NM_LH16 = 0x00,
16080 NM_SH16 = 0x01,
16081 NM_LHU16 = 0x02,
16082};
16083
16084/* P.RI instruction pool */
16085enum {
16086 NM_SIGRIE = 0x00,
16087 NM_P_SYSCALL = 0x01,
16088 NM_BREAK = 0x02,
16089 NM_SDBBP = 0x03,
16090};
16091
16092/* POOL32A0 instruction pool */
16093enum {
16094 NM_P_TRAP = 0x00,
16095 NM_SEB = 0x01,
16096 NM_SLLV = 0x02,
16097 NM_MUL = 0x03,
16098 NM_MFC0 = 0x06,
16099 NM_MFHC0 = 0x07,
16100 NM_SEH = 0x09,
16101 NM_SRLV = 0x0a,
16102 NM_MUH = 0x0b,
16103 NM_MTC0 = 0x0e,
16104 NM_MTHC0 = 0x0f,
16105 NM_SRAV = 0x12,
16106 NM_MULU = 0x13,
16107 NM_ROTRV = 0x1a,
16108 NM_MUHU = 0x1b,
16109 NM_ADD = 0x22,
16110 NM_DIV = 0x23,
16111 NM_ADDU = 0x2a,
16112 NM_MOD = 0x2b,
16113 NM_SUB = 0x32,
16114 NM_DIVU = 0x33,
16115 NM_RDHWR = 0x38,
16116 NM_SUBU = 0x3a,
16117 NM_MODU = 0x3b,
16118 NM_P_CMOVE = 0x42,
16119 NM_FORK = 0x45,
16120 NM_MFTR = 0x46,
16121 NM_MFHTR = 0x47,
16122 NM_AND = 0x4a,
16123 NM_YIELD = 0x4d,
16124 NM_MTTR = 0x4e,
16125 NM_MTHTR = 0x4f,
16126 NM_OR = 0x52,
16127 NM_D_E_MT_VPE = 0x56,
16128 NM_NOR = 0x5a,
16129 NM_XOR = 0x62,
16130 NM_SLT = 0x6a,
16131 NM_P_SLTU = 0x72,
16132 NM_SOV = 0x7a,
16133};
16134
b3979b6f
SM
16135/* POOL32A5 instruction pool */
16136enum {
16137 NM_CMP_EQ_PH = 0x00,
16138 NM_CMP_LT_PH = 0x08,
16139 NM_CMP_LE_PH = 0x10,
16140 NM_CMPGU_EQ_QB = 0x18,
16141 NM_CMPGU_LT_QB = 0x20,
16142 NM_CMPGU_LE_QB = 0x28,
16143 NM_CMPGDU_EQ_QB = 0x30,
16144 NM_CMPGDU_LT_QB = 0x38,
16145 NM_CMPGDU_LE_QB = 0x40,
16146 NM_CMPU_EQ_QB = 0x48,
16147 NM_CMPU_LT_QB = 0x50,
16148 NM_CMPU_LE_QB = 0x58,
16149 NM_ADDQ_S_W = 0x60,
16150 NM_SUBQ_S_W = 0x68,
16151 NM_ADDSC = 0x70,
16152 NM_ADDWC = 0x78,
16153
16154 NM_ADDQ_S_PH = 0x01,
16155 NM_ADDQH_R_PH = 0x09,
16156 NM_ADDQH_R_W = 0x11,
16157 NM_ADDU_S_QB = 0x19,
16158 NM_ADDU_S_PH = 0x21,
16159 NM_ADDUH_R_QB = 0x29,
16160 NM_SHRAV_R_PH = 0x31,
16161 NM_SHRAV_R_QB = 0x39,
16162 NM_SUBQ_S_PH = 0x41,
16163 NM_SUBQH_R_PH = 0x49,
16164 NM_SUBQH_R_W = 0x51,
16165 NM_SUBU_S_QB = 0x59,
16166 NM_SUBU_S_PH = 0x61,
16167 NM_SUBUH_R_QB = 0x69,
16168 NM_SHLLV_S_PH = 0x71,
16169 NM_PRECR_SRA_R_PH_W = 0x79,
16170
16171 NM_MULEU_S_PH_QBL = 0x12,
16172 NM_MULEU_S_PH_QBR = 0x1a,
16173 NM_MULQ_RS_PH = 0x22,
16174 NM_MULQ_S_PH = 0x2a,
16175 NM_MULQ_RS_W = 0x32,
16176 NM_MULQ_S_W = 0x3a,
16177 NM_APPEND = 0x42,
16178 NM_MODSUB = 0x52,
16179 NM_SHRAV_R_W = 0x5a,
16180 NM_SHRLV_PH = 0x62,
16181 NM_SHRLV_QB = 0x6a,
16182 NM_SHLLV_QB = 0x72,
16183 NM_SHLLV_S_W = 0x7a,
16184
16185 NM_SHILO = 0x03,
16186
16187 NM_MULEQ_S_W_PHL = 0x04,
16188 NM_MULEQ_S_W_PHR = 0x0c,
16189
16190 NM_MUL_S_PH = 0x05,
16191 NM_PRECR_QB_PH = 0x0d,
16192 NM_PRECRQ_QB_PH = 0x15,
16193 NM_PRECRQ_PH_W = 0x1d,
16194 NM_PRECRQ_RS_PH_W = 0x25,
16195 NM_PRECRQU_S_QB_PH = 0x2d,
16196 NM_PACKRL_PH = 0x35,
16197 NM_PICK_QB = 0x3d,
16198 NM_PICK_PH = 0x45,
16199
16200 NM_SHRA_R_W = 0x5e,
16201 NM_SHRA_R_PH = 0x66,
16202 NM_SHLL_S_PH = 0x76,
16203 NM_SHLL_S_W = 0x7e,
16204
16205 NM_REPL_PH = 0x07
16206};
16207
261c95a0
YK
16208/* POOL32A7 instruction pool */
16209enum {
16210 NM_P_LSX = 0x00,
16211 NM_LSA = 0x01,
16212 NM_EXTW = 0x03,
16213 NM_POOL32AXF = 0x07,
16214};
16215
16216/* P.SR instruction pool */
16217enum {
16218 NM_PP_SR = 0x00,
16219 NM_P_SR_F = 0x01,
16220};
16221
16222/* P.SHIFT instruction pool */
16223enum {
16224 NM_P_SLL = 0x00,
16225 NM_SRL = 0x02,
16226 NM_SRA = 0x04,
16227 NM_ROTR = 0x06,
16228};
16229
16230/* P.ROTX instruction pool */
16231enum {
16232 NM_ROTX = 0x00,
16233};
16234
16235/* P.INS instruction pool */
16236enum {
16237 NM_INS = 0x00,
16238};
16239
16240/* P.EXT instruction pool */
16241enum {
16242 NM_EXT = 0x00,
16243};
16244
16245/* POOL32F_0 (fmt) instruction pool */
16246enum {
16247 NM_RINT_S = 0x04,
16248 NM_RINT_D = 0x44,
16249 NM_ADD_S = 0x06,
16250 NM_SELEQZ_S = 0x07,
16251 NM_SELEQZ_D = 0x47,
16252 NM_CLASS_S = 0x0c,
16253 NM_CLASS_D = 0x4c,
16254 NM_SUB_S = 0x0e,
16255 NM_SELNEZ_S = 0x0f,
16256 NM_SELNEZ_D = 0x4f,
16257 NM_MUL_S = 0x16,
16258 NM_SEL_S = 0x17,
16259 NM_SEL_D = 0x57,
16260 NM_DIV_S = 0x1e,
16261 NM_ADD_D = 0x26,
16262 NM_SUB_D = 0x2e,
16263 NM_MUL_D = 0x36,
16264 NM_MADDF_S = 0x37,
16265 NM_MADDF_D = 0x77,
16266 NM_DIV_D = 0x3e,
16267 NM_MSUBF_S = 0x3f,
16268 NM_MSUBF_D = 0x7f,
16269};
16270
16271/* POOL32F_3 instruction pool */
16272enum {
16273 NM_MIN_FMT = 0x00,
16274 NM_MAX_FMT = 0x01,
16275 NM_MINA_FMT = 0x04,
16276 NM_MAXA_FMT = 0x05,
16277 NM_POOL32FXF = 0x07,
16278};
16279
16280/* POOL32F_5 instruction pool */
16281enum {
16282 NM_CMP_CONDN_S = 0x00,
16283 NM_CMP_CONDN_D = 0x02,
16284};
16285
16286/* P.GP.LH instruction pool */
16287enum {
16288 NM_LHGP = 0x00,
16289 NM_LHUGP = 0x01,
16290};
16291
16292/* P.GP.SH instruction pool */
16293enum {
16294 NM_SHGP = 0x00,
16295};
16296
16297/* P.GP.CP1 instruction pool */
16298enum {
16299 NM_LWC1GP = 0x00,
16300 NM_SWC1GP = 0x01,
16301 NM_LDC1GP = 0x02,
16302 NM_SDC1GP = 0x03,
16303};
16304
16305/* P.LS.S0 instruction pool */
16306enum {
16307 NM_LBS9 = 0x00,
16308 NM_LHS9 = 0x04,
16309 NM_LWS9 = 0x08,
16310 NM_LDS9 = 0x0c,
16311
16312 NM_SBS9 = 0x01,
16313 NM_SHS9 = 0x05,
16314 NM_SWS9 = 0x09,
16315 NM_SDS9 = 0x0d,
16316
16317 NM_LBUS9 = 0x02,
16318 NM_LHUS9 = 0x06,
16319 NM_LWC1S9 = 0x0a,
16320 NM_LDC1S9 = 0x0e,
16321
16322 NM_P_PREFS9 = 0x03,
16323 NM_LWUS9 = 0x07,
16324 NM_SWC1S9 = 0x0b,
16325 NM_SDC1S9 = 0x0f,
16326};
16327
16328/* P.LS.S1 instruction pool */
16329enum {
16330 NM_ASET_ACLR = 0x02,
16331 NM_UALH = 0x04,
16332 NM_UASH = 0x05,
16333 NM_CACHE = 0x07,
16334 NM_P_LL = 0x0a,
16335 NM_P_SC = 0x0b,
16336};
16337
16338/* P.LS.WM instruction pool */
16339enum {
16340 NM_LWM = 0x00,
16341 NM_SWM = 0x01,
16342};
16343
16344/* P.LS.UAWM instruction pool */
16345enum {
16346 NM_UALWM = 0x00,
16347 NM_UASWM = 0x01,
16348};
16349
16350/* P.BR3A instruction pool */
16351enum {
16352 NM_BC1EQZC = 0x00,
16353 NM_BC1NEZC = 0x01,
16354 NM_BC2EQZC = 0x02,
16355 NM_BC2NEZC = 0x03,
16356 NM_BPOSGE32C = 0x04,
16357};
16358
16359/* P16.RI instruction pool */
16360enum {
16361 NM_P16_SYSCALL = 0x01,
16362 NM_BREAK16 = 0x02,
16363 NM_SDBBP16 = 0x03,
16364};
16365
16366/* POOL16C_0 instruction pool */
16367enum {
16368 NM_POOL16C_00 = 0x00,
16369};
16370
16371/* P16.JRC instruction pool */
16372enum {
16373 NM_JRC = 0x00,
16374 NM_JALRC16 = 0x01,
16375};
16376
16377/* P.SYSCALL instruction pool */
16378enum {
16379 NM_SYSCALL = 0x00,
16380 NM_HYPCALL = 0x01,
16381};
16382
16383/* P.TRAP instruction pool */
16384enum {
16385 NM_TEQ = 0x00,
16386 NM_TNE = 0x01,
16387};
16388
16389/* P.CMOVE instruction pool */
16390enum {
16391 NM_MOVZ = 0x00,
16392 NM_MOVN = 0x01,
16393};
16394
16395/* POOL32Axf instruction pool */
16396enum {
b3979b6f
SM
16397 NM_POOL32AXF_1 = 0x01,
16398 NM_POOL32AXF_2 = 0x02,
261c95a0
YK
16399 NM_POOL32AXF_4 = 0x04,
16400 NM_POOL32AXF_5 = 0x05,
b3979b6f
SM
16401 NM_POOL32AXF_7 = 0x07,
16402};
16403
16404/* POOL32Axf_1 instruction pool */
16405enum {
16406 NM_POOL32AXF_1_0 = 0x00,
16407 NM_POOL32AXF_1_1 = 0x01,
16408 NM_POOL32AXF_1_3 = 0x03,
16409 NM_POOL32AXF_1_4 = 0x04,
16410 NM_POOL32AXF_1_5 = 0x05,
16411 NM_POOL32AXF_1_7 = 0x07,
16412};
16413
16414/* POOL32Axf_2 instruction pool */
16415enum {
16416 NM_POOL32AXF_2_0_7 = 0x00,
16417 NM_POOL32AXF_2_8_15 = 0x01,
16418 NM_POOL32AXF_2_16_23 = 0x02,
16419 NM_POOL32AXF_2_24_31 = 0x03,
16420};
16421
16422/* POOL32Axf_7 instruction pool */
16423enum {
16424 NM_SHRA_R_QB = 0x0,
16425 NM_SHRL_PH = 0x1,
16426 NM_REPL_QB = 0x2,
16427};
16428
16429/* POOL32Axf_1_0 instruction pool */
16430enum {
16431 NM_MFHI = 0x0,
16432 NM_MFLO = 0x1,
16433 NM_MTHI = 0x2,
16434 NM_MTLO = 0x3,
16435};
16436
16437/* POOL32Axf_1_1 instruction pool */
16438enum {
16439 NM_MTHLIP = 0x0,
16440 NM_SHILOV = 0x1,
16441};
16442
16443/* POOL32Axf_1_3 instruction pool */
16444enum {
16445 NM_RDDSP = 0x0,
16446 NM_WRDSP = 0x1,
16447 NM_EXTP = 0x2,
16448 NM_EXTPDP = 0x3,
16449};
16450
16451/* POOL32Axf_1_4 instruction pool */
16452enum {
16453 NM_SHLL_QB = 0x0,
16454 NM_SHRL_QB = 0x1,
16455};
16456
16457/* POOL32Axf_1_5 instruction pool */
16458enum {
16459 NM_MAQ_S_W_PHR = 0x0,
16460 NM_MAQ_S_W_PHL = 0x1,
16461 NM_MAQ_SA_W_PHR = 0x2,
16462 NM_MAQ_SA_W_PHL = 0x3,
16463};
16464
16465/* POOL32Axf_1_7 instruction pool */
16466enum {
16467 NM_EXTR_W = 0x0,
16468 NM_EXTR_R_W = 0x1,
16469 NM_EXTR_RS_W = 0x2,
16470 NM_EXTR_S_H = 0x3,
16471};
16472
16473/* POOL32Axf_2_0_7 instruction pool */
16474enum {
16475 NM_DPA_W_PH = 0x0,
16476 NM_DPAQ_S_W_PH = 0x1,
16477 NM_DPS_W_PH = 0x2,
16478 NM_DPSQ_S_W_PH = 0x3,
16479 NM_BALIGN = 0x4,
16480 NM_MADD = 0x5,
16481 NM_MULT = 0x6,
16482 NM_EXTRV_W = 0x7,
16483};
16484
16485/* POOL32Axf_2_8_15 instruction pool */
16486enum {
16487 NM_DPAX_W_PH = 0x0,
16488 NM_DPAQ_SA_L_W = 0x1,
16489 NM_DPSX_W_PH = 0x2,
16490 NM_DPSQ_SA_L_W = 0x3,
16491 NM_MADDU = 0x5,
16492 NM_MULTU = 0x6,
16493 NM_EXTRV_R_W = 0x7,
16494};
16495
16496/* POOL32Axf_2_16_23 instruction pool */
16497enum {
16498 NM_DPAU_H_QBL = 0x0,
16499 NM_DPAQX_S_W_PH = 0x1,
16500 NM_DPSU_H_QBL = 0x2,
16501 NM_DPSQX_S_W_PH = 0x3,
16502 NM_EXTPV = 0x4,
16503 NM_MSUB = 0x5,
16504 NM_MULSA_W_PH = 0x6,
16505 NM_EXTRV_RS_W = 0x7,
16506};
16507
16508/* POOL32Axf_2_24_31 instruction pool */
16509enum {
16510 NM_DPAU_H_QBR = 0x0,
16511 NM_DPAQX_SA_W_PH = 0x1,
16512 NM_DPSU_H_QBR = 0x2,
16513 NM_DPSQX_SA_W_PH = 0x3,
16514 NM_EXTPDPV = 0x4,
16515 NM_MSUBU = 0x5,
16516 NM_MULSAQ_S_W_PH = 0x6,
16517 NM_EXTRV_S_H = 0x7,
261c95a0
YK
16518};
16519
16520/* POOL32Axf_{4, 5} instruction pool */
16521enum {
16522 NM_CLO = 0x25,
16523 NM_CLZ = 0x2d,
16524
16525 NM_TLBP = 0x01,
16526 NM_TLBR = 0x09,
16527 NM_TLBWI = 0x11,
16528 NM_TLBWR = 0x19,
16529 NM_TLBINV = 0x03,
16530 NM_TLBINVF = 0x0b,
16531 NM_DI = 0x23,
16532 NM_EI = 0x2b,
16533 NM_RDPGPR = 0x70,
16534 NM_WRPGPR = 0x78,
16535 NM_WAIT = 0x61,
16536 NM_DERET = 0x71,
16537 NM_ERETX = 0x79,
b3979b6f
SM
16538
16539 /* nanoMIPS DSP instructions */
16540 NM_ABSQ_S_QB = 0x00,
16541 NM_ABSQ_S_PH = 0x08,
16542 NM_ABSQ_S_W = 0x10,
16543 NM_PRECEQ_W_PHL = 0x28,
16544 NM_PRECEQ_W_PHR = 0x30,
16545 NM_PRECEQU_PH_QBL = 0x38,
16546 NM_PRECEQU_PH_QBR = 0x48,
16547 NM_PRECEU_PH_QBL = 0x58,
16548 NM_PRECEU_PH_QBR = 0x68,
16549 NM_PRECEQU_PH_QBLA = 0x39,
16550 NM_PRECEQU_PH_QBRA = 0x49,
16551 NM_PRECEU_PH_QBLA = 0x59,
16552 NM_PRECEU_PH_QBRA = 0x69,
16553 NM_REPLV_PH = 0x01,
16554 NM_REPLV_QB = 0x09,
16555 NM_BITREV = 0x18,
16556 NM_INSV = 0x20,
16557 NM_RADDU_W_QB = 0x78,
16558
16559 NM_BITSWAP = 0x05,
16560 NM_WSBH = 0x3d,
261c95a0
YK
16561};
16562
16563/* PP.SR instruction pool */
16564enum {
16565 NM_SAVE = 0x00,
16566 NM_RESTORE = 0x02,
16567 NM_RESTORE_JRC = 0x03,
16568};
16569
16570/* P.SR.F instruction pool */
16571enum {
16572 NM_SAVEF = 0x00,
16573 NM_RESTOREF = 0x01,
16574};
16575
16576/* P16.SYSCALL instruction pool */
16577enum {
16578 NM_SYSCALL16 = 0x00,
16579 NM_HYPCALL16 = 0x01,
16580};
16581
16582/* POOL16C_00 instruction pool */
16583enum {
16584 NM_NOT16 = 0x00,
16585 NM_XOR16 = 0x01,
16586 NM_AND16 = 0x02,
16587 NM_OR16 = 0x03,
16588};
16589
16590/* PP.LSX and PP.LSXS instruction pool */
16591enum {
16592 NM_LBX = 0x00,
16593 NM_LHX = 0x04,
16594 NM_LWX = 0x08,
16595 NM_LDX = 0x0c,
16596
16597 NM_SBX = 0x01,
16598 NM_SHX = 0x05,
16599 NM_SWX = 0x09,
16600 NM_SDX = 0x0d,
16601
16602 NM_LBUX = 0x02,
16603 NM_LHUX = 0x06,
16604 NM_LWC1X = 0x0a,
16605 NM_LDC1X = 0x0e,
16606
16607 NM_LWUX = 0x07,
16608 NM_SWC1X = 0x0b,
16609 NM_SDC1X = 0x0f,
16610
16611 NM_LHXS = 0x04,
16612 NM_LWXS = 0x08,
16613 NM_LDXS = 0x0c,
16614
16615 NM_SHXS = 0x05,
16616 NM_SWXS = 0x09,
16617 NM_SDXS = 0x0d,
16618
16619 NM_LHUXS = 0x06,
16620 NM_LWC1XS = 0x0a,
16621 NM_LDC1XS = 0x0e,
16622
16623 NM_LWUXS = 0x07,
16624 NM_SWC1XS = 0x0b,
16625 NM_SDC1XS = 0x0f,
16626};
16627
16628/* ERETx instruction pool */
16629enum {
16630 NM_ERET = 0x00,
16631 NM_ERETNC = 0x01,
16632};
16633
16634/* POOL32FxF_{0, 1} insturction pool */
16635enum {
16636 NM_CFC1 = 0x40,
16637 NM_CTC1 = 0x60,
16638 NM_MFC1 = 0x80,
16639 NM_MTC1 = 0xa0,
16640 NM_MFHC1 = 0xc0,
16641 NM_MTHC1 = 0xe0,
16642
16643 NM_CVT_S_PL = 0x84,
16644 NM_CVT_S_PU = 0xa4,
16645
16646 NM_CVT_L_S = 0x004,
16647 NM_CVT_L_D = 0x104,
16648 NM_CVT_W_S = 0x024,
16649 NM_CVT_W_D = 0x124,
16650
16651 NM_RSQRT_S = 0x008,
16652 NM_RSQRT_D = 0x108,
16653
16654 NM_SQRT_S = 0x028,
16655 NM_SQRT_D = 0x128,
16656
16657 NM_RECIP_S = 0x048,
16658 NM_RECIP_D = 0x148,
16659
16660 NM_FLOOR_L_S = 0x00c,
16661 NM_FLOOR_L_D = 0x10c,
16662
16663 NM_FLOOR_W_S = 0x02c,
16664 NM_FLOOR_W_D = 0x12c,
16665
16666 NM_CEIL_L_S = 0x04c,
16667 NM_CEIL_L_D = 0x14c,
16668 NM_CEIL_W_S = 0x06c,
16669 NM_CEIL_W_D = 0x16c,
16670 NM_TRUNC_L_S = 0x08c,
16671 NM_TRUNC_L_D = 0x18c,
16672 NM_TRUNC_W_S = 0x0ac,
16673 NM_TRUNC_W_D = 0x1ac,
16674 NM_ROUND_L_S = 0x0cc,
16675 NM_ROUND_L_D = 0x1cc,
16676 NM_ROUND_W_S = 0x0ec,
16677 NM_ROUND_W_D = 0x1ec,
16678
16679 NM_MOV_S = 0x01,
16680 NM_MOV_D = 0x81,
16681 NM_ABS_S = 0x0d,
16682 NM_ABS_D = 0x8d,
16683 NM_NEG_S = 0x2d,
16684 NM_NEG_D = 0xad,
16685 NM_CVT_D_S = 0x04d,
16686 NM_CVT_D_W = 0x0cd,
16687 NM_CVT_D_L = 0x14d,
16688 NM_CVT_S_D = 0x06d,
16689 NM_CVT_S_W = 0x0ed,
16690 NM_CVT_S_L = 0x16d,
16691};
16692
16693/* P.LL instruction pool */
16694enum {
16695 NM_LL = 0x00,
16696 NM_LLWP = 0x01,
16697};
16698
16699/* P.SC instruction pool */
16700enum {
16701 NM_SC = 0x00,
16702 NM_SCWP = 0x01,
16703};
16704
16705/* P.DVP instruction pool */
16706enum {
16707 NM_DVP = 0x00,
16708 NM_EVP = 0x01,
16709};
16710
c533c0f4
AM
16711
16712/*
16713 *
16714 * nanoMIPS decoding engine
16715 *
16716 */
16717
6bfa9f4c
AM
16718
16719/* extraction utilities */
16720
16721#define NANOMIPS_EXTRACT_RD(op) ((op >> 7) & 0x7)
16722#define NANOMIPS_EXTRACT_RS(op) ((op >> 4) & 0x7)
16723#define NANOMIPS_EXTRACT_RS2(op) uMIPS_RS(op)
16724#define NANOMIPS_EXTRACT_RS1(op) ((op >> 1) & 0x7)
16725#define NANOMIPS_EXTRACT_RD5(op) ((op >> 5) & 0x1f)
16726#define NANOMIPS_EXTRACT_RS5(op) (op & 0x1f)
16727
ea4ca3c2
YK
16728/* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr3'). */
16729static inline int decode_gpr_gpr3(int r)
16730{
16731 static const int map[] = { 16, 17, 18, 19, 4, 5, 6, 7 };
16732
16733 return map[r & 0x7];
16734}
16735
16736/* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr4'). */
16737static inline int decode_gpr_gpr4(int r)
16738{
16739 static const int map[] = { 8, 9, 10, 11, 4, 5, 6, 7,
16740 16, 17, 18, 19, 20, 21, 22, 23 };
16741
16742 return map[r & 0xf];
16743}
16744
6bfa9f4c 16745
c533c0f4
AM
16746static int decode_nanomips_opc(CPUMIPSState *env, DisasContext *ctx)
16747{
ea4ca3c2
YK
16748 uint32_t op;
16749 int rt = decode_gpr_gpr3(NANOMIPS_EXTRACT_RD(ctx->opcode));
16750 int rs = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS(ctx->opcode));
16751 int rd = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS1(ctx->opcode));
16752 int imm;
16753
16754 /* make sure instructions are on a halfword boundary */
16755 if (ctx->base.pc_next & 0x1) {
16756 TCGv tmp = tcg_const_tl(ctx->base.pc_next);
16757 tcg_gen_st_tl(tmp, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
16758 tcg_temp_free(tmp);
16759 generate_exception_end(ctx, EXCP_AdEL);
16760 return 2;
16761 }
16762
16763 op = extract32(ctx->opcode, 10, 6);
16764 switch (op) {
16765 case NM_P16_MV:
16766 break;
16767 case NM_P16_SHIFT:
16768 break;
16769 case NM_P16C:
16770 break;
16771 case NM_P16_A1:
16772 switch (extract32(ctx->opcode, 6, 1)) {
16773 case NM_ADDIUR1SP:
16774 imm = extract32(ctx->opcode, 0, 6) << 2;
16775 gen_arith_imm(ctx, OPC_ADDIU, rt, 29, imm);
16776 break;
16777 default:
16778 generate_exception_end(ctx, EXCP_RI);
16779 break;
16780 }
16781 break;
16782 case NM_P16_A2:
16783 switch (extract32(ctx->opcode, 3, 1)) {
16784 case NM_ADDIUR2:
16785 imm = extract32(ctx->opcode, 0, 3) << 2;
16786 gen_arith_imm(ctx, OPC_ADDIU, rt, rs, imm);
16787 break;
16788 case NM_P_ADDIURS5:
16789 rt = extract32(ctx->opcode, 5, 5);
16790 if (rt != 0) {
16791 /* imm = sign_extend(s[3] . s[2:0] , from_nbits = 4) */
16792 imm = (sextract32(ctx->opcode, 4, 1) << 3) |
16793 (extract32(ctx->opcode, 0, 3));
16794 gen_arith_imm(ctx, OPC_ADDIU, rt, rt, imm);
16795 }
16796 break;
16797 }
16798 break;
16799 case NM_P16_ADDU:
16800 switch (ctx->opcode & 0x1) {
16801 case NM_ADDU16:
16802 gen_arith(ctx, OPC_ADDU, rd, rs, rt);
16803 break;
16804 case NM_SUBU16:
16805 gen_arith(ctx, OPC_SUBU, rd, rs, rt);
16806 break;
16807 }
16808 break;
16809 case NM_P16_4X4:
16810 rt = (extract32(ctx->opcode, 9, 1) << 3) |
16811 extract32(ctx->opcode, 5, 3);
16812 rs = (extract32(ctx->opcode, 4, 1) << 3) |
16813 extract32(ctx->opcode, 0, 3);
16814 rt = decode_gpr_gpr4(rt);
16815 rs = decode_gpr_gpr4(rs);
16816 switch ((extract32(ctx->opcode, 7, 2) & 0x2) |
16817 (extract32(ctx->opcode, 3, 1))) {
16818 case NM_ADDU4X4:
16819 gen_arith(ctx, OPC_ADDU, rt, rs, rt);
16820 break;
16821 case NM_MUL4X4:
16822 gen_r6_muldiv(ctx, R6_OPC_MUL, rt, rs, rt);
16823 break;
16824 default:
16825 generate_exception_end(ctx, EXCP_RI);
16826 break;
16827 }
16828 break;
16829 case NM_LI16:
16830 break;
16831 case NM_ANDI16:
16832 break;
16833 case NM_P16_LB:
16834 break;
16835 case NM_P16_LH:
16836 break;
16837 case NM_LW16:
16838 break;
16839 case NM_LWSP16:
16840 break;
16841 case NM_LW4X4:
16842 break;
16843 case NM_SW4X4:
16844 break;
16845 case NM_LWGP16:
16846 break;
16847 case NM_SWSP16:
16848 break;
16849 case NM_SW16:
16850 break;
16851 case NM_SWGP16:
16852 break;
16853 case NM_BC16:
764371d2
SM
16854 gen_compute_branch_nm(ctx, OPC_BEQ, 2, 0, 0,
16855 (sextract32(ctx->opcode, 0, 1) << 10) |
16856 (extract32(ctx->opcode, 1, 9) << 1));
ea4ca3c2
YK
16857 break;
16858 case NM_BALC16:
764371d2
SM
16859 gen_compute_branch_nm(ctx, OPC_BGEZAL, 2, 0, 0,
16860 (sextract32(ctx->opcode, 0, 1) << 10) |
16861 (extract32(ctx->opcode, 1, 9) << 1));
ea4ca3c2
YK
16862 break;
16863 case NM_BEQZC16:
764371d2
SM
16864 gen_compute_branch_nm(ctx, OPC_BEQ, 2, rt, 0,
16865 (sextract32(ctx->opcode, 0, 1) << 7) |
16866 (extract32(ctx->opcode, 1, 6) << 1));
ea4ca3c2
YK
16867 break;
16868 case NM_BNEZC16:
764371d2
SM
16869 gen_compute_branch_nm(ctx, OPC_BNE, 2, rt, 0,
16870 (sextract32(ctx->opcode, 0, 1) << 7) |
16871 (extract32(ctx->opcode, 1, 6) << 1));
ea4ca3c2
YK
16872 break;
16873 case NM_P16_BR:
764371d2
SM
16874 switch (ctx->opcode & 0xf) {
16875 case 0:
16876 /* P16.JRC */
16877 switch (extract32(ctx->opcode, 4, 1)) {
16878 case NM_JRC:
16879 gen_compute_branch_nm(ctx, OPC_JR, 2,
16880 extract32(ctx->opcode, 5, 5), 0, 0);
16881 break;
16882 case NM_JALRC16:
16883 gen_compute_branch_nm(ctx, OPC_JALR, 2,
16884 extract32(ctx->opcode, 5, 5), 31, 0);
16885 break;
16886 }
16887 break;
16888 default:
16889 {
16890 /* P16.BRI */
16891 uint32_t opc = extract32(ctx->opcode, 4, 3) <
16892 extract32(ctx->opcode, 7, 3) ? OPC_BEQ : OPC_BNE;
16893 gen_compute_branch_nm(ctx, opc, 2, rs, rt,
16894 extract32(ctx->opcode, 0, 4) << 1);
16895 }
16896 break;
16897 }
ea4ca3c2
YK
16898 break;
16899 case NM_P16_SR:
16900 break;
16901 case NM_MOVEP:
16902 break;
16903 case NM_MOVEPREV:
16904 break;
16905 default:
16906 break;
16907 }
16908
c533c0f4
AM
16909 return 2;
16910}
16911
16912
3c824109
NF
16913/* SmartMIPS extension to MIPS32 */
16914
16915#if defined(TARGET_MIPS64)
16916
16917/* MDMX extension to MIPS64 */
16918
16919#endif
16920
9b1a1d68 16921/* MIPSDSP functions. */
d75c135e 16922static void gen_mipsdsp_ld(DisasContext *ctx, uint32_t opc,
9b1a1d68
JL
16923 int rd, int base, int offset)
16924{
9b1a1d68
JL
16925 TCGv t0;
16926
9b1a1d68
JL
16927 check_dsp(ctx);
16928 t0 = tcg_temp_new();
16929
16930 if (base == 0) {
16931 gen_load_gpr(t0, offset);
16932 } else if (offset == 0) {
16933 gen_load_gpr(t0, base);
16934 } else {
16935 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[offset]);
16936 }
16937
9b1a1d68
JL
16938 switch (opc) {
16939 case OPC_LBUX:
5f68f5ae 16940 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB);
9b1a1d68 16941 gen_store_gpr(t0, rd);
9b1a1d68
JL
16942 break;
16943 case OPC_LHX:
5f68f5ae 16944 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW);
9b1a1d68 16945 gen_store_gpr(t0, rd);
9b1a1d68
JL
16946 break;
16947 case OPC_LWX:
5f68f5ae 16948 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
9b1a1d68 16949 gen_store_gpr(t0, rd);
9b1a1d68
JL
16950 break;
16951#if defined(TARGET_MIPS64)
16952 case OPC_LDX:
5f68f5ae 16953 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
9b1a1d68 16954 gen_store_gpr(t0, rd);
9b1a1d68
JL
16955 break;
16956#endif
16957 }
9b1a1d68
JL
16958 tcg_temp_free(t0);
16959}
16960
461c08df
JL
16961static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
16962 int ret, int v1, int v2)
16963{
461c08df
JL
16964 TCGv v1_t;
16965 TCGv v2_t;
16966
16967 if (ret == 0) {
16968 /* Treat as NOP. */
461c08df
JL
16969 return;
16970 }
16971
16972 v1_t = tcg_temp_new();
16973 v2_t = tcg_temp_new();
16974
16975 gen_load_gpr(v1_t, v1);
16976 gen_load_gpr(v2_t, v2);
16977
16978 switch (op1) {
16979 /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
16980 case OPC_MULT_G_2E:
16981 check_dspr2(ctx);
16982 switch (op2) {
16983 case OPC_ADDUH_QB:
16984 gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t);
16985 break;
16986 case OPC_ADDUH_R_QB:
16987 gen_helper_adduh_r_qb(cpu_gpr[ret], v1_t, v2_t);
16988 break;
16989 case OPC_ADDQH_PH:
16990 gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t);
16991 break;
16992 case OPC_ADDQH_R_PH:
16993 gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
16994 break;
16995 case OPC_ADDQH_W:
16996 gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t);
16997 break;
16998 case OPC_ADDQH_R_W:
16999 gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t);
17000 break;
17001 case OPC_SUBUH_QB:
17002 gen_helper_subuh_qb(cpu_gpr[ret], v1_t, v2_t);
17003 break;
17004 case OPC_SUBUH_R_QB:
17005 gen_helper_subuh_r_qb(cpu_gpr[ret], v1_t, v2_t);
17006 break;
17007 case OPC_SUBQH_PH:
17008 gen_helper_subqh_ph(cpu_gpr[ret], v1_t, v2_t);
17009 break;
17010 case OPC_SUBQH_R_PH:
17011 gen_helper_subqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
17012 break;
17013 case OPC_SUBQH_W:
17014 gen_helper_subqh_w(cpu_gpr[ret], v1_t, v2_t);
17015 break;
17016 case OPC_SUBQH_R_W:
17017 gen_helper_subqh_r_w(cpu_gpr[ret], v1_t, v2_t);
17018 break;
17019 }
17020 break;
17021 case OPC_ABSQ_S_PH_DSP:
17022 switch (op2) {
17023 case OPC_ABSQ_S_QB:
17024 check_dspr2(ctx);
17025 gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, cpu_env);
17026 break;
17027 case OPC_ABSQ_S_PH:
17028 check_dsp(ctx);
17029 gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, cpu_env);
17030 break;
17031 case OPC_ABSQ_S_W:
17032 check_dsp(ctx);
17033 gen_helper_absq_s_w(cpu_gpr[ret], v2_t, cpu_env);
17034 break;
17035 case OPC_PRECEQ_W_PHL:
17036 check_dsp(ctx);
17037 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000);
17038 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
17039 break;
17040 case OPC_PRECEQ_W_PHR:
17041 check_dsp(ctx);
17042 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF);
17043 tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16);
17044 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
17045 break;
17046 case OPC_PRECEQU_PH_QBL:
17047 check_dsp(ctx);
17048 gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t);
17049 break;
17050 case OPC_PRECEQU_PH_QBR:
17051 check_dsp(ctx);
17052 gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t);
17053 break;
17054 case OPC_PRECEQU_PH_QBLA:
17055 check_dsp(ctx);
17056 gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t);
17057 break;
17058 case OPC_PRECEQU_PH_QBRA:
17059 check_dsp(ctx);
17060 gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t);
17061 break;
17062 case OPC_PRECEU_PH_QBL:
17063 check_dsp(ctx);
17064 gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t);
17065 break;
17066 case OPC_PRECEU_PH_QBR:
17067 check_dsp(ctx);
17068 gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t);
17069 break;
17070 case OPC_PRECEU_PH_QBLA:
17071 check_dsp(ctx);
17072 gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t);
17073 break;
17074 case OPC_PRECEU_PH_QBRA:
17075 check_dsp(ctx);
17076 gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t);
17077 break;
17078 }
17079 break;
17080 case OPC_ADDU_QB_DSP:
17081 switch (op2) {
17082 case OPC_ADDQ_PH:
17083 check_dsp(ctx);
17084 gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
17085 break;
17086 case OPC_ADDQ_S_PH:
17087 check_dsp(ctx);
17088 gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
17089 break;
17090 case OPC_ADDQ_S_W:
17091 check_dsp(ctx);
17092 gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
17093 break;
17094 case OPC_ADDU_QB:
17095 check_dsp(ctx);
17096 gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
17097 break;
17098 case OPC_ADDU_S_QB:
17099 check_dsp(ctx);
17100 gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
17101 break;
17102 case OPC_ADDU_PH:
17103 check_dspr2(ctx);
17104 gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
17105 break;
17106 case OPC_ADDU_S_PH:
17107 check_dspr2(ctx);
17108 gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
17109 break;
17110 case OPC_SUBQ_PH:
17111 check_dsp(ctx);
17112 gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
17113 break;
17114 case OPC_SUBQ_S_PH:
17115 check_dsp(ctx);
17116 gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
17117 break;
17118 case OPC_SUBQ_S_W:
17119 check_dsp(ctx);
17120 gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
17121 break;
17122 case OPC_SUBU_QB:
17123 check_dsp(ctx);
17124 gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
17125 break;
17126 case OPC_SUBU_S_QB:
17127 check_dsp(ctx);
17128 gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
17129 break;
17130 case OPC_SUBU_PH:
17131 check_dspr2(ctx);
17132 gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
17133 break;
17134 case OPC_SUBU_S_PH:
17135 check_dspr2(ctx);
17136 gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
17137 break;
17138 case OPC_ADDSC:
17139 check_dsp(ctx);
17140 gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
17141 break;
17142 case OPC_ADDWC:
17143 check_dsp(ctx);
17144 gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
17145 break;
17146 case OPC_MODSUB:
17147 check_dsp(ctx);
17148 gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t);
17149 break;
17150 case OPC_RADDU_W_QB:
17151 check_dsp(ctx);
17152 gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t);
17153 break;
17154 }
17155 break;
17156 case OPC_CMPU_EQ_QB_DSP:
17157 switch (op2) {
17158 case OPC_PRECR_QB_PH:
17159 check_dspr2(ctx);
17160 gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t);
17161 break;
17162 case OPC_PRECRQ_QB_PH:
17163 check_dsp(ctx);
17164 gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t);
17165 break;
17166 case OPC_PRECR_SRA_PH_W:
17167 check_dspr2(ctx);
17168 {
17169 TCGv_i32 sa_t = tcg_const_i32(v2);
17170 gen_helper_precr_sra_ph_w(cpu_gpr[ret], sa_t, v1_t,
17171 cpu_gpr[ret]);
17172 tcg_temp_free_i32(sa_t);
17173 break;
17174 }
17175 case OPC_PRECR_SRA_R_PH_W:
17176 check_dspr2(ctx);
17177 {
17178 TCGv_i32 sa_t = tcg_const_i32(v2);
17179 gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t,
17180 cpu_gpr[ret]);
17181 tcg_temp_free_i32(sa_t);
17182 break;
17183 }
17184 case OPC_PRECRQ_PH_W:
17185 check_dsp(ctx);
17186 gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t);
17187 break;
17188 case OPC_PRECRQ_RS_PH_W:
17189 check_dsp(ctx);
17190 gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
17191 break;
17192 case OPC_PRECRQU_S_QB_PH:
17193 check_dsp(ctx);
17194 gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
17195 break;
17196 }
17197 break;
17198#ifdef TARGET_MIPS64
17199 case OPC_ABSQ_S_QH_DSP:
17200 switch (op2) {
17201 case OPC_PRECEQ_L_PWL:
17202 check_dsp(ctx);
17203 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull);
17204 break;
17205 case OPC_PRECEQ_L_PWR:
17206 check_dsp(ctx);
17207 tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32);
17208 break;
17209 case OPC_PRECEQ_PW_QHL:
17210 check_dsp(ctx);
17211 gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t);
17212 break;
17213 case OPC_PRECEQ_PW_QHR:
17214 check_dsp(ctx);
17215 gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t);
17216 break;
17217 case OPC_PRECEQ_PW_QHLA:
17218 check_dsp(ctx);
17219 gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t);
17220 break;
17221 case OPC_PRECEQ_PW_QHRA:
17222 check_dsp(ctx);
17223 gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t);
17224 break;
17225 case OPC_PRECEQU_QH_OBL:
17226 check_dsp(ctx);
17227 gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t);
17228 break;
17229 case OPC_PRECEQU_QH_OBR:
17230 check_dsp(ctx);
17231 gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t);
17232 break;
17233 case OPC_PRECEQU_QH_OBLA:
17234 check_dsp(ctx);
17235 gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t);
17236 break;
17237 case OPC_PRECEQU_QH_OBRA:
17238 check_dsp(ctx);
17239 gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t);
17240 break;
17241 case OPC_PRECEU_QH_OBL:
17242 check_dsp(ctx);
17243 gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t);
17244 break;
17245 case OPC_PRECEU_QH_OBR:
17246 check_dsp(ctx);
17247 gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t);
17248 break;
17249 case OPC_PRECEU_QH_OBLA:
17250 check_dsp(ctx);
17251 gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t);
17252 break;
17253 case OPC_PRECEU_QH_OBRA:
17254 check_dsp(ctx);
17255 gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t);
17256 break;
17257 case OPC_ABSQ_S_OB:
17258 check_dspr2(ctx);
17259 gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, cpu_env);
17260 break;
17261 case OPC_ABSQ_S_PW:
17262 check_dsp(ctx);
17263 gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, cpu_env);
17264 break;
17265 case OPC_ABSQ_S_QH:
17266 check_dsp(ctx);
17267 gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, cpu_env);
17268 break;
17269 }
17270 break;
17271 case OPC_ADDU_OB_DSP:
17272 switch (op2) {
17273 case OPC_RADDU_L_OB:
17274 check_dsp(ctx);
17275 gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t);
17276 break;
17277 case OPC_SUBQ_PW:
17278 check_dsp(ctx);
17279 gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
17280 break;
17281 case OPC_SUBQ_S_PW:
17282 check_dsp(ctx);
17283 gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
17284 break;
17285 case OPC_SUBQ_QH:
17286 check_dsp(ctx);
17287 gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
17288 break;
17289 case OPC_SUBQ_S_QH:
17290 check_dsp(ctx);
17291 gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
17292 break;
17293 case OPC_SUBU_OB:
17294 check_dsp(ctx);
17295 gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
17296 break;
17297 case OPC_SUBU_S_OB:
17298 check_dsp(ctx);
17299 gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
17300 break;
17301 case OPC_SUBU_QH:
17302 check_dspr2(ctx);
17303 gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
17304 break;
17305 case OPC_SUBU_S_QH:
17306 check_dspr2(ctx);
17307 gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
17308 break;
17309 case OPC_SUBUH_OB:
17310 check_dspr2(ctx);
17311 gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t);
17312 break;
17313 case OPC_SUBUH_R_OB:
17314 check_dspr2(ctx);
17315 gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t);
17316 break;
17317 case OPC_ADDQ_PW:
17318 check_dsp(ctx);
17319 gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
17320 break;
17321 case OPC_ADDQ_S_PW:
17322 check_dsp(ctx);
17323 gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
17324 break;
17325 case OPC_ADDQ_QH:
17326 check_dsp(ctx);
17327 gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
17328 break;
17329 case OPC_ADDQ_S_QH:
17330 check_dsp(ctx);
17331 gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
17332 break;
17333 case OPC_ADDU_OB:
17334 check_dsp(ctx);
17335 gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
17336 break;
17337 case OPC_ADDU_S_OB:
17338 check_dsp(ctx);
17339 gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
17340 break;
17341 case OPC_ADDU_QH:
17342 check_dspr2(ctx);
17343 gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
17344 break;
17345 case OPC_ADDU_S_QH:
17346 check_dspr2(ctx);
17347 gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
17348 break;
17349 case OPC_ADDUH_OB:
17350 check_dspr2(ctx);
17351 gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t);
17352 break;
17353 case OPC_ADDUH_R_OB:
17354 check_dspr2(ctx);
17355 gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t);
17356 break;
17357 }
17358 break;
17359 case OPC_CMPU_EQ_OB_DSP:
17360 switch (op2) {
17361 case OPC_PRECR_OB_QH:
17362 check_dspr2(ctx);
17363 gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t);
17364 break;
17365 case OPC_PRECR_SRA_QH_PW:
17366 check_dspr2(ctx);
17367 {
17368 TCGv_i32 ret_t = tcg_const_i32(ret);
17369 gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t);
17370 tcg_temp_free_i32(ret_t);
17371 break;
17372 }
17373 case OPC_PRECR_SRA_R_QH_PW:
17374 check_dspr2(ctx);
17375 {
17376 TCGv_i32 sa_v = tcg_const_i32(ret);
17377 gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v);
17378 tcg_temp_free_i32(sa_v);
17379 break;
17380 }
17381 case OPC_PRECRQ_OB_QH:
17382 check_dsp(ctx);
17383 gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t);
17384 break;
17385 case OPC_PRECRQ_PW_L:
17386 check_dsp(ctx);
17387 gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t);
17388 break;
17389 case OPC_PRECRQ_QH_PW:
17390 check_dsp(ctx);
17391 gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t);
17392 break;
17393 case OPC_PRECRQ_RS_QH_PW:
17394 check_dsp(ctx);
17395 gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
17396 break;
17397 case OPC_PRECRQU_S_OB_QH:
17398 check_dsp(ctx);
17399 gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
17400 break;
17401 }
17402 break;
17403#endif
17404 }
17405
17406 tcg_temp_free(v1_t);
17407 tcg_temp_free(v2_t);
461c08df 17408}
9b1a1d68 17409
77c5fa8b
JL
17410static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc,
17411 int ret, int v1, int v2)
17412{
17413 uint32_t op2;
77c5fa8b
JL
17414 TCGv t0;
17415 TCGv v1_t;
17416 TCGv v2_t;
17417
17418 if (ret == 0) {
17419 /* Treat as NOP. */
77c5fa8b
JL
17420 return;
17421 }
17422
17423 t0 = tcg_temp_new();
17424 v1_t = tcg_temp_new();
17425 v2_t = tcg_temp_new();
17426
17427 tcg_gen_movi_tl(t0, v1);
17428 gen_load_gpr(v1_t, v1);
17429 gen_load_gpr(v2_t, v2);
17430
17431 switch (opc) {
17432 case OPC_SHLL_QB_DSP:
17433 {
17434 op2 = MASK_SHLL_QB(ctx->opcode);
17435 switch (op2) {
17436 case OPC_SHLL_QB:
17437 check_dsp(ctx);
17438 gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, cpu_env);
17439 break;
17440 case OPC_SHLLV_QB:
17441 check_dsp(ctx);
17442 gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
17443 break;
17444 case OPC_SHLL_PH:
17445 check_dsp(ctx);
17446 gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
17447 break;
17448 case OPC_SHLLV_PH:
17449 check_dsp(ctx);
17450 gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
17451 break;
17452 case OPC_SHLL_S_PH:
17453 check_dsp(ctx);
17454 gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
17455 break;
17456 case OPC_SHLLV_S_PH:
17457 check_dsp(ctx);
17458 gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
17459 break;
17460 case OPC_SHLL_S_W:
17461 check_dsp(ctx);
17462 gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, cpu_env);
17463 break;
17464 case OPC_SHLLV_S_W:
17465 check_dsp(ctx);
17466 gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
17467 break;
17468 case OPC_SHRL_QB:
17469 check_dsp(ctx);
17470 gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t);
17471 break;
17472 case OPC_SHRLV_QB:
17473 check_dsp(ctx);
17474 gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t);
17475 break;
17476 case OPC_SHRL_PH:
17477 check_dspr2(ctx);
17478 gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t);
17479 break;
17480 case OPC_SHRLV_PH:
17481 check_dspr2(ctx);
17482 gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t);
17483 break;
17484 case OPC_SHRA_QB:
17485 check_dspr2(ctx);
17486 gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t);
17487 break;
17488 case OPC_SHRA_R_QB:
17489 check_dspr2(ctx);
17490 gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t);
17491 break;
17492 case OPC_SHRAV_QB:
17493 check_dspr2(ctx);
17494 gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t);
17495 break;
17496 case OPC_SHRAV_R_QB:
17497 check_dspr2(ctx);
17498 gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t);
17499 break;
17500 case OPC_SHRA_PH:
17501 check_dsp(ctx);
17502 gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t);
17503 break;
17504 case OPC_SHRA_R_PH:
17505 check_dsp(ctx);
17506 gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t);
17507 break;
17508 case OPC_SHRAV_PH:
17509 check_dsp(ctx);
17510 gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t);
17511 break;
17512 case OPC_SHRAV_R_PH:
17513 check_dsp(ctx);
17514 gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t);
17515 break;
17516 case OPC_SHRA_R_W:
17517 check_dsp(ctx);
17518 gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t);
17519 break;
17520 case OPC_SHRAV_R_W:
17521 check_dsp(ctx);
17522 gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t);
17523 break;
17524 default: /* Invalid */
17525 MIPS_INVAL("MASK SHLL.QB");
9c708c7f 17526 generate_exception_end(ctx, EXCP_RI);
77c5fa8b
JL
17527 break;
17528 }
17529 break;
17530 }
17531#ifdef TARGET_MIPS64
17532 case OPC_SHLL_OB_DSP:
17533 op2 = MASK_SHLL_OB(ctx->opcode);
17534 switch (op2) {
17535 case OPC_SHLL_PW:
17536 check_dsp(ctx);
17537 gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
17538 break;
17539 case OPC_SHLLV_PW:
17540 check_dsp(ctx);
17541 gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
17542 break;
17543 case OPC_SHLL_S_PW:
17544 check_dsp(ctx);
17545 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
17546 break;
17547 case OPC_SHLLV_S_PW:
17548 check_dsp(ctx);
17549 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
17550 break;
17551 case OPC_SHLL_OB:
17552 check_dsp(ctx);
17553 gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, cpu_env);
17554 break;
17555 case OPC_SHLLV_OB:
17556 check_dsp(ctx);
17557 gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, cpu_env);
17558 break;
17559 case OPC_SHLL_QH:
17560 check_dsp(ctx);
17561 gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
17562 break;
17563 case OPC_SHLLV_QH:
17564 check_dsp(ctx);
17565 gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
17566 break;
17567 case OPC_SHLL_S_QH:
17568 check_dsp(ctx);
17569 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
17570 break;
17571 case OPC_SHLLV_S_QH:
17572 check_dsp(ctx);
17573 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
17574 break;
17575 case OPC_SHRA_OB:
17576 check_dspr2(ctx);
17577 gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0);
17578 break;
17579 case OPC_SHRAV_OB:
17580 check_dspr2(ctx);
17581 gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t);
17582 break;
17583 case OPC_SHRA_R_OB:
17584 check_dspr2(ctx);
17585 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0);
17586 break;
17587 case OPC_SHRAV_R_OB:
17588 check_dspr2(ctx);
17589 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t);
17590 break;
17591 case OPC_SHRA_PW:
17592 check_dsp(ctx);
17593 gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0);
17594 break;
17595 case OPC_SHRAV_PW:
17596 check_dsp(ctx);
17597 gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t);
17598 break;
17599 case OPC_SHRA_R_PW:
17600 check_dsp(ctx);
17601 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0);
17602 break;
17603 case OPC_SHRAV_R_PW:
17604 check_dsp(ctx);
17605 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t);
17606 break;
17607 case OPC_SHRA_QH:
17608 check_dsp(ctx);
17609 gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0);
17610 break;
17611 case OPC_SHRAV_QH:
17612 check_dsp(ctx);
17613 gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t);
17614 break;
17615 case OPC_SHRA_R_QH:
17616 check_dsp(ctx);
17617 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0);
17618 break;
17619 case OPC_SHRAV_R_QH:
17620 check_dsp(ctx);
17621 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t);
17622 break;
17623 case OPC_SHRL_OB:
17624 check_dsp(ctx);
17625 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0);
17626 break;
17627 case OPC_SHRLV_OB:
17628 check_dsp(ctx);
17629 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t);
17630 break;
17631 case OPC_SHRL_QH:
17632 check_dspr2(ctx);
17633 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0);
17634 break;
17635 case OPC_SHRLV_QH:
17636 check_dspr2(ctx);
17637 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t);
17638 break;
17639 default: /* Invalid */
17640 MIPS_INVAL("MASK SHLL.OB");
9c708c7f 17641 generate_exception_end(ctx, EXCP_RI);
77c5fa8b
JL
17642 break;
17643 }
17644 break;
17645#endif
17646 }
17647
17648 tcg_temp_free(t0);
17649 tcg_temp_free(v1_t);
17650 tcg_temp_free(v2_t);
77c5fa8b
JL
17651}
17652
a22260ae
JL
17653static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2,
17654 int ret, int v1, int v2, int check_ret)
17655{
a22260ae
JL
17656 TCGv_i32 t0;
17657 TCGv v1_t;
17658 TCGv v2_t;
17659
17660 if ((ret == 0) && (check_ret == 1)) {
17661 /* Treat as NOP. */
a22260ae
JL
17662 return;
17663 }
17664
17665 t0 = tcg_temp_new_i32();
17666 v1_t = tcg_temp_new();
17667 v2_t = tcg_temp_new();
17668
17669 tcg_gen_movi_i32(t0, ret);
17670 gen_load_gpr(v1_t, v1);
17671 gen_load_gpr(v2_t, v2);
17672
17673 switch (op1) {
17674 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
17675 * the same mask and op1. */
17676 case OPC_MULT_G_2E:
639eadb9 17677 check_dspr2(ctx);
a22260ae
JL
17678 switch (op2) {
17679 case OPC_MUL_PH:
17680 gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
17681 break;
17682 case OPC_MUL_S_PH:
17683 gen_helper_mul_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
17684 break;
17685 case OPC_MULQ_S_W:
17686 gen_helper_mulq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
17687 break;
17688 case OPC_MULQ_RS_W:
17689 gen_helper_mulq_rs_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
17690 break;
17691 }
17692 break;
17693 case OPC_DPA_W_PH_DSP:
17694 switch (op2) {
17695 case OPC_DPAU_H_QBL:
17696 check_dsp(ctx);
17697 gen_helper_dpau_h_qbl(t0, v1_t, v2_t, cpu_env);
17698 break;
17699 case OPC_DPAU_H_QBR:
17700 check_dsp(ctx);
17701 gen_helper_dpau_h_qbr(t0, v1_t, v2_t, cpu_env);
17702 break;
17703 case OPC_DPSU_H_QBL:
17704 check_dsp(ctx);
17705 gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, cpu_env);
17706 break;
17707 case OPC_DPSU_H_QBR:
17708 check_dsp(ctx);
17709 gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, cpu_env);
17710 break;
17711 case OPC_DPA_W_PH:
17712 check_dspr2(ctx);
17713 gen_helper_dpa_w_ph(t0, v1_t, v2_t, cpu_env);
17714 break;
17715 case OPC_DPAX_W_PH:
17716 check_dspr2(ctx);
17717 gen_helper_dpax_w_ph(t0, v1_t, v2_t, cpu_env);
17718 break;
17719 case OPC_DPAQ_S_W_PH:
17720 check_dsp(ctx);
17721 gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
17722 break;
17723 case OPC_DPAQX_S_W_PH:
17724 check_dspr2(ctx);
17725 gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
17726 break;
17727 case OPC_DPAQX_SA_W_PH:
17728 check_dspr2(ctx);
17729 gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
17730 break;
17731 case OPC_DPS_W_PH:
17732 check_dspr2(ctx);
17733 gen_helper_dps_w_ph(t0, v1_t, v2_t, cpu_env);
17734 break;
17735 case OPC_DPSX_W_PH:
17736 check_dspr2(ctx);
17737 gen_helper_dpsx_w_ph(t0, v1_t, v2_t, cpu_env);
17738 break;
17739 case OPC_DPSQ_S_W_PH:
17740 check_dsp(ctx);
17741 gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, cpu_env);
17742 break;
17743 case OPC_DPSQX_S_W_PH:
17744 check_dspr2(ctx);
17745 gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
17746 break;
17747 case OPC_DPSQX_SA_W_PH:
17748 check_dspr2(ctx);
17749 gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
17750 break;
17751 case OPC_MULSAQ_S_W_PH:
17752 check_dsp(ctx);
17753 gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
17754 break;
17755 case OPC_DPAQ_SA_L_W:
17756 check_dsp(ctx);
17757 gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, cpu_env);
17758 break;
17759 case OPC_DPSQ_SA_L_W:
17760 check_dsp(ctx);
17761 gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, cpu_env);
17762 break;
17763 case OPC_MAQ_S_W_PHL:
17764 check_dsp(ctx);
17765 gen_helper_maq_s_w_phl(t0, v1_t, v2_t, cpu_env);
17766 break;
17767 case OPC_MAQ_S_W_PHR:
17768 check_dsp(ctx);
17769 gen_helper_maq_s_w_phr(t0, v1_t, v2_t, cpu_env);
17770 break;
17771 case OPC_MAQ_SA_W_PHL:
17772 check_dsp(ctx);
17773 gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, cpu_env);
17774 break;
17775 case OPC_MAQ_SA_W_PHR:
17776 check_dsp(ctx);
17777 gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, cpu_env);
17778 break;
17779 case OPC_MULSA_W_PH:
17780 check_dspr2(ctx);
17781 gen_helper_mulsa_w_ph(t0, v1_t, v2_t, cpu_env);
17782 break;
17783 }
17784 break;
17785#ifdef TARGET_MIPS64
17786 case OPC_DPAQ_W_QH_DSP:
17787 {
17788 int ac = ret & 0x03;
17789 tcg_gen_movi_i32(t0, ac);
17790
17791 switch (op2) {
17792 case OPC_DMADD:
17793 check_dsp(ctx);
17794 gen_helper_dmadd(v1_t, v2_t, t0, cpu_env);
17795 break;
17796 case OPC_DMADDU:
17797 check_dsp(ctx);
17798 gen_helper_dmaddu(v1_t, v2_t, t0, cpu_env);
17799 break;
17800 case OPC_DMSUB:
17801 check_dsp(ctx);
17802 gen_helper_dmsub(v1_t, v2_t, t0, cpu_env);
17803 break;
17804 case OPC_DMSUBU:
17805 check_dsp(ctx);
17806 gen_helper_dmsubu(v1_t, v2_t, t0, cpu_env);
17807 break;
17808 case OPC_DPA_W_QH:
17809 check_dspr2(ctx);
17810 gen_helper_dpa_w_qh(v1_t, v2_t, t0, cpu_env);
17811 break;
17812 case OPC_DPAQ_S_W_QH:
17813 check_dsp(ctx);
17814 gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
17815 break;
17816 case OPC_DPAQ_SA_L_PW:
17817 check_dsp(ctx);
17818 gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
17819 break;
17820 case OPC_DPAU_H_OBL:
17821 check_dsp(ctx);
17822 gen_helper_dpau_h_obl(v1_t, v2_t, t0, cpu_env);
17823 break;
17824 case OPC_DPAU_H_OBR:
17825 check_dsp(ctx);
17826 gen_helper_dpau_h_obr(v1_t, v2_t, t0, cpu_env);
17827 break;
17828 case OPC_DPS_W_QH:
17829 check_dspr2(ctx);
17830 gen_helper_dps_w_qh(v1_t, v2_t, t0, cpu_env);
17831 break;
17832 case OPC_DPSQ_S_W_QH:
17833 check_dsp(ctx);
17834 gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, cpu_env);
17835 break;
17836 case OPC_DPSQ_SA_L_PW:
17837 check_dsp(ctx);
17838 gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
17839 break;
17840 case OPC_DPSU_H_OBL:
17841 check_dsp(ctx);
17842 gen_helper_dpsu_h_obl(v1_t, v2_t, t0, cpu_env);
17843 break;
17844 case OPC_DPSU_H_OBR:
17845 check_dsp(ctx);
17846 gen_helper_dpsu_h_obr(v1_t, v2_t, t0, cpu_env);
17847 break;
17848 case OPC_MAQ_S_L_PWL:
17849 check_dsp(ctx);
17850 gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, cpu_env);
17851 break;
17852 case OPC_MAQ_S_L_PWR:
17853 check_dsp(ctx);
17854 gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, cpu_env);
17855 break;
17856 case OPC_MAQ_S_W_QHLL:
17857 check_dsp(ctx);
17858 gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, cpu_env);
17859 break;
17860 case OPC_MAQ_SA_W_QHLL:
17861 check_dsp(ctx);
17862 gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, cpu_env);
17863 break;
17864 case OPC_MAQ_S_W_QHLR:
17865 check_dsp(ctx);
17866 gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, cpu_env);
17867 break;
17868 case OPC_MAQ_SA_W_QHLR:
17869 check_dsp(ctx);
17870 gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, cpu_env);
17871 break;
17872 case OPC_MAQ_S_W_QHRL:
17873 check_dsp(ctx);
17874 gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, cpu_env);
17875 break;
17876 case OPC_MAQ_SA_W_QHRL:
17877 check_dsp(ctx);
17878 gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, cpu_env);
17879 break;
17880 case OPC_MAQ_S_W_QHRR:
17881 check_dsp(ctx);
17882 gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, cpu_env);
17883 break;
17884 case OPC_MAQ_SA_W_QHRR:
17885 check_dsp(ctx);
17886 gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, cpu_env);
17887 break;
17888 case OPC_MULSAQ_S_L_PW:
17889 check_dsp(ctx);
17890 gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, cpu_env);
17891 break;
17892 case OPC_MULSAQ_S_W_QH:
17893 check_dsp(ctx);
17894 gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
17895 break;
17896 }
17897 }
17898 break;
17899#endif
17900 case OPC_ADDU_QB_DSP:
17901 switch (op2) {
17902 case OPC_MULEU_S_PH_QBL:
17903 check_dsp(ctx);
17904 gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
17905 break;
17906 case OPC_MULEU_S_PH_QBR:
17907 check_dsp(ctx);
17908 gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
17909 break;
17910 case OPC_MULQ_RS_PH:
17911 check_dsp(ctx);
17912 gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
17913 break;
17914 case OPC_MULEQ_S_W_PHL:
17915 check_dsp(ctx);
17916 gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
17917 break;
17918 case OPC_MULEQ_S_W_PHR:
17919 check_dsp(ctx);
17920 gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
17921 break;
17922 case OPC_MULQ_S_PH:
17923 check_dspr2(ctx);
17924 gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
17925 break;
17926 }
17927 break;
17928#ifdef TARGET_MIPS64
17929 case OPC_ADDU_OB_DSP:
17930 switch (op2) {
17931 case OPC_MULEQ_S_PW_QHL:
17932 check_dsp(ctx);
17933 gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
17934 break;
17935 case OPC_MULEQ_S_PW_QHR:
17936 check_dsp(ctx);
17937 gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
17938 break;
17939 case OPC_MULEU_S_QH_OBL:
17940 check_dsp(ctx);
17941 gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
17942 break;
17943 case OPC_MULEU_S_QH_OBR:
17944 check_dsp(ctx);
17945 gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
17946 break;
17947 case OPC_MULQ_RS_QH:
17948 check_dsp(ctx);
17949 gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
17950 break;
17951 }
17952 break;
17953#endif
17954 }
17955
17956 tcg_temp_free_i32(t0);
17957 tcg_temp_free(v1_t);
17958 tcg_temp_free(v2_t);
a22260ae
JL
17959}
17960
d75c135e 17961static void gen_mipsdsp_bitinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
1cb6686c
JL
17962 int ret, int val)
17963{
1cb6686c
JL
17964 int16_t imm;
17965 TCGv t0;
17966 TCGv val_t;
17967
17968 if (ret == 0) {
17969 /* Treat as NOP. */
1cb6686c
JL
17970 return;
17971 }
17972
17973 t0 = tcg_temp_new();
17974 val_t = tcg_temp_new();
17975 gen_load_gpr(val_t, val);
17976
17977 switch (op1) {
17978 case OPC_ABSQ_S_PH_DSP:
17979 switch (op2) {
17980 case OPC_BITREV:
17981 check_dsp(ctx);
17982 gen_helper_bitrev(cpu_gpr[ret], val_t);
17983 break;
17984 case OPC_REPL_QB:
17985 check_dsp(ctx);
17986 {
17987 target_long result;
17988 imm = (ctx->opcode >> 16) & 0xFF;
17989 result = (uint32_t)imm << 24 |
17990 (uint32_t)imm << 16 |
17991 (uint32_t)imm << 8 |
17992 (uint32_t)imm;
17993 result = (int32_t)result;
17994 tcg_gen_movi_tl(cpu_gpr[ret], result);
17995 }
17996 break;
17997 case OPC_REPLV_QB:
17998 check_dsp(ctx);
17999 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
18000 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
18001 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
18002 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
18003 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
18004 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
18005 break;
18006 case OPC_REPL_PH:
18007 check_dsp(ctx);
18008 {
18009 imm = (ctx->opcode >> 16) & 0x03FF;
c4aaba92 18010 imm = (int16_t)(imm << 6) >> 6;
1cb6686c
JL
18011 tcg_gen_movi_tl(cpu_gpr[ret], \
18012 (target_long)((int32_t)imm << 16 | \
c4aaba92 18013 (uint16_t)imm));
1cb6686c
JL
18014 }
18015 break;
18016 case OPC_REPLV_PH:
18017 check_dsp(ctx);
18018 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
18019 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
18020 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
18021 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
18022 break;
18023 }
18024 break;
18025#ifdef TARGET_MIPS64
18026 case OPC_ABSQ_S_QH_DSP:
18027 switch (op2) {
18028 case OPC_REPL_OB:
18029 check_dsp(ctx);
18030 {
18031 target_long temp;
18032
18033 imm = (ctx->opcode >> 16) & 0xFF;
18034 temp = ((uint64_t)imm << 8) | (uint64_t)imm;
18035 temp = (temp << 16) | temp;
18036 temp = (temp << 32) | temp;
18037 tcg_gen_movi_tl(cpu_gpr[ret], temp);
18038 break;
18039 }
18040 case OPC_REPL_PW:
18041 check_dsp(ctx);
18042 {
18043 target_long temp;
18044
18045 imm = (ctx->opcode >> 16) & 0x03FF;
18046 imm = (int16_t)(imm << 6) >> 6;
18047 temp = ((target_long)imm << 32) \
18048 | ((target_long)imm & 0xFFFFFFFF);
18049 tcg_gen_movi_tl(cpu_gpr[ret], temp);
18050 break;
18051 }
18052 case OPC_REPL_QH:
18053 check_dsp(ctx);
18054 {
18055 target_long temp;
18056
18057 imm = (ctx->opcode >> 16) & 0x03FF;
18058 imm = (int16_t)(imm << 6) >> 6;
18059
18060 temp = ((uint64_t)(uint16_t)imm << 48) |
18061 ((uint64_t)(uint16_t)imm << 32) |
18062 ((uint64_t)(uint16_t)imm << 16) |
18063 (uint64_t)(uint16_t)imm;
18064 tcg_gen_movi_tl(cpu_gpr[ret], temp);
18065 break;
18066 }
18067 case OPC_REPLV_OB:
18068 check_dsp(ctx);
18069 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
18070 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
18071 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
18072 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
18073 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
18074 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
18075 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
18076 break;
18077 case OPC_REPLV_PW:
18078 check_dsp(ctx);
18079 tcg_gen_ext32u_i64(cpu_gpr[ret], val_t);
18080 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
18081 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
18082 break;
18083 case OPC_REPLV_QH:
18084 check_dsp(ctx);
18085 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
18086 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
18087 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
18088 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
18089 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
18090 break;
18091 }
18092 break;
18093#endif
18094 }
18095 tcg_temp_free(t0);
18096 tcg_temp_free(val_t);
1cb6686c
JL
18097}
18098
26690560
JL
18099static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx,
18100 uint32_t op1, uint32_t op2,
18101 int ret, int v1, int v2, int check_ret)
18102{
26690560
JL
18103 TCGv t1;
18104 TCGv v1_t;
18105 TCGv v2_t;
18106
18107 if ((ret == 0) && (check_ret == 1)) {
18108 /* Treat as NOP. */
26690560
JL
18109 return;
18110 }
18111
26690560
JL
18112 t1 = tcg_temp_new();
18113 v1_t = tcg_temp_new();
18114 v2_t = tcg_temp_new();
18115
18116 gen_load_gpr(v1_t, v1);
18117 gen_load_gpr(v2_t, v2);
18118
18119 switch (op1) {
26690560
JL
18120 case OPC_CMPU_EQ_QB_DSP:
18121 switch (op2) {
18122 case OPC_CMPU_EQ_QB:
18123 check_dsp(ctx);
18124 gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
18125 break;
18126 case OPC_CMPU_LT_QB:
18127 check_dsp(ctx);
18128 gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
18129 break;
18130 case OPC_CMPU_LE_QB:
18131 check_dsp(ctx);
18132 gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
18133 break;
18134 case OPC_CMPGU_EQ_QB:
18135 check_dsp(ctx);
18136 gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t);
18137 break;
18138 case OPC_CMPGU_LT_QB:
18139 check_dsp(ctx);
18140 gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t);
18141 break;
18142 case OPC_CMPGU_LE_QB:
18143 check_dsp(ctx);
18144 gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t);
18145 break;
18146 case OPC_CMPGDU_EQ_QB:
18147 check_dspr2(ctx);
18148 gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t);
18149 tcg_gen_mov_tl(cpu_gpr[ret], t1);
18150 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
18151 tcg_gen_shli_tl(t1, t1, 24);
18152 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
18153 break;
18154 case OPC_CMPGDU_LT_QB:
18155 check_dspr2(ctx);
18156 gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t);
18157 tcg_gen_mov_tl(cpu_gpr[ret], t1);
18158 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
18159 tcg_gen_shli_tl(t1, t1, 24);
18160 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
18161 break;
18162 case OPC_CMPGDU_LE_QB:
18163 check_dspr2(ctx);
18164 gen_helper_cmpgu_le_qb(t1, v1_t, v2_t);
18165 tcg_gen_mov_tl(cpu_gpr[ret], t1);
18166 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
18167 tcg_gen_shli_tl(t1, t1, 24);
18168 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
18169 break;
18170 case OPC_CMP_EQ_PH:
18171 check_dsp(ctx);
18172 gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
18173 break;
18174 case OPC_CMP_LT_PH:
18175 check_dsp(ctx);
18176 gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
18177 break;
18178 case OPC_CMP_LE_PH:
18179 check_dsp(ctx);
18180 gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
18181 break;
18182 case OPC_PICK_QB:
18183 check_dsp(ctx);
18184 gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
18185 break;
18186 case OPC_PICK_PH:
18187 check_dsp(ctx);
18188 gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
18189 break;
18190 case OPC_PACKRL_PH:
18191 check_dsp(ctx);
18192 gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t);
18193 break;
18194 }
18195 break;
18196#ifdef TARGET_MIPS64
18197 case OPC_CMPU_EQ_OB_DSP:
18198 switch (op2) {
18199 case OPC_CMP_EQ_PW:
18200 check_dsp(ctx);
18201 gen_helper_cmp_eq_pw(v1_t, v2_t, cpu_env);
18202 break;
18203 case OPC_CMP_LT_PW:
18204 check_dsp(ctx);
18205 gen_helper_cmp_lt_pw(v1_t, v2_t, cpu_env);
18206 break;
18207 case OPC_CMP_LE_PW:
18208 check_dsp(ctx);
18209 gen_helper_cmp_le_pw(v1_t, v2_t, cpu_env);
18210 break;
18211 case OPC_CMP_EQ_QH:
18212 check_dsp(ctx);
18213 gen_helper_cmp_eq_qh(v1_t, v2_t, cpu_env);
18214 break;
18215 case OPC_CMP_LT_QH:
18216 check_dsp(ctx);
18217 gen_helper_cmp_lt_qh(v1_t, v2_t, cpu_env);
18218 break;
18219 case OPC_CMP_LE_QH:
18220 check_dsp(ctx);
18221 gen_helper_cmp_le_qh(v1_t, v2_t, cpu_env);
18222 break;
18223 case OPC_CMPGDU_EQ_OB:
18224 check_dspr2(ctx);
18225 gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
18226 break;
18227 case OPC_CMPGDU_LT_OB:
18228 check_dspr2(ctx);
18229 gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
18230 break;
18231 case OPC_CMPGDU_LE_OB:
18232 check_dspr2(ctx);
18233 gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
18234 break;
18235 case OPC_CMPGU_EQ_OB:
18236 check_dsp(ctx);
18237 gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t);
18238 break;
18239 case OPC_CMPGU_LT_OB:
18240 check_dsp(ctx);
18241 gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t);
18242 break;
18243 case OPC_CMPGU_LE_OB:
18244 check_dsp(ctx);
18245 gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t);
18246 break;
18247 case OPC_CMPU_EQ_OB:
18248 check_dsp(ctx);
18249 gen_helper_cmpu_eq_ob(v1_t, v2_t, cpu_env);
18250 break;
18251 case OPC_CMPU_LT_OB:
18252 check_dsp(ctx);
18253 gen_helper_cmpu_lt_ob(v1_t, v2_t, cpu_env);
18254 break;
18255 case OPC_CMPU_LE_OB:
18256 check_dsp(ctx);
18257 gen_helper_cmpu_le_ob(v1_t, v2_t, cpu_env);
18258 break;
18259 case OPC_PACKRL_PW:
18260 check_dsp(ctx);
18261 gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t);
18262 break;
18263 case OPC_PICK_OB:
18264 check_dsp(ctx);
18265 gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
18266 break;
18267 case OPC_PICK_PW:
18268 check_dsp(ctx);
18269 gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
18270 break;
18271 case OPC_PICK_QH:
18272 check_dsp(ctx);
18273 gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
18274 break;
18275 }
18276 break;
df6126a7
AJ
18277#endif
18278 }
18279
18280 tcg_temp_free(t1);
18281 tcg_temp_free(v1_t);
18282 tcg_temp_free(v2_t);
df6126a7
AJ
18283}
18284
18285static void gen_mipsdsp_append(CPUMIPSState *env, DisasContext *ctx,
18286 uint32_t op1, int rt, int rs, int sa)
18287{
df6126a7
AJ
18288 TCGv t0;
18289
18290 check_dspr2(ctx);
18291
18292 if (rt == 0) {
18293 /* Treat as NOP. */
df6126a7
AJ
18294 return;
18295 }
18296
18297 t0 = tcg_temp_new();
18298 gen_load_gpr(t0, rs);
18299
18300 switch (op1) {
18301 case OPC_APPEND_DSP:
18302 switch (MASK_APPEND(ctx->opcode)) {
18303 case OPC_APPEND:
18304 if (sa != 0) {
18305 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 32 - sa);
18306 }
18307 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
18308 break;
18309 case OPC_PREPEND:
18310 if (sa != 0) {
18311 tcg_gen_ext32u_tl(cpu_gpr[rt], cpu_gpr[rt]);
18312 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
18313 tcg_gen_shli_tl(t0, t0, 32 - sa);
18314 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
18315 }
18316 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
18317 break;
18318 case OPC_BALIGN:
18319 sa &= 3;
18320 if (sa != 0 && sa != 2) {
18321 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
18322 tcg_gen_ext32u_tl(t0, t0);
18323 tcg_gen_shri_tl(t0, t0, 8 * (4 - sa));
18324 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
18325 }
18326 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
18327 break;
18328 default: /* Invalid */
18329 MIPS_INVAL("MASK APPEND");
9c708c7f 18330 generate_exception_end(ctx, EXCP_RI);
df6126a7
AJ
18331 break;
18332 }
18333 break;
18334#ifdef TARGET_MIPS64
26690560 18335 case OPC_DAPPEND_DSP:
df6126a7 18336 switch (MASK_DAPPEND(ctx->opcode)) {
26690560 18337 case OPC_DAPPEND:
df6126a7
AJ
18338 if (sa != 0) {
18339 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 64 - sa);
18340 }
26690560
JL
18341 break;
18342 case OPC_PREPENDD:
df6126a7
AJ
18343 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], 0x20 | sa);
18344 tcg_gen_shli_tl(t0, t0, 64 - (0x20 | sa));
18345 tcg_gen_or_tl(cpu_gpr[rt], t0, t0);
26690560
JL
18346 break;
18347 case OPC_PREPENDW:
df6126a7
AJ
18348 if (sa != 0) {
18349 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
18350 tcg_gen_shli_tl(t0, t0, 64 - sa);
18351 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
18352 }
26690560
JL
18353 break;
18354 case OPC_DBALIGN:
df6126a7
AJ
18355 sa &= 7;
18356 if (sa != 0 && sa != 2 && sa != 4) {
18357 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
18358 tcg_gen_shri_tl(t0, t0, 8 * (8 - sa));
18359 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
18360 }
26690560
JL
18361 break;
18362 default: /* Invalid */
18363 MIPS_INVAL("MASK DAPPEND");
9c708c7f 18364 generate_exception_end(ctx, EXCP_RI);
26690560
JL
18365 break;
18366 }
18367 break;
18368#endif
18369 }
df6126a7 18370 tcg_temp_free(t0);
26690560
JL
18371}
18372
b53371ed
JL
18373static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
18374 int ret, int v1, int v2, int check_ret)
18375
18376{
b53371ed
JL
18377 TCGv t0;
18378 TCGv t1;
18379 TCGv v1_t;
18380 TCGv v2_t;
18381 int16_t imm;
18382
18383 if ((ret == 0) && (check_ret == 1)) {
18384 /* Treat as NOP. */
b53371ed
JL
18385 return;
18386 }
18387
18388 t0 = tcg_temp_new();
18389 t1 = tcg_temp_new();
18390 v1_t = tcg_temp_new();
18391 v2_t = tcg_temp_new();
18392
18393 gen_load_gpr(v1_t, v1);
18394 gen_load_gpr(v2_t, v2);
18395
18396 switch (op1) {
18397 case OPC_EXTR_W_DSP:
18398 check_dsp(ctx);
18399 switch (op2) {
18400 case OPC_EXTR_W:
18401 tcg_gen_movi_tl(t0, v2);
18402 tcg_gen_movi_tl(t1, v1);
18403 gen_helper_extr_w(cpu_gpr[ret], t0, t1, cpu_env);
18404 break;
18405 case OPC_EXTR_R_W:
18406 tcg_gen_movi_tl(t0, v2);
18407 tcg_gen_movi_tl(t1, v1);
18408 gen_helper_extr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
18409 break;
18410 case OPC_EXTR_RS_W:
18411 tcg_gen_movi_tl(t0, v2);
18412 tcg_gen_movi_tl(t1, v1);
18413 gen_helper_extr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
18414 break;
18415 case OPC_EXTR_S_H:
18416 tcg_gen_movi_tl(t0, v2);
18417 tcg_gen_movi_tl(t1, v1);
18418 gen_helper_extr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
18419 break;
18420 case OPC_EXTRV_S_H:
18421 tcg_gen_movi_tl(t0, v2);
18422 gen_helper_extr_s_h(cpu_gpr[ret], t0, v1_t, cpu_env);
18423 break;
18424 case OPC_EXTRV_W:
18425 tcg_gen_movi_tl(t0, v2);
18426 gen_helper_extr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
18427 break;
18428 case OPC_EXTRV_R_W:
18429 tcg_gen_movi_tl(t0, v2);
18430 gen_helper_extr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
18431 break;
18432 case OPC_EXTRV_RS_W:
18433 tcg_gen_movi_tl(t0, v2);
18434 gen_helper_extr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
18435 break;
18436 case OPC_EXTP:
18437 tcg_gen_movi_tl(t0, v2);
18438 tcg_gen_movi_tl(t1, v1);
18439 gen_helper_extp(cpu_gpr[ret], t0, t1, cpu_env);
18440 break;
18441 case OPC_EXTPV:
18442 tcg_gen_movi_tl(t0, v2);
18443 gen_helper_extp(cpu_gpr[ret], t0, v1_t, cpu_env);
18444 break;
18445 case OPC_EXTPDP:
18446 tcg_gen_movi_tl(t0, v2);
18447 tcg_gen_movi_tl(t1, v1);
18448 gen_helper_extpdp(cpu_gpr[ret], t0, t1, cpu_env);
18449 break;
18450 case OPC_EXTPDPV:
18451 tcg_gen_movi_tl(t0, v2);
18452 gen_helper_extpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
18453 break;
18454 case OPC_SHILO:
18455 imm = (ctx->opcode >> 20) & 0x3F;
18456 tcg_gen_movi_tl(t0, ret);
18457 tcg_gen_movi_tl(t1, imm);
18458 gen_helper_shilo(t0, t1, cpu_env);
18459 break;
18460 case OPC_SHILOV:
18461 tcg_gen_movi_tl(t0, ret);
18462 gen_helper_shilo(t0, v1_t, cpu_env);
18463 break;
18464 case OPC_MTHLIP:
18465 tcg_gen_movi_tl(t0, ret);
18466 gen_helper_mthlip(t0, v1_t, cpu_env);
18467 break;
18468 case OPC_WRDSP:
18469 imm = (ctx->opcode >> 11) & 0x3FF;
18470 tcg_gen_movi_tl(t0, imm);
18471 gen_helper_wrdsp(v1_t, t0, cpu_env);
18472 break;
18473 case OPC_RDDSP:
18474 imm = (ctx->opcode >> 16) & 0x03FF;
18475 tcg_gen_movi_tl(t0, imm);
18476 gen_helper_rddsp(cpu_gpr[ret], t0, cpu_env);
18477 break;
18478 }
18479 break;
18480#ifdef TARGET_MIPS64
18481 case OPC_DEXTR_W_DSP:
18482 check_dsp(ctx);
18483 switch (op2) {
18484 case OPC_DMTHLIP:
18485 tcg_gen_movi_tl(t0, ret);
18486 gen_helper_dmthlip(v1_t, t0, cpu_env);
18487 break;
18488 case OPC_DSHILO:
18489 {
18490 int shift = (ctx->opcode >> 19) & 0x7F;
18491 int ac = (ctx->opcode >> 11) & 0x03;
18492 tcg_gen_movi_tl(t0, shift);
18493 tcg_gen_movi_tl(t1, ac);
18494 gen_helper_dshilo(t0, t1, cpu_env);
18495 break;
18496 }
18497 case OPC_DSHILOV:
18498 {
18499 int ac = (ctx->opcode >> 11) & 0x03;
18500 tcg_gen_movi_tl(t0, ac);
18501 gen_helper_dshilo(v1_t, t0, cpu_env);
18502 break;
18503 }
18504 case OPC_DEXTP:
18505 tcg_gen_movi_tl(t0, v2);
18506 tcg_gen_movi_tl(t1, v1);
18507
18508 gen_helper_dextp(cpu_gpr[ret], t0, t1, cpu_env);
18509 break;
18510 case OPC_DEXTPV:
18511 tcg_gen_movi_tl(t0, v2);
18512 gen_helper_dextp(cpu_gpr[ret], t0, v1_t, cpu_env);
18513 break;
18514 case OPC_DEXTPDP:
18515 tcg_gen_movi_tl(t0, v2);
18516 tcg_gen_movi_tl(t1, v1);
18517 gen_helper_dextpdp(cpu_gpr[ret], t0, t1, cpu_env);
18518 break;
18519 case OPC_DEXTPDPV:
18520 tcg_gen_movi_tl(t0, v2);
18521 gen_helper_dextpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
18522 break;
18523 case OPC_DEXTR_L:
18524 tcg_gen_movi_tl(t0, v2);
18525 tcg_gen_movi_tl(t1, v1);
18526 gen_helper_dextr_l(cpu_gpr[ret], t0, t1, cpu_env);
18527 break;
18528 case OPC_DEXTR_R_L:
18529 tcg_gen_movi_tl(t0, v2);
18530 tcg_gen_movi_tl(t1, v1);
18531 gen_helper_dextr_r_l(cpu_gpr[ret], t0, t1, cpu_env);
18532 break;
18533 case OPC_DEXTR_RS_L:
18534 tcg_gen_movi_tl(t0, v2);
18535 tcg_gen_movi_tl(t1, v1);
18536 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, t1, cpu_env);
18537 break;
18538 case OPC_DEXTR_W:
18539 tcg_gen_movi_tl(t0, v2);
18540 tcg_gen_movi_tl(t1, v1);
18541 gen_helper_dextr_w(cpu_gpr[ret], t0, t1, cpu_env);
18542 break;
18543 case OPC_DEXTR_R_W:
18544 tcg_gen_movi_tl(t0, v2);
18545 tcg_gen_movi_tl(t1, v1);
18546 gen_helper_dextr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
18547 break;
18548 case OPC_DEXTR_RS_W:
18549 tcg_gen_movi_tl(t0, v2);
18550 tcg_gen_movi_tl(t1, v1);
18551 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
18552 break;
18553 case OPC_DEXTR_S_H:
18554 tcg_gen_movi_tl(t0, v2);
18555 tcg_gen_movi_tl(t1, v1);
18556 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
18557 break;
18558 case OPC_DEXTRV_S_H:
18559 tcg_gen_movi_tl(t0, v2);
18560 tcg_gen_movi_tl(t1, v1);
18561 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
18562 break;
18563 case OPC_DEXTRV_L:
18564 tcg_gen_movi_tl(t0, v2);
18565 gen_helper_dextr_l(cpu_gpr[ret], t0, v1_t, cpu_env);
18566 break;
18567 case OPC_DEXTRV_R_L:
18568 tcg_gen_movi_tl(t0, v2);
18569 gen_helper_dextr_r_l(cpu_gpr[ret], t0, v1_t, cpu_env);
18570 break;
18571 case OPC_DEXTRV_RS_L:
18572 tcg_gen_movi_tl(t0, v2);
18573 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, v1_t, cpu_env);
18574 break;
18575 case OPC_DEXTRV_W:
18576 tcg_gen_movi_tl(t0, v2);
18577 gen_helper_dextr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
18578 break;
18579 case OPC_DEXTRV_R_W:
18580 tcg_gen_movi_tl(t0, v2);
18581 gen_helper_dextr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
18582 break;
18583 case OPC_DEXTRV_RS_W:
18584 tcg_gen_movi_tl(t0, v2);
18585 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
18586 break;
18587 }
18588 break;
18589#endif
18590 }
18591
18592 tcg_temp_free(t0);
18593 tcg_temp_free(t1);
18594 tcg_temp_free(v1_t);
18595 tcg_temp_free(v2_t);
b53371ed
JL
18596}
18597
9b1a1d68
JL
18598/* End MIPSDSP functions. */
18599
10dc65db
LA
18600static void decode_opc_special_r6(CPUMIPSState *env, DisasContext *ctx)
18601{
4267d3e6 18602 int rs, rt, rd, sa;
b42ee5e1 18603 uint32_t op1, op2;
10dc65db
LA
18604
18605 rs = (ctx->opcode >> 21) & 0x1f;
18606 rt = (ctx->opcode >> 16) & 0x1f;
18607 rd = (ctx->opcode >> 11) & 0x1f;
4267d3e6 18608 sa = (ctx->opcode >> 6) & 0x1f;
10dc65db
LA
18609
18610 op1 = MASK_SPECIAL(ctx->opcode);
18611 switch (op1) {
d4ea6acd 18612 case OPC_LSA:
1f1b4c00 18613 gen_lsa(ctx, op1, rd, rs, rt, extract32(ctx->opcode, 6, 2));
d4ea6acd 18614 break;
c2e19f3c
AM
18615 case OPC_MULT:
18616 case OPC_MULTU:
18617 case OPC_DIV:
18618 case OPC_DIVU:
b42ee5e1
LA
18619 op2 = MASK_R6_MULDIV(ctx->opcode);
18620 switch (op2) {
18621 case R6_OPC_MUL:
18622 case R6_OPC_MUH:
18623 case R6_OPC_MULU:
18624 case R6_OPC_MUHU:
18625 case R6_OPC_DIV:
18626 case R6_OPC_MOD:
18627 case R6_OPC_DIVU:
18628 case R6_OPC_MODU:
18629 gen_r6_muldiv(ctx, op2, rd, rs, rt);
18630 break;
18631 default:
18632 MIPS_INVAL("special_r6 muldiv");
9c708c7f 18633 generate_exception_end(ctx, EXCP_RI);
b42ee5e1
LA
18634 break;
18635 }
18636 break;
10dc65db
LA
18637 case OPC_SELEQZ:
18638 case OPC_SELNEZ:
18639 gen_cond_move(ctx, op1, rd, rs, rt);
18640 break;
4267d3e6
LA
18641 case R6_OPC_CLO:
18642 case R6_OPC_CLZ:
18643 if (rt == 0 && sa == 1) {
18644 /* Major opcode and function field is shared with preR6 MFHI/MTHI.
18645 We need additionally to check other fields */
18646 gen_cl(ctx, op1, rd, rs);
18647 } else {
9c708c7f 18648 generate_exception_end(ctx, EXCP_RI);
4267d3e6
LA
18649 }
18650 break;
18651 case R6_OPC_SDBBP:
3b3c1694
LA
18652 if (is_uhi(extract32(ctx->opcode, 6, 20))) {
18653 gen_helper_do_semihosting(cpu_env);
faf1f68b 18654 } else {
3b3c1694 18655 if (ctx->hflags & MIPS_HFLAG_SBRI) {
9c708c7f 18656 generate_exception_end(ctx, EXCP_RI);
3b3c1694 18657 } else {
9c708c7f 18658 generate_exception_end(ctx, EXCP_DBp);
3b3c1694 18659 }
faf1f68b 18660 }
4267d3e6 18661 break;
b42ee5e1 18662#if defined(TARGET_MIPS64)
d4ea6acd
LA
18663 case OPC_DLSA:
18664 check_mips_64(ctx);
1f1b4c00 18665 gen_lsa(ctx, op1, rd, rs, rt, extract32(ctx->opcode, 6, 2));
d4ea6acd 18666 break;
4267d3e6
LA
18667 case R6_OPC_DCLO:
18668 case R6_OPC_DCLZ:
18669 if (rt == 0 && sa == 1) {
18670 /* Major opcode and function field is shared with preR6 MFHI/MTHI.
18671 We need additionally to check other fields */
18672 check_mips_64(ctx);
18673 gen_cl(ctx, op1, rd, rs);
18674 } else {
9c708c7f 18675 generate_exception_end(ctx, EXCP_RI);
4267d3e6
LA
18676 }
18677 break;
c2e19f3c
AM
18678 case OPC_DMULT:
18679 case OPC_DMULTU:
18680 case OPC_DDIV:
18681 case OPC_DDIVU:
18682
b42ee5e1
LA
18683 op2 = MASK_R6_MULDIV(ctx->opcode);
18684 switch (op2) {
18685 case R6_OPC_DMUL:
18686 case R6_OPC_DMUH:
18687 case R6_OPC_DMULU:
18688 case R6_OPC_DMUHU:
18689 case R6_OPC_DDIV:
18690 case R6_OPC_DMOD:
18691 case R6_OPC_DDIVU:
18692 case R6_OPC_DMODU:
18693 check_mips_64(ctx);
18694 gen_r6_muldiv(ctx, op2, rd, rs, rt);
18695 break;
18696 default:
18697 MIPS_INVAL("special_r6 muldiv");
9c708c7f 18698 generate_exception_end(ctx, EXCP_RI);
b42ee5e1
LA
18699 break;
18700 }
18701 break;
18702#endif
10dc65db
LA
18703 default: /* Invalid */
18704 MIPS_INVAL("special_r6");
9c708c7f 18705 generate_exception_end(ctx, EXCP_RI);
10dc65db
LA
18706 break;
18707 }
18708}
18709
18710static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx)
18711{
b42ee5e1 18712 int rs, rt, rd, sa;
10dc65db
LA
18713 uint32_t op1;
18714
18715 rs = (ctx->opcode >> 21) & 0x1f;
18716 rt = (ctx->opcode >> 16) & 0x1f;
18717 rd = (ctx->opcode >> 11) & 0x1f;
b42ee5e1 18718 sa = (ctx->opcode >> 6) & 0x1f;
10dc65db
LA
18719
18720 op1 = MASK_SPECIAL(ctx->opcode);
18721 switch (op1) {
18722 case OPC_MOVN: /* Conditional move */
18723 case OPC_MOVZ:
18724 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32 |
18725 INSN_LOONGSON2E | INSN_LOONGSON2F);
18726 gen_cond_move(ctx, op1, rd, rs, rt);
18727 break;
18728 case OPC_MFHI: /* Move from HI/LO */
18729 case OPC_MFLO:
18730 gen_HILO(ctx, op1, rs & 3, rd);
18731 break;
18732 case OPC_MTHI:
18733 case OPC_MTLO: /* Move to HI/LO */
18734 gen_HILO(ctx, op1, rd & 3, rs);
18735 break;
18736 case OPC_MOVCI:
18737 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
18738 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
18739 check_cp1_enabled(ctx);
18740 gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
18741 (ctx->opcode >> 16) & 1);
18742 } else {
18743 generate_exception_err(ctx, EXCP_CpU, 1);
18744 }
18745 break;
b42ee5e1
LA
18746 case OPC_MULT:
18747 case OPC_MULTU:
18748 if (sa) {
18749 check_insn(ctx, INSN_VR54XX);
18750 op1 = MASK_MUL_VR54XX(ctx->opcode);
18751 gen_mul_vr54xx(ctx, op1, rd, rs, rt);
18752 } else {
18753 gen_muldiv(ctx, op1, rd & 3, rs, rt);
18754 }
18755 break;
18756 case OPC_DIV:
18757 case OPC_DIVU:
18758 gen_muldiv(ctx, op1, 0, rs, rt);
18759 break;
18760#if defined(TARGET_MIPS64)
c2e19f3c
AM
18761 case OPC_DMULT:
18762 case OPC_DMULTU:
18763 case OPC_DDIV:
18764 case OPC_DDIVU:
b42ee5e1
LA
18765 check_insn(ctx, ISA_MIPS3);
18766 check_mips_64(ctx);
18767 gen_muldiv(ctx, op1, 0, rs, rt);
18768 break;
18769#endif
0aefa333 18770 case OPC_JR:
b231c103 18771 gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
0aefa333 18772 break;
4267d3e6
LA
18773 case OPC_SPIM:
18774#ifdef MIPS_STRICT_STANDARD
18775 MIPS_INVAL("SPIM");
9c708c7f 18776 generate_exception_end(ctx, EXCP_RI);
4267d3e6
LA
18777#else
18778 /* Implemented as RI exception for now. */
18779 MIPS_INVAL("spim (unofficial)");
9c708c7f 18780 generate_exception_end(ctx, EXCP_RI);
4267d3e6
LA
18781#endif
18782 break;
10dc65db
LA
18783 default: /* Invalid */
18784 MIPS_INVAL("special_legacy");
9c708c7f 18785 generate_exception_end(ctx, EXCP_RI);
10dc65db
LA
18786 break;
18787 }
18788}
18789
099e5b4d 18790static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx)
3c824109 18791{
3c824109 18792 int rs, rt, rd, sa;
099e5b4d 18793 uint32_t op1;
3c824109 18794
3c824109
NF
18795 rs = (ctx->opcode >> 21) & 0x1f;
18796 rt = (ctx->opcode >> 16) & 0x1f;
18797 rd = (ctx->opcode >> 11) & 0x1f;
18798 sa = (ctx->opcode >> 6) & 0x1f;
099e5b4d
LA
18799
18800 op1 = MASK_SPECIAL(ctx->opcode);
18801 switch (op1) {
18802 case OPC_SLL: /* Shift with immediate */
339cd2a8
LA
18803 if (sa == 5 && rd == 0 &&
18804 rs == 0 && rt == 0) { /* PAUSE */
18805 if ((ctx->insn_flags & ISA_MIPS32R6) &&
18806 (ctx->hflags & MIPS_HFLAG_BMASK)) {
9c708c7f 18807 generate_exception_end(ctx, EXCP_RI);
339cd2a8
LA
18808 break;
18809 }
18810 }
18811 /* Fallthrough */
099e5b4d
LA
18812 case OPC_SRA:
18813 gen_shift_imm(ctx, op1, rd, rt, sa);
18814 break;
18815 case OPC_SRL:
18816 switch ((ctx->opcode >> 21) & 0x1f) {
18817 case 1:
18818 /* rotr is decoded as srl on non-R2 CPUs */
18819 if (ctx->insn_flags & ISA_MIPS32R2) {
18820 op1 = OPC_ROTR;
ea63e2c3 18821 }
099e5b4d
LA
18822 /* Fallthrough */
18823 case 0:
18824 gen_shift_imm(ctx, op1, rd, rt, sa);
ea63e2c3 18825 break;
099e5b4d 18826 default:
9c708c7f 18827 generate_exception_end(ctx, EXCP_RI);
ea63e2c3 18828 break;
099e5b4d
LA
18829 }
18830 break;
c2e19f3c
AM
18831 case OPC_ADD:
18832 case OPC_ADDU:
18833 case OPC_SUB:
18834 case OPC_SUBU:
099e5b4d
LA
18835 gen_arith(ctx, op1, rd, rs, rt);
18836 break;
18837 case OPC_SLLV: /* Shifts */
18838 case OPC_SRAV:
18839 gen_shift(ctx, op1, rd, rs, rt);
18840 break;
18841 case OPC_SRLV:
18842 switch ((ctx->opcode >> 6) & 0x1f) {
18843 case 1:
18844 /* rotrv is decoded as srlv on non-R2 CPUs */
18845 if (ctx->insn_flags & ISA_MIPS32R2) {
18846 op1 = OPC_ROTRV;
26135ead 18847 }
099e5b4d
LA
18848 /* Fallthrough */
18849 case 0:
18850 gen_shift(ctx, op1, rd, rs, rt);
26135ead 18851 break;
099e5b4d 18852 default:
9c708c7f 18853 generate_exception_end(ctx, EXCP_RI);
6af0bf9c 18854 break;
099e5b4d
LA
18855 }
18856 break;
18857 case OPC_SLT: /* Set on less than */
18858 case OPC_SLTU:
18859 gen_slt(ctx, op1, rd, rs, rt);
18860 break;
18861 case OPC_AND: /* Logic*/
18862 case OPC_OR:
18863 case OPC_NOR:
18864 case OPC_XOR:
18865 gen_logic(ctx, op1, rd, rs, rt);
18866 break;
0aefa333 18867 case OPC_JALR:
b231c103 18868 gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
099e5b4d 18869 break;
c2e19f3c
AM
18870 case OPC_TGE: /* Traps */
18871 case OPC_TGEU:
18872 case OPC_TLT:
18873 case OPC_TLTU:
18874 case OPC_TEQ:
099e5b4d 18875 case OPC_TNE:
d9224450 18876 check_insn(ctx, ISA_MIPS2);
099e5b4d
LA
18877 gen_trap(ctx, op1, rs, rt, -1);
18878 break;
d4ea6acd 18879 case OPC_LSA: /* OPC_PMON */
f7685877
YK
18880 if ((ctx->insn_flags & ISA_MIPS32R6) ||
18881 (env->CP0_Config3 & (1 << CP0C3_MSAP))) {
d4ea6acd
LA
18882 decode_opc_special_r6(env, ctx);
18883 } else {
18884 /* Pmon entry point, also R4010 selsl */
b48cfdff 18885#ifdef MIPS_STRICT_STANDARD
d4ea6acd 18886 MIPS_INVAL("PMON / selsl");
9c708c7f 18887 generate_exception_end(ctx, EXCP_RI);
b48cfdff 18888#else
d4ea6acd 18889 gen_helper_0e0i(pmon, sa);
b48cfdff 18890#endif
d4ea6acd 18891 }
099e5b4d
LA
18892 break;
18893 case OPC_SYSCALL:
9c708c7f 18894 generate_exception_end(ctx, EXCP_SYSCALL);
099e5b4d
LA
18895 break;
18896 case OPC_BREAK:
9c708c7f 18897 generate_exception_end(ctx, EXCP_BREAK);
099e5b4d 18898 break;
099e5b4d 18899 case OPC_SYNC:
d9224450 18900 check_insn(ctx, ISA_MIPS2);
d208ac0c 18901 gen_sync(extract32(ctx->opcode, 6, 5));
099e5b4d 18902 break;
4ad40f36 18903
d26bc211 18904#if defined(TARGET_MIPS64)
099e5b4d
LA
18905 /* MIPS64 specific opcodes */
18906 case OPC_DSLL:
18907 case OPC_DSRA:
18908 case OPC_DSLL32:
18909 case OPC_DSRA32:
18910 check_insn(ctx, ISA_MIPS3);
18911 check_mips_64(ctx);
18912 gen_shift_imm(ctx, op1, rd, rt, sa);
18913 break;
18914 case OPC_DSRL:
18915 switch ((ctx->opcode >> 21) & 0x1f) {
18916 case 1:
18917 /* drotr is decoded as dsrl on non-R2 CPUs */
18918 if (ctx->insn_flags & ISA_MIPS32R2) {
18919 op1 = OPC_DROTR;
ea63e2c3 18920 }
099e5b4d
LA
18921 /* Fallthrough */
18922 case 0:
d75c135e 18923 check_insn(ctx, ISA_MIPS3);
e189e748 18924 check_mips_64(ctx);
099e5b4d 18925 gen_shift_imm(ctx, op1, rd, rt, sa);
7a387fff 18926 break;
099e5b4d 18927 default:
9c708c7f 18928 generate_exception_end(ctx, EXCP_RI);
460f00c4 18929 break;
099e5b4d
LA
18930 }
18931 break;
18932 case OPC_DSRL32:
18933 switch ((ctx->opcode >> 21) & 0x1f) {
18934 case 1:
18935 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
18936 if (ctx->insn_flags & ISA_MIPS32R2) {
18937 op1 = OPC_DROTR32;
ea63e2c3 18938 }
099e5b4d
LA
18939 /* Fallthrough */
18940 case 0:
d75c135e 18941 check_insn(ctx, ISA_MIPS3);
e189e748 18942 check_mips_64(ctx);
099e5b4d 18943 gen_shift_imm(ctx, op1, rd, rt, sa);
7a387fff 18944 break;
099e5b4d 18945 default:
9c708c7f 18946 generate_exception_end(ctx, EXCP_RI);
6af0bf9c
FB
18947 break;
18948 }
18949 break;
c2e19f3c
AM
18950 case OPC_DADD:
18951 case OPC_DADDU:
18952 case OPC_DSUB:
18953 case OPC_DSUBU:
099e5b4d
LA
18954 check_insn(ctx, ISA_MIPS3);
18955 check_mips_64(ctx);
18956 gen_arith(ctx, op1, rd, rs, rt);
18957 break;
18958 case OPC_DSLLV:
18959 case OPC_DSRAV:
18960 check_insn(ctx, ISA_MIPS3);
18961 check_mips_64(ctx);
18962 gen_shift(ctx, op1, rd, rs, rt);
18963 break;
18964 case OPC_DSRLV:
18965 switch ((ctx->opcode >> 6) & 0x1f) {
18966 case 1:
18967 /* drotrv is decoded as dsrlv on non-R2 CPUs */
18968 if (ctx->insn_flags & ISA_MIPS32R2) {
18969 op1 = OPC_DROTRV;
6af0bf9c 18970 }
099e5b4d
LA
18971 /* Fallthrough */
18972 case 0:
18973 check_insn(ctx, ISA_MIPS3);
e189e748 18974 check_mips_64(ctx);
099e5b4d 18975 gen_shift(ctx, op1, rd, rs, rt);
161f85e6 18976 break;
099e5b4d 18977 default:
9c708c7f 18978 generate_exception_end(ctx, EXCP_RI);
6af0bf9c
FB
18979 break;
18980 }
18981 break;
f7685877
YK
18982 case OPC_DLSA:
18983 if ((ctx->insn_flags & ISA_MIPS32R6) ||
18984 (env->CP0_Config3 & (1 << CP0C3_MSAP))) {
18985 decode_opc_special_r6(env, ctx);
18986 }
18987 break;
099e5b4d 18988#endif
10dc65db
LA
18989 default:
18990 if (ctx->insn_flags & ISA_MIPS32R6) {
18991 decode_opc_special_r6(env, ctx);
18992 } else {
18993 decode_opc_special_legacy(env, ctx);
18994 }
18995 }
18996}
18997
10dc65db 18998static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx)
099e5b4d
LA
18999{
19000 int rs, rt, rd;
19001 uint32_t op1;
6c5c1e20 19002
4267d3e6
LA
19003 check_insn_opc_removed(ctx, ISA_MIPS32R6);
19004
099e5b4d
LA
19005 rs = (ctx->opcode >> 21) & 0x1f;
19006 rt = (ctx->opcode >> 16) & 0x1f;
19007 rd = (ctx->opcode >> 11) & 0x1f;
19008
19009 op1 = MASK_SPECIAL2(ctx->opcode);
19010 switch (op1) {
c2e19f3c
AM
19011 case OPC_MADD: /* Multiply and add/sub */
19012 case OPC_MADDU:
19013 case OPC_MSUB:
19014 case OPC_MSUBU:
099e5b4d
LA
19015 check_insn(ctx, ISA_MIPS32);
19016 gen_muldiv(ctx, op1, rd & 3, rs, rt);
19017 break;
19018 case OPC_MUL:
099e5b4d
LA
19019 gen_arith(ctx, op1, rd, rs, rt);
19020 break;
fac5a073
LA
19021 case OPC_DIV_G_2F:
19022 case OPC_DIVU_G_2F:
19023 case OPC_MULT_G_2F:
19024 case OPC_MULTU_G_2F:
19025 case OPC_MOD_G_2F:
19026 case OPC_MODU_G_2F:
19027 check_insn(ctx, INSN_LOONGSON2F);
19028 gen_loongson_integer(ctx, op1, rd, rs, rt);
19029 break;
099e5b4d
LA
19030 case OPC_CLO:
19031 case OPC_CLZ:
19032 check_insn(ctx, ISA_MIPS32);
19033 gen_cl(ctx, op1, rd, rs);
19034 break;
19035 case OPC_SDBBP:
3b3c1694
LA
19036 if (is_uhi(extract32(ctx->opcode, 6, 20))) {
19037 gen_helper_do_semihosting(cpu_env);
19038 } else {
19039 /* XXX: not clear which exception should be raised
19040 * when in debug mode...
19041 */
19042 check_insn(ctx, ISA_MIPS32);
9c708c7f 19043 generate_exception_end(ctx, EXCP_DBp);
3b3c1694 19044 }
099e5b4d 19045 break;
9b1a1d68 19046#if defined(TARGET_MIPS64)
099e5b4d
LA
19047 case OPC_DCLO:
19048 case OPC_DCLZ:
19049 check_insn(ctx, ISA_MIPS64);
19050 check_mips_64(ctx);
19051 gen_cl(ctx, op1, rd, rs);
19052 break;
4267d3e6
LA
19053 case OPC_DMULT_G_2F:
19054 case OPC_DMULTU_G_2F:
19055 case OPC_DDIV_G_2F:
19056 case OPC_DDIVU_G_2F:
19057 case OPC_DMOD_G_2F:
19058 case OPC_DMODU_G_2F:
19059 check_insn(ctx, INSN_LOONGSON2F);
19060 gen_loongson_integer(ctx, op1, rd, rs, rt);
19061 break;
10dc65db 19062#endif
4267d3e6
LA
19063 default: /* Invalid */
19064 MIPS_INVAL("special2_legacy");
9c708c7f 19065 generate_exception_end(ctx, EXCP_RI);
4267d3e6 19066 break;
10dc65db
LA
19067 }
19068}
19069
19070static void decode_opc_special3_r6(CPUMIPSState *env, DisasContext *ctx)
19071{
15eacb9b
YK
19072 int rs, rt, rd, sa;
19073 uint32_t op1, op2;
10dc65db
LA
19074 int16_t imm;
19075
19076 rs = (ctx->opcode >> 21) & 0x1f;
19077 rt = (ctx->opcode >> 16) & 0x1f;
15eacb9b
YK
19078 rd = (ctx->opcode >> 11) & 0x1f;
19079 sa = (ctx->opcode >> 6) & 0x1f;
10dc65db
LA
19080 imm = (int16_t)ctx->opcode >> 7;
19081
19082 op1 = MASK_SPECIAL3(ctx->opcode);
19083 switch (op1) {
bf7910c6
LA
19084 case R6_OPC_PREF:
19085 if (rt >= 24) {
19086 /* hint codes 24-31 are reserved and signal RI */
9c708c7f 19087 generate_exception_end(ctx, EXCP_RI);
bf7910c6
LA
19088 }
19089 /* Treat as NOP. */
19090 break;
19091 case R6_OPC_CACHE:
40d48212 19092 check_cp0_enabled(ctx);
0d74a222
LA
19093 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
19094 gen_cache_operation(ctx, rt, rs, imm);
19095 }
bf7910c6 19096 break;
10dc65db
LA
19097 case R6_OPC_SC:
19098 gen_st_cond(ctx, op1, rt, rs, imm);
19099 break;
19100 case R6_OPC_LL:
19101 gen_ld(ctx, op1, rt, rs, imm);
19102 break;
15eacb9b
YK
19103 case OPC_BSHFL:
19104 {
19105 if (rd == 0) {
19106 /* Treat as NOP. */
19107 break;
19108 }
15eacb9b
YK
19109 op2 = MASK_BSHFL(ctx->opcode);
19110 switch (op2) {
c2e19f3c
AM
19111 case OPC_ALIGN:
19112 case OPC_ALIGN_END:
1f1b4c00 19113 gen_align(ctx, OPC_ALIGN, rd, rs, rt, sa & 3);
15eacb9b
YK
19114 break;
19115 case OPC_BITSWAP:
1f1b4c00 19116 gen_bitswap(ctx, op2, rd, rt);
15eacb9b
YK
19117 break;
19118 }
15eacb9b
YK
19119 }
19120 break;
bf7910c6
LA
19121#if defined(TARGET_MIPS64)
19122 case R6_OPC_SCD:
19123 gen_st_cond(ctx, op1, rt, rs, imm);
19124 break;
19125 case R6_OPC_LLD:
19126 gen_ld(ctx, op1, rt, rs, imm);
19127 break;
15eacb9b
YK
19128 case OPC_DBSHFL:
19129 check_mips_64(ctx);
19130 {
19131 if (rd == 0) {
19132 /* Treat as NOP. */
19133 break;
19134 }
15eacb9b
YK
19135 op2 = MASK_DBSHFL(ctx->opcode);
19136 switch (op2) {
c2e19f3c
AM
19137 case OPC_DALIGN:
19138 case OPC_DALIGN_END:
1f1b4c00 19139 gen_align(ctx, OPC_DALIGN, rd, rs, rt, sa & 7);
15eacb9b
YK
19140 break;
19141 case OPC_DBITSWAP:
1f1b4c00 19142 gen_bitswap(ctx, op2, rd, rt);
15eacb9b
YK
19143 break;
19144 }
1f1b4c00 19145
15eacb9b
YK
19146 }
19147 break;
bf7910c6 19148#endif
10dc65db
LA
19149 default: /* Invalid */
19150 MIPS_INVAL("special3_r6");
9c708c7f 19151 generate_exception_end(ctx, EXCP_RI);
10dc65db
LA
19152 break;
19153 }
19154}
19155
19156static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx)
19157{
fac5a073 19158 int rs, rt, rd;
099e5b4d 19159 uint32_t op1, op2;
099e5b4d
LA
19160
19161 rs = (ctx->opcode >> 21) & 0x1f;
19162 rt = (ctx->opcode >> 16) & 0x1f;
19163 rd = (ctx->opcode >> 11) & 0x1f;
099e5b4d
LA
19164
19165 op1 = MASK_SPECIAL3(ctx->opcode);
19166 switch (op1) {
c2e19f3c
AM
19167 case OPC_DIV_G_2E:
19168 case OPC_DIVU_G_2E:
19169 case OPC_MOD_G_2E:
19170 case OPC_MODU_G_2E:
19171 case OPC_MULT_G_2E:
19172 case OPC_MULTU_G_2E:
099e5b4d
LA
19173 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
19174 * the same mask and op1. */
19175 if ((ctx->insn_flags & ASE_DSPR2) && (op1 == OPC_MULT_G_2E)) {
19176 op2 = MASK_ADDUH_QB(ctx->opcode);
461c08df 19177 switch (op2) {
099e5b4d
LA
19178 case OPC_ADDUH_QB:
19179 case OPC_ADDUH_R_QB:
19180 case OPC_ADDQH_PH:
19181 case OPC_ADDQH_R_PH:
19182 case OPC_ADDQH_W:
19183 case OPC_ADDQH_R_W:
19184 case OPC_SUBUH_QB:
19185 case OPC_SUBUH_R_QB:
19186 case OPC_SUBQH_PH:
19187 case OPC_SUBQH_R_PH:
19188 case OPC_SUBQH_W:
19189 case OPC_SUBQH_R_W:
461c08df
JL
19190 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
19191 break;
099e5b4d
LA
19192 case OPC_MUL_PH:
19193 case OPC_MUL_S_PH:
19194 case OPC_MULQ_S_W:
19195 case OPC_MULQ_RS_W:
19196 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
1cb6686c 19197 break;
461c08df 19198 default:
099e5b4d 19199 MIPS_INVAL("MASK ADDUH.QB");
9c708c7f 19200 generate_exception_end(ctx, EXCP_RI);
461c08df
JL
19201 break;
19202 }
099e5b4d
LA
19203 } else if (ctx->insn_flags & INSN_LOONGSON2E) {
19204 gen_loongson_integer(ctx, op1, rd, rs, rt);
19205 } else {
9c708c7f 19206 generate_exception_end(ctx, EXCP_RI);
099e5b4d
LA
19207 }
19208 break;
19209 case OPC_LX_DSP:
19210 op2 = MASK_LX(ctx->opcode);
19211 switch (op2) {
19212#if defined(TARGET_MIPS64)
19213 case OPC_LDX:
19214#endif
19215 case OPC_LBUX:
19216 case OPC_LHX:
19217 case OPC_LWX:
19218 gen_mipsdsp_ld(ctx, op2, rd, rs, rt);
19219 break;
19220 default: /* Invalid */
19221 MIPS_INVAL("MASK LX");
9c708c7f 19222 generate_exception_end(ctx, EXCP_RI);
099e5b4d
LA
19223 break;
19224 }
19225 break;
19226 case OPC_ABSQ_S_PH_DSP:
19227 op2 = MASK_ABSQ_S_PH(ctx->opcode);
19228 switch (op2) {
19229 case OPC_ABSQ_S_QB:
19230 case OPC_ABSQ_S_PH:
19231 case OPC_ABSQ_S_W:
19232 case OPC_PRECEQ_W_PHL:
19233 case OPC_PRECEQ_W_PHR:
19234 case OPC_PRECEQU_PH_QBL:
19235 case OPC_PRECEQU_PH_QBR:
19236 case OPC_PRECEQU_PH_QBLA:
19237 case OPC_PRECEQU_PH_QBRA:
19238 case OPC_PRECEU_PH_QBL:
19239 case OPC_PRECEU_PH_QBR:
19240 case OPC_PRECEU_PH_QBLA:
19241 case OPC_PRECEU_PH_QBRA:
19242 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
19243 break;
19244 case OPC_BITREV:
19245 case OPC_REPL_QB:
19246 case OPC_REPLV_QB:
19247 case OPC_REPL_PH:
19248 case OPC_REPLV_PH:
19249 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
19250 break;
19251 default:
19252 MIPS_INVAL("MASK ABSQ_S.PH");
9c708c7f 19253 generate_exception_end(ctx, EXCP_RI);
099e5b4d
LA
19254 break;
19255 }
19256 break;
19257 case OPC_ADDU_QB_DSP:
19258 op2 = MASK_ADDU_QB(ctx->opcode);
19259 switch (op2) {
19260 case OPC_ADDQ_PH:
19261 case OPC_ADDQ_S_PH:
19262 case OPC_ADDQ_S_W:
19263 case OPC_ADDU_QB:
19264 case OPC_ADDU_S_QB:
19265 case OPC_ADDU_PH:
19266 case OPC_ADDU_S_PH:
19267 case OPC_SUBQ_PH:
19268 case OPC_SUBQ_S_PH:
19269 case OPC_SUBQ_S_W:
19270 case OPC_SUBU_QB:
19271 case OPC_SUBU_S_QB:
19272 case OPC_SUBU_PH:
19273 case OPC_SUBU_S_PH:
19274 case OPC_ADDSC:
19275 case OPC_ADDWC:
19276 case OPC_MODSUB:
19277 case OPC_RADDU_W_QB:
19278 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
19279 break;
19280 case OPC_MULEU_S_PH_QBL:
19281 case OPC_MULEU_S_PH_QBR:
19282 case OPC_MULQ_RS_PH:
19283 case OPC_MULEQ_S_W_PHL:
19284 case OPC_MULEQ_S_W_PHR:
19285 case OPC_MULQ_S_PH:
19286 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
19287 break;
19288 default: /* Invalid */
19289 MIPS_INVAL("MASK ADDU.QB");
9c708c7f 19290 generate_exception_end(ctx, EXCP_RI);
461c08df 19291 break;
461c08df 19292
099e5b4d
LA
19293 }
19294 break;
19295 case OPC_CMPU_EQ_QB_DSP:
19296 op2 = MASK_CMPU_EQ_QB(ctx->opcode);
19297 switch (op2) {
19298 case OPC_PRECR_SRA_PH_W:
19299 case OPC_PRECR_SRA_R_PH_W:
19300 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
461c08df 19301 break;
099e5b4d
LA
19302 case OPC_PRECR_QB_PH:
19303 case OPC_PRECRQ_QB_PH:
19304 case OPC_PRECRQ_PH_W:
19305 case OPC_PRECRQ_RS_PH_W:
19306 case OPC_PRECRQU_S_QB_PH:
19307 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
461c08df 19308 break;
099e5b4d
LA
19309 case OPC_CMPU_EQ_QB:
19310 case OPC_CMPU_LT_QB:
19311 case OPC_CMPU_LE_QB:
19312 case OPC_CMP_EQ_PH:
19313 case OPC_CMP_LT_PH:
19314 case OPC_CMP_LE_PH:
19315 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
77c5fa8b 19316 break;
099e5b4d
LA
19317 case OPC_CMPGU_EQ_QB:
19318 case OPC_CMPGU_LT_QB:
19319 case OPC_CMPGU_LE_QB:
19320 case OPC_CMPGDU_EQ_QB:
19321 case OPC_CMPGDU_LT_QB:
19322 case OPC_CMPGDU_LE_QB:
19323 case OPC_PICK_QB:
19324 case OPC_PICK_PH:
19325 case OPC_PACKRL_PH:
19326 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
19327 break;
19328 default: /* Invalid */
19329 MIPS_INVAL("MASK CMPU.EQ.QB");
9c708c7f 19330 generate_exception_end(ctx, EXCP_RI);
099e5b4d
LA
19331 break;
19332 }
19333 break;
19334 case OPC_SHLL_QB_DSP:
19335 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
19336 break;
19337 case OPC_DPA_W_PH_DSP:
19338 op2 = MASK_DPA_W_PH(ctx->opcode);
19339 switch (op2) {
19340 case OPC_DPAU_H_QBL:
19341 case OPC_DPAU_H_QBR:
19342 case OPC_DPSU_H_QBL:
19343 case OPC_DPSU_H_QBR:
19344 case OPC_DPA_W_PH:
19345 case OPC_DPAX_W_PH:
19346 case OPC_DPAQ_S_W_PH:
19347 case OPC_DPAQX_S_W_PH:
19348 case OPC_DPAQX_SA_W_PH:
19349 case OPC_DPS_W_PH:
19350 case OPC_DPSX_W_PH:
19351 case OPC_DPSQ_S_W_PH:
19352 case OPC_DPSQX_S_W_PH:
19353 case OPC_DPSQX_SA_W_PH:
19354 case OPC_MULSAQ_S_W_PH:
19355 case OPC_DPAQ_SA_L_W:
19356 case OPC_DPSQ_SA_L_W:
19357 case OPC_MAQ_S_W_PHL:
19358 case OPC_MAQ_S_W_PHR:
19359 case OPC_MAQ_SA_W_PHL:
19360 case OPC_MAQ_SA_W_PHR:
19361 case OPC_MULSA_W_PH:
19362 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
19363 break;
19364 default: /* Invalid */
19365 MIPS_INVAL("MASK DPAW.PH");
9c708c7f 19366 generate_exception_end(ctx, EXCP_RI);
099e5b4d
LA
19367 break;
19368 }
19369 break;
19370 case OPC_INSV_DSP:
19371 op2 = MASK_INSV(ctx->opcode);
19372 switch (op2) {
19373 case OPC_INSV:
19374 check_dsp(ctx);
19375 {
19376 TCGv t0, t1;
19377
19378 if (rt == 0) {
099e5b4d
LA
19379 break;
19380 }
19381
19382 t0 = tcg_temp_new();
19383 t1 = tcg_temp_new();
19384
19385 gen_load_gpr(t0, rt);
19386 gen_load_gpr(t1, rs);
19387
19388 gen_helper_insv(cpu_gpr[rt], cpu_env, t1, t0);
19389
19390 tcg_temp_free(t0);
19391 tcg_temp_free(t1);
a22260ae
JL
19392 break;
19393 }
099e5b4d
LA
19394 default: /* Invalid */
19395 MIPS_INVAL("MASK INSV");
9c708c7f 19396 generate_exception_end(ctx, EXCP_RI);
099e5b4d
LA
19397 break;
19398 }
19399 break;
19400 case OPC_APPEND_DSP:
19401 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
19402 break;
19403 case OPC_EXTR_W_DSP:
19404 op2 = MASK_EXTR_W(ctx->opcode);
19405 switch (op2) {
19406 case OPC_EXTR_W:
19407 case OPC_EXTR_R_W:
19408 case OPC_EXTR_RS_W:
19409 case OPC_EXTR_S_H:
19410 case OPC_EXTRV_S_H:
19411 case OPC_EXTRV_W:
19412 case OPC_EXTRV_R_W:
19413 case OPC_EXTRV_RS_W:
19414 case OPC_EXTP:
19415 case OPC_EXTPV:
19416 case OPC_EXTPDP:
19417 case OPC_EXTPDPV:
19418 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
19419 break;
19420 case OPC_RDDSP:
19421 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 1);
19422 break;
19423 case OPC_SHILO:
19424 case OPC_SHILOV:
19425 case OPC_MTHLIP:
19426 case OPC_WRDSP:
19427 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
19428 break;
19429 default: /* Invalid */
19430 MIPS_INVAL("MASK EXTR.W");
9c708c7f 19431 generate_exception_end(ctx, EXCP_RI);
099e5b4d
LA
19432 break;
19433 }
19434 break;
099e5b4d 19435#if defined(TARGET_MIPS64)
c2e19f3c
AM
19436 case OPC_DDIV_G_2E:
19437 case OPC_DDIVU_G_2E:
19438 case OPC_DMULT_G_2E:
19439 case OPC_DMULTU_G_2E:
19440 case OPC_DMOD_G_2E:
19441 case OPC_DMODU_G_2E:
fac5a073
LA
19442 check_insn(ctx, INSN_LOONGSON2E);
19443 gen_loongson_integer(ctx, op1, rd, rs, rt);
099e5b4d 19444 break;
099e5b4d
LA
19445 case OPC_ABSQ_S_QH_DSP:
19446 op2 = MASK_ABSQ_S_QH(ctx->opcode);
19447 switch (op2) {
19448 case OPC_PRECEQ_L_PWL:
19449 case OPC_PRECEQ_L_PWR:
19450 case OPC_PRECEQ_PW_QHL:
19451 case OPC_PRECEQ_PW_QHR:
19452 case OPC_PRECEQ_PW_QHLA:
19453 case OPC_PRECEQ_PW_QHRA:
19454 case OPC_PRECEQU_QH_OBL:
19455 case OPC_PRECEQU_QH_OBR:
19456 case OPC_PRECEQU_QH_OBLA:
19457 case OPC_PRECEQU_QH_OBRA:
19458 case OPC_PRECEU_QH_OBL:
19459 case OPC_PRECEU_QH_OBR:
19460 case OPC_PRECEU_QH_OBLA:
19461 case OPC_PRECEU_QH_OBRA:
19462 case OPC_ABSQ_S_OB:
19463 case OPC_ABSQ_S_PW:
19464 case OPC_ABSQ_S_QH:
19465 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
19466 break;
19467 case OPC_REPL_OB:
19468 case OPC_REPL_PW:
19469 case OPC_REPL_QH:
19470 case OPC_REPLV_OB:
19471 case OPC_REPLV_PW:
19472 case OPC_REPLV_QH:
19473 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
19474 break;
19475 default: /* Invalid */
19476 MIPS_INVAL("MASK ABSQ_S.QH");
9c708c7f 19477 generate_exception_end(ctx, EXCP_RI);
099e5b4d
LA
19478 break;
19479 }
19480 break;
19481 case OPC_ADDU_OB_DSP:
19482 op2 = MASK_ADDU_OB(ctx->opcode);
19483 switch (op2) {
19484 case OPC_RADDU_L_OB:
19485 case OPC_SUBQ_PW:
19486 case OPC_SUBQ_S_PW:
19487 case OPC_SUBQ_QH:
19488 case OPC_SUBQ_S_QH:
19489 case OPC_SUBU_OB:
19490 case OPC_SUBU_S_OB:
19491 case OPC_SUBU_QH:
19492 case OPC_SUBU_S_QH:
19493 case OPC_SUBUH_OB:
19494 case OPC_SUBUH_R_OB:
19495 case OPC_ADDQ_PW:
19496 case OPC_ADDQ_S_PW:
19497 case OPC_ADDQ_QH:
19498 case OPC_ADDQ_S_QH:
19499 case OPC_ADDU_OB:
19500 case OPC_ADDU_S_OB:
19501 case OPC_ADDU_QH:
19502 case OPC_ADDU_S_QH:
19503 case OPC_ADDUH_OB:
19504 case OPC_ADDUH_R_OB:
19505 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
a22260ae 19506 break;
099e5b4d
LA
19507 case OPC_MULEQ_S_PW_QHL:
19508 case OPC_MULEQ_S_PW_QHR:
19509 case OPC_MULEU_S_QH_OBL:
19510 case OPC_MULEU_S_QH_OBR:
19511 case OPC_MULQ_RS_QH:
19512 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
1cb6686c 19513 break;
099e5b4d
LA
19514 default: /* Invalid */
19515 MIPS_INVAL("MASK ADDU.OB");
9c708c7f 19516 generate_exception_end(ctx, EXCP_RI);
26690560 19517 break;
099e5b4d
LA
19518 }
19519 break;
19520 case OPC_CMPU_EQ_OB_DSP:
19521 op2 = MASK_CMPU_EQ_OB(ctx->opcode);
19522 switch (op2) {
19523 case OPC_PRECR_SRA_QH_PW:
19524 case OPC_PRECR_SRA_R_QH_PW:
19525 /* Return value is rt. */
19526 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
b53371ed 19527 break;
099e5b4d
LA
19528 case OPC_PRECR_OB_QH:
19529 case OPC_PRECRQ_OB_QH:
19530 case OPC_PRECRQ_PW_L:
19531 case OPC_PRECRQ_QH_PW:
19532 case OPC_PRECRQ_RS_QH_PW:
19533 case OPC_PRECRQU_S_OB_QH:
19534 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
4368b29a 19535 break;
099e5b4d
LA
19536 case OPC_CMPU_EQ_OB:
19537 case OPC_CMPU_LT_OB:
19538 case OPC_CMPU_LE_OB:
19539 case OPC_CMP_EQ_QH:
19540 case OPC_CMP_LT_QH:
19541 case OPC_CMP_LE_QH:
19542 case OPC_CMP_EQ_PW:
19543 case OPC_CMP_LT_PW:
19544 case OPC_CMP_LE_PW:
19545 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
7a387fff 19546 break;
099e5b4d
LA
19547 case OPC_CMPGDU_EQ_OB:
19548 case OPC_CMPGDU_LT_OB:
19549 case OPC_CMPGDU_LE_OB:
19550 case OPC_CMPGU_EQ_OB:
19551 case OPC_CMPGU_LT_OB:
19552 case OPC_CMPGU_LE_OB:
19553 case OPC_PACKRL_PW:
19554 case OPC_PICK_OB:
19555 case OPC_PICK_PW:
19556 case OPC_PICK_QH:
19557 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
c6d6dd7c 19558 break;
099e5b4d
LA
19559 default: /* Invalid */
19560 MIPS_INVAL("MASK CMPU_EQ.OB");
9c708c7f 19561 generate_exception_end(ctx, EXCP_RI);
161f85e6 19562 break;
099e5b4d
LA
19563 }
19564 break;
19565 case OPC_DAPPEND_DSP:
19566 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
19567 break;
19568 case OPC_DEXTR_W_DSP:
19569 op2 = MASK_DEXTR_W(ctx->opcode);
19570 switch (op2) {
19571 case OPC_DEXTP:
19572 case OPC_DEXTPDP:
19573 case OPC_DEXTPDPV:
19574 case OPC_DEXTPV:
19575 case OPC_DEXTR_L:
19576 case OPC_DEXTR_R_L:
19577 case OPC_DEXTR_RS_L:
19578 case OPC_DEXTR_W:
19579 case OPC_DEXTR_R_W:
19580 case OPC_DEXTR_RS_W:
19581 case OPC_DEXTR_S_H:
19582 case OPC_DEXTRV_L:
19583 case OPC_DEXTRV_R_L:
19584 case OPC_DEXTRV_RS_L:
19585 case OPC_DEXTRV_S_H:
19586 case OPC_DEXTRV_W:
19587 case OPC_DEXTRV_R_W:
19588 case OPC_DEXTRV_RS_W:
19589 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
461c08df 19590 break;
099e5b4d
LA
19591 case OPC_DMTHLIP:
19592 case OPC_DSHILO:
19593 case OPC_DSHILOV:
19594 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
461c08df 19595 break;
099e5b4d
LA
19596 default: /* Invalid */
19597 MIPS_INVAL("MASK EXTR.W");
9c708c7f 19598 generate_exception_end(ctx, EXCP_RI);
461c08df 19599 break;
099e5b4d
LA
19600 }
19601 break;
19602 case OPC_DPAQ_W_QH_DSP:
19603 op2 = MASK_DPAQ_W_QH(ctx->opcode);
19604 switch (op2) {
19605 case OPC_DPAU_H_OBL:
19606 case OPC_DPAU_H_OBR:
19607 case OPC_DPSU_H_OBL:
19608 case OPC_DPSU_H_OBR:
19609 case OPC_DPA_W_QH:
19610 case OPC_DPAQ_S_W_QH:
19611 case OPC_DPS_W_QH:
19612 case OPC_DPSQ_S_W_QH:
19613 case OPC_MULSAQ_S_W_QH:
19614 case OPC_DPAQ_SA_L_PW:
19615 case OPC_DPSQ_SA_L_PW:
19616 case OPC_MULSAQ_S_L_PW:
19617 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
19618 break;
19619 case OPC_MAQ_S_W_QHLL:
19620 case OPC_MAQ_S_W_QHLR:
19621 case OPC_MAQ_S_W_QHRL:
19622 case OPC_MAQ_S_W_QHRR:
19623 case OPC_MAQ_SA_W_QHLL:
19624 case OPC_MAQ_SA_W_QHLR:
19625 case OPC_MAQ_SA_W_QHRL:
19626 case OPC_MAQ_SA_W_QHRR:
19627 case OPC_MAQ_S_L_PWL:
19628 case OPC_MAQ_S_L_PWR:
19629 case OPC_DMADD:
19630 case OPC_DMADDU:
19631 case OPC_DMSUB:
19632 case OPC_DMSUBU:
19633 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
26690560 19634 break;
099e5b4d
LA
19635 default: /* Invalid */
19636 MIPS_INVAL("MASK DPAQ.W.QH");
9c708c7f 19637 generate_exception_end(ctx, EXCP_RI);
b53371ed 19638 break;
099e5b4d
LA
19639 }
19640 break;
19641 case OPC_DINSV_DSP:
19642 op2 = MASK_INSV(ctx->opcode);
19643 switch (op2) {
19644 case OPC_DINSV:
19645 {
19646 TCGv t0, t1;
19647
19648 if (rt == 0) {
a22260ae
JL
19649 break;
19650 }
099e5b4d 19651 check_dsp(ctx);
1cb6686c 19652
099e5b4d
LA
19653 t0 = tcg_temp_new();
19654 t1 = tcg_temp_new();
1cb6686c 19655
099e5b4d
LA
19656 gen_load_gpr(t0, rt);
19657 gen_load_gpr(t1, rs);
1cb6686c 19658
099e5b4d 19659 gen_helper_dinsv(cpu_gpr[rt], cpu_env, t1, t0);
62eb3b9a 19660
099e5b4d
LA
19661 tcg_temp_free(t0);
19662 tcg_temp_free(t1);
77c5fa8b 19663 break;
099e5b4d 19664 }
7a387fff 19665 default: /* Invalid */
099e5b4d 19666 MIPS_INVAL("MASK DINSV");
9c708c7f 19667 generate_exception_end(ctx, EXCP_RI);
7a387fff
TS
19668 break;
19669 }
19670 break;
099e5b4d
LA
19671 case OPC_SHLL_OB_DSP:
19672 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
19673 break;
19674#endif
fac5a073
LA
19675 default: /* Invalid */
19676 MIPS_INVAL("special3_legacy");
9c708c7f 19677 generate_exception_end(ctx, EXCP_RI);
fac5a073
LA
19678 break;
19679 }
19680}
19681
19682static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx)
19683{
19684 int rs, rt, rd, sa;
19685 uint32_t op1, op2;
76964147 19686 int16_t imm;
fac5a073
LA
19687
19688 rs = (ctx->opcode >> 21) & 0x1f;
19689 rt = (ctx->opcode >> 16) & 0x1f;
19690 rd = (ctx->opcode >> 11) & 0x1f;
19691 sa = (ctx->opcode >> 6) & 0x1f;
76964147 19692 imm = sextract32(ctx->opcode, 7, 9);
fac5a073
LA
19693
19694 op1 = MASK_SPECIAL3(ctx->opcode);
76964147
JH
19695
19696 /*
19697 * EVA loads and stores overlap Loongson 2E instructions decoded by
19698 * decode_opc_special3_legacy(), so be careful to allow their decoding when
19699 * EVA is absent.
19700 */
19701 if (ctx->eva) {
19702 switch (op1) {
c2e19f3c
AM
19703 case OPC_LWLE:
19704 case OPC_LWRE:
76964147
JH
19705 check_insn_opc_removed(ctx, ISA_MIPS32R6);
19706 /* fall through */
c2e19f3c
AM
19707 case OPC_LBUE:
19708 case OPC_LHUE:
19709 case OPC_LBE:
19710 case OPC_LHE:
19711 case OPC_LLE:
19712 case OPC_LWE:
76964147
JH
19713 check_cp0_enabled(ctx);
19714 gen_ld(ctx, op1, rt, rs, imm);
19715 return;
c2e19f3c
AM
19716 case OPC_SWLE:
19717 case OPC_SWRE:
76964147
JH
19718 check_insn_opc_removed(ctx, ISA_MIPS32R6);
19719 /* fall through */
c2e19f3c
AM
19720 case OPC_SBE:
19721 case OPC_SHE:
76964147
JH
19722 case OPC_SWE:
19723 check_cp0_enabled(ctx);
19724 gen_st(ctx, op1, rt, rs, imm);
19725 return;
19726 case OPC_SCE:
19727 check_cp0_enabled(ctx);
19728 gen_st_cond(ctx, op1, rt, rs, imm);
19729 return;
19730 case OPC_CACHEE:
19731 check_cp0_enabled(ctx);
19732 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
19733 gen_cache_operation(ctx, rt, rs, imm);
19734 }
19735 /* Treat as NOP. */
19736 return;
19737 case OPC_PREFE:
19738 check_cp0_enabled(ctx);
19739 /* Treat as NOP. */
19740 return;
19741 }
19742 }
19743
fac5a073
LA
19744 switch (op1) {
19745 case OPC_EXT:
19746 case OPC_INS:
19747 check_insn(ctx, ISA_MIPS32R2);
19748 gen_bitops(ctx, op1, rt, rs, sa, rd);
19749 break;
19750 case OPC_BSHFL:
fac5a073 19751 op2 = MASK_BSHFL(ctx->opcode);
15eacb9b 19752 switch (op2) {
c2e19f3c
AM
19753 case OPC_ALIGN:
19754 case OPC_ALIGN_END:
15eacb9b
YK
19755 case OPC_BITSWAP:
19756 check_insn(ctx, ISA_MIPS32R6);
19757 decode_opc_special3_r6(env, ctx);
19758 break;
19759 default:
19760 check_insn(ctx, ISA_MIPS32R2);
19761 gen_bshfl(ctx, op2, rt, rd);
19762 break;
19763 }
fac5a073
LA
19764 break;
19765#if defined(TARGET_MIPS64)
c2e19f3c
AM
19766 case OPC_DEXTM:
19767 case OPC_DEXTU:
19768 case OPC_DEXT:
19769 case OPC_DINSM:
19770 case OPC_DINSU:
19771 case OPC_DINS:
fac5a073
LA
19772 check_insn(ctx, ISA_MIPS64R2);
19773 check_mips_64(ctx);
19774 gen_bitops(ctx, op1, rt, rs, sa, rd);
19775 break;
19776 case OPC_DBSHFL:
fac5a073 19777 op2 = MASK_DBSHFL(ctx->opcode);
15eacb9b 19778 switch (op2) {
c2e19f3c
AM
19779 case OPC_DALIGN:
19780 case OPC_DALIGN_END:
15eacb9b
YK
19781 case OPC_DBITSWAP:
19782 check_insn(ctx, ISA_MIPS32R6);
19783 decode_opc_special3_r6(env, ctx);
19784 break;
19785 default:
19786 check_insn(ctx, ISA_MIPS64R2);
19787 check_mips_64(ctx);
19788 op2 = MASK_DBSHFL(ctx->opcode);
19789 gen_bshfl(ctx, op2, rt, rd);
19790 break;
19791 }
fac5a073
LA
19792 break;
19793#endif
19794 case OPC_RDHWR:
b00c7218 19795 gen_rdhwr(ctx, rt, rd, extract32(ctx->opcode, 6, 3));
fac5a073
LA
19796 break;
19797 case OPC_FORK:
19798 check_insn(ctx, ASE_MT);
19799 {
19800 TCGv t0 = tcg_temp_new();
19801 TCGv t1 = tcg_temp_new();
19802
19803 gen_load_gpr(t0, rt);
19804 gen_load_gpr(t1, rs);
19805 gen_helper_fork(t0, t1);
19806 tcg_temp_free(t0);
19807 tcg_temp_free(t1);
19808 }
19809 break;
19810 case OPC_YIELD:
19811 check_insn(ctx, ASE_MT);
19812 {
19813 TCGv t0 = tcg_temp_new();
19814
fac5a073
LA
19815 gen_load_gpr(t0, rs);
19816 gen_helper_yield(t0, cpu_env, t0);
19817 gen_store_gpr(t0, rd);
19818 tcg_temp_free(t0);
19819 }
19820 break;
10dc65db
LA
19821 default:
19822 if (ctx->insn_flags & ISA_MIPS32R6) {
19823 decode_opc_special3_r6(env, ctx);
19824 } else {
19825 decode_opc_special3_legacy(env, ctx);
19826 }
099e5b4d
LA
19827 }
19828}
19829
863f264d
YK
19830/* MIPS SIMD Architecture (MSA) */
19831static inline int check_msa_access(DisasContext *ctx)
19832{
19833 if (unlikely((ctx->hflags & MIPS_HFLAG_FPU) &&
19834 !(ctx->hflags & MIPS_HFLAG_F64))) {
9c708c7f 19835 generate_exception_end(ctx, EXCP_RI);
863f264d
YK
19836 return 0;
19837 }
19838
19839 if (unlikely(!(ctx->hflags & MIPS_HFLAG_MSA))) {
19840 if (ctx->insn_flags & ASE_MSA) {
9c708c7f 19841 generate_exception_end(ctx, EXCP_MSADIS);
863f264d
YK
19842 return 0;
19843 } else {
9c708c7f 19844 generate_exception_end(ctx, EXCP_RI);
863f264d
YK
19845 return 0;
19846 }
19847 }
19848 return 1;
19849}
19850
5692c6e1
YK
19851static void gen_check_zero_element(TCGv tresult, uint8_t df, uint8_t wt)
19852{
19853 /* generates tcg ops to check if any element is 0 */
19854 /* Note this function only works with MSA_WRLEN = 128 */
19855 uint64_t eval_zero_or_big = 0;
19856 uint64_t eval_big = 0;
19857 TCGv_i64 t0 = tcg_temp_new_i64();
19858 TCGv_i64 t1 = tcg_temp_new_i64();
19859 switch (df) {
19860 case DF_BYTE:
19861 eval_zero_or_big = 0x0101010101010101ULL;
19862 eval_big = 0x8080808080808080ULL;
19863 break;
19864 case DF_HALF:
19865 eval_zero_or_big = 0x0001000100010001ULL;
19866 eval_big = 0x8000800080008000ULL;
19867 break;
19868 case DF_WORD:
19869 eval_zero_or_big = 0x0000000100000001ULL;
19870 eval_big = 0x8000000080000000ULL;
19871 break;
19872 case DF_DOUBLE:
19873 eval_zero_or_big = 0x0000000000000001ULL;
19874 eval_big = 0x8000000000000000ULL;
19875 break;
19876 }
19877 tcg_gen_subi_i64(t0, msa_wr_d[wt<<1], eval_zero_or_big);
19878 tcg_gen_andc_i64(t0, t0, msa_wr_d[wt<<1]);
19879 tcg_gen_andi_i64(t0, t0, eval_big);
19880 tcg_gen_subi_i64(t1, msa_wr_d[(wt<<1)+1], eval_zero_or_big);
19881 tcg_gen_andc_i64(t1, t1, msa_wr_d[(wt<<1)+1]);
19882 tcg_gen_andi_i64(t1, t1, eval_big);
19883 tcg_gen_or_i64(t0, t0, t1);
19884 /* if all bits are zero then all elements are not zero */
19885 /* if some bit is non-zero then some element is zero */
19886 tcg_gen_setcondi_i64(TCG_COND_NE, t0, t0, 0);
19887 tcg_gen_trunc_i64_tl(tresult, t0);
19888 tcg_temp_free_i64(t0);
19889 tcg_temp_free_i64(t1);
19890}
19891
19892static void gen_msa_branch(CPUMIPSState *env, DisasContext *ctx, uint32_t op1)
19893{
19894 uint8_t df = (ctx->opcode >> 21) & 0x3;
19895 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
19896 int64_t s16 = (int16_t)ctx->opcode;
19897
19898 check_msa_access(ctx);
19899
075a1fe7 19900 if (ctx->hflags & MIPS_HFLAG_BMASK) {
9c708c7f 19901 generate_exception_end(ctx, EXCP_RI);
5692c6e1
YK
19902 return;
19903 }
19904 switch (op1) {
19905 case OPC_BZ_V:
19906 case OPC_BNZ_V:
19907 {
19908 TCGv_i64 t0 = tcg_temp_new_i64();
19909 tcg_gen_or_i64(t0, msa_wr_d[wt<<1], msa_wr_d[(wt<<1)+1]);
19910 tcg_gen_setcondi_i64((op1 == OPC_BZ_V) ?
19911 TCG_COND_EQ : TCG_COND_NE, t0, t0, 0);
19912 tcg_gen_trunc_i64_tl(bcond, t0);
19913 tcg_temp_free_i64(t0);
19914 }
19915 break;
19916 case OPC_BZ_B:
19917 case OPC_BZ_H:
19918 case OPC_BZ_W:
19919 case OPC_BZ_D:
19920 gen_check_zero_element(bcond, df, wt);
19921 break;
19922 case OPC_BNZ_B:
19923 case OPC_BNZ_H:
19924 case OPC_BNZ_W:
19925 case OPC_BNZ_D:
19926 gen_check_zero_element(bcond, df, wt);
19927 tcg_gen_setcondi_tl(TCG_COND_EQ, bcond, bcond, 0);
19928 break;
19929 }
19930
eeb3bba8 19931 ctx->btarget = ctx->base.pc_next + (s16 << 2) + 4;
5692c6e1
YK
19932
19933 ctx->hflags |= MIPS_HFLAG_BC;
19934 ctx->hflags |= MIPS_HFLAG_BDS32;
19935}
19936
4c789546
YK
19937static void gen_msa_i8(CPUMIPSState *env, DisasContext *ctx)
19938{
19939#define MASK_MSA_I8(op) (MASK_MSA_MINOR(op) | (op & (0x03 << 24)))
19940 uint8_t i8 = (ctx->opcode >> 16) & 0xff;
19941 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
19942 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
19943
19944 TCGv_i32 twd = tcg_const_i32(wd);
19945 TCGv_i32 tws = tcg_const_i32(ws);
19946 TCGv_i32 ti8 = tcg_const_i32(i8);
19947
19948 switch (MASK_MSA_I8(ctx->opcode)) {
19949 case OPC_ANDI_B:
19950 gen_helper_msa_andi_b(cpu_env, twd, tws, ti8);
19951 break;
19952 case OPC_ORI_B:
19953 gen_helper_msa_ori_b(cpu_env, twd, tws, ti8);
19954 break;
19955 case OPC_NORI_B:
19956 gen_helper_msa_nori_b(cpu_env, twd, tws, ti8);
19957 break;
19958 case OPC_XORI_B:
19959 gen_helper_msa_xori_b(cpu_env, twd, tws, ti8);
19960 break;
19961 case OPC_BMNZI_B:
19962 gen_helper_msa_bmnzi_b(cpu_env, twd, tws, ti8);
19963 break;
19964 case OPC_BMZI_B:
19965 gen_helper_msa_bmzi_b(cpu_env, twd, tws, ti8);
19966 break;
19967 case OPC_BSELI_B:
19968 gen_helper_msa_bseli_b(cpu_env, twd, tws, ti8);
19969 break;
19970 case OPC_SHF_B:
19971 case OPC_SHF_H:
19972 case OPC_SHF_W:
19973 {
19974 uint8_t df = (ctx->opcode >> 24) & 0x3;
19975 if (df == DF_DOUBLE) {
9c708c7f 19976 generate_exception_end(ctx, EXCP_RI);
4c789546
YK
19977 } else {
19978 TCGv_i32 tdf = tcg_const_i32(df);
19979 gen_helper_msa_shf_df(cpu_env, tdf, twd, tws, ti8);
19980 tcg_temp_free_i32(tdf);
19981 }
19982 }
19983 break;
19984 default:
19985 MIPS_INVAL("MSA instruction");
9c708c7f 19986 generate_exception_end(ctx, EXCP_RI);
4c789546
YK
19987 break;
19988 }
19989
19990 tcg_temp_free_i32(twd);
19991 tcg_temp_free_i32(tws);
19992 tcg_temp_free_i32(ti8);
19993}
19994
80e71591
YK
19995static void gen_msa_i5(CPUMIPSState *env, DisasContext *ctx)
19996{
19997#define MASK_MSA_I5(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
19998 uint8_t df = (ctx->opcode >> 21) & 0x3;
19999 int8_t s5 = (int8_t) sextract32(ctx->opcode, 16, 5);
20000 uint8_t u5 = (ctx->opcode >> 16) & 0x1f;
20001 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
20002 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
20003
20004 TCGv_i32 tdf = tcg_const_i32(df);
20005 TCGv_i32 twd = tcg_const_i32(wd);
20006 TCGv_i32 tws = tcg_const_i32(ws);
20007 TCGv_i32 timm = tcg_temp_new_i32();
20008 tcg_gen_movi_i32(timm, u5);
20009
20010 switch (MASK_MSA_I5(ctx->opcode)) {
20011 case OPC_ADDVI_df:
20012 gen_helper_msa_addvi_df(cpu_env, tdf, twd, tws, timm);
20013 break;
20014 case OPC_SUBVI_df:
20015 gen_helper_msa_subvi_df(cpu_env, tdf, twd, tws, timm);
20016 break;
20017 case OPC_MAXI_S_df:
20018 tcg_gen_movi_i32(timm, s5);
20019 gen_helper_msa_maxi_s_df(cpu_env, tdf, twd, tws, timm);
20020 break;
20021 case OPC_MAXI_U_df:
20022 gen_helper_msa_maxi_u_df(cpu_env, tdf, twd, tws, timm);
20023 break;
20024 case OPC_MINI_S_df:
20025 tcg_gen_movi_i32(timm, s5);
20026 gen_helper_msa_mini_s_df(cpu_env, tdf, twd, tws, timm);
20027 break;
20028 case OPC_MINI_U_df:
20029 gen_helper_msa_mini_u_df(cpu_env, tdf, twd, tws, timm);
20030 break;
20031 case OPC_CEQI_df:
20032 tcg_gen_movi_i32(timm, s5);
20033 gen_helper_msa_ceqi_df(cpu_env, tdf, twd, tws, timm);
20034 break;
20035 case OPC_CLTI_S_df:
20036 tcg_gen_movi_i32(timm, s5);
20037 gen_helper_msa_clti_s_df(cpu_env, tdf, twd, tws, timm);
20038 break;
20039 case OPC_CLTI_U_df:
20040 gen_helper_msa_clti_u_df(cpu_env, tdf, twd, tws, timm);
20041 break;
20042 case OPC_CLEI_S_df:
20043 tcg_gen_movi_i32(timm, s5);
20044 gen_helper_msa_clei_s_df(cpu_env, tdf, twd, tws, timm);
20045 break;
20046 case OPC_CLEI_U_df:
20047 gen_helper_msa_clei_u_df(cpu_env, tdf, twd, tws, timm);
20048 break;
20049 case OPC_LDI_df:
20050 {
20051 int32_t s10 = sextract32(ctx->opcode, 11, 10);
20052 tcg_gen_movi_i32(timm, s10);
20053 gen_helper_msa_ldi_df(cpu_env, tdf, twd, timm);
20054 }
20055 break;
20056 default:
20057 MIPS_INVAL("MSA instruction");
9c708c7f 20058 generate_exception_end(ctx, EXCP_RI);
80e71591
YK
20059 break;
20060 }
20061
20062 tcg_temp_free_i32(tdf);
20063 tcg_temp_free_i32(twd);
20064 tcg_temp_free_i32(tws);
20065 tcg_temp_free_i32(timm);
20066}
20067
d4cf28de
YK
20068static void gen_msa_bit(CPUMIPSState *env, DisasContext *ctx)
20069{
20070#define MASK_MSA_BIT(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
20071 uint8_t dfm = (ctx->opcode >> 16) & 0x7f;
20072 uint32_t df = 0, m = 0;
20073 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
20074 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
20075
20076 TCGv_i32 tdf;
20077 TCGv_i32 tm;
20078 TCGv_i32 twd;
20079 TCGv_i32 tws;
20080
20081 if ((dfm & 0x40) == 0x00) {
20082 m = dfm & 0x3f;
20083 df = DF_DOUBLE;
20084 } else if ((dfm & 0x60) == 0x40) {
20085 m = dfm & 0x1f;
20086 df = DF_WORD;
20087 } else if ((dfm & 0x70) == 0x60) {
20088 m = dfm & 0x0f;
20089 df = DF_HALF;
20090 } else if ((dfm & 0x78) == 0x70) {
20091 m = dfm & 0x7;
20092 df = DF_BYTE;
20093 } else {
9c708c7f 20094 generate_exception_end(ctx, EXCP_RI);
d4cf28de
YK
20095 return;
20096 }
20097
20098 tdf = tcg_const_i32(df);
20099 tm = tcg_const_i32(m);
20100 twd = tcg_const_i32(wd);
20101 tws = tcg_const_i32(ws);
20102
20103 switch (MASK_MSA_BIT(ctx->opcode)) {
20104 case OPC_SLLI_df:
20105 gen_helper_msa_slli_df(cpu_env, tdf, twd, tws, tm);
20106 break;
20107 case OPC_SRAI_df:
20108 gen_helper_msa_srai_df(cpu_env, tdf, twd, tws, tm);
20109 break;
20110 case OPC_SRLI_df:
20111 gen_helper_msa_srli_df(cpu_env, tdf, twd, tws, tm);
20112 break;
20113 case OPC_BCLRI_df:
20114 gen_helper_msa_bclri_df(cpu_env, tdf, twd, tws, tm);
20115 break;
20116 case OPC_BSETI_df:
20117 gen_helper_msa_bseti_df(cpu_env, tdf, twd, tws, tm);
20118 break;
20119 case OPC_BNEGI_df:
20120 gen_helper_msa_bnegi_df(cpu_env, tdf, twd, tws, tm);
20121 break;
20122 case OPC_BINSLI_df:
20123 gen_helper_msa_binsli_df(cpu_env, tdf, twd, tws, tm);
20124 break;
20125 case OPC_BINSRI_df:
20126 gen_helper_msa_binsri_df(cpu_env, tdf, twd, tws, tm);
20127 break;
20128 case OPC_SAT_S_df:
20129 gen_helper_msa_sat_s_df(cpu_env, tdf, twd, tws, tm);
20130 break;
20131 case OPC_SAT_U_df:
20132 gen_helper_msa_sat_u_df(cpu_env, tdf, twd, tws, tm);
20133 break;
20134 case OPC_SRARI_df:
20135 gen_helper_msa_srari_df(cpu_env, tdf, twd, tws, tm);
20136 break;
20137 case OPC_SRLRI_df:
20138 gen_helper_msa_srlri_df(cpu_env, tdf, twd, tws, tm);
20139 break;
20140 default:
20141 MIPS_INVAL("MSA instruction");
9c708c7f 20142 generate_exception_end(ctx, EXCP_RI);
d4cf28de
YK
20143 break;
20144 }
20145
20146 tcg_temp_free_i32(tdf);
20147 tcg_temp_free_i32(tm);
20148 tcg_temp_free_i32(twd);
20149 tcg_temp_free_i32(tws);
20150}
20151
28f99f08
YK
20152static void gen_msa_3r(CPUMIPSState *env, DisasContext *ctx)
20153{
20154#define MASK_MSA_3R(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
20155 uint8_t df = (ctx->opcode >> 21) & 0x3;
20156 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
20157 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
20158 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
20159
20160 TCGv_i32 tdf = tcg_const_i32(df);
20161 TCGv_i32 twd = tcg_const_i32(wd);
20162 TCGv_i32 tws = tcg_const_i32(ws);
20163 TCGv_i32 twt = tcg_const_i32(wt);
20164
20165 switch (MASK_MSA_3R(ctx->opcode)) {
20166 case OPC_SLL_df:
20167 gen_helper_msa_sll_df(cpu_env, tdf, twd, tws, twt);
20168 break;
20169 case OPC_ADDV_df:
20170 gen_helper_msa_addv_df(cpu_env, tdf, twd, tws, twt);
20171 break;
20172 case OPC_CEQ_df:
20173 gen_helper_msa_ceq_df(cpu_env, tdf, twd, tws, twt);
20174 break;
20175 case OPC_ADD_A_df:
20176 gen_helper_msa_add_a_df(cpu_env, tdf, twd, tws, twt);
20177 break;
20178 case OPC_SUBS_S_df:
20179 gen_helper_msa_subs_s_df(cpu_env, tdf, twd, tws, twt);
20180 break;
20181 case OPC_MULV_df:
20182 gen_helper_msa_mulv_df(cpu_env, tdf, twd, tws, twt);
20183 break;
20184 case OPC_SLD_df:
20185 gen_helper_msa_sld_df(cpu_env, tdf, twd, tws, twt);
20186 break;
20187 case OPC_VSHF_df:
20188 gen_helper_msa_vshf_df(cpu_env, tdf, twd, tws, twt);
20189 break;
20190 case OPC_SRA_df:
20191 gen_helper_msa_sra_df(cpu_env, tdf, twd, tws, twt);
20192 break;
20193 case OPC_SUBV_df:
20194 gen_helper_msa_subv_df(cpu_env, tdf, twd, tws, twt);
20195 break;
20196 case OPC_ADDS_A_df:
20197 gen_helper_msa_adds_a_df(cpu_env, tdf, twd, tws, twt);
20198 break;
20199 case OPC_SUBS_U_df:
20200 gen_helper_msa_subs_u_df(cpu_env, tdf, twd, tws, twt);
20201 break;
20202 case OPC_MADDV_df:
20203 gen_helper_msa_maddv_df(cpu_env, tdf, twd, tws, twt);
20204 break;
20205 case OPC_SPLAT_df:
20206 gen_helper_msa_splat_df(cpu_env, tdf, twd, tws, twt);
20207 break;
20208 case OPC_SRAR_df:
20209 gen_helper_msa_srar_df(cpu_env, tdf, twd, tws, twt);
20210 break;
20211 case OPC_SRL_df:
20212 gen_helper_msa_srl_df(cpu_env, tdf, twd, tws, twt);
20213 break;
20214 case OPC_MAX_S_df:
20215 gen_helper_msa_max_s_df(cpu_env, tdf, twd, tws, twt);
20216 break;
20217 case OPC_CLT_S_df:
20218 gen_helper_msa_clt_s_df(cpu_env, tdf, twd, tws, twt);
20219 break;
20220 case OPC_ADDS_S_df:
20221 gen_helper_msa_adds_s_df(cpu_env, tdf, twd, tws, twt);
20222 break;
20223 case OPC_SUBSUS_U_df:
20224 gen_helper_msa_subsus_u_df(cpu_env, tdf, twd, tws, twt);
20225 break;
20226 case OPC_MSUBV_df:
20227 gen_helper_msa_msubv_df(cpu_env, tdf, twd, tws, twt);
20228 break;
20229 case OPC_PCKEV_df:
20230 gen_helper_msa_pckev_df(cpu_env, tdf, twd, tws, twt);
20231 break;
20232 case OPC_SRLR_df:
20233 gen_helper_msa_srlr_df(cpu_env, tdf, twd, tws, twt);
20234 break;
20235 case OPC_BCLR_df:
20236 gen_helper_msa_bclr_df(cpu_env, tdf, twd, tws, twt);
20237 break;
20238 case OPC_MAX_U_df:
20239 gen_helper_msa_max_u_df(cpu_env, tdf, twd, tws, twt);
20240 break;
20241 case OPC_CLT_U_df:
20242 gen_helper_msa_clt_u_df(cpu_env, tdf, twd, tws, twt);
20243 break;
20244 case OPC_ADDS_U_df:
20245 gen_helper_msa_adds_u_df(cpu_env, tdf, twd, tws, twt);
20246 break;
20247 case OPC_SUBSUU_S_df:
20248 gen_helper_msa_subsuu_s_df(cpu_env, tdf, twd, tws, twt);
20249 break;
20250 case OPC_PCKOD_df:
20251 gen_helper_msa_pckod_df(cpu_env, tdf, twd, tws, twt);
20252 break;
20253 case OPC_BSET_df:
20254 gen_helper_msa_bset_df(cpu_env, tdf, twd, tws, twt);
20255 break;
20256 case OPC_MIN_S_df:
20257 gen_helper_msa_min_s_df(cpu_env, tdf, twd, tws, twt);
20258 break;
20259 case OPC_CLE_S_df:
20260 gen_helper_msa_cle_s_df(cpu_env, tdf, twd, tws, twt);
20261 break;
20262 case OPC_AVE_S_df:
20263 gen_helper_msa_ave_s_df(cpu_env, tdf, twd, tws, twt);
20264 break;
20265 case OPC_ASUB_S_df:
20266 gen_helper_msa_asub_s_df(cpu_env, tdf, twd, tws, twt);
20267 break;
20268 case OPC_DIV_S_df:
20269 gen_helper_msa_div_s_df(cpu_env, tdf, twd, tws, twt);
20270 break;
20271 case OPC_ILVL_df:
20272 gen_helper_msa_ilvl_df(cpu_env, tdf, twd, tws, twt);
20273 break;
20274 case OPC_BNEG_df:
20275 gen_helper_msa_bneg_df(cpu_env, tdf, twd, tws, twt);
20276 break;
20277 case OPC_MIN_U_df:
20278 gen_helper_msa_min_u_df(cpu_env, tdf, twd, tws, twt);
20279 break;
20280 case OPC_CLE_U_df:
20281 gen_helper_msa_cle_u_df(cpu_env, tdf, twd, tws, twt);
20282 break;
20283 case OPC_AVE_U_df:
20284 gen_helper_msa_ave_u_df(cpu_env, tdf, twd, tws, twt);
20285 break;
20286 case OPC_ASUB_U_df:
20287 gen_helper_msa_asub_u_df(cpu_env, tdf, twd, tws, twt);
20288 break;
20289 case OPC_DIV_U_df:
20290 gen_helper_msa_div_u_df(cpu_env, tdf, twd, tws, twt);
20291 break;
20292 case OPC_ILVR_df:
20293 gen_helper_msa_ilvr_df(cpu_env, tdf, twd, tws, twt);
20294 break;
20295 case OPC_BINSL_df:
20296 gen_helper_msa_binsl_df(cpu_env, tdf, twd, tws, twt);
20297 break;
20298 case OPC_MAX_A_df:
20299 gen_helper_msa_max_a_df(cpu_env, tdf, twd, tws, twt);
20300 break;
20301 case OPC_AVER_S_df:
20302 gen_helper_msa_aver_s_df(cpu_env, tdf, twd, tws, twt);
20303 break;
20304 case OPC_MOD_S_df:
20305 gen_helper_msa_mod_s_df(cpu_env, tdf, twd, tws, twt);
20306 break;
20307 case OPC_ILVEV_df:
20308 gen_helper_msa_ilvev_df(cpu_env, tdf, twd, tws, twt);
20309 break;
20310 case OPC_BINSR_df:
20311 gen_helper_msa_binsr_df(cpu_env, tdf, twd, tws, twt);
20312 break;
20313 case OPC_MIN_A_df:
20314 gen_helper_msa_min_a_df(cpu_env, tdf, twd, tws, twt);
20315 break;
20316 case OPC_AVER_U_df:
20317 gen_helper_msa_aver_u_df(cpu_env, tdf, twd, tws, twt);
20318 break;
20319 case OPC_MOD_U_df:
20320 gen_helper_msa_mod_u_df(cpu_env, tdf, twd, tws, twt);
20321 break;
20322 case OPC_ILVOD_df:
20323 gen_helper_msa_ilvod_df(cpu_env, tdf, twd, tws, twt);
20324 break;
20325
20326 case OPC_DOTP_S_df:
20327 case OPC_DOTP_U_df:
20328 case OPC_DPADD_S_df:
20329 case OPC_DPADD_U_df:
20330 case OPC_DPSUB_S_df:
20331 case OPC_HADD_S_df:
20332 case OPC_DPSUB_U_df:
20333 case OPC_HADD_U_df:
20334 case OPC_HSUB_S_df:
20335 case OPC_HSUB_U_df:
20336 if (df == DF_BYTE) {
9c708c7f
PD
20337 generate_exception_end(ctx, EXCP_RI);
20338 break;
28f99f08
YK
20339 }
20340 switch (MASK_MSA_3R(ctx->opcode)) {
20341 case OPC_DOTP_S_df:
20342 gen_helper_msa_dotp_s_df(cpu_env, tdf, twd, tws, twt);
20343 break;
20344 case OPC_DOTP_U_df:
20345 gen_helper_msa_dotp_u_df(cpu_env, tdf, twd, tws, twt);
20346 break;
20347 case OPC_DPADD_S_df:
20348 gen_helper_msa_dpadd_s_df(cpu_env, tdf, twd, tws, twt);
20349 break;
20350 case OPC_DPADD_U_df:
20351 gen_helper_msa_dpadd_u_df(cpu_env, tdf, twd, tws, twt);
20352 break;
20353 case OPC_DPSUB_S_df:
20354 gen_helper_msa_dpsub_s_df(cpu_env, tdf, twd, tws, twt);
20355 break;
20356 case OPC_HADD_S_df:
20357 gen_helper_msa_hadd_s_df(cpu_env, tdf, twd, tws, twt);
20358 break;
20359 case OPC_DPSUB_U_df:
20360 gen_helper_msa_dpsub_u_df(cpu_env, tdf, twd, tws, twt);
20361 break;
20362 case OPC_HADD_U_df:
20363 gen_helper_msa_hadd_u_df(cpu_env, tdf, twd, tws, twt);
20364 break;
20365 case OPC_HSUB_S_df:
20366 gen_helper_msa_hsub_s_df(cpu_env, tdf, twd, tws, twt);
20367 break;
20368 case OPC_HSUB_U_df:
20369 gen_helper_msa_hsub_u_df(cpu_env, tdf, twd, tws, twt);
20370 break;
20371 }
20372 break;
20373 default:
20374 MIPS_INVAL("MSA instruction");
9c708c7f 20375 generate_exception_end(ctx, EXCP_RI);
28f99f08
YK
20376 break;
20377 }
20378 tcg_temp_free_i32(twd);
20379 tcg_temp_free_i32(tws);
20380 tcg_temp_free_i32(twt);
20381 tcg_temp_free_i32(tdf);
20382}
20383
1e608ec1
YK
20384static void gen_msa_elm_3e(CPUMIPSState *env, DisasContext *ctx)
20385{
20386#define MASK_MSA_ELM_DF3E(op) (MASK_MSA_MINOR(op) | (op & (0x3FF << 16)))
20387 uint8_t source = (ctx->opcode >> 11) & 0x1f;
20388 uint8_t dest = (ctx->opcode >> 6) & 0x1f;
20389 TCGv telm = tcg_temp_new();
20390 TCGv_i32 tsr = tcg_const_i32(source);
20391 TCGv_i32 tdt = tcg_const_i32(dest);
20392
20393 switch (MASK_MSA_ELM_DF3E(ctx->opcode)) {
20394 case OPC_CTCMSA:
20395 gen_load_gpr(telm, source);
20396 gen_helper_msa_ctcmsa(cpu_env, telm, tdt);
20397 break;
20398 case OPC_CFCMSA:
20399 gen_helper_msa_cfcmsa(telm, cpu_env, tsr);
20400 gen_store_gpr(telm, dest);
20401 break;
20402 case OPC_MOVE_V:
20403 gen_helper_msa_move_v(cpu_env, tdt, tsr);
20404 break;
20405 default:
20406 MIPS_INVAL("MSA instruction");
9c708c7f 20407 generate_exception_end(ctx, EXCP_RI);
1e608ec1
YK
20408 break;
20409 }
20410
20411 tcg_temp_free(telm);
20412 tcg_temp_free_i32(tdt);
20413 tcg_temp_free_i32(tsr);
20414}
20415
20416static void gen_msa_elm_df(CPUMIPSState *env, DisasContext *ctx, uint32_t df,
20417 uint32_t n)
20418{
20419#define MASK_MSA_ELM(op) (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
20420 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
20421 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
20422
20423 TCGv_i32 tws = tcg_const_i32(ws);
20424 TCGv_i32 twd = tcg_const_i32(wd);
20425 TCGv_i32 tn = tcg_const_i32(n);
20426 TCGv_i32 tdf = tcg_const_i32(df);
20427
20428 switch (MASK_MSA_ELM(ctx->opcode)) {
20429 case OPC_SLDI_df:
20430 gen_helper_msa_sldi_df(cpu_env, tdf, twd, tws, tn);
20431 break;
20432 case OPC_SPLATI_df:
20433 gen_helper_msa_splati_df(cpu_env, tdf, twd, tws, tn);
20434 break;
20435 case OPC_INSVE_df:
20436 gen_helper_msa_insve_df(cpu_env, tdf, twd, tws, tn);
20437 break;
20438 case OPC_COPY_S_df:
20439 case OPC_COPY_U_df:
20440 case OPC_INSERT_df:
20441#if !defined(TARGET_MIPS64)
20442 /* Double format valid only for MIPS64 */
20443 if (df == DF_DOUBLE) {
9c708c7f 20444 generate_exception_end(ctx, EXCP_RI);
1e608ec1
YK
20445 break;
20446 }
20447#endif
20448 switch (MASK_MSA_ELM(ctx->opcode)) {
20449 case OPC_COPY_S_df:
cab48881
MD
20450 if (likely(wd != 0)) {
20451 gen_helper_msa_copy_s_df(cpu_env, tdf, twd, tws, tn);
20452 }
1e608ec1
YK
20453 break;
20454 case OPC_COPY_U_df:
cab48881
MD
20455 if (likely(wd != 0)) {
20456 gen_helper_msa_copy_u_df(cpu_env, tdf, twd, tws, tn);
20457 }
1e608ec1
YK
20458 break;
20459 case OPC_INSERT_df:
20460 gen_helper_msa_insert_df(cpu_env, tdf, twd, tws, tn);
20461 break;
20462 }
20463 break;
20464 default:
20465 MIPS_INVAL("MSA instruction");
9c708c7f 20466 generate_exception_end(ctx, EXCP_RI);
1e608ec1
YK
20467 }
20468 tcg_temp_free_i32(twd);
20469 tcg_temp_free_i32(tws);
20470 tcg_temp_free_i32(tn);
20471 tcg_temp_free_i32(tdf);
20472}
20473
20474static void gen_msa_elm(CPUMIPSState *env, DisasContext *ctx)
20475{
20476 uint8_t dfn = (ctx->opcode >> 16) & 0x3f;
20477 uint32_t df = 0, n = 0;
20478
20479 if ((dfn & 0x30) == 0x00) {
20480 n = dfn & 0x0f;
20481 df = DF_BYTE;
20482 } else if ((dfn & 0x38) == 0x20) {
20483 n = dfn & 0x07;
20484 df = DF_HALF;
20485 } else if ((dfn & 0x3c) == 0x30) {
20486 n = dfn & 0x03;
20487 df = DF_WORD;
20488 } else if ((dfn & 0x3e) == 0x38) {
20489 n = dfn & 0x01;
20490 df = DF_DOUBLE;
20491 } else if (dfn == 0x3E) {
20492 /* CTCMSA, CFCMSA, MOVE.V */
20493 gen_msa_elm_3e(env, ctx);
20494 return;
20495 } else {
9c708c7f 20496 generate_exception_end(ctx, EXCP_RI);
1e608ec1
YK
20497 return;
20498 }
20499
20500 gen_msa_elm_df(env, ctx, df, n);
20501}
20502
7d05b9c8
YK
20503static void gen_msa_3rf(CPUMIPSState *env, DisasContext *ctx)
20504{
20505#define MASK_MSA_3RF(op) (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
20506 uint8_t df = (ctx->opcode >> 21) & 0x1;
20507 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
20508 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
20509 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
20510
20511 TCGv_i32 twd = tcg_const_i32(wd);
20512 TCGv_i32 tws = tcg_const_i32(ws);
20513 TCGv_i32 twt = tcg_const_i32(wt);
20514 TCGv_i32 tdf = tcg_temp_new_i32();
20515
20516 /* adjust df value for floating-point instruction */
20517 tcg_gen_movi_i32(tdf, df + 2);
20518
20519 switch (MASK_MSA_3RF(ctx->opcode)) {
20520 case OPC_FCAF_df:
20521 gen_helper_msa_fcaf_df(cpu_env, tdf, twd, tws, twt);
20522 break;
20523 case OPC_FADD_df:
20524 gen_helper_msa_fadd_df(cpu_env, tdf, twd, tws, twt);
20525 break;
20526 case OPC_FCUN_df:
20527 gen_helper_msa_fcun_df(cpu_env, tdf, twd, tws, twt);
20528 break;
20529 case OPC_FSUB_df:
20530 gen_helper_msa_fsub_df(cpu_env, tdf, twd, tws, twt);
20531 break;
20532 case OPC_FCOR_df:
20533 gen_helper_msa_fcor_df(cpu_env, tdf, twd, tws, twt);
20534 break;
20535 case OPC_FCEQ_df:
20536 gen_helper_msa_fceq_df(cpu_env, tdf, twd, tws, twt);
20537 break;
20538 case OPC_FMUL_df:
20539 gen_helper_msa_fmul_df(cpu_env, tdf, twd, tws, twt);
20540 break;
20541 case OPC_FCUNE_df:
20542 gen_helper_msa_fcune_df(cpu_env, tdf, twd, tws, twt);
20543 break;
20544 case OPC_FCUEQ_df:
20545 gen_helper_msa_fcueq_df(cpu_env, tdf, twd, tws, twt);
20546 break;
20547 case OPC_FDIV_df:
20548 gen_helper_msa_fdiv_df(cpu_env, tdf, twd, tws, twt);
20549 break;
20550 case OPC_FCNE_df:
20551 gen_helper_msa_fcne_df(cpu_env, tdf, twd, tws, twt);
20552 break;
20553 case OPC_FCLT_df:
20554 gen_helper_msa_fclt_df(cpu_env, tdf, twd, tws, twt);
20555 break;
20556 case OPC_FMADD_df:
20557 gen_helper_msa_fmadd_df(cpu_env, tdf, twd, tws, twt);
20558 break;
20559 case OPC_MUL_Q_df:
20560 tcg_gen_movi_i32(tdf, df + 1);
20561 gen_helper_msa_mul_q_df(cpu_env, tdf, twd, tws, twt);
20562 break;
20563 case OPC_FCULT_df:
20564 gen_helper_msa_fcult_df(cpu_env, tdf, twd, tws, twt);
20565 break;
20566 case OPC_FMSUB_df:
20567 gen_helper_msa_fmsub_df(cpu_env, tdf, twd, tws, twt);
20568 break;
20569 case OPC_MADD_Q_df:
20570 tcg_gen_movi_i32(tdf, df + 1);
20571 gen_helper_msa_madd_q_df(cpu_env, tdf, twd, tws, twt);
20572 break;
20573 case OPC_FCLE_df:
20574 gen_helper_msa_fcle_df(cpu_env, tdf, twd, tws, twt);
20575 break;
20576 case OPC_MSUB_Q_df:
20577 tcg_gen_movi_i32(tdf, df + 1);
20578 gen_helper_msa_msub_q_df(cpu_env, tdf, twd, tws, twt);
20579 break;
20580 case OPC_FCULE_df:
20581 gen_helper_msa_fcule_df(cpu_env, tdf, twd, tws, twt);
20582 break;
20583 case OPC_FEXP2_df:
20584 gen_helper_msa_fexp2_df(cpu_env, tdf, twd, tws, twt);
20585 break;
20586 case OPC_FSAF_df:
20587 gen_helper_msa_fsaf_df(cpu_env, tdf, twd, tws, twt);
20588 break;
20589 case OPC_FEXDO_df:
20590 gen_helper_msa_fexdo_df(cpu_env, tdf, twd, tws, twt);
20591 break;
20592 case OPC_FSUN_df:
20593 gen_helper_msa_fsun_df(cpu_env, tdf, twd, tws, twt);
20594 break;
20595 case OPC_FSOR_df:
20596 gen_helper_msa_fsor_df(cpu_env, tdf, twd, tws, twt);
20597 break;
20598 case OPC_FSEQ_df:
20599 gen_helper_msa_fseq_df(cpu_env, tdf, twd, tws, twt);
20600 break;
20601 case OPC_FTQ_df:
20602 gen_helper_msa_ftq_df(cpu_env, tdf, twd, tws, twt);
20603 break;
20604 case OPC_FSUNE_df:
20605 gen_helper_msa_fsune_df(cpu_env, tdf, twd, tws, twt);
20606 break;
20607 case OPC_FSUEQ_df:
20608 gen_helper_msa_fsueq_df(cpu_env, tdf, twd, tws, twt);
20609 break;
20610 case OPC_FSNE_df:
20611 gen_helper_msa_fsne_df(cpu_env, tdf, twd, tws, twt);
20612 break;
20613 case OPC_FSLT_df:
20614 gen_helper_msa_fslt_df(cpu_env, tdf, twd, tws, twt);
20615 break;
20616 case OPC_FMIN_df:
20617 gen_helper_msa_fmin_df(cpu_env, tdf, twd, tws, twt);
20618 break;
20619 case OPC_MULR_Q_df:
20620 tcg_gen_movi_i32(tdf, df + 1);
20621 gen_helper_msa_mulr_q_df(cpu_env, tdf, twd, tws, twt);
20622 break;
20623 case OPC_FSULT_df:
20624 gen_helper_msa_fsult_df(cpu_env, tdf, twd, tws, twt);
20625 break;
20626 case OPC_FMIN_A_df:
20627 gen_helper_msa_fmin_a_df(cpu_env, tdf, twd, tws, twt);
20628 break;
20629 case OPC_MADDR_Q_df:
20630 tcg_gen_movi_i32(tdf, df + 1);
20631 gen_helper_msa_maddr_q_df(cpu_env, tdf, twd, tws, twt);
20632 break;
20633 case OPC_FSLE_df:
20634 gen_helper_msa_fsle_df(cpu_env, tdf, twd, tws, twt);
20635 break;
20636 case OPC_FMAX_df:
20637 gen_helper_msa_fmax_df(cpu_env, tdf, twd, tws, twt);
20638 break;
20639 case OPC_MSUBR_Q_df:
20640 tcg_gen_movi_i32(tdf, df + 1);
20641 gen_helper_msa_msubr_q_df(cpu_env, tdf, twd, tws, twt);
20642 break;
20643 case OPC_FSULE_df:
20644 gen_helper_msa_fsule_df(cpu_env, tdf, twd, tws, twt);
20645 break;
20646 case OPC_FMAX_A_df:
20647 gen_helper_msa_fmax_a_df(cpu_env, tdf, twd, tws, twt);
20648 break;
20649 default:
20650 MIPS_INVAL("MSA instruction");
9c708c7f 20651 generate_exception_end(ctx, EXCP_RI);
7d05b9c8
YK
20652 break;
20653 }
20654
20655 tcg_temp_free_i32(twd);
20656 tcg_temp_free_i32(tws);
20657 tcg_temp_free_i32(twt);
20658 tcg_temp_free_i32(tdf);
20659}
20660
cbe50b9a
YK
20661static void gen_msa_2r(CPUMIPSState *env, DisasContext *ctx)
20662{
20663#define MASK_MSA_2R(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
20664 (op & (0x7 << 18)))
20665 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
20666 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
20667 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
20668 uint8_t df = (ctx->opcode >> 16) & 0x3;
20669 TCGv_i32 twd = tcg_const_i32(wd);
20670 TCGv_i32 tws = tcg_const_i32(ws);
20671 TCGv_i32 twt = tcg_const_i32(wt);
20672 TCGv_i32 tdf = tcg_const_i32(df);
20673
20674 switch (MASK_MSA_2R(ctx->opcode)) {
20675 case OPC_FILL_df:
20676#if !defined(TARGET_MIPS64)
20677 /* Double format valid only for MIPS64 */
20678 if (df == DF_DOUBLE) {
9c708c7f 20679 generate_exception_end(ctx, EXCP_RI);
cbe50b9a
YK
20680 break;
20681 }
20682#endif
20683 gen_helper_msa_fill_df(cpu_env, tdf, twd, tws); /* trs */
20684 break;
20685 case OPC_PCNT_df:
20686 gen_helper_msa_pcnt_df(cpu_env, tdf, twd, tws);
20687 break;
20688 case OPC_NLOC_df:
20689 gen_helper_msa_nloc_df(cpu_env, tdf, twd, tws);
20690 break;
20691 case OPC_NLZC_df:
20692 gen_helper_msa_nlzc_df(cpu_env, tdf, twd, tws);
20693 break;
20694 default:
20695 MIPS_INVAL("MSA instruction");
9c708c7f 20696 generate_exception_end(ctx, EXCP_RI);
cbe50b9a
YK
20697 break;
20698 }
20699
20700 tcg_temp_free_i32(twd);
20701 tcg_temp_free_i32(tws);
20702 tcg_temp_free_i32(twt);
20703 tcg_temp_free_i32(tdf);
20704}
20705
3bdeb688
YK
20706static void gen_msa_2rf(CPUMIPSState *env, DisasContext *ctx)
20707{
20708#define MASK_MSA_2RF(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
20709 (op & (0xf << 17)))
20710 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
20711 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
20712 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
20713 uint8_t df = (ctx->opcode >> 16) & 0x1;
20714 TCGv_i32 twd = tcg_const_i32(wd);
20715 TCGv_i32 tws = tcg_const_i32(ws);
20716 TCGv_i32 twt = tcg_const_i32(wt);
20717 /* adjust df value for floating-point instruction */
20718 TCGv_i32 tdf = tcg_const_i32(df + 2);
20719
20720 switch (MASK_MSA_2RF(ctx->opcode)) {
20721 case OPC_FCLASS_df:
20722 gen_helper_msa_fclass_df(cpu_env, tdf, twd, tws);
20723 break;
20724 case OPC_FTRUNC_S_df:
20725 gen_helper_msa_ftrunc_s_df(cpu_env, tdf, twd, tws);
20726 break;
20727 case OPC_FTRUNC_U_df:
20728 gen_helper_msa_ftrunc_u_df(cpu_env, tdf, twd, tws);
20729 break;
20730 case OPC_FSQRT_df:
20731 gen_helper_msa_fsqrt_df(cpu_env, tdf, twd, tws);
20732 break;
20733 case OPC_FRSQRT_df:
20734 gen_helper_msa_frsqrt_df(cpu_env, tdf, twd, tws);
20735 break;
20736 case OPC_FRCP_df:
20737 gen_helper_msa_frcp_df(cpu_env, tdf, twd, tws);
20738 break;
20739 case OPC_FRINT_df:
20740 gen_helper_msa_frint_df(cpu_env, tdf, twd, tws);
20741 break;
20742 case OPC_FLOG2_df:
20743 gen_helper_msa_flog2_df(cpu_env, tdf, twd, tws);
20744 break;
20745 case OPC_FEXUPL_df:
20746 gen_helper_msa_fexupl_df(cpu_env, tdf, twd, tws);
20747 break;
20748 case OPC_FEXUPR_df:
20749 gen_helper_msa_fexupr_df(cpu_env, tdf, twd, tws);
20750 break;
20751 case OPC_FFQL_df:
20752 gen_helper_msa_ffql_df(cpu_env, tdf, twd, tws);
20753 break;
20754 case OPC_FFQR_df:
20755 gen_helper_msa_ffqr_df(cpu_env, tdf, twd, tws);
20756 break;
20757 case OPC_FTINT_S_df:
20758 gen_helper_msa_ftint_s_df(cpu_env, tdf, twd, tws);
20759 break;
20760 case OPC_FTINT_U_df:
20761 gen_helper_msa_ftint_u_df(cpu_env, tdf, twd, tws);
20762 break;
20763 case OPC_FFINT_S_df:
20764 gen_helper_msa_ffint_s_df(cpu_env, tdf, twd, tws);
20765 break;
20766 case OPC_FFINT_U_df:
20767 gen_helper_msa_ffint_u_df(cpu_env, tdf, twd, tws);
20768 break;
20769 }
20770
20771 tcg_temp_free_i32(twd);
20772 tcg_temp_free_i32(tws);
20773 tcg_temp_free_i32(twt);
20774 tcg_temp_free_i32(tdf);
20775}
20776
cbe50b9a
YK
20777static void gen_msa_vec_v(CPUMIPSState *env, DisasContext *ctx)
20778{
20779#define MASK_MSA_VEC(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)))
20780 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
20781 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
20782 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
20783 TCGv_i32 twd = tcg_const_i32(wd);
20784 TCGv_i32 tws = tcg_const_i32(ws);
20785 TCGv_i32 twt = tcg_const_i32(wt);
20786
20787 switch (MASK_MSA_VEC(ctx->opcode)) {
20788 case OPC_AND_V:
20789 gen_helper_msa_and_v(cpu_env, twd, tws, twt);
20790 break;
20791 case OPC_OR_V:
20792 gen_helper_msa_or_v(cpu_env, twd, tws, twt);
20793 break;
20794 case OPC_NOR_V:
20795 gen_helper_msa_nor_v(cpu_env, twd, tws, twt);
20796 break;
20797 case OPC_XOR_V:
20798 gen_helper_msa_xor_v(cpu_env, twd, tws, twt);
20799 break;
20800 case OPC_BMNZ_V:
20801 gen_helper_msa_bmnz_v(cpu_env, twd, tws, twt);
20802 break;
20803 case OPC_BMZ_V:
20804 gen_helper_msa_bmz_v(cpu_env, twd, tws, twt);
20805 break;
20806 case OPC_BSEL_V:
20807 gen_helper_msa_bsel_v(cpu_env, twd, tws, twt);
20808 break;
20809 default:
20810 MIPS_INVAL("MSA instruction");
9c708c7f 20811 generate_exception_end(ctx, EXCP_RI);
cbe50b9a
YK
20812 break;
20813 }
20814
20815 tcg_temp_free_i32(twd);
20816 tcg_temp_free_i32(tws);
20817 tcg_temp_free_i32(twt);
20818}
20819
20820static void gen_msa_vec(CPUMIPSState *env, DisasContext *ctx)
20821{
20822 switch (MASK_MSA_VEC(ctx->opcode)) {
20823 case OPC_AND_V:
20824 case OPC_OR_V:
20825 case OPC_NOR_V:
20826 case OPC_XOR_V:
20827 case OPC_BMNZ_V:
20828 case OPC_BMZ_V:
20829 case OPC_BSEL_V:
20830 gen_msa_vec_v(env, ctx);
20831 break;
20832 case OPC_MSA_2R:
20833 gen_msa_2r(env, ctx);
20834 break;
3bdeb688
YK
20835 case OPC_MSA_2RF:
20836 gen_msa_2rf(env, ctx);
20837 break;
cbe50b9a
YK
20838 default:
20839 MIPS_INVAL("MSA instruction");
9c708c7f 20840 generate_exception_end(ctx, EXCP_RI);
cbe50b9a
YK
20841 break;
20842 }
20843}
20844
4c789546
YK
20845static void gen_msa(CPUMIPSState *env, DisasContext *ctx)
20846{
20847 uint32_t opcode = ctx->opcode;
20848 check_insn(ctx, ASE_MSA);
20849 check_msa_access(ctx);
20850
20851 switch (MASK_MSA_MINOR(opcode)) {
20852 case OPC_MSA_I8_00:
20853 case OPC_MSA_I8_01:
20854 case OPC_MSA_I8_02:
20855 gen_msa_i8(env, ctx);
20856 break;
80e71591
YK
20857 case OPC_MSA_I5_06:
20858 case OPC_MSA_I5_07:
20859 gen_msa_i5(env, ctx);
20860 break;
d4cf28de
YK
20861 case OPC_MSA_BIT_09:
20862 case OPC_MSA_BIT_0A:
20863 gen_msa_bit(env, ctx);
20864 break;
28f99f08
YK
20865 case OPC_MSA_3R_0D:
20866 case OPC_MSA_3R_0E:
20867 case OPC_MSA_3R_0F:
20868 case OPC_MSA_3R_10:
20869 case OPC_MSA_3R_11:
20870 case OPC_MSA_3R_12:
20871 case OPC_MSA_3R_13:
20872 case OPC_MSA_3R_14:
20873 case OPC_MSA_3R_15:
20874 gen_msa_3r(env, ctx);
20875 break;
1e608ec1
YK
20876 case OPC_MSA_ELM:
20877 gen_msa_elm(env, ctx);
20878 break;
7d05b9c8
YK
20879 case OPC_MSA_3RF_1A:
20880 case OPC_MSA_3RF_1B:
20881 case OPC_MSA_3RF_1C:
20882 gen_msa_3rf(env, ctx);
20883 break;
cbe50b9a
YK
20884 case OPC_MSA_VEC:
20885 gen_msa_vec(env, ctx);
20886 break;
f7685877
YK
20887 case OPC_LD_B:
20888 case OPC_LD_H:
20889 case OPC_LD_W:
20890 case OPC_LD_D:
20891 case OPC_ST_B:
20892 case OPC_ST_H:
20893 case OPC_ST_W:
20894 case OPC_ST_D:
20895 {
20896 int32_t s10 = sextract32(ctx->opcode, 16, 10);
20897 uint8_t rs = (ctx->opcode >> 11) & 0x1f;
20898 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
20899 uint8_t df = (ctx->opcode >> 0) & 0x3;
20900
f7685877 20901 TCGv_i32 twd = tcg_const_i32(wd);
adc370a4
YK
20902 TCGv taddr = tcg_temp_new();
20903 gen_base_offset_addr(ctx, taddr, rs, s10 << df);
f7685877
YK
20904
20905 switch (MASK_MSA_MINOR(opcode)) {
20906 case OPC_LD_B:
adc370a4
YK
20907 gen_helper_msa_ld_b(cpu_env, twd, taddr);
20908 break;
f7685877 20909 case OPC_LD_H:
adc370a4
YK
20910 gen_helper_msa_ld_h(cpu_env, twd, taddr);
20911 break;
f7685877 20912 case OPC_LD_W:
adc370a4
YK
20913 gen_helper_msa_ld_w(cpu_env, twd, taddr);
20914 break;
f7685877 20915 case OPC_LD_D:
adc370a4 20916 gen_helper_msa_ld_d(cpu_env, twd, taddr);
f7685877
YK
20917 break;
20918 case OPC_ST_B:
adc370a4
YK
20919 gen_helper_msa_st_b(cpu_env, twd, taddr);
20920 break;
f7685877 20921 case OPC_ST_H:
adc370a4
YK
20922 gen_helper_msa_st_h(cpu_env, twd, taddr);
20923 break;
f7685877 20924 case OPC_ST_W:
adc370a4
YK
20925 gen_helper_msa_st_w(cpu_env, twd, taddr);
20926 break;
f7685877 20927 case OPC_ST_D:
adc370a4 20928 gen_helper_msa_st_d(cpu_env, twd, taddr);
f7685877
YK
20929 break;
20930 }
20931
20932 tcg_temp_free_i32(twd);
adc370a4 20933 tcg_temp_free(taddr);
f7685877
YK
20934 }
20935 break;
4c789546
YK
20936 default:
20937 MIPS_INVAL("MSA instruction");
9c708c7f 20938 generate_exception_end(ctx, EXCP_RI);
4c789546
YK
20939 break;
20940 }
20941
20942}
20943
d2bfa6e6 20944static void decode_opc(CPUMIPSState *env, DisasContext *ctx)
099e5b4d
LA
20945{
20946 int32_t offset;
20947 int rs, rt, rd, sa;
20948 uint32_t op, op1;
20949 int16_t imm;
20950
20951 /* make sure instructions are on a word boundary */
eeb3bba8
EC
20952 if (ctx->base.pc_next & 0x3) {
20953 env->CP0_BadVAddr = ctx->base.pc_next;
aea14095 20954 generate_exception_err(ctx, EXCP_AdEL, EXCP_INST_NOTAVAIL);
099e5b4d
LA
20955 return;
20956 }
20957
20958 /* Handle blikely not taken case */
20959 if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
42a268c2 20960 TCGLabel *l1 = gen_new_label();
099e5b4d 20961
099e5b4d
LA
20962 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
20963 tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
eeb3bba8 20964 gen_goto_tb(ctx, 1, ctx->base.pc_next + 4);
099e5b4d
LA
20965 gen_set_label(l1);
20966 }
20967
099e5b4d
LA
20968 op = MASK_OP_MAJOR(ctx->opcode);
20969 rs = (ctx->opcode >> 21) & 0x1f;
20970 rt = (ctx->opcode >> 16) & 0x1f;
20971 rd = (ctx->opcode >> 11) & 0x1f;
20972 sa = (ctx->opcode >> 6) & 0x1f;
20973 imm = (int16_t)ctx->opcode;
20974 switch (op) {
20975 case OPC_SPECIAL:
20976 decode_opc_special(env, ctx);
20977 break;
20978 case OPC_SPECIAL2:
4267d3e6 20979 decode_opc_special2_legacy(env, ctx);
099e5b4d
LA
20980 break;
20981 case OPC_SPECIAL3:
20982 decode_opc_special3(env, ctx);
20983 break;
7a387fff
TS
20984 case OPC_REGIMM:
20985 op1 = MASK_REGIMM(ctx->opcode);
20986 switch (op1) {
fecd2646
LA
20987 case OPC_BLTZL: /* REGIMM branches */
20988 case OPC_BGEZL:
20989 case OPC_BLTZALL:
20990 case OPC_BGEZALL:
d9224450 20991 check_insn(ctx, ISA_MIPS2);
fecd2646 20992 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d9224450 20993 /* Fallthrough */
fecd2646
LA
20994 case OPC_BLTZ:
20995 case OPC_BGEZ:
b231c103 20996 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
0aefa333 20997 break;
fecd2646
LA
20998 case OPC_BLTZAL:
20999 case OPC_BGEZAL:
0aefa333
YK
21000 if (ctx->insn_flags & ISA_MIPS32R6) {
21001 if (rs == 0) {
21002 /* OPC_NAL, OPC_BAL */
b231c103 21003 gen_compute_branch(ctx, op1, 4, 0, -1, imm << 2, 4);
0aefa333 21004 } else {
9c708c7f 21005 generate_exception_end(ctx, EXCP_RI);
0aefa333
YK
21006 }
21007 } else {
b231c103 21008 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
0aefa333 21009 }
c9602061 21010 break;
c2e19f3c
AM
21011 case OPC_TGEI: /* REGIMM traps */
21012 case OPC_TGEIU:
21013 case OPC_TLTI:
21014 case OPC_TLTIU:
21015 case OPC_TEQI:
21016
7a387fff 21017 case OPC_TNEI:
d9224450 21018 check_insn(ctx, ISA_MIPS2);
fecd2646 21019 check_insn_opc_removed(ctx, ISA_MIPS32R6);
7a387fff
TS
21020 gen_trap(ctx, op1, rs, -1, imm);
21021 break;
bb238210
YK
21022 case OPC_SIGRIE:
21023 check_insn(ctx, ISA_MIPS32R6);
21024 generate_exception_end(ctx, EXCP_RI);
21025 break;
7a387fff 21026 case OPC_SYNCI:
d75c135e 21027 check_insn(ctx, ISA_MIPS32R2);
a83bddd6
DZ
21028 /* Break the TB to be able to sync copied instructions
21029 immediately */
eeb3bba8 21030 ctx->base.is_jmp = DISAS_STOP;
6af0bf9c 21031 break;
e45a93e2
JL
21032 case OPC_BPOSGE32: /* MIPS DSP branch */
21033#if defined(TARGET_MIPS64)
21034 case OPC_BPOSGE64:
21035#endif
21036 check_dsp(ctx);
b231c103 21037 gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2, 4);
e45a93e2 21038 break;
d4ea6acd
LA
21039#if defined(TARGET_MIPS64)
21040 case OPC_DAHI:
21041 check_insn(ctx, ISA_MIPS32R6);
21042 check_mips_64(ctx);
21043 if (rs != 0) {
21044 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 32);
21045 }
d4ea6acd
LA
21046 break;
21047 case OPC_DATI:
21048 check_insn(ctx, ISA_MIPS32R6);
21049 check_mips_64(ctx);
21050 if (rs != 0) {
21051 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 48);
21052 }
d4ea6acd
LA
21053 break;
21054#endif
6af0bf9c 21055 default: /* Invalid */
923617a3 21056 MIPS_INVAL("regimm");
9c708c7f 21057 generate_exception_end(ctx, EXCP_RI);
6af0bf9c
FB
21058 break;
21059 }
21060 break;
7a387fff 21061 case OPC_CP0:
387a8fe5 21062 check_cp0_enabled(ctx);
7a387fff 21063 op1 = MASK_CP0(ctx->opcode);
6af0bf9c 21064 switch (op1) {
7a387fff
TS
21065 case OPC_MFC0:
21066 case OPC_MTC0:
ead9360e
TS
21067 case OPC_MFTR:
21068 case OPC_MTTR:
5204ea79
LA
21069 case OPC_MFHC0:
21070 case OPC_MTHC0:
d26bc211 21071#if defined(TARGET_MIPS64)
7a387fff
TS
21072 case OPC_DMFC0:
21073 case OPC_DMTC0:
21074#endif
f1aa6320 21075#ifndef CONFIG_USER_ONLY
932e71cd 21076 gen_cp0(env, ctx, op1, rt, rd);
0eaef5aa 21077#endif /* !CONFIG_USER_ONLY */
7a387fff 21078 break;
c38a1d52
AR
21079 case OPC_C0:
21080 case OPC_C0_1:
21081 case OPC_C0_2:
21082 case OPC_C0_3:
21083 case OPC_C0_4:
21084 case OPC_C0_5:
21085 case OPC_C0_6:
21086 case OPC_C0_7:
21087 case OPC_C0_8:
21088 case OPC_C0_9:
21089 case OPC_C0_A:
21090 case OPC_C0_B:
21091 case OPC_C0_C:
21092 case OPC_C0_D:
21093 case OPC_C0_E:
21094 case OPC_C0_F:
f1aa6320 21095#ifndef CONFIG_USER_ONLY
932e71cd 21096 gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
0eaef5aa 21097#endif /* !CONFIG_USER_ONLY */
7a387fff
TS
21098 break;
21099 case OPC_MFMC0:
8706c382 21100#ifndef CONFIG_USER_ONLY
932e71cd 21101 {
099e5b4d 21102 uint32_t op2;
35fbce2c 21103 TCGv t0 = tcg_temp_new();
6c5c1e20 21104
0eaef5aa 21105 op2 = MASK_MFMC0(ctx->opcode);
6c5c1e20
TS
21106 switch (op2) {
21107 case OPC_DMT:
d75c135e 21108 check_insn(ctx, ASE_MT);
9ed5726c 21109 gen_helper_dmt(t0);
35fbce2c 21110 gen_store_gpr(t0, rt);
6c5c1e20
TS
21111 break;
21112 case OPC_EMT:
d75c135e 21113 check_insn(ctx, ASE_MT);
9ed5726c 21114 gen_helper_emt(t0);
35fbce2c 21115 gen_store_gpr(t0, rt);
da80682b 21116 break;
6c5c1e20 21117 case OPC_DVPE:
d75c135e 21118 check_insn(ctx, ASE_MT);
895c2d04 21119 gen_helper_dvpe(t0, cpu_env);
35fbce2c 21120 gen_store_gpr(t0, rt);
6c5c1e20
TS
21121 break;
21122 case OPC_EVPE:
d75c135e 21123 check_insn(ctx, ASE_MT);
895c2d04 21124 gen_helper_evpe(t0, cpu_env);
35fbce2c 21125 gen_store_gpr(t0, rt);
6c5c1e20 21126 break;
01bc435b
YK
21127 case OPC_DVP:
21128 check_insn(ctx, ISA_MIPS32R6);
21129 if (ctx->vp) {
21130 gen_helper_dvp(t0, cpu_env);
21131 gen_store_gpr(t0, rt);
21132 }
21133 break;
21134 case OPC_EVP:
21135 check_insn(ctx, ISA_MIPS32R6);
21136 if (ctx->vp) {
21137 gen_helper_evp(t0, cpu_env);
21138 gen_store_gpr(t0, rt);
21139 }
21140 break;
6c5c1e20 21141 case OPC_DI:
d75c135e 21142 check_insn(ctx, ISA_MIPS32R2);
867abc7e 21143 save_cpu_state(ctx, 1);
895c2d04 21144 gen_helper_di(t0, cpu_env);
35fbce2c 21145 gen_store_gpr(t0, rt);
d2bfa6e6
MR
21146 /* Stop translation as we may have switched
21147 the execution mode. */
eeb3bba8 21148 ctx->base.is_jmp = DISAS_STOP;
6c5c1e20
TS
21149 break;
21150 case OPC_EI:
d75c135e 21151 check_insn(ctx, ISA_MIPS32R2);
867abc7e 21152 save_cpu_state(ctx, 1);
895c2d04 21153 gen_helper_ei(t0, cpu_env);
35fbce2c 21154 gen_store_gpr(t0, rt);
b28425ba
EC
21155 /* DISAS_STOP isn't sufficient, we need to ensure we break
21156 out of translated code to check for pending interrupts */
eeb3bba8
EC
21157 gen_save_pc(ctx->base.pc_next + 4);
21158 ctx->base.is_jmp = DISAS_EXIT;
6c5c1e20
TS
21159 break;
21160 default: /* Invalid */
21161 MIPS_INVAL("mfmc0");
9c708c7f 21162 generate_exception_end(ctx, EXCP_RI);
6c5c1e20
TS
21163 break;
21164 }
6c5c1e20 21165 tcg_temp_free(t0);
7a387fff 21166 }
0eaef5aa 21167#endif /* !CONFIG_USER_ONLY */
6af0bf9c 21168 break;
7a387fff 21169 case OPC_RDPGPR:
d75c135e 21170 check_insn(ctx, ISA_MIPS32R2);
be24bb4f 21171 gen_load_srsgpr(rt, rd);
ead9360e 21172 break;
7a387fff 21173 case OPC_WRPGPR:
d75c135e 21174 check_insn(ctx, ISA_MIPS32R2);
be24bb4f 21175 gen_store_srsgpr(rt, rd);
38121543 21176 break;
6af0bf9c 21177 default:
923617a3 21178 MIPS_INVAL("cp0");
9c708c7f 21179 generate_exception_end(ctx, EXCP_RI);
6af0bf9c
FB
21180 break;
21181 }
21182 break;
31837be3
YK
21183 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC, OPC_ADDI */
21184 if (ctx->insn_flags & ISA_MIPS32R6) {
21185 /* OPC_BOVC, OPC_BEQZALC, OPC_BEQC */
21186 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
21187 } else {
21188 /* OPC_ADDI */
21189 /* Arithmetic with immediate opcode */
21190 gen_arith_imm(ctx, op, rt, rs, imm);
21191 }
21192 break;
324d9e32 21193 case OPC_ADDIU:
d75c135e 21194 gen_arith_imm(ctx, op, rt, rs, imm);
7a387fff 21195 break;
324d9e32
AJ
21196 case OPC_SLTI: /* Set on less than with immediate opcode */
21197 case OPC_SLTIU:
d75c135e 21198 gen_slt_imm(ctx, op, rt, rs, imm);
324d9e32
AJ
21199 break;
21200 case OPC_ANDI: /* Arithmetic with immediate opcode */
d4ea6acd 21201 case OPC_LUI: /* OPC_AUI */
324d9e32
AJ
21202 case OPC_ORI:
21203 case OPC_XORI:
d75c135e 21204 gen_logic_imm(ctx, op, rt, rs, imm);
324d9e32 21205 break;
c2e19f3c
AM
21206 case OPC_J: /* Jump */
21207 case OPC_JAL:
7a387fff 21208 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
b231c103 21209 gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
c9602061 21210 break;
31837be3
YK
21211 /* Branch */
21212 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC, OPC_BLEZL */
21213 if (ctx->insn_flags & ISA_MIPS32R6) {
21214 if (rt == 0) {
9c708c7f 21215 generate_exception_end(ctx, EXCP_RI);
31837be3
YK
21216 break;
21217 }
21218 /* OPC_BLEZC, OPC_BGEZC, OPC_BGEC */
21219 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
21220 } else {
21221 /* OPC_BLEZL */
b231c103 21222 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
31837be3
YK
21223 }
21224 break;
21225 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC, OPC_BGTZL */
21226 if (ctx->insn_flags & ISA_MIPS32R6) {
21227 if (rt == 0) {
9c708c7f 21228 generate_exception_end(ctx, EXCP_RI);
31837be3
YK
21229 break;
21230 }
21231 /* OPC_BGTZC, OPC_BLTZC, OPC_BLTC */
21232 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
21233 } else {
21234 /* OPC_BGTZL */
b231c103 21235 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
31837be3
YK
21236 }
21237 break;
21238 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC, OPC_BLEZ */
21239 if (rt == 0) {
21240 /* OPC_BLEZ */
b231c103 21241 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
31837be3
YK
21242 } else {
21243 check_insn(ctx, ISA_MIPS32R6);
21244 /* OPC_BLEZALC, OPC_BGEZALC, OPC_BGEUC */
21245 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
21246 }
21247 break;
21248 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC, OPC_BGTZ */
21249 if (rt == 0) {
21250 /* OPC_BGTZ */
b231c103 21251 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
31837be3
YK
21252 } else {
21253 check_insn(ctx, ISA_MIPS32R6);
21254 /* OPC_BGTZALC, OPC_BLTZALC, OPC_BLTUC */
21255 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
21256 }
21257 break;
21258 case OPC_BEQL:
21259 case OPC_BNEL:
d9224450 21260 check_insn(ctx, ISA_MIPS2);
fecd2646 21261 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d9224450 21262 /* Fallthrough */
31837be3
YK
21263 case OPC_BEQ:
21264 case OPC_BNE:
b231c103 21265 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
c9602061 21266 break;
d9224450
MR
21267 case OPC_LL: /* Load and stores */
21268 check_insn(ctx, ISA_MIPS2);
21269 /* Fallthrough */
21270 case OPC_LWL:
fecd2646
LA
21271 case OPC_LWR:
21272 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d9224450 21273 /* Fallthrough */
c2e19f3c
AM
21274 case OPC_LB:
21275 case OPC_LH:
21276 case OPC_LW:
21277 case OPC_LWPC:
21278 case OPC_LBU:
21279 case OPC_LHU:
d75c135e 21280 gen_ld(ctx, op, rt, rs, imm);
5c13fdfd 21281 break;
fecd2646 21282 case OPC_SWL:
7a387fff 21283 case OPC_SWR:
fecd2646 21284 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b6f3b233 21285 /* fall through */
c2e19f3c
AM
21286 case OPC_SB:
21287 case OPC_SH:
fecd2646 21288 case OPC_SW:
5c13fdfd 21289 gen_st(ctx, op, rt, rs, imm);
7a387fff 21290 break;
d66c7132 21291 case OPC_SC:
d9224450 21292 check_insn(ctx, ISA_MIPS2);
4368b29a 21293 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d66c7132
AJ
21294 gen_st_cond(ctx, op, rt, rs, imm);
21295 break;
7a387fff 21296 case OPC_CACHE:
bf7910c6 21297 check_insn_opc_removed(ctx, ISA_MIPS32R6);
2e15497c 21298 check_cp0_enabled(ctx);
d75c135e 21299 check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
0d74a222
LA
21300 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
21301 gen_cache_operation(ctx, rt, rs, imm);
21302 }
ead9360e 21303 /* Treat as NOP. */
34ae7b51 21304 break;
7a387fff 21305 case OPC_PREF:
bf7910c6 21306 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d75c135e 21307 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
ead9360e 21308 /* Treat as NOP. */
6af0bf9c 21309 break;
4ad40f36 21310
923617a3 21311 /* Floating point (COP1). */
7a387fff
TS
21312 case OPC_LWC1:
21313 case OPC_LDC1:
21314 case OPC_SWC1:
21315 case OPC_SDC1:
5ab5c041 21316 gen_cop1_ldst(ctx, op, rt, rs, imm);
6ea83fed
FB
21317 break;
21318
7a387fff 21319 case OPC_CP1:
5692c6e1
YK
21320 op1 = MASK_CP1(ctx->opcode);
21321
21322 switch (op1) {
21323 case OPC_MFHC1:
21324 case OPC_MTHC1:
5e755519 21325 check_cp1_enabled(ctx);
5692c6e1 21326 check_insn(ctx, ISA_MIPS32R2);
146dd620 21327 /* fall through */
5692c6e1
YK
21328 case OPC_MFC1:
21329 case OPC_CFC1:
21330 case OPC_MTC1:
21331 case OPC_CTC1:
21332 check_cp1_enabled(ctx);
21333 gen_cp1(ctx, op1, rt, rd);
21334 break;
d26bc211 21335#if defined(TARGET_MIPS64)
5692c6e1
YK
21336 case OPC_DMFC1:
21337 case OPC_DMTC1:
21338 check_cp1_enabled(ctx);
21339 check_insn(ctx, ISA_MIPS3);
d9224450 21340 check_mips_64(ctx);
5692c6e1
YK
21341 gen_cp1(ctx, op1, rt, rd);
21342 break;
e189e748 21343#endif
5692c6e1
YK
21344 case OPC_BC1EQZ: /* OPC_BC1ANY2 */
21345 check_cp1_enabled(ctx);
21346 if (ctx->insn_flags & ISA_MIPS32R6) {
21347 /* OPC_BC1EQZ */
31837be3 21348 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
65935f07 21349 rt, imm << 2, 4);
5692c6e1
YK
21350 } else {
21351 /* OPC_BC1ANY2 */
b8aa4598 21352 check_cop1x(ctx);
d75c135e 21353 check_insn(ctx, ASE_MIPS3D);
d75c135e 21354 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
5a5012ec 21355 (rt >> 2) & 0x7, imm << 2);
5692c6e1
YK
21356 }
21357 break;
21358 case OPC_BC1NEZ:
21359 check_cp1_enabled(ctx);
21360 check_insn(ctx, ISA_MIPS32R6);
21361 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
65935f07 21362 rt, imm << 2, 4);
5692c6e1
YK
21363 break;
21364 case OPC_BC1ANY4:
21365 check_cp1_enabled(ctx);
21366 check_insn_opc_removed(ctx, ISA_MIPS32R6);
21367 check_cop1x(ctx);
21368 check_insn(ctx, ASE_MIPS3D);
21369 /* fall through */
21370 case OPC_BC1:
21371 check_cp1_enabled(ctx);
21372 check_insn_opc_removed(ctx, ISA_MIPS32R6);
21373 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
21374 (rt >> 2) & 0x7, imm << 2);
21375 break;
21376 case OPC_PS_FMT:
e29c9628 21377 check_ps(ctx);
b6f3b233 21378 /* fall through */
5692c6e1
YK
21379 case OPC_S_FMT:
21380 case OPC_D_FMT:
21381 check_cp1_enabled(ctx);
21382 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
21383 (imm >> 8) & 0x7);
21384 break;
21385 case OPC_W_FMT:
21386 case OPC_L_FMT:
21387 {
21388 int r6_op = ctx->opcode & FOP(0x3f, 0x1f);
21389 check_cp1_enabled(ctx);
21390 if (ctx->insn_flags & ISA_MIPS32R6) {
21391 switch (r6_op) {
21392 case R6_OPC_CMP_AF_S:
21393 case R6_OPC_CMP_UN_S:
21394 case R6_OPC_CMP_EQ_S:
21395 case R6_OPC_CMP_UEQ_S:
21396 case R6_OPC_CMP_LT_S:
21397 case R6_OPC_CMP_ULT_S:
21398 case R6_OPC_CMP_LE_S:
21399 case R6_OPC_CMP_ULE_S:
21400 case R6_OPC_CMP_SAF_S:
21401 case R6_OPC_CMP_SUN_S:
21402 case R6_OPC_CMP_SEQ_S:
21403 case R6_OPC_CMP_SEUQ_S:
21404 case R6_OPC_CMP_SLT_S:
21405 case R6_OPC_CMP_SULT_S:
21406 case R6_OPC_CMP_SLE_S:
21407 case R6_OPC_CMP_SULE_S:
21408 case R6_OPC_CMP_OR_S:
21409 case R6_OPC_CMP_UNE_S:
21410 case R6_OPC_CMP_NE_S:
21411 case R6_OPC_CMP_SOR_S:
21412 case R6_OPC_CMP_SUNE_S:
21413 case R6_OPC_CMP_SNE_S:
21414 gen_r6_cmp_s(ctx, ctx->opcode & 0x1f, rt, rd, sa);
21415 break;
21416 case R6_OPC_CMP_AF_D:
21417 case R6_OPC_CMP_UN_D:
21418 case R6_OPC_CMP_EQ_D:
21419 case R6_OPC_CMP_UEQ_D:
21420 case R6_OPC_CMP_LT_D:
21421 case R6_OPC_CMP_ULT_D:
21422 case R6_OPC_CMP_LE_D:
21423 case R6_OPC_CMP_ULE_D:
21424 case R6_OPC_CMP_SAF_D:
21425 case R6_OPC_CMP_SUN_D:
21426 case R6_OPC_CMP_SEQ_D:
21427 case R6_OPC_CMP_SEUQ_D:
21428 case R6_OPC_CMP_SLT_D:
21429 case R6_OPC_CMP_SULT_D:
21430 case R6_OPC_CMP_SLE_D:
21431 case R6_OPC_CMP_SULE_D:
21432 case R6_OPC_CMP_OR_D:
21433 case R6_OPC_CMP_UNE_D:
21434 case R6_OPC_CMP_NE_D:
21435 case R6_OPC_CMP_SOR_D:
21436 case R6_OPC_CMP_SUNE_D:
21437 case R6_OPC_CMP_SNE_D:
21438 gen_r6_cmp_d(ctx, ctx->opcode & 0x1f, rt, rd, sa);
21439 break;
21440 default:
d2bfa6e6
MR
21441 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f),
21442 rt, rd, sa, (imm >> 8) & 0x7);
21443
5692c6e1 21444 break;
3f493883 21445 }
5692c6e1
YK
21446 } else {
21447 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
21448 (imm >> 8) & 0x7);
36d23958 21449 }
5692c6e1
YK
21450 break;
21451 }
21452 case OPC_BZ_V:
21453 case OPC_BNZ_V:
21454 case OPC_BZ_B:
21455 case OPC_BZ_H:
21456 case OPC_BZ_W:
21457 case OPC_BZ_D:
21458 case OPC_BNZ_B:
21459 case OPC_BNZ_H:
21460 case OPC_BNZ_W:
21461 case OPC_BNZ_D:
21462 check_insn(ctx, ASE_MSA);
21463 gen_msa_branch(env, ctx, op1);
21464 break;
21465 default:
21466 MIPS_INVAL("cp1");
9c708c7f 21467 generate_exception_end(ctx, EXCP_RI);
5692c6e1 21468 break;
6ea83fed 21469 }
4ad40f36
FB
21470 break;
21471
31837be3
YK
21472 /* Compact branches [R6] and COP2 [non-R6] */
21473 case OPC_BC: /* OPC_LWC2 */
21474 case OPC_BALC: /* OPC_SWC2 */
21475 if (ctx->insn_flags & ISA_MIPS32R6) {
21476 /* OPC_BC, OPC_BALC */
21477 gen_compute_compact_branch(ctx, op, 0, 0,
21478 sextract32(ctx->opcode << 2, 0, 28));
21479 } else {
21480 /* OPC_LWC2, OPC_SWC2 */
21481 /* COP2: Not implemented. */
21482 generate_exception_err(ctx, EXCP_CpU, 2);
21483 }
21484 break;
21485 case OPC_BEQZC: /* OPC_JIC, OPC_LDC2 */
21486 case OPC_BNEZC: /* OPC_JIALC, OPC_SDC2 */
21487 if (ctx->insn_flags & ISA_MIPS32R6) {
21488 if (rs != 0) {
21489 /* OPC_BEQZC, OPC_BNEZC */
21490 gen_compute_compact_branch(ctx, op, rs, 0,
21491 sextract32(ctx->opcode << 2, 0, 23));
21492 } else {
21493 /* OPC_JIC, OPC_JIALC */
21494 gen_compute_compact_branch(ctx, op, 0, rt, imm);
21495 }
21496 } else {
21497 /* OPC_LWC2, OPC_SWC2 */
21498 /* COP2: Not implemented. */
21499 generate_exception_err(ctx, EXCP_CpU, 2);
21500 }
4ad40f36 21501 break;
bd277fa1 21502 case OPC_CP2:
d75c135e 21503 check_insn(ctx, INSN_LOONGSON2F);
bd277fa1
RH
21504 /* Note that these instructions use different fields. */
21505 gen_loongson_multimedia(ctx, sa, rd, rt);
21506 break;
4ad40f36 21507
7a387fff 21508 case OPC_CP3:
fecd2646 21509 check_insn_opc_removed(ctx, ISA_MIPS32R6);
5ab5c041 21510 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
5e755519 21511 check_cp1_enabled(ctx);
36d23958
TS
21512 op1 = MASK_CP3(ctx->opcode);
21513 switch (op1) {
d9224450
MR
21514 case OPC_LUXC1:
21515 case OPC_SUXC1:
21516 check_insn(ctx, ISA_MIPS5 | ISA_MIPS32R2);
21517 /* Fallthrough */
5a5012ec
TS
21518 case OPC_LWXC1:
21519 case OPC_LDXC1:
5a5012ec
TS
21520 case OPC_SWXC1:
21521 case OPC_SDXC1:
d9224450 21522 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
93b12ccc 21523 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
5a5012ec 21524 break;
e0c84da7 21525 case OPC_PREFX:
d9224450 21526 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
ead9360e 21527 /* Treat as NOP. */
e0c84da7 21528 break;
5a5012ec 21529 case OPC_ALNV_PS:
d9224450
MR
21530 check_insn(ctx, ISA_MIPS5 | ISA_MIPS32R2);
21531 /* Fallthrough */
5a5012ec
TS
21532 case OPC_MADD_S:
21533 case OPC_MADD_D:
21534 case OPC_MADD_PS:
21535 case OPC_MSUB_S:
21536 case OPC_MSUB_D:
21537 case OPC_MSUB_PS:
21538 case OPC_NMADD_S:
21539 case OPC_NMADD_D:
21540 case OPC_NMADD_PS:
21541 case OPC_NMSUB_S:
21542 case OPC_NMSUB_D:
21543 case OPC_NMSUB_PS:
d9224450 21544 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
5a5012ec
TS
21545 gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
21546 break;
36d23958 21547 default:
923617a3 21548 MIPS_INVAL("cp3");
9c708c7f 21549 generate_exception_end(ctx, EXCP_RI);
36d23958
TS
21550 break;
21551 }
21552 } else {
e397ee33 21553 generate_exception_err(ctx, EXCP_CpU, 1);
7a387fff 21554 }
4ad40f36
FB
21555 break;
21556
d26bc211 21557#if defined(TARGET_MIPS64)
7a387fff 21558 /* MIPS64 opcodes */
c2e19f3c
AM
21559 case OPC_LDL:
21560 case OPC_LDR:
bf7910c6 21561 case OPC_LLD:
fecd2646 21562 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b6f3b233 21563 /* fall through */
fecd2646 21564 case OPC_LWU:
7a387fff 21565 case OPC_LD:
d75c135e 21566 check_insn(ctx, ISA_MIPS3);
5c13fdfd 21567 check_mips_64(ctx);
d75c135e 21568 gen_ld(ctx, op, rt, rs, imm);
5c13fdfd 21569 break;
c2e19f3c
AM
21570 case OPC_SDL:
21571 case OPC_SDR:
fecd2646 21572 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b6f3b233 21573 /* fall through */
7a387fff 21574 case OPC_SD:
d75c135e 21575 check_insn(ctx, ISA_MIPS3);
e189e748 21576 check_mips_64(ctx);
5c13fdfd 21577 gen_st(ctx, op, rt, rs, imm);
7a387fff 21578 break;
d66c7132 21579 case OPC_SCD:
bf7910c6 21580 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d75c135e 21581 check_insn(ctx, ISA_MIPS3);
d66c7132
AJ
21582 check_mips_64(ctx);
21583 gen_st_cond(ctx, op, rt, rs, imm);
21584 break;
31837be3
YK
21585 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC, OPC_DADDI */
21586 if (ctx->insn_flags & ISA_MIPS32R6) {
21587 /* OPC_BNVC, OPC_BNEZALC, OPC_BNEC */
21588 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
21589 } else {
21590 /* OPC_DADDI */
21591 check_insn(ctx, ISA_MIPS3);
21592 check_mips_64(ctx);
21593 gen_arith_imm(ctx, op, rt, rs, imm);
21594 }
21595 break;
324d9e32 21596 case OPC_DADDIU:
d75c135e 21597 check_insn(ctx, ISA_MIPS3);
e189e748 21598 check_mips_64(ctx);
d75c135e 21599 gen_arith_imm(ctx, op, rt, rs, imm);
7a387fff 21600 break;
31837be3
YK
21601#else
21602 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
21603 if (ctx->insn_flags & ISA_MIPS32R6) {
21604 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
21605 } else {
21606 MIPS_INVAL("major opcode");
9c708c7f 21607 generate_exception_end(ctx, EXCP_RI);
31837be3
YK
21608 }
21609 break;
6af0bf9c 21610#endif
d4ea6acd
LA
21611 case OPC_DAUI: /* OPC_JALX */
21612 if (ctx->insn_flags & ISA_MIPS32R6) {
21613#if defined(TARGET_MIPS64)
21614 /* OPC_DAUI */
21615 check_mips_64(ctx);
db77d852
LA
21616 if (rs == 0) {
21617 generate_exception(ctx, EXCP_RI);
21618 } else if (rt != 0) {
d4ea6acd
LA
21619 TCGv t0 = tcg_temp_new();
21620 gen_load_gpr(t0, rs);
21621 tcg_gen_addi_tl(cpu_gpr[rt], t0, imm << 16);
21622 tcg_temp_free(t0);
21623 }
d4ea6acd 21624#else
9c708c7f 21625 generate_exception_end(ctx, EXCP_RI);
d4ea6acd
LA
21626 MIPS_INVAL("major opcode");
21627#endif
21628 } else {
21629 /* OPC_JALX */
21630 check_insn(ctx, ASE_MIPS16 | ASE_MICROMIPS);
21631 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
b231c103 21632 gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
d4ea6acd 21633 }
364d4831 21634 break;
4c789546 21635 case OPC_MSA: /* OPC_MDMX */
7a387fff 21636 /* MDMX: Not implemented. */
4c789546 21637 gen_msa(env, ctx);
d4ea6acd
LA
21638 break;
21639 case OPC_PCREL:
21640 check_insn(ctx, ISA_MIPS32R6);
eeb3bba8 21641 gen_pcrel(ctx, ctx->opcode, ctx->base.pc_next, rs);
d4ea6acd 21642 break;
6af0bf9c 21643 default: /* Invalid */
923617a3 21644 MIPS_INVAL("major opcode");
9c708c7f 21645 generate_exception_end(ctx, EXCP_RI);
6af0bf9c
FB
21646 break;
21647 }
6af0bf9c
FB
21648}
21649
18f440ed 21650static void mips_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
6af0bf9c 21651{
18f440ed 21652 DisasContext *ctx = container_of(dcbase, DisasContext, base);
9c489ea6 21653 CPUMIPSState *env = cs->env_ptr;
12be9258 21654
18f440ed 21655 ctx->page_start = ctx->base.pc_first & TARGET_PAGE_MASK;
12be9258
EC
21656 ctx->saved_pc = -1;
21657 ctx->insn_flags = env->insn_flags;
21658 ctx->CP0_Config1 = env->CP0_Config1;
21659 ctx->btarget = 0;
21660 ctx->kscrexist = (env->CP0_Config4 >> CP0C4_KScrExist) & 0xff;
21661 ctx->rxi = (env->CP0_Config3 >> CP0C3_RXI) & 1;
21662 ctx->ie = (env->CP0_Config4 >> CP0C4_IE) & 3;
21663 ctx->bi = (env->CP0_Config3 >> CP0C3_BI) & 1;
21664 ctx->bp = (env->CP0_Config3 >> CP0C3_BP) & 1;
21665 ctx->PAMask = env->PAMask;
21666 ctx->mvh = (env->CP0_Config5 >> CP0C5_MVH) & 1;
21667 ctx->eva = (env->CP0_Config5 >> CP0C5_EVA) & 1;
21668 ctx->sc = (env->CP0_Config3 >> CP0C3_SC) & 1;
21669 ctx->CP0_LLAddr_shift = env->CP0_LLAddr_shift;
21670 ctx->cmgcr = (env->CP0_Config3 >> CP0C3_CMGCR) & 1;
4ad40f36 21671 /* Restore delay slot state from the tb context. */
12be9258
EC
21672 ctx->hflags = (uint32_t)ctx->base.tb->flags; /* FIXME: maybe use 64 bits? */
21673 ctx->ulri = (env->CP0_Config3 >> CP0C3_ULRI) & 1;
21674 ctx->ps = ((env->active_fpu.fcr0 >> FCR0_PS) & 1) ||
e29c9628 21675 (env->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F));
12be9258
EC
21676 ctx->vp = (env->CP0_Config5 >> CP0C5_VP) & 1;
21677 ctx->mrp = (env->CP0_Config5 >> CP0C5_MRP) & 1;
21678 ctx->nan2008 = (env->active_fpu.fcr31 >> FCR31_NAN2008) & 1;
21679 ctx->abs2008 = (env->active_fpu.fcr31 >> FCR31_ABS2008) & 1;
21680 restore_cpu_state(env, ctx);
932e71cd 21681#ifdef CONFIG_USER_ONLY
12be9258 21682 ctx->mem_idx = MIPS_HFLAG_UM;
932e71cd 21683#else
12be9258 21684 ctx->mem_idx = hflags_mmu_index(ctx->hflags);
932e71cd 21685#endif
12be9258
EC
21686 ctx->default_tcg_memop_mask = (ctx->insn_flags & ISA_MIPS32R6) ?
21687 MO_UNALN : MO_ALIGN;
190ce7fb 21688
18f440ed
EC
21689 LOG_DISAS("\ntb %p idx %d hflags %04x\n", ctx->base.tb, ctx->mem_idx,
21690 ctx->hflags);
21691}
12be9258 21692
18f440ed
EC
21693static void mips_tr_tb_start(DisasContextBase *dcbase, CPUState *cs)
21694{
21695}
b933066a 21696
18f440ed
EC
21697static void mips_tr_insn_start(DisasContextBase *dcbase, CPUState *cs)
21698{
21699 DisasContext *ctx = container_of(dcbase, DisasContext, base);
c9602061 21700
18f440ed
EC
21701 tcg_gen_insn_start(ctx->base.pc_next, ctx->hflags & MIPS_HFLAG_BMASK,
21702 ctx->btarget);
21703}
31837be3 21704
18f440ed
EC
21705static bool mips_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cs,
21706 const CPUBreakpoint *bp)
21707{
21708 DisasContext *ctx = container_of(dcbase, DisasContext, base);
c9602061 21709
18f440ed
EC
21710 save_cpu_state(ctx, 1);
21711 ctx->base.is_jmp = DISAS_NORETURN;
21712 gen_helper_raise_exception_debug(cpu_env);
21713 /* The address covered by the breakpoint must be included in
21714 [tb->pc, tb->pc + tb->size) in order to for it to be
21715 properly cleared -- thus we increment the PC here so that
21716 the logic setting tb->size below does the right thing. */
21717 ctx->base.pc_next += 4;
21718 return true;
21719}
4ad40f36 21720
18f440ed
EC
21721static void mips_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
21722{
21723 CPUMIPSState *env = cs->env_ptr;
21724 DisasContext *ctx = container_of(dcbase, DisasContext, base);
21725 int insn_bytes;
21726 int is_slot;
4ad40f36 21727
18f440ed 21728 is_slot = ctx->hflags & MIPS_HFLAG_BMASK;
c533c0f4
AM
21729 if (ctx->insn_flags & ISA_NANOMIPS32) {
21730 ctx->opcode = cpu_lduw_code(env, ctx->base.pc_next);
21731 insn_bytes = decode_nanomips_opc(env, ctx);
21732 } else if (!(ctx->hflags & MIPS_HFLAG_M16)) {
18f440ed
EC
21733 ctx->opcode = cpu_ldl_code(env, ctx->base.pc_next);
21734 insn_bytes = 4;
21735 decode_opc(env, ctx);
21736 } else if (ctx->insn_flags & ASE_MICROMIPS) {
21737 ctx->opcode = cpu_lduw_code(env, ctx->base.pc_next);
21738 insn_bytes = decode_micromips_opc(env, ctx);
21739 } else if (ctx->insn_flags & ASE_MIPS16) {
21740 ctx->opcode = cpu_lduw_code(env, ctx->base.pc_next);
21741 insn_bytes = decode_mips16_opc(env, ctx);
21742 } else {
21743 generate_exception_end(ctx, EXCP_RI);
21744 g_assert(ctx->base.is_jmp == DISAS_NORETURN);
21745 return;
21746 }
faf7aaa9 21747
18f440ed
EC
21748 if (ctx->hflags & MIPS_HFLAG_BMASK) {
21749 if (!(ctx->hflags & (MIPS_HFLAG_BDS16 | MIPS_HFLAG_BDS32 |
21750 MIPS_HFLAG_FBNSLOT))) {
21751 /* force to generate branch as there is neither delay nor
21752 forbidden slot */
21753 is_slot = 1;
21754 }
21755 if ((ctx->hflags & MIPS_HFLAG_M16) &&
21756 (ctx->hflags & MIPS_HFLAG_FBNSLOT)) {
21757 /* Force to generate branch as microMIPS R6 doesn't restrict
21758 branches in the forbidden slot. */
21759 is_slot = 1;
eeb3bba8 21760 }
18f440ed
EC
21761 }
21762 if (is_slot) {
21763 gen_branch(ctx, insn_bytes);
21764 }
21765 ctx->base.pc_next += insn_bytes;
1b530a6d 21766
18f440ed
EC
21767 if (ctx->base.is_jmp != DISAS_NEXT) {
21768 return;
6af0bf9c 21769 }
18f440ed
EC
21770 /* Execute a branch and its delay slot as a single instruction.
21771 This is what GDB expects and is consistent with what the
21772 hardware does (e.g. if a delay slot instruction faults, the
21773 reported PC is the PC of the branch). */
21774 if (ctx->base.singlestep_enabled &&
21775 (ctx->hflags & MIPS_HFLAG_BMASK) == 0) {
21776 ctx->base.is_jmp = DISAS_TOO_MANY;
21777 }
21778 if (ctx->base.pc_next - ctx->page_start >= TARGET_PAGE_SIZE) {
21779 ctx->base.is_jmp = DISAS_TOO_MANY;
ed2803da 21780 }
18f440ed
EC
21781}
21782
21783static void mips_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
21784{
21785 DisasContext *ctx = container_of(dcbase, DisasContext, base);
21786
12be9258
EC
21787 if (ctx->base.singlestep_enabled && ctx->base.is_jmp != DISAS_NORETURN) {
21788 save_cpu_state(ctx, ctx->base.is_jmp != DISAS_EXIT);
9c708c7f 21789 gen_helper_raise_exception_debug(cpu_env);
16c00cb2 21790 } else {
12be9258 21791 switch (ctx->base.is_jmp) {
b28425ba 21792 case DISAS_STOP:
12be9258 21793 gen_save_pc(ctx->base.pc_next);
cd314a7d 21794 tcg_gen_lookup_and_goto_ptr();
df1561e2 21795 break;
b28425ba 21796 case DISAS_NEXT:
18f440ed 21797 case DISAS_TOO_MANY:
12be9258
EC
21798 save_cpu_state(ctx, 0);
21799 gen_goto_tb(ctx, 0, ctx->base.pc_next);
16c00cb2 21800 break;
b28425ba 21801 case DISAS_EXIT:
07ea28b4 21802 tcg_gen_exit_tb(NULL, 0);
16c00cb2 21803 break;
b28425ba 21804 case DISAS_NORETURN:
5a5012ec 21805 break;
18f440ed
EC
21806 default:
21807 g_assert_not_reached();
6958549d 21808 }
6af0bf9c 21809 }
18f440ed
EC
21810}
21811
21812static void mips_tr_disas_log(const DisasContextBase *dcbase, CPUState *cs)
21813{
21814 qemu_log("IN: %s\n", lookup_symbol(dcbase->pc_first));
21815 log_target_disas(cs, dcbase->pc_first, dcbase->tb->size);
21816}
21817
21818static const TranslatorOps mips_tr_ops = {
21819 .init_disas_context = mips_tr_init_disas_context,
21820 .tb_start = mips_tr_tb_start,
21821 .insn_start = mips_tr_insn_start,
21822 .breakpoint_check = mips_tr_breakpoint_check,
21823 .translate_insn = mips_tr_translate_insn,
21824 .tb_stop = mips_tr_tb_stop,
21825 .disas_log = mips_tr_disas_log,
21826};
21827
21828void gen_intermediate_code(CPUState *cs, struct TranslationBlock *tb)
21829{
21830 DisasContext ctx;
21831
21832 translator_loop(&mips_tr_ops, &ctx.base, cs, tb);
6af0bf9c
FB
21833}
21834
7db13fae 21835static void fpu_dump_state(CPUMIPSState *env, FILE *f, fprintf_function fpu_fprintf,
8706c382 21836 int flags)
6ea83fed
FB
21837{
21838 int i;
5e755519 21839 int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
5a5012ec 21840
2a5612e6
SW
21841#define printfpr(fp) \
21842 do { \
21843 if (is_fpu64) \
21844 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
21845 " fd:%13g fs:%13g psu: %13g\n", \
21846 (fp)->w[FP_ENDIAN_IDX], (fp)->d, \
21847 (double)(fp)->fd, \
21848 (double)(fp)->fs[FP_ENDIAN_IDX], \
21849 (double)(fp)->fs[!FP_ENDIAN_IDX]); \
21850 else { \
21851 fpr_t tmp; \
21852 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
21853 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
21854 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
21855 " fd:%13g fs:%13g psu:%13g\n", \
21856 tmp.w[FP_ENDIAN_IDX], tmp.d, \
21857 (double)tmp.fd, \
21858 (double)tmp.fs[FP_ENDIAN_IDX], \
21859 (double)tmp.fs[!FP_ENDIAN_IDX]); \
21860 } \
6ea83fed
FB
21861 } while(0)
21862
5a5012ec 21863
9a78eead
SW
21864 fpu_fprintf(f, "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%02x\n",
21865 env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64,
f01be154 21866 get_float_exception_flags(&env->active_fpu.fp_status));
5a5012ec
TS
21867 for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
21868 fpu_fprintf(f, "%3s: ", fregnames[i]);
f01be154 21869 printfpr(&env->active_fpu.fpr[i]);
6ea83fed
FB
21870 }
21871
21872#undef printfpr
21873}
21874
878096ee
AF
21875void mips_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
21876 int flags)
6af0bf9c 21877{
878096ee
AF
21878 MIPSCPU *cpu = MIPS_CPU(cs);
21879 CPUMIPSState *env = &cpu->env;
6af0bf9c 21880 int i;
3b46e624 21881
a7200c9f
SW
21882 cpu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
21883 " LO=0x" TARGET_FMT_lx " ds %04x "
21884 TARGET_FMT_lx " " TARGET_FMT_ld "\n",
3d5be870
TS
21885 env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
21886 env->hflags, env->btarget, env->bcond);
6af0bf9c
FB
21887 for (i = 0; i < 32; i++) {
21888 if ((i & 3) == 0)
21889 cpu_fprintf(f, "GPR%02d:", i);
b5dc7732 21890 cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
6af0bf9c
FB
21891 if ((i & 3) == 3)
21892 cpu_fprintf(f, "\n");
21893 }
568b600d 21894
3594c774 21895 cpu_fprintf(f, "CP0 Status 0x%08x Cause 0x%08x EPC 0x" TARGET_FMT_lx "\n",
5e755519 21896 env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
284b731a
LA
21897 cpu_fprintf(f, " Config0 0x%08x Config1 0x%08x LLAddr 0x%016"
21898 PRIx64 "\n",
5499b6ff 21899 env->CP0_Config0, env->CP0_Config1, env->lladdr);
27e1fb13
MR
21900 cpu_fprintf(f, " Config2 0x%08x Config3 0x%08x\n",
21901 env->CP0_Config2, env->CP0_Config3);
21902 cpu_fprintf(f, " Config4 0x%08x Config5 0x%08x\n",
21903 env->CP0_Config4, env->CP0_Config5);
1cc5af69 21904 if ((flags & CPU_DUMP_FPU) && (env->hflags & MIPS_HFLAG_FPU)) {
7a387fff 21905 fpu_dump_state(env, f, cpu_fprintf, flags);
1cc5af69 21906 }
6af0bf9c
FB
21907}
21908
78ce64f4 21909void mips_tcg_init(void)
39454628 21910{
f01be154 21911 int i;
39454628 21912
f764718d 21913 cpu_gpr[0] = NULL;
bb928dbe 21914 for (i = 1; i < 32; i++)
e1ccc054 21915 cpu_gpr[i] = tcg_global_mem_new(cpu_env,
7db13fae 21916 offsetof(CPUMIPSState, active_tc.gpr[i]),
4b2eb8d2 21917 regnames[i]);
d73ee8a2 21918
863f264d
YK
21919 for (i = 0; i < 32; i++) {
21920 int off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[0]);
21921 msa_wr_d[i * 2] =
e1ccc054 21922 tcg_global_mem_new_i64(cpu_env, off, msaregnames[i * 2]);
cb269f27
YK
21923 /* The scalar floating-point unit (FPU) registers are mapped on
21924 * the MSA vector registers. */
21925 fpu_f64[i] = msa_wr_d[i * 2];
863f264d
YK
21926 off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[1]);
21927 msa_wr_d[i * 2 + 1] =
e1ccc054 21928 tcg_global_mem_new_i64(cpu_env, off, msaregnames[i * 2 + 1]);
863f264d
YK
21929 }
21930
e1ccc054 21931 cpu_PC = tcg_global_mem_new(cpu_env,
7db13fae 21932 offsetof(CPUMIPSState, active_tc.PC), "PC");
4b2eb8d2 21933 for (i = 0; i < MIPS_DSP_ACC; i++) {
e1ccc054 21934 cpu_HI[i] = tcg_global_mem_new(cpu_env,
7db13fae 21935 offsetof(CPUMIPSState, active_tc.HI[i]),
4b2eb8d2 21936 regnames_HI[i]);
e1ccc054 21937 cpu_LO[i] = tcg_global_mem_new(cpu_env,
7db13fae 21938 offsetof(CPUMIPSState, active_tc.LO[i]),
4b2eb8d2 21939 regnames_LO[i]);
4b2eb8d2 21940 }
e1ccc054 21941 cpu_dspctrl = tcg_global_mem_new(cpu_env,
7db13fae 21942 offsetof(CPUMIPSState, active_tc.DSPControl),
4b2eb8d2 21943 "DSPControl");
e1ccc054 21944 bcond = tcg_global_mem_new(cpu_env,
7db13fae 21945 offsetof(CPUMIPSState, bcond), "bcond");
e1ccc054 21946 btarget = tcg_global_mem_new(cpu_env,
7db13fae 21947 offsetof(CPUMIPSState, btarget), "btarget");
e1ccc054 21948 hflags = tcg_global_mem_new_i32(cpu_env,
7db13fae 21949 offsetof(CPUMIPSState, hflags), "hflags");
41db4607 21950
e1ccc054 21951 fpu_fcr0 = tcg_global_mem_new_i32(cpu_env,
7db13fae 21952 offsetof(CPUMIPSState, active_fpu.fcr0),
a7812ae4 21953 "fcr0");
e1ccc054 21954 fpu_fcr31 = tcg_global_mem_new_i32(cpu_env,
7db13fae 21955 offsetof(CPUMIPSState, active_fpu.fcr31),
a7812ae4 21956 "fcr31");
39454628
TS
21957}
21958
5b27a92d 21959#include "translate_init.inc.c"
aaed909a 21960
27e38392
PMD
21961void cpu_mips_realize_env(CPUMIPSState *env)
21962{
21963 env->exception_base = (int32_t)0xBFC00000;
21964
21965#ifndef CONFIG_USER_ONLY
21966 mmu_init(env, env->cpu_model);
21967#endif
21968 fpu_init(env, env->cpu_model);
21969 mvp_init(env, env->cpu_model);
21970}
21971
a7519f2b 21972bool cpu_supports_cps_smp(const char *cpu_type)
bff384a4 21973{
a7519f2b
IM
21974 const MIPSCPUClass *mcc = MIPS_CPU_CLASS(object_class_by_name(cpu_type));
21975 return (mcc->cpu_def->CP0_Config3 & (1 << CP0C3_CMGCR)) != 0;
bff384a4
LA
21976}
21977
a7519f2b 21978bool cpu_supports_isa(const char *cpu_type, unsigned int isa)
bed9e5ce 21979{
a7519f2b
IM
21980 const MIPSCPUClass *mcc = MIPS_CPU_CLASS(object_class_by_name(cpu_type));
21981 return (mcc->cpu_def->insn_flags & isa) != 0;
bed9e5ce
PB
21982}
21983
89777fd1
LA
21984void cpu_set_exception_base(int vp_index, target_ulong address)
21985{
21986 MIPSCPU *vp = MIPS_CPU(qemu_get_cpu(vp_index));
21987 vp->env.exception_base = address;
21988}
21989
1bba0dc9 21990void cpu_state_reset(CPUMIPSState *env)
6ae81775 21991{
55e5c285
AF
21992 MIPSCPU *cpu = mips_env_get_cpu(env);
21993 CPUState *cs = CPU(cpu);
6ae81775 21994
51cc2e78
BS
21995 /* Reset registers to their default values */
21996 env->CP0_PRid = env->cpu_model->CP0_PRid;
21997 env->CP0_Config0 = env->cpu_model->CP0_Config0;
21998#ifdef TARGET_WORDS_BIGENDIAN
21999 env->CP0_Config0 |= (1 << CP0C0_BE);
22000#endif
22001 env->CP0_Config1 = env->cpu_model->CP0_Config1;
22002 env->CP0_Config2 = env->cpu_model->CP0_Config2;
22003 env->CP0_Config3 = env->cpu_model->CP0_Config3;
b4160af1
PJ
22004 env->CP0_Config4 = env->cpu_model->CP0_Config4;
22005 env->CP0_Config4_rw_bitmask = env->cpu_model->CP0_Config4_rw_bitmask;
b4dd99a3
PJ
22006 env->CP0_Config5 = env->cpu_model->CP0_Config5;
22007 env->CP0_Config5_rw_bitmask = env->cpu_model->CP0_Config5_rw_bitmask;
51cc2e78
BS
22008 env->CP0_Config6 = env->cpu_model->CP0_Config6;
22009 env->CP0_Config7 = env->cpu_model->CP0_Config7;
2a6e32dd
AJ
22010 env->CP0_LLAddr_rw_bitmask = env->cpu_model->CP0_LLAddr_rw_bitmask
22011 << env->cpu_model->CP0_LLAddr_shift;
22012 env->CP0_LLAddr_shift = env->cpu_model->CP0_LLAddr_shift;
51cc2e78
BS
22013 env->SYNCI_Step = env->cpu_model->SYNCI_Step;
22014 env->CCRes = env->cpu_model->CCRes;
22015 env->CP0_Status_rw_bitmask = env->cpu_model->CP0_Status_rw_bitmask;
22016 env->CP0_TCStatus_rw_bitmask = env->cpu_model->CP0_TCStatus_rw_bitmask;
22017 env->CP0_SRSCtl = env->cpu_model->CP0_SRSCtl;
22018 env->current_tc = 0;
22019 env->SEGBITS = env->cpu_model->SEGBITS;
22020 env->SEGMask = (target_ulong)((1ULL << env->cpu_model->SEGBITS) - 1);
22021#if defined(TARGET_MIPS64)
22022 if (env->cpu_model->insn_flags & ISA_MIPS3) {
22023 env->SEGMask |= 3ULL << 62;
22024 }
22025#endif
22026 env->PABITS = env->cpu_model->PABITS;
51cc2e78
BS
22027 env->CP0_SRSConf0_rw_bitmask = env->cpu_model->CP0_SRSConf0_rw_bitmask;
22028 env->CP0_SRSConf0 = env->cpu_model->CP0_SRSConf0;
22029 env->CP0_SRSConf1_rw_bitmask = env->cpu_model->CP0_SRSConf1_rw_bitmask;
22030 env->CP0_SRSConf1 = env->cpu_model->CP0_SRSConf1;
22031 env->CP0_SRSConf2_rw_bitmask = env->cpu_model->CP0_SRSConf2_rw_bitmask;
22032 env->CP0_SRSConf2 = env->cpu_model->CP0_SRSConf2;
22033 env->CP0_SRSConf3_rw_bitmask = env->cpu_model->CP0_SRSConf3_rw_bitmask;
22034 env->CP0_SRSConf3 = env->cpu_model->CP0_SRSConf3;
22035 env->CP0_SRSConf4_rw_bitmask = env->cpu_model->CP0_SRSConf4_rw_bitmask;
22036 env->CP0_SRSConf4 = env->cpu_model->CP0_SRSConf4;
7207c7f9
LA
22037 env->CP0_PageGrain_rw_bitmask = env->cpu_model->CP0_PageGrain_rw_bitmask;
22038 env->CP0_PageGrain = env->cpu_model->CP0_PageGrain;
74dbf824 22039 env->CP0_EBaseWG_rw_bitmask = env->cpu_model->CP0_EBaseWG_rw_bitmask;
f1cb0951 22040 env->active_fpu.fcr0 = env->cpu_model->CP1_fcr0;
599bc5e8 22041 env->active_fpu.fcr31_rw_bitmask = env->cpu_model->CP1_fcr31_rw_bitmask;
ba5c79f2 22042 env->active_fpu.fcr31 = env->cpu_model->CP1_fcr31;
863f264d 22043 env->msair = env->cpu_model->MSAIR;
51cc2e78
BS
22044 env->insn_flags = env->cpu_model->insn_flags;
22045
0eaef5aa 22046#if defined(CONFIG_USER_ONLY)
03e6e501 22047 env->CP0_Status = (MIPS_HFLAG_UM << CP0St_KSU);
68473f15
RH
22048# ifdef TARGET_MIPS64
22049 /* Enable 64-bit register mode. */
22050 env->CP0_Status |= (1 << CP0St_PX);
22051# endif
22052# ifdef TARGET_ABI_MIPSN64
22053 /* Enable 64-bit address mode. */
22054 env->CP0_Status |= (1 << CP0St_UX);
22055# endif
94159135
MI
22056 /* Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
22057 hardware registers. */
22058 env->CP0_HWREna |= 0x0000000F;
91a75935 22059 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
03e6e501 22060 env->CP0_Status |= (1 << CP0St_CU1);
91a75935 22061 }
6f0af304
PJ
22062 if (env->CP0_Config3 & (1 << CP0C3_DSPP)) {
22063 env->CP0_Status |= (1 << CP0St_MX);
853c3240 22064 }
4d66261f
PJ
22065# if defined(TARGET_MIPS64)
22066 /* For MIPS64, init FR bit to 1 if FPU unit is there and bit is writable. */
22067 if ((env->CP0_Config1 & (1 << CP0C1_FP)) &&
22068 (env->CP0_Status_rw_bitmask & (1 << CP0St_FR))) {
68473f15
RH
22069 env->CP0_Status |= (1 << CP0St_FR);
22070 }
4d66261f 22071# endif
932e71cd
AJ
22072#else
22073 if (env->hflags & MIPS_HFLAG_BMASK) {
22074 /* If the exception was raised from a delay slot,
22075 come back to the jump. */
c3577479
MR
22076 env->CP0_ErrorEPC = (env->active_tc.PC
22077 - (env->hflags & MIPS_HFLAG_B16 ? 2 : 4));
aa328add 22078 } else {
932e71cd
AJ
22079 env->CP0_ErrorEPC = env->active_tc.PC;
22080 }
89777fd1 22081 env->active_tc.PC = env->exception_base;
51cc2e78
BS
22082 env->CP0_Random = env->tlb->nb_tlb - 1;
22083 env->tlb->tlb_in_use = env->tlb->nb_tlb;
932e71cd 22084 env->CP0_Wired = 0;
01bc435b 22085 env->CP0_GlobalNumber = (cs->cpu_index & 0xFF) << CP0GN_VPId;
0a2672b7 22086 env->CP0_EBase = (cs->cpu_index & 0x3FF);
d3d93c6c 22087 if (mips_um_ksegs_enabled()) {
0a2672b7
JH
22088 env->CP0_EBase |= 0x40000000;
22089 } else {
74dbf824 22090 env->CP0_EBase |= (int32_t)0x80000000;
0a2672b7 22091 }
c870e3f5
YK
22092 if (env->CP0_Config3 & (1 << CP0C3_CMGCR)) {
22093 env->CP0_CMGCRBase = 0x1fbf8000 >> 4;
22094 }
a0c80608
PB
22095 env->CP0_EntryHi_ASID_mask = (env->CP0_Config4 & (1 << CP0C4_AE)) ?
22096 0x3ff : 0xff;
932e71cd
AJ
22097 env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
22098 /* vectored interrupts not implemented, timer on int 7,
22099 no performance counters. */
22100 env->CP0_IntCtl = 0xe0000000;
22101 {
22102 int i;
22103
22104 for (i = 0; i < 7; i++) {
22105 env->CP0_WatchLo[i] = 0;
22106 env->CP0_WatchHi[i] = 0x80000000;
fd88b6ab 22107 }
932e71cd
AJ
22108 env->CP0_WatchLo[7] = 0;
22109 env->CP0_WatchHi[7] = 0;
fd88b6ab 22110 }
932e71cd
AJ
22111 /* Count register increments in debug mode, EJTAG version 1 */
22112 env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
9e56e756 22113
4b69c7e2
JH
22114 cpu_mips_store_count(env, 1);
22115
9e56e756
EI
22116 if (env->CP0_Config3 & (1 << CP0C3_MT)) {
22117 int i;
22118
22119 /* Only TC0 on VPE 0 starts as active. */
22120 for (i = 0; i < ARRAY_SIZE(env->tcs); i++) {
55e5c285 22121 env->tcs[i].CP0_TCBind = cs->cpu_index << CP0TCBd_CurVPE;
9e56e756
EI
22122 env->tcs[i].CP0_TCHalt = 1;
22123 }
22124 env->active_tc.CP0_TCHalt = 1;
259186a7 22125 cs->halted = 1;
9e56e756 22126
55e5c285 22127 if (cs->cpu_index == 0) {
9e56e756
EI
22128 /* VPE0 starts up enabled. */
22129 env->mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
22130 env->CP0_VPEConf0 |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
22131
22132 /* TC0 starts up unhalted. */
259186a7 22133 cs->halted = 0;
9e56e756
EI
22134 env->active_tc.CP0_TCHalt = 0;
22135 env->tcs[0].CP0_TCHalt = 0;
22136 /* With thread 0 active. */
22137 env->active_tc.CP0_TCStatus = (1 << CP0TCSt_A);
22138 env->tcs[0].CP0_TCStatus = (1 << CP0TCSt_A);
22139 }
22140 }
cec56a73
JH
22141
22142 /*
22143 * Configure default legacy segmentation control. We use this regardless of
22144 * whether segmentation control is presented to the guest.
22145 */
22146 /* KSeg3 (seg0 0xE0000000..0xFFFFFFFF) */
22147 env->CP0_SegCtl0 = (CP0SC_AM_MK << CP0SC_AM);
22148 /* KSeg2 (seg1 0xC0000000..0xDFFFFFFF) */
22149 env->CP0_SegCtl0 |= ((CP0SC_AM_MSK << CP0SC_AM)) << 16;
22150 /* KSeg1 (seg2 0xA0000000..0x9FFFFFFF) */
22151 env->CP0_SegCtl1 = (0 << CP0SC_PA) | (CP0SC_AM_UK << CP0SC_AM) |
22152 (2 << CP0SC_C);
22153 /* KSeg0 (seg3 0x80000000..0x9FFFFFFF) */
22154 env->CP0_SegCtl1 |= ((0 << CP0SC_PA) | (CP0SC_AM_UK << CP0SC_AM) |
22155 (3 << CP0SC_C)) << 16;
22156 /* USeg (seg4 0x40000000..0x7FFFFFFF) */
22157 env->CP0_SegCtl2 = (2 << CP0SC_PA) | (CP0SC_AM_MUSK << CP0SC_AM) |
22158 (1 << CP0SC_EU) | (2 << CP0SC_C);
22159 /* USeg (seg5 0x00000000..0x3FFFFFFF) */
22160 env->CP0_SegCtl2 |= ((0 << CP0SC_PA) | (CP0SC_AM_MUSK << CP0SC_AM) |
22161 (1 << CP0SC_EU) | (2 << CP0SC_C)) << 16;
22162 /* XKPhys (note, SegCtl2.XR = 0, so XAM won't be used) */
22163 env->CP0_SegCtl1 |= (CP0SC_AM_UK << CP0SC1_XAM);
51cc2e78 22164#endif
ddc584bd
LA
22165 if ((env->insn_flags & ISA_MIPS32R6) &&
22166 (env->active_fpu.fcr0 & (1 << FCR0_F64))) {
22167 /* Status.FR = 0 mode in 64-bit FPU not allowed in R6 */
22168 env->CP0_Status |= (1 << CP0St_FR);
22169 }
22170
0bbc0396
SM
22171 if (env->CP0_Config3 & (1 << CP0C3_ISA) & (1 << (CP0C3_ISA + 1))) {
22172 /* microMIPS on reset when Config3.ISA is 3 */
0305d194
YK
22173 env->hflags |= MIPS_HFLAG_M16;
22174 }
22175
863f264d
YK
22176 /* MSA */
22177 if (env->CP0_Config3 & (1 << CP0C3_MSAP)) {
22178 msa_reset(env);
22179 }
22180
03e6e501 22181 compute_hflags(env);
599bc5e8 22182 restore_fp_status(env);
e117f526 22183 restore_pamask(env);
27103424 22184 cs->exception_index = EXCP_NONE;
3b3c1694
LA
22185
22186 if (semihosting_get_argc()) {
22187 /* UHI interface can be used to obtain argc and argv */
22188 env->active_tc.gpr[4] = -1;
22189 }
6af0bf9c 22190}
d2856f1a 22191
bad729e2
RH
22192void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb,
22193 target_ulong *data)
d2856f1a 22194{
bad729e2 22195 env->active_tc.PC = data[0];
d2856f1a 22196 env->hflags &= ~MIPS_HFLAG_BMASK;
bad729e2 22197 env->hflags |= data[1];
4636401d
AJ
22198 switch (env->hflags & MIPS_HFLAG_BMASK_BASE) {
22199 case MIPS_HFLAG_BR:
22200 break;
22201 case MIPS_HFLAG_BC:
22202 case MIPS_HFLAG_BL:
22203 case MIPS_HFLAG_B:
bad729e2 22204 env->btarget = data[2];
4636401d
AJ
22205 break;
22206 }
d2856f1a 22207}
This page took 5.366206 seconds and 4 git commands to generate.