]> git.proxmox.com Git - mirror_qemu.git/blame - target/mips/translate.c
target/mips: Avoid case statements formulated by ranges - part 1
[mirror_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,
905 OPC_C0_FIRST = (0x10 << 21) | OPC_CP0,
906 OPC_C0_LAST = (0x1F << 21) | OPC_CP0,
6ea83fed 907};
7a387fff
TS
908
909/* MFMC0 opcodes */
b48cfdff 910#define MASK_MFMC0(op) MASK_CP0(op) | (op & 0xFFFF)
7a387fff
TS
911
912enum {
ead9360e
TS
913 OPC_DMT = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
914 OPC_EMT = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
915 OPC_DVPE = 0x01 | (0 << 5) | OPC_MFMC0,
916 OPC_EVPE = 0x01 | (1 << 5) | OPC_MFMC0,
7a387fff
TS
917 OPC_DI = (0 << 5) | (0x0C << 11) | OPC_MFMC0,
918 OPC_EI = (1 << 5) | (0x0C << 11) | OPC_MFMC0,
01bc435b
YK
919 OPC_DVP = 0x04 | (0 << 3) | (1 << 5) | (0 << 11) | OPC_MFMC0,
920 OPC_EVP = 0x04 | (0 << 3) | (0 << 5) | (0 << 11) | OPC_MFMC0,
7a387fff
TS
921};
922
923/* Coprocessor 0 (with rs == C0) */
924#define MASK_C0(op) MASK_CP0(op) | (op & 0x3F)
925
926enum {
927 OPC_TLBR = 0x01 | OPC_C0,
928 OPC_TLBWI = 0x02 | OPC_C0,
9456c2fb
LA
929 OPC_TLBINV = 0x03 | OPC_C0,
930 OPC_TLBINVF = 0x04 | OPC_C0,
7a387fff
TS
931 OPC_TLBWR = 0x06 | OPC_C0,
932 OPC_TLBP = 0x08 | OPC_C0,
933 OPC_RFE = 0x10 | OPC_C0,
934 OPC_ERET = 0x18 | OPC_C0,
935 OPC_DERET = 0x1F | OPC_C0,
936 OPC_WAIT = 0x20 | OPC_C0,
937};
938
939/* Coprocessor 1 (rs field) */
940#define MASK_CP1(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
941
bf4120ad
NF
942/* Values for the fmt field in FP instructions */
943enum {
944 /* 0 - 15 are reserved */
e459440a
AJ
945 FMT_S = 16, /* single fp */
946 FMT_D = 17, /* double fp */
947 FMT_E = 18, /* extended fp */
948 FMT_Q = 19, /* quad fp */
949 FMT_W = 20, /* 32-bit fixed */
950 FMT_L = 21, /* 64-bit fixed */
951 FMT_PS = 22, /* paired single fp */
bf4120ad
NF
952 /* 23 - 31 are reserved */
953};
954
7a387fff
TS
955enum {
956 OPC_MFC1 = (0x00 << 21) | OPC_CP1,
957 OPC_DMFC1 = (0x01 << 21) | OPC_CP1,
958 OPC_CFC1 = (0x02 << 21) | OPC_CP1,
5a5012ec 959 OPC_MFHC1 = (0x03 << 21) | OPC_CP1,
7a387fff
TS
960 OPC_MTC1 = (0x04 << 21) | OPC_CP1,
961 OPC_DMTC1 = (0x05 << 21) | OPC_CP1,
962 OPC_CTC1 = (0x06 << 21) | OPC_CP1,
5a5012ec 963 OPC_MTHC1 = (0x07 << 21) | OPC_CP1,
7a387fff 964 OPC_BC1 = (0x08 << 21) | OPC_CP1, /* bc */
5a5012ec
TS
965 OPC_BC1ANY2 = (0x09 << 21) | OPC_CP1,
966 OPC_BC1ANY4 = (0x0A << 21) | OPC_CP1,
239dfebe
YK
967 OPC_BZ_V = (0x0B << 21) | OPC_CP1,
968 OPC_BNZ_V = (0x0F << 21) | OPC_CP1,
e459440a
AJ
969 OPC_S_FMT = (FMT_S << 21) | OPC_CP1,
970 OPC_D_FMT = (FMT_D << 21) | OPC_CP1,
971 OPC_E_FMT = (FMT_E << 21) | OPC_CP1,
972 OPC_Q_FMT = (FMT_Q << 21) | OPC_CP1,
973 OPC_W_FMT = (FMT_W << 21) | OPC_CP1,
974 OPC_L_FMT = (FMT_L << 21) | OPC_CP1,
975 OPC_PS_FMT = (FMT_PS << 21) | OPC_CP1,
31837be3
YK
976 OPC_BC1EQZ = (0x09 << 21) | OPC_CP1,
977 OPC_BC1NEZ = (0x0D << 21) | OPC_CP1,
239dfebe
YK
978 OPC_BZ_B = (0x18 << 21) | OPC_CP1,
979 OPC_BZ_H = (0x19 << 21) | OPC_CP1,
980 OPC_BZ_W = (0x1A << 21) | OPC_CP1,
981 OPC_BZ_D = (0x1B << 21) | OPC_CP1,
982 OPC_BNZ_B = (0x1C << 21) | OPC_CP1,
983 OPC_BNZ_H = (0x1D << 21) | OPC_CP1,
984 OPC_BNZ_W = (0x1E << 21) | OPC_CP1,
985 OPC_BNZ_D = (0x1F << 21) | OPC_CP1,
7a387fff
TS
986};
987
5a5012ec
TS
988#define MASK_CP1_FUNC(op) MASK_CP1(op) | (op & 0x3F)
989#define MASK_BC1(op) MASK_CP1(op) | (op & (0x3 << 16))
990
7a387fff
TS
991enum {
992 OPC_BC1F = (0x00 << 16) | OPC_BC1,
993 OPC_BC1T = (0x01 << 16) | OPC_BC1,
994 OPC_BC1FL = (0x02 << 16) | OPC_BC1,
995 OPC_BC1TL = (0x03 << 16) | OPC_BC1,
996};
997
5a5012ec
TS
998enum {
999 OPC_BC1FANY2 = (0x00 << 16) | OPC_BC1ANY2,
1000 OPC_BC1TANY2 = (0x01 << 16) | OPC_BC1ANY2,
1001};
1002
1003enum {
1004 OPC_BC1FANY4 = (0x00 << 16) | OPC_BC1ANY4,
1005 OPC_BC1TANY4 = (0x01 << 16) | OPC_BC1ANY4,
1006};
7a387fff
TS
1007
1008#define MASK_CP2(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
e0c84da7
TS
1009
1010enum {
1011 OPC_MFC2 = (0x00 << 21) | OPC_CP2,
1012 OPC_DMFC2 = (0x01 << 21) | OPC_CP2,
1013 OPC_CFC2 = (0x02 << 21) | OPC_CP2,
1014 OPC_MFHC2 = (0x03 << 21) | OPC_CP2,
1015 OPC_MTC2 = (0x04 << 21) | OPC_CP2,
1016 OPC_DMTC2 = (0x05 << 21) | OPC_CP2,
1017 OPC_CTC2 = (0x06 << 21) | OPC_CP2,
1018 OPC_MTHC2 = (0x07 << 21) | OPC_CP2,
1019 OPC_BC2 = (0x08 << 21) | OPC_CP2,
31837be3
YK
1020 OPC_BC2EQZ = (0x09 << 21) | OPC_CP2,
1021 OPC_BC2NEZ = (0x0D << 21) | OPC_CP2,
e0c84da7
TS
1022};
1023
bd277fa1
RH
1024#define MASK_LMI(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)) | (op & 0x1F))
1025
1026enum {
1027 OPC_PADDSH = (24 << 21) | (0x00) | OPC_CP2,
1028 OPC_PADDUSH = (25 << 21) | (0x00) | OPC_CP2,
1029 OPC_PADDH = (26 << 21) | (0x00) | OPC_CP2,
1030 OPC_PADDW = (27 << 21) | (0x00) | OPC_CP2,
1031 OPC_PADDSB = (28 << 21) | (0x00) | OPC_CP2,
1032 OPC_PADDUSB = (29 << 21) | (0x00) | OPC_CP2,
1033 OPC_PADDB = (30 << 21) | (0x00) | OPC_CP2,
1034 OPC_PADDD = (31 << 21) | (0x00) | OPC_CP2,
1035
1036 OPC_PSUBSH = (24 << 21) | (0x01) | OPC_CP2,
1037 OPC_PSUBUSH = (25 << 21) | (0x01) | OPC_CP2,
1038 OPC_PSUBH = (26 << 21) | (0x01) | OPC_CP2,
1039 OPC_PSUBW = (27 << 21) | (0x01) | OPC_CP2,
1040 OPC_PSUBSB = (28 << 21) | (0x01) | OPC_CP2,
1041 OPC_PSUBUSB = (29 << 21) | (0x01) | OPC_CP2,
1042 OPC_PSUBB = (30 << 21) | (0x01) | OPC_CP2,
1043 OPC_PSUBD = (31 << 21) | (0x01) | OPC_CP2,
1044
1045 OPC_PSHUFH = (24 << 21) | (0x02) | OPC_CP2,
1046 OPC_PACKSSWH = (25 << 21) | (0x02) | OPC_CP2,
1047 OPC_PACKSSHB = (26 << 21) | (0x02) | OPC_CP2,
1048 OPC_PACKUSHB = (27 << 21) | (0x02) | OPC_CP2,
1049 OPC_XOR_CP2 = (28 << 21) | (0x02) | OPC_CP2,
1050 OPC_NOR_CP2 = (29 << 21) | (0x02) | OPC_CP2,
1051 OPC_AND_CP2 = (30 << 21) | (0x02) | OPC_CP2,
1052 OPC_PANDN = (31 << 21) | (0x02) | OPC_CP2,
1053
1054 OPC_PUNPCKLHW = (24 << 21) | (0x03) | OPC_CP2,
1055 OPC_PUNPCKHHW = (25 << 21) | (0x03) | OPC_CP2,
1056 OPC_PUNPCKLBH = (26 << 21) | (0x03) | OPC_CP2,
1057 OPC_PUNPCKHBH = (27 << 21) | (0x03) | OPC_CP2,
1058 OPC_PINSRH_0 = (28 << 21) | (0x03) | OPC_CP2,
1059 OPC_PINSRH_1 = (29 << 21) | (0x03) | OPC_CP2,
1060 OPC_PINSRH_2 = (30 << 21) | (0x03) | OPC_CP2,
1061 OPC_PINSRH_3 = (31 << 21) | (0x03) | OPC_CP2,
1062
1063 OPC_PAVGH = (24 << 21) | (0x08) | OPC_CP2,
1064 OPC_PAVGB = (25 << 21) | (0x08) | OPC_CP2,
1065 OPC_PMAXSH = (26 << 21) | (0x08) | OPC_CP2,
1066 OPC_PMINSH = (27 << 21) | (0x08) | OPC_CP2,
1067 OPC_PMAXUB = (28 << 21) | (0x08) | OPC_CP2,
1068 OPC_PMINUB = (29 << 21) | (0x08) | OPC_CP2,
1069
1070 OPC_PCMPEQW = (24 << 21) | (0x09) | OPC_CP2,
1071 OPC_PCMPGTW = (25 << 21) | (0x09) | OPC_CP2,
1072 OPC_PCMPEQH = (26 << 21) | (0x09) | OPC_CP2,
1073 OPC_PCMPGTH = (27 << 21) | (0x09) | OPC_CP2,
1074 OPC_PCMPEQB = (28 << 21) | (0x09) | OPC_CP2,
1075 OPC_PCMPGTB = (29 << 21) | (0x09) | OPC_CP2,
1076
1077 OPC_PSLLW = (24 << 21) | (0x0A) | OPC_CP2,
1078 OPC_PSLLH = (25 << 21) | (0x0A) | OPC_CP2,
1079 OPC_PMULLH = (26 << 21) | (0x0A) | OPC_CP2,
1080 OPC_PMULHH = (27 << 21) | (0x0A) | OPC_CP2,
1081 OPC_PMULUW = (28 << 21) | (0x0A) | OPC_CP2,
1082 OPC_PMULHUH = (29 << 21) | (0x0A) | OPC_CP2,
1083
1084 OPC_PSRLW = (24 << 21) | (0x0B) | OPC_CP2,
1085 OPC_PSRLH = (25 << 21) | (0x0B) | OPC_CP2,
1086 OPC_PSRAW = (26 << 21) | (0x0B) | OPC_CP2,
1087 OPC_PSRAH = (27 << 21) | (0x0B) | OPC_CP2,
1088 OPC_PUNPCKLWD = (28 << 21) | (0x0B) | OPC_CP2,
1089 OPC_PUNPCKHWD = (29 << 21) | (0x0B) | OPC_CP2,
1090
1091 OPC_ADDU_CP2 = (24 << 21) | (0x0C) | OPC_CP2,
1092 OPC_OR_CP2 = (25 << 21) | (0x0C) | OPC_CP2,
1093 OPC_ADD_CP2 = (26 << 21) | (0x0C) | OPC_CP2,
1094 OPC_DADD_CP2 = (27 << 21) | (0x0C) | OPC_CP2,
1095 OPC_SEQU_CP2 = (28 << 21) | (0x0C) | OPC_CP2,
1096 OPC_SEQ_CP2 = (29 << 21) | (0x0C) | OPC_CP2,
1097
1098 OPC_SUBU_CP2 = (24 << 21) | (0x0D) | OPC_CP2,
1099 OPC_PASUBUB = (25 << 21) | (0x0D) | OPC_CP2,
1100 OPC_SUB_CP2 = (26 << 21) | (0x0D) | OPC_CP2,
1101 OPC_DSUB_CP2 = (27 << 21) | (0x0D) | OPC_CP2,
1102 OPC_SLTU_CP2 = (28 << 21) | (0x0D) | OPC_CP2,
1103 OPC_SLT_CP2 = (29 << 21) | (0x0D) | OPC_CP2,
1104
1105 OPC_SLL_CP2 = (24 << 21) | (0x0E) | OPC_CP2,
1106 OPC_DSLL_CP2 = (25 << 21) | (0x0E) | OPC_CP2,
1107 OPC_PEXTRH = (26 << 21) | (0x0E) | OPC_CP2,
1108 OPC_PMADDHW = (27 << 21) | (0x0E) | OPC_CP2,
1109 OPC_SLEU_CP2 = (28 << 21) | (0x0E) | OPC_CP2,
1110 OPC_SLE_CP2 = (29 << 21) | (0x0E) | OPC_CP2,
1111
1112 OPC_SRL_CP2 = (24 << 21) | (0x0F) | OPC_CP2,
1113 OPC_DSRL_CP2 = (25 << 21) | (0x0F) | OPC_CP2,
1114 OPC_SRA_CP2 = (26 << 21) | (0x0F) | OPC_CP2,
1115 OPC_DSRA_CP2 = (27 << 21) | (0x0F) | OPC_CP2,
1116 OPC_BIADD = (28 << 21) | (0x0F) | OPC_CP2,
1117 OPC_PMOVMSKB = (29 << 21) | (0x0F) | OPC_CP2,
1118};
1119
1120
e0c84da7
TS
1121#define MASK_CP3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
1122
1123enum {
1124 OPC_LWXC1 = 0x00 | OPC_CP3,
1125 OPC_LDXC1 = 0x01 | OPC_CP3,
1126 OPC_LUXC1 = 0x05 | OPC_CP3,
1127 OPC_SWXC1 = 0x08 | OPC_CP3,
1128 OPC_SDXC1 = 0x09 | OPC_CP3,
1129 OPC_SUXC1 = 0x0D | OPC_CP3,
1130 OPC_PREFX = 0x0F | OPC_CP3,
1131 OPC_ALNV_PS = 0x1E | OPC_CP3,
1132 OPC_MADD_S = 0x20 | OPC_CP3,
1133 OPC_MADD_D = 0x21 | OPC_CP3,
1134 OPC_MADD_PS = 0x26 | OPC_CP3,
1135 OPC_MSUB_S = 0x28 | OPC_CP3,
1136 OPC_MSUB_D = 0x29 | OPC_CP3,
1137 OPC_MSUB_PS = 0x2E | OPC_CP3,
1138 OPC_NMADD_S = 0x30 | OPC_CP3,
fbcc6828 1139 OPC_NMADD_D = 0x31 | OPC_CP3,
e0c84da7
TS
1140 OPC_NMADD_PS= 0x36 | OPC_CP3,
1141 OPC_NMSUB_S = 0x38 | OPC_CP3,
1142 OPC_NMSUB_D = 0x39 | OPC_CP3,
1143 OPC_NMSUB_PS= 0x3E | OPC_CP3,
1144};
1145
239dfebe
YK
1146/* MSA Opcodes */
1147#define MASK_MSA_MINOR(op) (MASK_OP_MAJOR(op) | (op & 0x3F))
1148enum {
1149 OPC_MSA_I8_00 = 0x00 | OPC_MSA,
1150 OPC_MSA_I8_01 = 0x01 | OPC_MSA,
1151 OPC_MSA_I8_02 = 0x02 | OPC_MSA,
1152 OPC_MSA_I5_06 = 0x06 | OPC_MSA,
1153 OPC_MSA_I5_07 = 0x07 | OPC_MSA,
1154 OPC_MSA_BIT_09 = 0x09 | OPC_MSA,
1155 OPC_MSA_BIT_0A = 0x0A | OPC_MSA,
1156 OPC_MSA_3R_0D = 0x0D | OPC_MSA,
1157 OPC_MSA_3R_0E = 0x0E | OPC_MSA,
1158 OPC_MSA_3R_0F = 0x0F | OPC_MSA,
1159 OPC_MSA_3R_10 = 0x10 | OPC_MSA,
1160 OPC_MSA_3R_11 = 0x11 | OPC_MSA,
1161 OPC_MSA_3R_12 = 0x12 | OPC_MSA,
1162 OPC_MSA_3R_13 = 0x13 | OPC_MSA,
1163 OPC_MSA_3R_14 = 0x14 | OPC_MSA,
1164 OPC_MSA_3R_15 = 0x15 | OPC_MSA,
1165 OPC_MSA_ELM = 0x19 | OPC_MSA,
1166 OPC_MSA_3RF_1A = 0x1A | OPC_MSA,
1167 OPC_MSA_3RF_1B = 0x1B | OPC_MSA,
1168 OPC_MSA_3RF_1C = 0x1C | OPC_MSA,
1169 OPC_MSA_VEC = 0x1E | OPC_MSA,
1170
1171 /* MI10 instruction */
1172 OPC_LD_B = (0x20) | OPC_MSA,
1173 OPC_LD_H = (0x21) | OPC_MSA,
1174 OPC_LD_W = (0x22) | OPC_MSA,
1175 OPC_LD_D = (0x23) | OPC_MSA,
1176 OPC_ST_B = (0x24) | OPC_MSA,
1177 OPC_ST_H = (0x25) | OPC_MSA,
1178 OPC_ST_W = (0x26) | OPC_MSA,
1179 OPC_ST_D = (0x27) | OPC_MSA,
1180};
1181
1182enum {
1183 /* I5 instruction df(bits 22..21) = _b, _h, _w, _d */
1184 OPC_ADDVI_df = (0x0 << 23) | OPC_MSA_I5_06,
1185 OPC_CEQI_df = (0x0 << 23) | OPC_MSA_I5_07,
1186 OPC_SUBVI_df = (0x1 << 23) | OPC_MSA_I5_06,
1187 OPC_MAXI_S_df = (0x2 << 23) | OPC_MSA_I5_06,
1188 OPC_CLTI_S_df = (0x2 << 23) | OPC_MSA_I5_07,
1189 OPC_MAXI_U_df = (0x3 << 23) | OPC_MSA_I5_06,
1190 OPC_CLTI_U_df = (0x3 << 23) | OPC_MSA_I5_07,
1191 OPC_MINI_S_df = (0x4 << 23) | OPC_MSA_I5_06,
1192 OPC_CLEI_S_df = (0x4 << 23) | OPC_MSA_I5_07,
1193 OPC_MINI_U_df = (0x5 << 23) | OPC_MSA_I5_06,
1194 OPC_CLEI_U_df = (0x5 << 23) | OPC_MSA_I5_07,
1195 OPC_LDI_df = (0x6 << 23) | OPC_MSA_I5_07,
1196
1197 /* I8 instruction */
1198 OPC_ANDI_B = (0x0 << 24) | OPC_MSA_I8_00,
1199 OPC_BMNZI_B = (0x0 << 24) | OPC_MSA_I8_01,
1200 OPC_SHF_B = (0x0 << 24) | OPC_MSA_I8_02,
1201 OPC_ORI_B = (0x1 << 24) | OPC_MSA_I8_00,
1202 OPC_BMZI_B = (0x1 << 24) | OPC_MSA_I8_01,
1203 OPC_SHF_H = (0x1 << 24) | OPC_MSA_I8_02,
1204 OPC_NORI_B = (0x2 << 24) | OPC_MSA_I8_00,
1205 OPC_BSELI_B = (0x2 << 24) | OPC_MSA_I8_01,
1206 OPC_SHF_W = (0x2 << 24) | OPC_MSA_I8_02,
1207 OPC_XORI_B = (0x3 << 24) | OPC_MSA_I8_00,
1208
1209 /* VEC/2R/2RF instruction */
1210 OPC_AND_V = (0x00 << 21) | OPC_MSA_VEC,
1211 OPC_OR_V = (0x01 << 21) | OPC_MSA_VEC,
1212 OPC_NOR_V = (0x02 << 21) | OPC_MSA_VEC,
1213 OPC_XOR_V = (0x03 << 21) | OPC_MSA_VEC,
1214 OPC_BMNZ_V = (0x04 << 21) | OPC_MSA_VEC,
1215 OPC_BMZ_V = (0x05 << 21) | OPC_MSA_VEC,
1216 OPC_BSEL_V = (0x06 << 21) | OPC_MSA_VEC,
1217
1218 OPC_MSA_2R = (0x18 << 21) | OPC_MSA_VEC,
1219 OPC_MSA_2RF = (0x19 << 21) | OPC_MSA_VEC,
1220
1221 /* 2R instruction df(bits 17..16) = _b, _h, _w, _d */
1222 OPC_FILL_df = (0x00 << 18) | OPC_MSA_2R,
1223 OPC_PCNT_df = (0x01 << 18) | OPC_MSA_2R,
1224 OPC_NLOC_df = (0x02 << 18) | OPC_MSA_2R,
1225 OPC_NLZC_df = (0x03 << 18) | OPC_MSA_2R,
1226
1227 /* 2RF instruction df(bit 16) = _w, _d */
1228 OPC_FCLASS_df = (0x00 << 17) | OPC_MSA_2RF,
1229 OPC_FTRUNC_S_df = (0x01 << 17) | OPC_MSA_2RF,
1230 OPC_FTRUNC_U_df = (0x02 << 17) | OPC_MSA_2RF,
1231 OPC_FSQRT_df = (0x03 << 17) | OPC_MSA_2RF,
1232 OPC_FRSQRT_df = (0x04 << 17) | OPC_MSA_2RF,
1233 OPC_FRCP_df = (0x05 << 17) | OPC_MSA_2RF,
1234 OPC_FRINT_df = (0x06 << 17) | OPC_MSA_2RF,
1235 OPC_FLOG2_df = (0x07 << 17) | OPC_MSA_2RF,
1236 OPC_FEXUPL_df = (0x08 << 17) | OPC_MSA_2RF,
1237 OPC_FEXUPR_df = (0x09 << 17) | OPC_MSA_2RF,
1238 OPC_FFQL_df = (0x0A << 17) | OPC_MSA_2RF,
1239 OPC_FFQR_df = (0x0B << 17) | OPC_MSA_2RF,
1240 OPC_FTINT_S_df = (0x0C << 17) | OPC_MSA_2RF,
1241 OPC_FTINT_U_df = (0x0D << 17) | OPC_MSA_2RF,
1242 OPC_FFINT_S_df = (0x0E << 17) | OPC_MSA_2RF,
1243 OPC_FFINT_U_df = (0x0F << 17) | OPC_MSA_2RF,
1244
1245 /* 3R instruction df(bits 22..21) = _b, _h, _w, d */
1246 OPC_SLL_df = (0x0 << 23) | OPC_MSA_3R_0D,
1247 OPC_ADDV_df = (0x0 << 23) | OPC_MSA_3R_0E,
1248 OPC_CEQ_df = (0x0 << 23) | OPC_MSA_3R_0F,
1249 OPC_ADD_A_df = (0x0 << 23) | OPC_MSA_3R_10,
1250 OPC_SUBS_S_df = (0x0 << 23) | OPC_MSA_3R_11,
1251 OPC_MULV_df = (0x0 << 23) | OPC_MSA_3R_12,
1252 OPC_DOTP_S_df = (0x0 << 23) | OPC_MSA_3R_13,
1253 OPC_SLD_df = (0x0 << 23) | OPC_MSA_3R_14,
1254 OPC_VSHF_df = (0x0 << 23) | OPC_MSA_3R_15,
1255 OPC_SRA_df = (0x1 << 23) | OPC_MSA_3R_0D,
1256 OPC_SUBV_df = (0x1 << 23) | OPC_MSA_3R_0E,
1257 OPC_ADDS_A_df = (0x1 << 23) | OPC_MSA_3R_10,
1258 OPC_SUBS_U_df = (0x1 << 23) | OPC_MSA_3R_11,
1259 OPC_MADDV_df = (0x1 << 23) | OPC_MSA_3R_12,
1260 OPC_DOTP_U_df = (0x1 << 23) | OPC_MSA_3R_13,
1261 OPC_SPLAT_df = (0x1 << 23) | OPC_MSA_3R_14,
1262 OPC_SRAR_df = (0x1 << 23) | OPC_MSA_3R_15,
1263 OPC_SRL_df = (0x2 << 23) | OPC_MSA_3R_0D,
1264 OPC_MAX_S_df = (0x2 << 23) | OPC_MSA_3R_0E,
1265 OPC_CLT_S_df = (0x2 << 23) | OPC_MSA_3R_0F,
1266 OPC_ADDS_S_df = (0x2 << 23) | OPC_MSA_3R_10,
1267 OPC_SUBSUS_U_df = (0x2 << 23) | OPC_MSA_3R_11,
1268 OPC_MSUBV_df = (0x2 << 23) | OPC_MSA_3R_12,
1269 OPC_DPADD_S_df = (0x2 << 23) | OPC_MSA_3R_13,
1270 OPC_PCKEV_df = (0x2 << 23) | OPC_MSA_3R_14,
1271 OPC_SRLR_df = (0x2 << 23) | OPC_MSA_3R_15,
1272 OPC_BCLR_df = (0x3 << 23) | OPC_MSA_3R_0D,
1273 OPC_MAX_U_df = (0x3 << 23) | OPC_MSA_3R_0E,
1274 OPC_CLT_U_df = (0x3 << 23) | OPC_MSA_3R_0F,
1275 OPC_ADDS_U_df = (0x3 << 23) | OPC_MSA_3R_10,
1276 OPC_SUBSUU_S_df = (0x3 << 23) | OPC_MSA_3R_11,
1277 OPC_DPADD_U_df = (0x3 << 23) | OPC_MSA_3R_13,
1278 OPC_PCKOD_df = (0x3 << 23) | OPC_MSA_3R_14,
1279 OPC_BSET_df = (0x4 << 23) | OPC_MSA_3R_0D,
1280 OPC_MIN_S_df = (0x4 << 23) | OPC_MSA_3R_0E,
1281 OPC_CLE_S_df = (0x4 << 23) | OPC_MSA_3R_0F,
1282 OPC_AVE_S_df = (0x4 << 23) | OPC_MSA_3R_10,
1283 OPC_ASUB_S_df = (0x4 << 23) | OPC_MSA_3R_11,
1284 OPC_DIV_S_df = (0x4 << 23) | OPC_MSA_3R_12,
1285 OPC_DPSUB_S_df = (0x4 << 23) | OPC_MSA_3R_13,
1286 OPC_ILVL_df = (0x4 << 23) | OPC_MSA_3R_14,
1287 OPC_HADD_S_df = (0x4 << 23) | OPC_MSA_3R_15,
1288 OPC_BNEG_df = (0x5 << 23) | OPC_MSA_3R_0D,
1289 OPC_MIN_U_df = (0x5 << 23) | OPC_MSA_3R_0E,
1290 OPC_CLE_U_df = (0x5 << 23) | OPC_MSA_3R_0F,
1291 OPC_AVE_U_df = (0x5 << 23) | OPC_MSA_3R_10,
1292 OPC_ASUB_U_df = (0x5 << 23) | OPC_MSA_3R_11,
1293 OPC_DIV_U_df = (0x5 << 23) | OPC_MSA_3R_12,
1294 OPC_DPSUB_U_df = (0x5 << 23) | OPC_MSA_3R_13,
1295 OPC_ILVR_df = (0x5 << 23) | OPC_MSA_3R_14,
1296 OPC_HADD_U_df = (0x5 << 23) | OPC_MSA_3R_15,
1297 OPC_BINSL_df = (0x6 << 23) | OPC_MSA_3R_0D,
1298 OPC_MAX_A_df = (0x6 << 23) | OPC_MSA_3R_0E,
1299 OPC_AVER_S_df = (0x6 << 23) | OPC_MSA_3R_10,
1300 OPC_MOD_S_df = (0x6 << 23) | OPC_MSA_3R_12,
1301 OPC_ILVEV_df = (0x6 << 23) | OPC_MSA_3R_14,
1302 OPC_HSUB_S_df = (0x6 << 23) | OPC_MSA_3R_15,
1303 OPC_BINSR_df = (0x7 << 23) | OPC_MSA_3R_0D,
1304 OPC_MIN_A_df = (0x7 << 23) | OPC_MSA_3R_0E,
1305 OPC_AVER_U_df = (0x7 << 23) | OPC_MSA_3R_10,
1306 OPC_MOD_U_df = (0x7 << 23) | OPC_MSA_3R_12,
1307 OPC_ILVOD_df = (0x7 << 23) | OPC_MSA_3R_14,
1308 OPC_HSUB_U_df = (0x7 << 23) | OPC_MSA_3R_15,
1309
1310 /* ELM instructions df(bits 21..16) = _b, _h, _w, _d */
1311 OPC_SLDI_df = (0x0 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1312 OPC_CTCMSA = (0x0 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1313 OPC_SPLATI_df = (0x1 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1314 OPC_CFCMSA = (0x1 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1315 OPC_COPY_S_df = (0x2 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1316 OPC_MOVE_V = (0x2 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1317 OPC_COPY_U_df = (0x3 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1318 OPC_INSERT_df = (0x4 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1319 OPC_INSVE_df = (0x5 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1320
1321 /* 3RF instruction _df(bit 21) = _w, _d */
1322 OPC_FCAF_df = (0x0 << 22) | OPC_MSA_3RF_1A,
1323 OPC_FADD_df = (0x0 << 22) | OPC_MSA_3RF_1B,
1324 OPC_FCUN_df = (0x1 << 22) | OPC_MSA_3RF_1A,
1325 OPC_FSUB_df = (0x1 << 22) | OPC_MSA_3RF_1B,
1326 OPC_FCOR_df = (0x1 << 22) | OPC_MSA_3RF_1C,
1327 OPC_FCEQ_df = (0x2 << 22) | OPC_MSA_3RF_1A,
1328 OPC_FMUL_df = (0x2 << 22) | OPC_MSA_3RF_1B,
1329 OPC_FCUNE_df = (0x2 << 22) | OPC_MSA_3RF_1C,
1330 OPC_FCUEQ_df = (0x3 << 22) | OPC_MSA_3RF_1A,
1331 OPC_FDIV_df = (0x3 << 22) | OPC_MSA_3RF_1B,
1332 OPC_FCNE_df = (0x3 << 22) | OPC_MSA_3RF_1C,
1333 OPC_FCLT_df = (0x4 << 22) | OPC_MSA_3RF_1A,
1334 OPC_FMADD_df = (0x4 << 22) | OPC_MSA_3RF_1B,
1335 OPC_MUL_Q_df = (0x4 << 22) | OPC_MSA_3RF_1C,
1336 OPC_FCULT_df = (0x5 << 22) | OPC_MSA_3RF_1A,
1337 OPC_FMSUB_df = (0x5 << 22) | OPC_MSA_3RF_1B,
1338 OPC_MADD_Q_df = (0x5 << 22) | OPC_MSA_3RF_1C,
1339 OPC_FCLE_df = (0x6 << 22) | OPC_MSA_3RF_1A,
1340 OPC_MSUB_Q_df = (0x6 << 22) | OPC_MSA_3RF_1C,
1341 OPC_FCULE_df = (0x7 << 22) | OPC_MSA_3RF_1A,
1342 OPC_FEXP2_df = (0x7 << 22) | OPC_MSA_3RF_1B,
1343 OPC_FSAF_df = (0x8 << 22) | OPC_MSA_3RF_1A,
1344 OPC_FEXDO_df = (0x8 << 22) | OPC_MSA_3RF_1B,
1345 OPC_FSUN_df = (0x9 << 22) | OPC_MSA_3RF_1A,
1346 OPC_FSOR_df = (0x9 << 22) | OPC_MSA_3RF_1C,
1347 OPC_FSEQ_df = (0xA << 22) | OPC_MSA_3RF_1A,
1348 OPC_FTQ_df = (0xA << 22) | OPC_MSA_3RF_1B,
1349 OPC_FSUNE_df = (0xA << 22) | OPC_MSA_3RF_1C,
1350 OPC_FSUEQ_df = (0xB << 22) | OPC_MSA_3RF_1A,
1351 OPC_FSNE_df = (0xB << 22) | OPC_MSA_3RF_1C,
1352 OPC_FSLT_df = (0xC << 22) | OPC_MSA_3RF_1A,
1353 OPC_FMIN_df = (0xC << 22) | OPC_MSA_3RF_1B,
1354 OPC_MULR_Q_df = (0xC << 22) | OPC_MSA_3RF_1C,
1355 OPC_FSULT_df = (0xD << 22) | OPC_MSA_3RF_1A,
1356 OPC_FMIN_A_df = (0xD << 22) | OPC_MSA_3RF_1B,
1357 OPC_MADDR_Q_df = (0xD << 22) | OPC_MSA_3RF_1C,
1358 OPC_FSLE_df = (0xE << 22) | OPC_MSA_3RF_1A,
1359 OPC_FMAX_df = (0xE << 22) | OPC_MSA_3RF_1B,
1360 OPC_MSUBR_Q_df = (0xE << 22) | OPC_MSA_3RF_1C,
1361 OPC_FSULE_df = (0xF << 22) | OPC_MSA_3RF_1A,
1362 OPC_FMAX_A_df = (0xF << 22) | OPC_MSA_3RF_1B,
1363
1364 /* BIT instruction df(bits 22..16) = _B _H _W _D */
1365 OPC_SLLI_df = (0x0 << 23) | OPC_MSA_BIT_09,
1366 OPC_SAT_S_df = (0x0 << 23) | OPC_MSA_BIT_0A,
1367 OPC_SRAI_df = (0x1 << 23) | OPC_MSA_BIT_09,
1368 OPC_SAT_U_df = (0x1 << 23) | OPC_MSA_BIT_0A,
1369 OPC_SRLI_df = (0x2 << 23) | OPC_MSA_BIT_09,
1370 OPC_SRARI_df = (0x2 << 23) | OPC_MSA_BIT_0A,
1371 OPC_BCLRI_df = (0x3 << 23) | OPC_MSA_BIT_09,
1372 OPC_SRLRI_df = (0x3 << 23) | OPC_MSA_BIT_0A,
1373 OPC_BSETI_df = (0x4 << 23) | OPC_MSA_BIT_09,
1374 OPC_BNEGI_df = (0x5 << 23) | OPC_MSA_BIT_09,
1375 OPC_BINSLI_df = (0x6 << 23) | OPC_MSA_BIT_09,
1376 OPC_BINSRI_df = (0x7 << 23) | OPC_MSA_BIT_09,
1377};
1378
39454628 1379/* global register indices */
a7812ae4 1380static TCGv cpu_gpr[32], cpu_PC;
340fff72 1381static TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC];
41db4607
AJ
1382static TCGv cpu_dspctrl, btarget, bcond;
1383static TCGv_i32 hflags;
a7812ae4 1384static TCGv_i32 fpu_fcr0, fpu_fcr31;
d73ee8a2 1385static TCGv_i64 fpu_f64[32];
863f264d 1386static TCGv_i64 msa_wr_d[64];
aa0bf00b 1387
022c62cb 1388#include "exec/gen-icount.h"
2e70f6ef 1389
895c2d04 1390#define gen_helper_0e0i(name, arg) do { \
a7812ae4 1391 TCGv_i32 helper_tmp = tcg_const_i32(arg); \
895c2d04 1392 gen_helper_##name(cpu_env, helper_tmp); \
a7812ae4
PB
1393 tcg_temp_free_i32(helper_tmp); \
1394 } while(0)
be24bb4f 1395
895c2d04 1396#define gen_helper_0e1i(name, arg1, arg2) do { \
a7812ae4 1397 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
895c2d04 1398 gen_helper_##name(cpu_env, arg1, helper_tmp); \
a7812ae4
PB
1399 tcg_temp_free_i32(helper_tmp); \
1400 } while(0)
be24bb4f 1401
895c2d04
BS
1402#define gen_helper_1e0i(name, ret, arg1) do { \
1403 TCGv_i32 helper_tmp = tcg_const_i32(arg1); \
1404 gen_helper_##name(ret, cpu_env, helper_tmp); \
1405 tcg_temp_free_i32(helper_tmp); \
1406 } while(0)
1407
1408#define gen_helper_1e1i(name, ret, arg1, arg2) do { \
1409 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
1410 gen_helper_##name(ret, cpu_env, arg1, helper_tmp); \
1411 tcg_temp_free_i32(helper_tmp); \
1412 } while(0)
1413
1414#define gen_helper_0e2i(name, arg1, arg2, arg3) do { \
1415 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
1416 gen_helper_##name(cpu_env, arg1, arg2, helper_tmp); \
1417 tcg_temp_free_i32(helper_tmp); \
1418 } while(0)
1419
1420#define gen_helper_1e2i(name, ret, arg1, arg2, arg3) do { \
a7812ae4 1421 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
895c2d04 1422 gen_helper_##name(ret, cpu_env, arg1, arg2, helper_tmp); \
a7812ae4
PB
1423 tcg_temp_free_i32(helper_tmp); \
1424 } while(0)
be24bb4f 1425
895c2d04 1426#define gen_helper_0e3i(name, arg1, arg2, arg3, arg4) do { \
a7812ae4 1427 TCGv_i32 helper_tmp = tcg_const_i32(arg4); \
895c2d04 1428 gen_helper_##name(cpu_env, arg1, arg2, arg3, helper_tmp); \
a7812ae4
PB
1429 tcg_temp_free_i32(helper_tmp); \
1430 } while(0)
c239529e 1431
8e9ade68 1432typedef struct DisasContext {
eeb3bba8
EC
1433 DisasContextBase base;
1434 target_ulong saved_pc;
18f440ed 1435 target_ulong page_start;
8e9ade68 1436 uint32_t opcode;
d75c135e 1437 int insn_flags;
5ab5c041 1438 int32_t CP0_Config1;
8e9ade68
TS
1439 /* Routine used to access memory */
1440 int mem_idx;
be3a8c53 1441 TCGMemOp default_tcg_memop_mask;
8e9ade68 1442 uint32_t hflags, saved_hflags;
8e9ade68 1443 target_ulong btarget;
d279279e 1444 bool ulri;
e98c0d17 1445 int kscrexist;
7207c7f9 1446 bool rxi;
9456c2fb 1447 int ie;
aea14095
LA
1448 bool bi;
1449 bool bp;
5204ea79
LA
1450 uint64_t PAMask;
1451 bool mvh;
76964147 1452 bool eva;
cec56a73 1453 bool sc;
5204ea79 1454 int CP0_LLAddr_shift;
e29c9628 1455 bool ps;
01bc435b 1456 bool vp;
c870e3f5 1457 bool cmgcr;
f6d4dd81 1458 bool mrp;
87552089 1459 bool nan2008;
6be77480 1460 bool abs2008;
8e9ade68
TS
1461} DisasContext;
1462
b28425ba
EC
1463#define DISAS_STOP DISAS_TARGET_0
1464#define DISAS_EXIT DISAS_TARGET_1
8e9ade68 1465
d73ee8a2
RH
1466static const char * const regnames[] = {
1467 "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
1468 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
1469 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
1470 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
1471};
6af0bf9c 1472
d73ee8a2
RH
1473static const char * const regnames_HI[] = {
1474 "HI0", "HI1", "HI2", "HI3",
1475};
4b2eb8d2 1476
d73ee8a2
RH
1477static const char * const regnames_LO[] = {
1478 "LO0", "LO1", "LO2", "LO3",
1479};
4b2eb8d2 1480
d73ee8a2
RH
1481static const char * const fregnames[] = {
1482 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
1483 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
1484 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
1485 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
1486};
958fb4a9 1487
863f264d
YK
1488static const char * const msaregnames[] = {
1489 "w0.d0", "w0.d1", "w1.d0", "w1.d1",
1490 "w2.d0", "w2.d1", "w3.d0", "w3.d1",
1491 "w4.d0", "w4.d1", "w5.d0", "w5.d1",
1492 "w6.d0", "w6.d1", "w7.d0", "w7.d1",
1493 "w8.d0", "w8.d1", "w9.d0", "w9.d1",
1494 "w10.d0", "w10.d1", "w11.d0", "w11.d1",
1495 "w12.d0", "w12.d1", "w13.d0", "w13.d1",
1496 "w14.d0", "w14.d1", "w15.d0", "w15.d1",
1497 "w16.d0", "w16.d1", "w17.d0", "w17.d1",
1498 "w18.d0", "w18.d1", "w19.d0", "w19.d1",
1499 "w20.d0", "w20.d1", "w21.d0", "w21.d1",
1500 "w22.d0", "w22.d1", "w23.d0", "w23.d1",
1501 "w24.d0", "w24.d1", "w25.d0", "w25.d1",
1502 "w26.d0", "w26.d1", "w27.d0", "w27.d1",
1503 "w28.d0", "w28.d1", "w29.d0", "w29.d1",
1504 "w30.d0", "w30.d1", "w31.d0", "w31.d1",
1505};
1506
9d68ac14 1507#define LOG_DISAS(...) \
fb7729e2
RH
1508 do { \
1509 if (MIPS_DEBUG_DISAS) { \
9d68ac14 1510 qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__); \
fb7729e2
RH
1511 } \
1512 } while (0)
1513
9d68ac14 1514#define MIPS_INVAL(op) \
fb7729e2
RH
1515 do { \
1516 if (MIPS_DEBUG_DISAS) { \
9d68ac14
AJ
1517 qemu_log_mask(CPU_LOG_TB_IN_ASM, \
1518 TARGET_FMT_lx ": %08x Invalid %s %03x %03x %03x\n", \
eeb3bba8
EC
1519 ctx->base.pc_next, ctx->opcode, op, \
1520 ctx->opcode >> 26, ctx->opcode & 0x3F, \
1521 ((ctx->opcode >> 16) & 0x1F)); \
fb7729e2
RH
1522 } \
1523 } while (0)
958fb4a9 1524
8e9ade68
TS
1525/* General purpose registers moves. */
1526static inline void gen_load_gpr (TCGv t, int reg)
aaa9128a 1527{
8e9ade68
TS
1528 if (reg == 0)
1529 tcg_gen_movi_tl(t, 0);
1530 else
4b2eb8d2 1531 tcg_gen_mov_tl(t, cpu_gpr[reg]);
aaa9128a
TS
1532}
1533
8e9ade68 1534static inline void gen_store_gpr (TCGv t, int reg)
aaa9128a 1535{
8e9ade68 1536 if (reg != 0)
4b2eb8d2 1537 tcg_gen_mov_tl(cpu_gpr[reg], t);
aaa9128a
TS
1538}
1539
8e9ade68 1540/* Moves to/from shadow registers. */
be24bb4f 1541static inline void gen_load_srsgpr (int from, int to)
aaa9128a 1542{
d9bea114 1543 TCGv t0 = tcg_temp_new();
be24bb4f
TS
1544
1545 if (from == 0)
d9bea114 1546 tcg_gen_movi_tl(t0, 0);
8e9ade68 1547 else {
d9bea114 1548 TCGv_i32 t2 = tcg_temp_new_i32();
a7812ae4 1549 TCGv_ptr addr = tcg_temp_new_ptr();
aaa9128a 1550
7db13fae 1551 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
d9bea114
AJ
1552 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1553 tcg_gen_andi_i32(t2, t2, 0xf);
1554 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1555 tcg_gen_ext_i32_ptr(addr, t2);
a7812ae4 1556 tcg_gen_add_ptr(addr, cpu_env, addr);
aaa9128a 1557
d9bea114 1558 tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from);
a7812ae4 1559 tcg_temp_free_ptr(addr);
d9bea114 1560 tcg_temp_free_i32(t2);
8e9ade68 1561 }
d9bea114
AJ
1562 gen_store_gpr(t0, to);
1563 tcg_temp_free(t0);
aaa9128a
TS
1564}
1565
be24bb4f 1566static inline void gen_store_srsgpr (int from, int to)
aaa9128a 1567{
be24bb4f 1568 if (to != 0) {
d9bea114
AJ
1569 TCGv t0 = tcg_temp_new();
1570 TCGv_i32 t2 = tcg_temp_new_i32();
a7812ae4 1571 TCGv_ptr addr = tcg_temp_new_ptr();
be24bb4f 1572
d9bea114 1573 gen_load_gpr(t0, from);
7db13fae 1574 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
d9bea114
AJ
1575 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1576 tcg_gen_andi_i32(t2, t2, 0xf);
1577 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1578 tcg_gen_ext_i32_ptr(addr, t2);
a7812ae4 1579 tcg_gen_add_ptr(addr, cpu_env, addr);
be24bb4f 1580
d9bea114 1581 tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to);
a7812ae4 1582 tcg_temp_free_ptr(addr);
d9bea114
AJ
1583 tcg_temp_free_i32(t2);
1584 tcg_temp_free(t0);
8e9ade68 1585 }
aaa9128a
TS
1586}
1587
eab9944c
LA
1588/* Tests */
1589static inline void gen_save_pc(target_ulong pc)
1590{
1591 tcg_gen_movi_tl(cpu_PC, pc);
1592}
1593
1594static inline void save_cpu_state(DisasContext *ctx, int do_save_pc)
1595{
1596 LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
eeb3bba8
EC
1597 if (do_save_pc && ctx->base.pc_next != ctx->saved_pc) {
1598 gen_save_pc(ctx->base.pc_next);
1599 ctx->saved_pc = ctx->base.pc_next;
eab9944c
LA
1600 }
1601 if (ctx->hflags != ctx->saved_hflags) {
1602 tcg_gen_movi_i32(hflags, ctx->hflags);
1603 ctx->saved_hflags = ctx->hflags;
1604 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
1605 case MIPS_HFLAG_BR:
1606 break;
1607 case MIPS_HFLAG_BC:
1608 case MIPS_HFLAG_BL:
1609 case MIPS_HFLAG_B:
1610 tcg_gen_movi_tl(btarget, ctx->btarget);
1611 break;
1612 }
1613 }
1614}
1615
1616static inline void restore_cpu_state(CPUMIPSState *env, DisasContext *ctx)
1617{
1618 ctx->saved_hflags = ctx->hflags;
1619 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
1620 case MIPS_HFLAG_BR:
1621 break;
1622 case MIPS_HFLAG_BC:
1623 case MIPS_HFLAG_BL:
1624 case MIPS_HFLAG_B:
1625 ctx->btarget = env->btarget;
1626 break;
1627 }
1628}
1629
1630static inline void generate_exception_err(DisasContext *ctx, int excp, int err)
1631{
1632 TCGv_i32 texcp = tcg_const_i32(excp);
1633 TCGv_i32 terr = tcg_const_i32(err);
1634 save_cpu_state(ctx, 1);
1635 gen_helper_raise_exception_err(cpu_env, texcp, terr);
1636 tcg_temp_free_i32(terr);
1637 tcg_temp_free_i32(texcp);
eeb3bba8 1638 ctx->base.is_jmp = DISAS_NORETURN;
eab9944c
LA
1639}
1640
1641static inline void generate_exception(DisasContext *ctx, int excp)
1642{
eab9944c
LA
1643 gen_helper_0e0i(raise_exception, excp);
1644}
1645
9c708c7f
PD
1646static inline void generate_exception_end(DisasContext *ctx, int excp)
1647{
1648 generate_exception_err(ctx, excp, 0);
1649}
1650
aaa9128a 1651/* Floating point register moves. */
7c979afd 1652static void gen_load_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
aa0bf00b 1653{
7c979afd
LA
1654 if (ctx->hflags & MIPS_HFLAG_FRE) {
1655 generate_exception(ctx, EXCP_RI);
1656 }
ecc7b3aa 1657 tcg_gen_extrl_i64_i32(t, fpu_f64[reg]);
6ea83fed
FB
1658}
1659
7c979afd 1660static void gen_store_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
aa0bf00b 1661{
7c979afd
LA
1662 TCGv_i64 t64;
1663 if (ctx->hflags & MIPS_HFLAG_FRE) {
1664 generate_exception(ctx, EXCP_RI);
1665 }
1666 t64 = tcg_temp_new_i64();
d73ee8a2
RH
1667 tcg_gen_extu_i32_i64(t64, t);
1668 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 0, 32);
1669 tcg_temp_free_i64(t64);
6d066274
AJ
1670}
1671
7f6613ce 1672static void gen_load_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
6d066274 1673{
7f6613ce 1674 if (ctx->hflags & MIPS_HFLAG_F64) {
71f303cd 1675 tcg_gen_extrh_i64_i32(t, fpu_f64[reg]);
7f6613ce 1676 } else {
7c979afd 1677 gen_load_fpr32(ctx, t, reg | 1);
7f6613ce 1678 }
6d066274
AJ
1679}
1680
7f6613ce 1681static void gen_store_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
6d066274 1682{
7f6613ce
PJ
1683 if (ctx->hflags & MIPS_HFLAG_F64) {
1684 TCGv_i64 t64 = tcg_temp_new_i64();
1685 tcg_gen_extu_i32_i64(t64, t);
1686 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 32, 32);
1687 tcg_temp_free_i64(t64);
1688 } else {
7c979afd 1689 gen_store_fpr32(ctx, t, reg | 1);
7f6613ce 1690 }
aa0bf00b 1691}
6ea83fed 1692
d73ee8a2 1693static void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
aa0bf00b 1694{
f364515c 1695 if (ctx->hflags & MIPS_HFLAG_F64) {
d73ee8a2 1696 tcg_gen_mov_i64(t, fpu_f64[reg]);
f364515c 1697 } else {
d73ee8a2 1698 tcg_gen_concat32_i64(t, fpu_f64[reg & ~1], fpu_f64[reg | 1]);
aa0bf00b
TS
1699 }
1700}
6ea83fed 1701
d73ee8a2 1702static void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
aa0bf00b 1703{
f364515c 1704 if (ctx->hflags & MIPS_HFLAG_F64) {
d73ee8a2 1705 tcg_gen_mov_i64(fpu_f64[reg], t);
f364515c 1706 } else {
d73ee8a2
RH
1707 TCGv_i64 t0;
1708 tcg_gen_deposit_i64(fpu_f64[reg & ~1], fpu_f64[reg & ~1], t, 0, 32);
1709 t0 = tcg_temp_new_i64();
6d066274 1710 tcg_gen_shri_i64(t0, t, 32);
d73ee8a2 1711 tcg_gen_deposit_i64(fpu_f64[reg | 1], fpu_f64[reg | 1], t0, 0, 32);
6d066274 1712 tcg_temp_free_i64(t0);
aa0bf00b
TS
1713 }
1714}
6ea83fed 1715
d94536f4 1716static inline int get_fp_bit (int cc)
a16336e4 1717{
d94536f4
AJ
1718 if (cc)
1719 return 24 + cc;
1720 else
1721 return 23;
a16336e4
TS
1722}
1723
48d38ca5 1724/* Addresses computation */
941694d0 1725static inline void gen_op_addr_add (DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1)
4ad40f36 1726{
941694d0 1727 tcg_gen_add_tl(ret, arg0, arg1);
48d38ca5
TS
1728
1729#if defined(TARGET_MIPS64)
01f72885 1730 if (ctx->hflags & MIPS_HFLAG_AWRAP) {
941694d0 1731 tcg_gen_ext32s_i64(ret, ret);
48d38ca5
TS
1732 }
1733#endif
4ad40f36
FB
1734}
1735
31837be3
YK
1736/* Addresses computation (translation time) */
1737static target_long addr_add(DisasContext *ctx, target_long base,
1738 target_long offset)
1739{
1740 target_long sum = base + offset;
1741
1742#if defined(TARGET_MIPS64)
1743 if (ctx->hflags & MIPS_HFLAG_AWRAP) {
1744 sum = (int32_t)sum;
1745 }
1746#endif
1747 return sum;
1748}
1749
71f303cd 1750/* Sign-extract the low 32-bits to a target_long. */
1f1b4c00
YK
1751static inline void gen_move_low32(TCGv ret, TCGv_i64 arg)
1752{
1753#if defined(TARGET_MIPS64)
71f303cd
RH
1754 tcg_gen_ext32s_i64(ret, arg);
1755#else
1756 tcg_gen_extrl_i64_i32(ret, arg);
1757#endif
1758}
1759
1760/* Sign-extract the high 32-bits to a target_long. */
1761static inline void gen_move_high32(TCGv ret, TCGv_i64 arg)
1762{
1763#if defined(TARGET_MIPS64)
1764 tcg_gen_sari_i64(ret, arg, 32);
1f1b4c00 1765#else
71f303cd 1766 tcg_gen_extrh_i64_i32(ret, arg);
1f1b4c00
YK
1767#endif
1768}
1769
356265ae 1770static inline void check_cp0_enabled(DisasContext *ctx)
387a8fe5 1771{
fe253235 1772 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
c2c65dab 1773 generate_exception_err(ctx, EXCP_CpU, 0);
387a8fe5
TS
1774}
1775
356265ae 1776static inline void check_cp1_enabled(DisasContext *ctx)
5e755519 1777{
fe253235 1778 if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
5e755519
TS
1779 generate_exception_err(ctx, EXCP_CpU, 1);
1780}
1781
b8aa4598
TS
1782/* Verify that the processor is running with COP1X instructions enabled.
1783 This is associated with the nabla symbol in the MIPS32 and MIPS64
1784 opcode tables. */
1785
356265ae 1786static inline void check_cop1x(DisasContext *ctx)
b8aa4598
TS
1787{
1788 if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
9c708c7f 1789 generate_exception_end(ctx, EXCP_RI);
b8aa4598
TS
1790}
1791
1792/* Verify that the processor is running with 64-bit floating-point
1793 operations enabled. */
1794
356265ae 1795static inline void check_cp1_64bitmode(DisasContext *ctx)
5e755519 1796{
b8aa4598 1797 if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
9c708c7f 1798 generate_exception_end(ctx, EXCP_RI);
5e755519
TS
1799}
1800
1801/*
1802 * Verify if floating point register is valid; an operation is not defined
1803 * if bit 0 of any register specification is set and the FR bit in the
1804 * Status register equals zero, since the register numbers specify an
1805 * even-odd pair of adjacent coprocessor general registers. When the FR bit
1806 * in the Status register equals one, both even and odd register numbers
1807 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
1808 *
1809 * Multiple 64 bit wide registers can be checked by calling
1810 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
1811 */
356265ae 1812static inline void check_cp1_registers(DisasContext *ctx, int regs)
5e755519 1813{
fe253235 1814 if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)))
9c708c7f 1815 generate_exception_end(ctx, EXCP_RI);
5e755519
TS
1816}
1817
853c3240
JL
1818/* Verify that the processor is running with DSP instructions enabled.
1819 This is enabled by CP0 Status register MX(24) bit.
1820 */
1821
1822static inline void check_dsp(DisasContext *ctx)
1823{
1824 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP))) {
ad153f15 1825 if (ctx->insn_flags & ASE_DSP) {
9c708c7f 1826 generate_exception_end(ctx, EXCP_DSPDIS);
ad153f15 1827 } else {
9c708c7f 1828 generate_exception_end(ctx, EXCP_RI);
ad153f15 1829 }
853c3240
JL
1830 }
1831}
1832
1833static inline void check_dspr2(DisasContext *ctx)
1834{
1835 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSPR2))) {
ad153f15 1836 if (ctx->insn_flags & ASE_DSP) {
9c708c7f 1837 generate_exception_end(ctx, EXCP_DSPDIS);
ad153f15 1838 } else {
9c708c7f 1839 generate_exception_end(ctx, EXCP_RI);
ad153f15 1840 }
853c3240
JL
1841 }
1842}
1843
3a95e3a7 1844/* This code generates a "reserved instruction" exception if the
e189e748 1845 CPU does not support the instruction set corresponding to flags. */
d75c135e 1846static inline void check_insn(DisasContext *ctx, int flags)
3a95e3a7 1847{
d75c135e 1848 if (unlikely(!(ctx->insn_flags & flags))) {
9c708c7f 1849 generate_exception_end(ctx, EXCP_RI);
d75c135e 1850 }
3a95e3a7
TS
1851}
1852
fecd2646
LA
1853/* This code generates a "reserved instruction" exception if the
1854 CPU has corresponding flag set which indicates that the instruction
1855 has been removed. */
1856static inline void check_insn_opc_removed(DisasContext *ctx, int flags)
1857{
1858 if (unlikely(ctx->insn_flags & flags)) {
9c708c7f 1859 generate_exception_end(ctx, EXCP_RI);
fecd2646
LA
1860 }
1861}
1862
e29c9628
YK
1863/* This code generates a "reserved instruction" exception if the
1864 CPU does not support 64-bit paired-single (PS) floating point data type */
1865static inline void check_ps(DisasContext *ctx)
1866{
1867 if (unlikely(!ctx->ps)) {
1868 generate_exception(ctx, EXCP_RI);
1869 }
1870 check_cp1_64bitmode(ctx);
1871}
1872
c7986fd6 1873#ifdef TARGET_MIPS64
e189e748
TS
1874/* This code generates a "reserved instruction" exception if 64-bit
1875 instructions are not enabled. */
356265ae 1876static inline void check_mips_64(DisasContext *ctx)
e189e748 1877{
fe253235 1878 if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
9c708c7f 1879 generate_exception_end(ctx, EXCP_RI);
e189e748 1880}
c7986fd6 1881#endif
e189e748 1882
5204ea79
LA
1883#ifndef CONFIG_USER_ONLY
1884static inline void check_mvh(DisasContext *ctx)
1885{
1886 if (unlikely(!ctx->mvh)) {
1887 generate_exception(ctx, EXCP_RI);
1888 }
1889}
1890#endif
1891
8153667c
NF
1892/* Define small wrappers for gen_load_fpr* so that we have a uniform
1893 calling interface for 32 and 64-bit FPRs. No sense in changing
1894 all callers for gen_load_fpr32 when we need the CTX parameter for
1895 this one use. */
7c979afd 1896#define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(ctx, x, y)
8153667c
NF
1897#define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
1898#define FOP_CONDS(type, abs, fmt, ifmt, bits) \
1899static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \
1900 int ft, int fs, int cc) \
1901{ \
1902 TCGv_i##bits fp0 = tcg_temp_new_i##bits (); \
1903 TCGv_i##bits fp1 = tcg_temp_new_i##bits (); \
1904 switch (ifmt) { \
1905 case FMT_PS: \
e29c9628 1906 check_ps(ctx); \
8153667c
NF
1907 break; \
1908 case FMT_D: \
1909 if (abs) { \
1910 check_cop1x(ctx); \
1911 } \
1912 check_cp1_registers(ctx, fs | ft); \
1913 break; \
1914 case FMT_S: \
1915 if (abs) { \
1916 check_cop1x(ctx); \
1917 } \
1918 break; \
1919 } \
1920 gen_ldcmp_fpr##bits (ctx, fp0, fs); \
1921 gen_ldcmp_fpr##bits (ctx, fp1, ft); \
1922 switch (n) { \
895c2d04
BS
1923 case 0: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc); break;\
1924 case 1: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc); break;\
1925 case 2: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc); break;\
1926 case 3: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc); break;\
1927 case 4: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc); break;\
1928 case 5: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc); break;\
1929 case 6: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc); break;\
1930 case 7: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc); break;\
1931 case 8: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc); break;\
1932 case 9: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); break;\
1933 case 10: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc); break;\
1934 case 11: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc); break;\
1935 case 12: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc); break;\
1936 case 13: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc); break;\
1937 case 14: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc); break;\
1938 case 15: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc); break;\
8153667c
NF
1939 default: abort(); \
1940 } \
1941 tcg_temp_free_i##bits (fp0); \
1942 tcg_temp_free_i##bits (fp1); \
1943}
1944
1945FOP_CONDS(, 0, d, FMT_D, 64)
1946FOP_CONDS(abs, 1, d, FMT_D, 64)
1947FOP_CONDS(, 0, s, FMT_S, 32)
1948FOP_CONDS(abs, 1, s, FMT_S, 32)
1949FOP_CONDS(, 0, ps, FMT_PS, 64)
1950FOP_CONDS(abs, 1, ps, FMT_PS, 64)
1951#undef FOP_CONDS
3f493883
YK
1952
1953#define FOP_CONDNS(fmt, ifmt, bits, STORE) \
1954static inline void gen_r6_cmp_ ## fmt(DisasContext * ctx, int n, \
1955 int ft, int fs, int fd) \
1956{ \
1957 TCGv_i ## bits fp0 = tcg_temp_new_i ## bits(); \
1958 TCGv_i ## bits fp1 = tcg_temp_new_i ## bits(); \
00fb4a11 1959 if (ifmt == FMT_D) { \
3f493883 1960 check_cp1_registers(ctx, fs | ft | fd); \
3f493883
YK
1961 } \
1962 gen_ldcmp_fpr ## bits(ctx, fp0, fs); \
1963 gen_ldcmp_fpr ## bits(ctx, fp1, ft); \
1964 switch (n) { \
1965 case 0: \
1966 gen_helper_r6_cmp_ ## fmt ## _af(fp0, cpu_env, fp0, fp1); \
1967 break; \
1968 case 1: \
1969 gen_helper_r6_cmp_ ## fmt ## _un(fp0, cpu_env, fp0, fp1); \
1970 break; \
1971 case 2: \
1972 gen_helper_r6_cmp_ ## fmt ## _eq(fp0, cpu_env, fp0, fp1); \
1973 break; \
1974 case 3: \
1975 gen_helper_r6_cmp_ ## fmt ## _ueq(fp0, cpu_env, fp0, fp1); \
1976 break; \
1977 case 4: \
1978 gen_helper_r6_cmp_ ## fmt ## _lt(fp0, cpu_env, fp0, fp1); \
1979 break; \
1980 case 5: \
1981 gen_helper_r6_cmp_ ## fmt ## _ult(fp0, cpu_env, fp0, fp1); \
1982 break; \
1983 case 6: \
1984 gen_helper_r6_cmp_ ## fmt ## _le(fp0, cpu_env, fp0, fp1); \
1985 break; \
1986 case 7: \
1987 gen_helper_r6_cmp_ ## fmt ## _ule(fp0, cpu_env, fp0, fp1); \
1988 break; \
1989 case 8: \
1990 gen_helper_r6_cmp_ ## fmt ## _saf(fp0, cpu_env, fp0, fp1); \
1991 break; \
1992 case 9: \
1993 gen_helper_r6_cmp_ ## fmt ## _sun(fp0, cpu_env, fp0, fp1); \
1994 break; \
1995 case 10: \
1996 gen_helper_r6_cmp_ ## fmt ## _seq(fp0, cpu_env, fp0, fp1); \
1997 break; \
1998 case 11: \
1999 gen_helper_r6_cmp_ ## fmt ## _sueq(fp0, cpu_env, fp0, fp1); \
2000 break; \
2001 case 12: \
2002 gen_helper_r6_cmp_ ## fmt ## _slt(fp0, cpu_env, fp0, fp1); \
2003 break; \
2004 case 13: \
2005 gen_helper_r6_cmp_ ## fmt ## _sult(fp0, cpu_env, fp0, fp1); \
2006 break; \
2007 case 14: \
2008 gen_helper_r6_cmp_ ## fmt ## _sle(fp0, cpu_env, fp0, fp1); \
2009 break; \
2010 case 15: \
2011 gen_helper_r6_cmp_ ## fmt ## _sule(fp0, cpu_env, fp0, fp1); \
2012 break; \
2013 case 17: \
2014 gen_helper_r6_cmp_ ## fmt ## _or(fp0, cpu_env, fp0, fp1); \
2015 break; \
2016 case 18: \
2017 gen_helper_r6_cmp_ ## fmt ## _une(fp0, cpu_env, fp0, fp1); \
2018 break; \
2019 case 19: \
2020 gen_helper_r6_cmp_ ## fmt ## _ne(fp0, cpu_env, fp0, fp1); \
2021 break; \
2022 case 25: \
2023 gen_helper_r6_cmp_ ## fmt ## _sor(fp0, cpu_env, fp0, fp1); \
2024 break; \
2025 case 26: \
2026 gen_helper_r6_cmp_ ## fmt ## _sune(fp0, cpu_env, fp0, fp1); \
2027 break; \
2028 case 27: \
2029 gen_helper_r6_cmp_ ## fmt ## _sne(fp0, cpu_env, fp0, fp1); \
2030 break; \
2031 default: \
2032 abort(); \
2033 } \
2034 STORE; \
2035 tcg_temp_free_i ## bits (fp0); \
2036 tcg_temp_free_i ## bits (fp1); \
2037}
2038
2039FOP_CONDNS(d, FMT_D, 64, gen_store_fpr64(ctx, fp0, fd))
7c979afd 2040FOP_CONDNS(s, FMT_S, 32, gen_store_fpr32(ctx, fp0, fd))
3f493883 2041#undef FOP_CONDNS
8153667c
NF
2042#undef gen_ldcmp_fpr32
2043#undef gen_ldcmp_fpr64
2044
958fb4a9 2045/* load/store instructions. */
e7139c44 2046#ifdef CONFIG_USER_ONLY
d9bea114 2047#define OP_LD_ATOMIC(insn,fname) \
dd4096cd
JH
2048static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx, \
2049 DisasContext *ctx) \
d9bea114
AJ
2050{ \
2051 TCGv t0 = tcg_temp_new(); \
2052 tcg_gen_mov_tl(t0, arg1); \
2053 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
7db13fae
AF
2054 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
2055 tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval)); \
d9bea114 2056 tcg_temp_free(t0); \
aaa9128a 2057}
e7139c44
AJ
2058#else
2059#define OP_LD_ATOMIC(insn,fname) \
dd4096cd
JH
2060static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx, \
2061 DisasContext *ctx) \
e7139c44 2062{ \
dd4096cd 2063 gen_helper_1e1i(insn, ret, arg1, mem_idx); \
e7139c44
AJ
2064}
2065#endif
aaa9128a
TS
2066OP_LD_ATOMIC(ll,ld32s);
2067#if defined(TARGET_MIPS64)
2068OP_LD_ATOMIC(lld,ld64);
2069#endif
2070#undef OP_LD_ATOMIC
2071
590bc601
PB
2072#ifdef CONFIG_USER_ONLY
2073#define OP_ST_ATOMIC(insn,fname,ldname,almask) \
dd4096cd
JH
2074static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, int mem_idx, \
2075 DisasContext *ctx) \
590bc601
PB
2076{ \
2077 TCGv t0 = tcg_temp_new(); \
42a268c2
RH
2078 TCGLabel *l1 = gen_new_label(); \
2079 TCGLabel *l2 = gen_new_label(); \
590bc601
PB
2080 \
2081 tcg_gen_andi_tl(t0, arg2, almask); \
2082 tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1); \
7db13fae 2083 tcg_gen_st_tl(arg2, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr)); \
590bc601
PB
2084 generate_exception(ctx, EXCP_AdES); \
2085 gen_set_label(l1); \
7db13fae 2086 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
590bc601
PB
2087 tcg_gen_brcond_tl(TCG_COND_NE, arg2, t0, l2); \
2088 tcg_gen_movi_tl(t0, rt | ((almask << 3) & 0x20)); \
7db13fae
AF
2089 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, llreg)); \
2090 tcg_gen_st_tl(arg1, cpu_env, offsetof(CPUMIPSState, llnewval)); \
9c708c7f 2091 generate_exception_end(ctx, EXCP_SC); \
590bc601
PB
2092 gen_set_label(l2); \
2093 tcg_gen_movi_tl(t0, 0); \
2094 gen_store_gpr(t0, rt); \
2095 tcg_temp_free(t0); \
2096}
2097#else
2098#define OP_ST_ATOMIC(insn,fname,ldname,almask) \
dd4096cd
JH
2099static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, int mem_idx, \
2100 DisasContext *ctx) \
590bc601
PB
2101{ \
2102 TCGv t0 = tcg_temp_new(); \
dd4096cd 2103 gen_helper_1e2i(insn, t0, arg1, arg2, mem_idx); \
590bc601 2104 gen_store_gpr(t0, rt); \
590bc601
PB
2105 tcg_temp_free(t0); \
2106}
2107#endif
590bc601 2108OP_ST_ATOMIC(sc,st32,ld32s,0x3);
aaa9128a 2109#if defined(TARGET_MIPS64)
590bc601 2110OP_ST_ATOMIC(scd,st64,ld64,0x7);
aaa9128a
TS
2111#endif
2112#undef OP_ST_ATOMIC
2113
662d7485 2114static void gen_base_offset_addr (DisasContext *ctx, TCGv addr,
72e1f16f 2115 int base, int offset)
662d7485
NF
2116{
2117 if (base == 0) {
2118 tcg_gen_movi_tl(addr, offset);
2119 } else if (offset == 0) {
2120 gen_load_gpr(addr, base);
2121 } else {
2122 tcg_gen_movi_tl(addr, offset);
2123 gen_op_addr_add(ctx, addr, cpu_gpr[base], addr);
2124 }
2125}
2126
364d4831
NF
2127static target_ulong pc_relative_pc (DisasContext *ctx)
2128{
eeb3bba8 2129 target_ulong pc = ctx->base.pc_next;
364d4831
NF
2130
2131 if (ctx->hflags & MIPS_HFLAG_BMASK) {
2132 int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
2133
2134 pc -= branch_bytes;
2135 }
2136
2137 pc &= ~(target_ulong)3;
2138 return pc;
2139}
2140
5c13fdfd 2141/* Load */
d75c135e 2142static void gen_ld(DisasContext *ctx, uint32_t opc,
72e1f16f 2143 int rt, int base, int offset)
6af0bf9c 2144{
fc40787a 2145 TCGv t0, t1, t2;
dd4096cd 2146 int mem_idx = ctx->mem_idx;
afa88c3a 2147
d75c135e 2148 if (rt == 0 && ctx->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)) {
afa88c3a
AJ
2149 /* Loongson CPU uses a load to zero register for prefetch.
2150 We emulate it as a NOP. On other CPU we must perform the
2151 actual memory access. */
afa88c3a
AJ
2152 return;
2153 }
6af0bf9c 2154
afa88c3a 2155 t0 = tcg_temp_new();
662d7485 2156 gen_base_offset_addr(ctx, t0, base, offset);
afa88c3a 2157
6af0bf9c 2158 switch (opc) {
d26bc211 2159#if defined(TARGET_MIPS64)
6e473128 2160 case OPC_LWU:
dd4096cd 2161 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL |
be3a8c53 2162 ctx->default_tcg_memop_mask);
78723684 2163 gen_store_gpr(t0, rt);
6e473128 2164 break;
6af0bf9c 2165 case OPC_LD:
dd4096cd 2166 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ |
be3a8c53 2167 ctx->default_tcg_memop_mask);
78723684 2168 gen_store_gpr(t0, rt);
6af0bf9c 2169 break;
7a387fff 2170 case OPC_LLD:
bf7910c6 2171 case R6_OPC_LLD:
dd4096cd 2172 op_ld_lld(t0, t0, mem_idx, ctx);
78723684 2173 gen_store_gpr(t0, rt);
7a387fff 2174 break;
6af0bf9c 2175 case OPC_LDL:
3cee3050 2176 t1 = tcg_temp_new();
908680c6
AJ
2177 /* Do a byte access to possibly trigger a page
2178 fault with the unaligned address. */
dd4096cd 2179 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
fc40787a
AJ
2180 tcg_gen_andi_tl(t1, t0, 7);
2181#ifndef TARGET_WORDS_BIGENDIAN
2182 tcg_gen_xori_tl(t1, t1, 7);
2183#endif
2184 tcg_gen_shli_tl(t1, t1, 3);
2185 tcg_gen_andi_tl(t0, t0, ~7);
dd4096cd 2186 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
fc40787a 2187 tcg_gen_shl_tl(t0, t0, t1);
eb02cc3f
AJ
2188 t2 = tcg_const_tl(-1);
2189 tcg_gen_shl_tl(t2, t2, t1);
78723684 2190 gen_load_gpr(t1, rt);
eb02cc3f 2191 tcg_gen_andc_tl(t1, t1, t2);
fc40787a
AJ
2192 tcg_temp_free(t2);
2193 tcg_gen_or_tl(t0, t0, t1);
3cee3050 2194 tcg_temp_free(t1);
fc40787a 2195 gen_store_gpr(t0, rt);
6af0bf9c 2196 break;
6af0bf9c 2197 case OPC_LDR:
3cee3050 2198 t1 = tcg_temp_new();
908680c6
AJ
2199 /* Do a byte access to possibly trigger a page
2200 fault with the unaligned address. */
dd4096cd 2201 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
fc40787a
AJ
2202 tcg_gen_andi_tl(t1, t0, 7);
2203#ifdef TARGET_WORDS_BIGENDIAN
2204 tcg_gen_xori_tl(t1, t1, 7);
2205#endif
2206 tcg_gen_shli_tl(t1, t1, 3);
2207 tcg_gen_andi_tl(t0, t0, ~7);
dd4096cd 2208 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
fc40787a
AJ
2209 tcg_gen_shr_tl(t0, t0, t1);
2210 tcg_gen_xori_tl(t1, t1, 63);
2211 t2 = tcg_const_tl(0xfffffffffffffffeull);
2212 tcg_gen_shl_tl(t2, t2, t1);
78723684 2213 gen_load_gpr(t1, rt);
fc40787a
AJ
2214 tcg_gen_and_tl(t1, t1, t2);
2215 tcg_temp_free(t2);
2216 tcg_gen_or_tl(t0, t0, t1);
3cee3050 2217 tcg_temp_free(t1);
fc40787a 2218 gen_store_gpr(t0, rt);
6af0bf9c 2219 break;
364d4831 2220 case OPC_LDPC:
3cee3050 2221 t1 = tcg_const_tl(pc_relative_pc(ctx));
364d4831 2222 gen_op_addr_add(ctx, t0, t0, t1);
3cee3050 2223 tcg_temp_free(t1);
dd4096cd 2224 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
364d4831
NF
2225 gen_store_gpr(t0, rt);
2226 break;
6af0bf9c 2227#endif
364d4831 2228 case OPC_LWPC:
3cee3050 2229 t1 = tcg_const_tl(pc_relative_pc(ctx));
364d4831 2230 gen_op_addr_add(ctx, t0, t0, t1);
3cee3050 2231 tcg_temp_free(t1);
dd4096cd 2232 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESL);
364d4831
NF
2233 gen_store_gpr(t0, rt);
2234 break;
76964147
JH
2235 case OPC_LWE:
2236 mem_idx = MIPS_HFLAG_UM;
2237 /* fall through */
6af0bf9c 2238 case OPC_LW:
dd4096cd 2239 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESL |
be3a8c53 2240 ctx->default_tcg_memop_mask);
78723684 2241 gen_store_gpr(t0, rt);
6af0bf9c 2242 break;
76964147
JH
2243 case OPC_LHE:
2244 mem_idx = MIPS_HFLAG_UM;
2245 /* fall through */
6af0bf9c 2246 case OPC_LH:
dd4096cd 2247 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESW |
be3a8c53 2248 ctx->default_tcg_memop_mask);
78723684 2249 gen_store_gpr(t0, rt);
6af0bf9c 2250 break;
76964147
JH
2251 case OPC_LHUE:
2252 mem_idx = MIPS_HFLAG_UM;
2253 /* fall through */
6af0bf9c 2254 case OPC_LHU:
dd4096cd 2255 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUW |
be3a8c53 2256 ctx->default_tcg_memop_mask);
78723684 2257 gen_store_gpr(t0, rt);
6af0bf9c 2258 break;
76964147
JH
2259 case OPC_LBE:
2260 mem_idx = MIPS_HFLAG_UM;
2261 /* fall through */
6af0bf9c 2262 case OPC_LB:
dd4096cd 2263 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_SB);
78723684 2264 gen_store_gpr(t0, rt);
6af0bf9c 2265 break;
76964147
JH
2266 case OPC_LBUE:
2267 mem_idx = MIPS_HFLAG_UM;
2268 /* fall through */
6af0bf9c 2269 case OPC_LBU:
dd4096cd 2270 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_UB);
78723684 2271 gen_store_gpr(t0, rt);
6af0bf9c 2272 break;
76964147
JH
2273 case OPC_LWLE:
2274 mem_idx = MIPS_HFLAG_UM;
2275 /* fall through */
6af0bf9c 2276 case OPC_LWL:
3cee3050 2277 t1 = tcg_temp_new();
908680c6
AJ
2278 /* Do a byte access to possibly trigger a page
2279 fault with the unaligned address. */
dd4096cd 2280 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
fc40787a
AJ
2281 tcg_gen_andi_tl(t1, t0, 3);
2282#ifndef TARGET_WORDS_BIGENDIAN
2283 tcg_gen_xori_tl(t1, t1, 3);
2284#endif
2285 tcg_gen_shli_tl(t1, t1, 3);
2286 tcg_gen_andi_tl(t0, t0, ~3);
dd4096cd 2287 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL);
fc40787a 2288 tcg_gen_shl_tl(t0, t0, t1);
eb02cc3f
AJ
2289 t2 = tcg_const_tl(-1);
2290 tcg_gen_shl_tl(t2, t2, t1);
6958549d 2291 gen_load_gpr(t1, rt);
eb02cc3f 2292 tcg_gen_andc_tl(t1, t1, t2);
fc40787a
AJ
2293 tcg_temp_free(t2);
2294 tcg_gen_or_tl(t0, t0, t1);
3cee3050 2295 tcg_temp_free(t1);
fc40787a
AJ
2296 tcg_gen_ext32s_tl(t0, t0);
2297 gen_store_gpr(t0, rt);
6af0bf9c 2298 break;
76964147
JH
2299 case OPC_LWRE:
2300 mem_idx = MIPS_HFLAG_UM;
2301 /* fall through */
6af0bf9c 2302 case OPC_LWR:
3cee3050 2303 t1 = tcg_temp_new();
908680c6
AJ
2304 /* Do a byte access to possibly trigger a page
2305 fault with the unaligned address. */
dd4096cd 2306 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
fc40787a
AJ
2307 tcg_gen_andi_tl(t1, t0, 3);
2308#ifdef TARGET_WORDS_BIGENDIAN
2309 tcg_gen_xori_tl(t1, t1, 3);
2310#endif
2311 tcg_gen_shli_tl(t1, t1, 3);
2312 tcg_gen_andi_tl(t0, t0, ~3);
dd4096cd 2313 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL);
fc40787a
AJ
2314 tcg_gen_shr_tl(t0, t0, t1);
2315 tcg_gen_xori_tl(t1, t1, 31);
2316 t2 = tcg_const_tl(0xfffffffeull);
2317 tcg_gen_shl_tl(t2, t2, t1);
6958549d 2318 gen_load_gpr(t1, rt);
fc40787a
AJ
2319 tcg_gen_and_tl(t1, t1, t2);
2320 tcg_temp_free(t2);
2321 tcg_gen_or_tl(t0, t0, t1);
3cee3050 2322 tcg_temp_free(t1);
c728154b 2323 tcg_gen_ext32s_tl(t0, t0);
fc40787a 2324 gen_store_gpr(t0, rt);
6af0bf9c 2325 break;
76964147
JH
2326 case OPC_LLE:
2327 mem_idx = MIPS_HFLAG_UM;
2328 /* fall through */
6af0bf9c 2329 case OPC_LL:
4368b29a 2330 case R6_OPC_LL:
dd4096cd 2331 op_ld_ll(t0, t0, mem_idx, ctx);
78723684 2332 gen_store_gpr(t0, rt);
6af0bf9c 2333 break;
d66c7132 2334 }
d66c7132 2335 tcg_temp_free(t0);
d66c7132
AJ
2336}
2337
5c13fdfd
AJ
2338/* Store */
2339static void gen_st (DisasContext *ctx, uint32_t opc, int rt,
72e1f16f 2340 int base, int offset)
5c13fdfd 2341{
5c13fdfd
AJ
2342 TCGv t0 = tcg_temp_new();
2343 TCGv t1 = tcg_temp_new();
dd4096cd 2344 int mem_idx = ctx->mem_idx;
5c13fdfd
AJ
2345
2346 gen_base_offset_addr(ctx, t0, base, offset);
2347 gen_load_gpr(t1, rt);
2348 switch (opc) {
2349#if defined(TARGET_MIPS64)
2350 case OPC_SD:
dd4096cd 2351 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEQ |
be3a8c53 2352 ctx->default_tcg_memop_mask);
5c13fdfd
AJ
2353 break;
2354 case OPC_SDL:
dd4096cd 2355 gen_helper_0e2i(sdl, t1, t0, mem_idx);
5c13fdfd
AJ
2356 break;
2357 case OPC_SDR:
dd4096cd 2358 gen_helper_0e2i(sdr, t1, t0, mem_idx);
5c13fdfd
AJ
2359 break;
2360#endif
76964147
JH
2361 case OPC_SWE:
2362 mem_idx = MIPS_HFLAG_UM;
2363 /* fall through */
5c13fdfd 2364 case OPC_SW:
dd4096cd 2365 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUL |
be3a8c53 2366 ctx->default_tcg_memop_mask);
5c13fdfd 2367 break;
76964147
JH
2368 case OPC_SHE:
2369 mem_idx = MIPS_HFLAG_UM;
2370 /* fall through */
5c13fdfd 2371 case OPC_SH:
dd4096cd 2372 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUW |
be3a8c53 2373 ctx->default_tcg_memop_mask);
5c13fdfd 2374 break;
76964147
JH
2375 case OPC_SBE:
2376 mem_idx = MIPS_HFLAG_UM;
2377 /* fall through */
5c13fdfd 2378 case OPC_SB:
dd4096cd 2379 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_8);
5c13fdfd 2380 break;
76964147
JH
2381 case OPC_SWLE:
2382 mem_idx = MIPS_HFLAG_UM;
2383 /* fall through */
5c13fdfd 2384 case OPC_SWL:
dd4096cd 2385 gen_helper_0e2i(swl, t1, t0, mem_idx);
5c13fdfd 2386 break;
76964147
JH
2387 case OPC_SWRE:
2388 mem_idx = MIPS_HFLAG_UM;
2389 /* fall through */
5c13fdfd 2390 case OPC_SWR:
dd4096cd 2391 gen_helper_0e2i(swr, t1, t0, mem_idx);
5c13fdfd
AJ
2392 break;
2393 }
5c13fdfd
AJ
2394 tcg_temp_free(t0);
2395 tcg_temp_free(t1);
2396}
2397
2398
d66c7132
AJ
2399/* Store conditional */
2400static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt,
2401 int base, int16_t offset)
2402{
d66c7132 2403 TCGv t0, t1;
dd4096cd 2404 int mem_idx = ctx->mem_idx;
d66c7132 2405
2d2826b9 2406#ifdef CONFIG_USER_ONLY
d66c7132 2407 t0 = tcg_temp_local_new();
d66c7132 2408 t1 = tcg_temp_local_new();
2d2826b9
AJ
2409#else
2410 t0 = tcg_temp_new();
2411 t1 = tcg_temp_new();
2412#endif
2413 gen_base_offset_addr(ctx, t0, base, offset);
d66c7132
AJ
2414 gen_load_gpr(t1, rt);
2415 switch (opc) {
2416#if defined(TARGET_MIPS64)
2417 case OPC_SCD:
bf7910c6 2418 case R6_OPC_SCD:
dd4096cd 2419 op_st_scd(t1, t0, rt, mem_idx, ctx);
d66c7132
AJ
2420 break;
2421#endif
76964147
JH
2422 case OPC_SCE:
2423 mem_idx = MIPS_HFLAG_UM;
2424 /* fall through */
6af0bf9c 2425 case OPC_SC:
4368b29a 2426 case R6_OPC_SC:
dd4096cd 2427 op_st_sc(t1, t0, rt, mem_idx, ctx);
6af0bf9c 2428 break;
6af0bf9c 2429 }
78723684 2430 tcg_temp_free(t1);
d66c7132 2431 tcg_temp_free(t0);
6af0bf9c
FB
2432}
2433
6ea83fed 2434/* Load and store */
7a387fff 2435static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
b52d3bfa 2436 TCGv t0)
6ea83fed 2437{
6ea83fed 2438 /* Don't do NOP if destination is zero: we must perform the actual
ead9360e 2439 memory access. */
6ea83fed
FB
2440 switch (opc) {
2441 case OPC_LWC1:
b6d96bed 2442 {
a7812ae4 2443 TCGv_i32 fp0 = tcg_temp_new_i32();
be3a8c53
YK
2444 tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, MO_TESL |
2445 ctx->default_tcg_memop_mask);
7c979afd 2446 gen_store_fpr32(ctx, fp0, ft);
a7812ae4 2447 tcg_temp_free_i32(fp0);
b6d96bed 2448 }
6ea83fed
FB
2449 break;
2450 case OPC_SWC1:
b6d96bed 2451 {
a7812ae4 2452 TCGv_i32 fp0 = tcg_temp_new_i32();
7c979afd 2453 gen_load_fpr32(ctx, fp0, ft);
be3a8c53
YK
2454 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL |
2455 ctx->default_tcg_memop_mask);
a7812ae4 2456 tcg_temp_free_i32(fp0);
b6d96bed 2457 }
6ea83fed
FB
2458 break;
2459 case OPC_LDC1:
b6d96bed 2460 {
a7812ae4 2461 TCGv_i64 fp0 = tcg_temp_new_i64();
be3a8c53
YK
2462 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ |
2463 ctx->default_tcg_memop_mask);
b6d96bed 2464 gen_store_fpr64(ctx, fp0, ft);
a7812ae4 2465 tcg_temp_free_i64(fp0);
b6d96bed 2466 }
6ea83fed
FB
2467 break;
2468 case OPC_SDC1:
b6d96bed 2469 {
a7812ae4 2470 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 2471 gen_load_fpr64(ctx, fp0, ft);
be3a8c53
YK
2472 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ |
2473 ctx->default_tcg_memop_mask);
a7812ae4 2474 tcg_temp_free_i64(fp0);
b6d96bed 2475 }
6ea83fed
FB
2476 break;
2477 default:
9d68ac14 2478 MIPS_INVAL("flt_ldst");
9c708c7f 2479 generate_exception_end(ctx, EXCP_RI);
b52d3bfa 2480 break;
6ea83fed 2481 }
6ea83fed 2482}
6ea83fed 2483
5ab5c041
AJ
2484static void gen_cop1_ldst(DisasContext *ctx, uint32_t op, int rt,
2485 int rs, int16_t imm)
26ebe468 2486{
b52d3bfa
YK
2487 TCGv t0 = tcg_temp_new();
2488
5ab5c041 2489 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
26ebe468 2490 check_cp1_enabled(ctx);
d9224450
MR
2491 switch (op) {
2492 case OPC_LDC1:
2493 case OPC_SDC1:
2494 check_insn(ctx, ISA_MIPS2);
2495 /* Fallthrough */
2496 default:
b52d3bfa
YK
2497 gen_base_offset_addr(ctx, t0, rs, imm);
2498 gen_flt_ldst(ctx, op, rt, t0);
d9224450 2499 }
26ebe468
NF
2500 } else {
2501 generate_exception_err(ctx, EXCP_CpU, 1);
2502 }
b52d3bfa 2503 tcg_temp_free(t0);
26ebe468
NF
2504}
2505
6af0bf9c 2506/* Arithmetic with immediate operand */
d75c135e 2507static void gen_arith_imm(DisasContext *ctx, uint32_t opc,
72e1f16f 2508 int rt, int rs, int imm)
6af0bf9c 2509{
324d9e32 2510 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
6af0bf9c 2511
7a387fff 2512 if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
ead9360e
TS
2513 /* If no destination, treat it as a NOP.
2514 For addi, we must generate the overflow exception when needed. */
324d9e32 2515 return;
6af0bf9c
FB
2516 }
2517 switch (opc) {
2518 case OPC_ADDI:
48d38ca5 2519 {
324d9e32
AJ
2520 TCGv t0 = tcg_temp_local_new();
2521 TCGv t1 = tcg_temp_new();
2522 TCGv t2 = tcg_temp_new();
42a268c2 2523 TCGLabel *l1 = gen_new_label();
48d38ca5 2524
324d9e32
AJ
2525 gen_load_gpr(t1, rs);
2526 tcg_gen_addi_tl(t0, t1, uimm);
2527 tcg_gen_ext32s_tl(t0, t0);
48d38ca5 2528
324d9e32
AJ
2529 tcg_gen_xori_tl(t1, t1, ~uimm);
2530 tcg_gen_xori_tl(t2, t0, uimm);
2531 tcg_gen_and_tl(t1, t1, t2);
2532 tcg_temp_free(t2);
2533 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2534 tcg_temp_free(t1);
48d38ca5
TS
2535 /* operands of same sign, result different sign */
2536 generate_exception(ctx, EXCP_OVERFLOW);
2537 gen_set_label(l1);
78723684 2538 tcg_gen_ext32s_tl(t0, t0);
324d9e32
AJ
2539 gen_store_gpr(t0, rt);
2540 tcg_temp_free(t0);
48d38ca5 2541 }
6af0bf9c
FB
2542 break;
2543 case OPC_ADDIU:
324d9e32
AJ
2544 if (rs != 0) {
2545 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2546 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
2547 } else {
2548 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2549 }
6af0bf9c 2550 break;
d26bc211 2551#if defined(TARGET_MIPS64)
7a387fff 2552 case OPC_DADDI:
48d38ca5 2553 {
324d9e32
AJ
2554 TCGv t0 = tcg_temp_local_new();
2555 TCGv t1 = tcg_temp_new();
2556 TCGv t2 = tcg_temp_new();
42a268c2 2557 TCGLabel *l1 = gen_new_label();
48d38ca5 2558
324d9e32
AJ
2559 gen_load_gpr(t1, rs);
2560 tcg_gen_addi_tl(t0, t1, uimm);
48d38ca5 2561
324d9e32
AJ
2562 tcg_gen_xori_tl(t1, t1, ~uimm);
2563 tcg_gen_xori_tl(t2, t0, uimm);
2564 tcg_gen_and_tl(t1, t1, t2);
2565 tcg_temp_free(t2);
2566 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2567 tcg_temp_free(t1);
48d38ca5
TS
2568 /* operands of same sign, result different sign */
2569 generate_exception(ctx, EXCP_OVERFLOW);
2570 gen_set_label(l1);
324d9e32
AJ
2571 gen_store_gpr(t0, rt);
2572 tcg_temp_free(t0);
48d38ca5 2573 }
7a387fff
TS
2574 break;
2575 case OPC_DADDIU:
324d9e32
AJ
2576 if (rs != 0) {
2577 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2578 } else {
2579 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2580 }
7a387fff
TS
2581 break;
2582#endif
324d9e32 2583 }
324d9e32
AJ
2584}
2585
2586/* Logic with immediate operand */
d75c135e 2587static void gen_logic_imm(DisasContext *ctx, uint32_t opc,
9fa77488 2588 int rt, int rs, int16_t imm)
324d9e32
AJ
2589{
2590 target_ulong uimm;
324d9e32
AJ
2591
2592 if (rt == 0) {
2593 /* If no destination, treat it as a NOP. */
324d9e32
AJ
2594 return;
2595 }
2596 uimm = (uint16_t)imm;
2597 switch (opc) {
6af0bf9c 2598 case OPC_ANDI:
324d9e32
AJ
2599 if (likely(rs != 0))
2600 tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2601 else
2602 tcg_gen_movi_tl(cpu_gpr[rt], 0);
6af0bf9c
FB
2603 break;
2604 case OPC_ORI:
324d9e32
AJ
2605 if (rs != 0)
2606 tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2607 else
2608 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
6af0bf9c
FB
2609 break;
2610 case OPC_XORI:
324d9e32
AJ
2611 if (likely(rs != 0))
2612 tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2613 else
2614 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
6af0bf9c
FB
2615 break;
2616 case OPC_LUI:
d4ea6acd
LA
2617 if (rs != 0 && (ctx->insn_flags & ISA_MIPS32R6)) {
2618 /* OPC_AUI */
2619 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm << 16);
2620 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
d4ea6acd
LA
2621 } else {
2622 tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
d4ea6acd 2623 }
7c2c3ea3
EJ
2624 break;
2625
2626 default:
6af0bf9c 2627 break;
324d9e32 2628 }
324d9e32
AJ
2629}
2630
2631/* Set on less than with immediate operand */
d75c135e 2632static void gen_slt_imm(DisasContext *ctx, uint32_t opc,
9fa77488 2633 int rt, int rs, int16_t imm)
324d9e32
AJ
2634{
2635 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
324d9e32
AJ
2636 TCGv t0;
2637
2638 if (rt == 0) {
2639 /* If no destination, treat it as a NOP. */
324d9e32
AJ
2640 return;
2641 }
2642 t0 = tcg_temp_new();
2643 gen_load_gpr(t0, rs);
2644 switch (opc) {
2645 case OPC_SLTI:
e68dd28f 2646 tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
324d9e32
AJ
2647 break;
2648 case OPC_SLTIU:
e68dd28f 2649 tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
324d9e32
AJ
2650 break;
2651 }
324d9e32
AJ
2652 tcg_temp_free(t0);
2653}
2654
2655/* Shifts with immediate operand */
d75c135e 2656static void gen_shift_imm(DisasContext *ctx, uint32_t opc,
324d9e32
AJ
2657 int rt, int rs, int16_t imm)
2658{
2659 target_ulong uimm = ((uint16_t)imm) & 0x1f;
324d9e32
AJ
2660 TCGv t0;
2661
2662 if (rt == 0) {
2663 /* If no destination, treat it as a NOP. */
324d9e32
AJ
2664 return;
2665 }
2666
2667 t0 = tcg_temp_new();
2668 gen_load_gpr(t0, rs);
2669 switch (opc) {
6af0bf9c 2670 case OPC_SLL:
78723684 2671 tcg_gen_shli_tl(t0, t0, uimm);
324d9e32 2672 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
6af0bf9c
FB
2673 break;
2674 case OPC_SRA:
324d9e32 2675 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
6af0bf9c
FB
2676 break;
2677 case OPC_SRL:
ea63e2c3
NF
2678 if (uimm != 0) {
2679 tcg_gen_ext32u_tl(t0, t0);
2680 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2681 } else {
2682 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
5a63bcb2 2683 }
ea63e2c3
NF
2684 break;
2685 case OPC_ROTR:
2686 if (uimm != 0) {
2687 TCGv_i32 t1 = tcg_temp_new_i32();
2688
2689 tcg_gen_trunc_tl_i32(t1, t0);
2690 tcg_gen_rotri_i32(t1, t1, uimm);
2691 tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
2692 tcg_temp_free_i32(t1);
3399e30f
NF
2693 } else {
2694 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
ea63e2c3 2695 }
7a387fff 2696 break;
d26bc211 2697#if defined(TARGET_MIPS64)
7a387fff 2698 case OPC_DSLL:
324d9e32 2699 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
7a387fff
TS
2700 break;
2701 case OPC_DSRA:
324d9e32 2702 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
7a387fff
TS
2703 break;
2704 case OPC_DSRL:
ea63e2c3 2705 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
ea63e2c3
NF
2706 break;
2707 case OPC_DROTR:
2708 if (uimm != 0) {
2709 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
3399e30f
NF
2710 } else {
2711 tcg_gen_mov_tl(cpu_gpr[rt], t0);
5a63bcb2 2712 }
7a387fff
TS
2713 break;
2714 case OPC_DSLL32:
324d9e32 2715 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
7a387fff
TS
2716 break;
2717 case OPC_DSRA32:
324d9e32 2718 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
7a387fff
TS
2719 break;
2720 case OPC_DSRL32:
ea63e2c3 2721 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
ea63e2c3
NF
2722 break;
2723 case OPC_DROTR32:
2724 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
6af0bf9c 2725 break;
7a387fff 2726#endif
6af0bf9c 2727 }
78723684 2728 tcg_temp_free(t0);
6af0bf9c
FB
2729}
2730
2731/* Arithmetic */
d75c135e
AJ
2732static void gen_arith(DisasContext *ctx, uint32_t opc,
2733 int rd, int rs, int rt)
6af0bf9c 2734{
7a387fff
TS
2735 if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
2736 && opc != OPC_DADD && opc != OPC_DSUB) {
ead9360e
TS
2737 /* If no destination, treat it as a NOP.
2738 For add & sub, we must generate the overflow exception when needed. */
460f00c4 2739 return;
185f0762 2740 }
460f00c4 2741
6af0bf9c
FB
2742 switch (opc) {
2743 case OPC_ADD:
48d38ca5 2744 {
460f00c4
AJ
2745 TCGv t0 = tcg_temp_local_new();
2746 TCGv t1 = tcg_temp_new();
2747 TCGv t2 = tcg_temp_new();
42a268c2 2748 TCGLabel *l1 = gen_new_label();
48d38ca5 2749
460f00c4
AJ
2750 gen_load_gpr(t1, rs);
2751 gen_load_gpr(t2, rt);
2752 tcg_gen_add_tl(t0, t1, t2);
2753 tcg_gen_ext32s_tl(t0, t0);
2754 tcg_gen_xor_tl(t1, t1, t2);
460f00c4 2755 tcg_gen_xor_tl(t2, t0, t2);
deb4203d 2756 tcg_gen_andc_tl(t1, t2, t1);
460f00c4
AJ
2757 tcg_temp_free(t2);
2758 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2759 tcg_temp_free(t1);
48d38ca5
TS
2760 /* operands of same sign, result different sign */
2761 generate_exception(ctx, EXCP_OVERFLOW);
2762 gen_set_label(l1);
460f00c4
AJ
2763 gen_store_gpr(t0, rd);
2764 tcg_temp_free(t0);
48d38ca5 2765 }
6af0bf9c
FB
2766 break;
2767 case OPC_ADDU:
460f00c4
AJ
2768 if (rs != 0 && rt != 0) {
2769 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2770 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2771 } else if (rs == 0 && rt != 0) {
2772 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2773 } else if (rs != 0 && rt == 0) {
2774 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2775 } else {
2776 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2777 }
6af0bf9c
FB
2778 break;
2779 case OPC_SUB:
48d38ca5 2780 {
460f00c4
AJ
2781 TCGv t0 = tcg_temp_local_new();
2782 TCGv t1 = tcg_temp_new();
2783 TCGv t2 = tcg_temp_new();
42a268c2 2784 TCGLabel *l1 = gen_new_label();
48d38ca5 2785
460f00c4
AJ
2786 gen_load_gpr(t1, rs);
2787 gen_load_gpr(t2, rt);
2788 tcg_gen_sub_tl(t0, t1, t2);
2789 tcg_gen_ext32s_tl(t0, t0);
2790 tcg_gen_xor_tl(t2, t1, t2);
2791 tcg_gen_xor_tl(t1, t0, t1);
2792 tcg_gen_and_tl(t1, t1, t2);
2793 tcg_temp_free(t2);
2794 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2795 tcg_temp_free(t1);
31e3104f 2796 /* operands of different sign, first operand and result different sign */
48d38ca5
TS
2797 generate_exception(ctx, EXCP_OVERFLOW);
2798 gen_set_label(l1);
460f00c4
AJ
2799 gen_store_gpr(t0, rd);
2800 tcg_temp_free(t0);
48d38ca5 2801 }
6af0bf9c
FB
2802 break;
2803 case OPC_SUBU:
460f00c4
AJ
2804 if (rs != 0 && rt != 0) {
2805 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2806 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2807 } else if (rs == 0 && rt != 0) {
2808 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
6bb72b18 2809 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
460f00c4
AJ
2810 } else if (rs != 0 && rt == 0) {
2811 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2812 } else {
2813 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2814 }
6af0bf9c 2815 break;
d26bc211 2816#if defined(TARGET_MIPS64)
7a387fff 2817 case OPC_DADD:
48d38ca5 2818 {
460f00c4
AJ
2819 TCGv t0 = tcg_temp_local_new();
2820 TCGv t1 = tcg_temp_new();
2821 TCGv t2 = tcg_temp_new();
42a268c2 2822 TCGLabel *l1 = gen_new_label();
48d38ca5 2823
460f00c4
AJ
2824 gen_load_gpr(t1, rs);
2825 gen_load_gpr(t2, rt);
2826 tcg_gen_add_tl(t0, t1, t2);
2827 tcg_gen_xor_tl(t1, t1, t2);
460f00c4 2828 tcg_gen_xor_tl(t2, t0, t2);
deb4203d 2829 tcg_gen_andc_tl(t1, t2, t1);
460f00c4
AJ
2830 tcg_temp_free(t2);
2831 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2832 tcg_temp_free(t1);
48d38ca5
TS
2833 /* operands of same sign, result different sign */
2834 generate_exception(ctx, EXCP_OVERFLOW);
2835 gen_set_label(l1);
460f00c4
AJ
2836 gen_store_gpr(t0, rd);
2837 tcg_temp_free(t0);
48d38ca5 2838 }
7a387fff
TS
2839 break;
2840 case OPC_DADDU:
460f00c4
AJ
2841 if (rs != 0 && rt != 0) {
2842 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2843 } else if (rs == 0 && rt != 0) {
2844 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2845 } else if (rs != 0 && rt == 0) {
2846 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2847 } else {
2848 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2849 }
7a387fff
TS
2850 break;
2851 case OPC_DSUB:
48d38ca5 2852 {
460f00c4
AJ
2853 TCGv t0 = tcg_temp_local_new();
2854 TCGv t1 = tcg_temp_new();
2855 TCGv t2 = tcg_temp_new();
42a268c2 2856 TCGLabel *l1 = gen_new_label();
48d38ca5 2857
460f00c4
AJ
2858 gen_load_gpr(t1, rs);
2859 gen_load_gpr(t2, rt);
2860 tcg_gen_sub_tl(t0, t1, t2);
2861 tcg_gen_xor_tl(t2, t1, t2);
2862 tcg_gen_xor_tl(t1, t0, t1);
2863 tcg_gen_and_tl(t1, t1, t2);
2864 tcg_temp_free(t2);
2865 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2866 tcg_temp_free(t1);
31e3104f 2867 /* operands of different sign, first operand and result different sign */
48d38ca5
TS
2868 generate_exception(ctx, EXCP_OVERFLOW);
2869 gen_set_label(l1);
460f00c4
AJ
2870 gen_store_gpr(t0, rd);
2871 tcg_temp_free(t0);
48d38ca5 2872 }
7a387fff
TS
2873 break;
2874 case OPC_DSUBU:
460f00c4
AJ
2875 if (rs != 0 && rt != 0) {
2876 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2877 } else if (rs == 0 && rt != 0) {
2878 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2879 } else if (rs != 0 && rt == 0) {
2880 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2881 } else {
2882 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2883 }
7a387fff
TS
2884 break;
2885#endif
460f00c4
AJ
2886 case OPC_MUL:
2887 if (likely(rs != 0 && rt != 0)) {
2888 tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2889 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2890 } else {
2891 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2892 }
6af0bf9c 2893 break;
460f00c4 2894 }
460f00c4
AJ
2895}
2896
2897/* Conditional move */
d75c135e 2898static void gen_cond_move(DisasContext *ctx, uint32_t opc,
9fa77488 2899 int rd, int rs, int rt)
460f00c4 2900{
acf12465 2901 TCGv t0, t1, t2;
460f00c4
AJ
2902
2903 if (rd == 0) {
acf12465 2904 /* If no destination, treat it as a NOP. */
460f00c4
AJ
2905 return;
2906 }
2907
acf12465
AJ
2908 t0 = tcg_temp_new();
2909 gen_load_gpr(t0, rt);
2910 t1 = tcg_const_tl(0);
2911 t2 = tcg_temp_new();
2912 gen_load_gpr(t2, rs);
460f00c4
AJ
2913 switch (opc) {
2914 case OPC_MOVN:
acf12465 2915 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
6af0bf9c 2916 break;
460f00c4 2917 case OPC_MOVZ:
acf12465 2918 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
460f00c4 2919 break;
b691d9d2
LA
2920 case OPC_SELNEZ:
2921 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, t1);
b691d9d2
LA
2922 break;
2923 case OPC_SELEQZ:
2924 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, t1);
b691d9d2 2925 break;
460f00c4 2926 }
acf12465
AJ
2927 tcg_temp_free(t2);
2928 tcg_temp_free(t1);
2929 tcg_temp_free(t0);
460f00c4
AJ
2930}
2931
2932/* Logic */
d75c135e 2933static void gen_logic(DisasContext *ctx, uint32_t opc,
9fa77488 2934 int rd, int rs, int rt)
460f00c4 2935{
460f00c4
AJ
2936 if (rd == 0) {
2937 /* If no destination, treat it as a NOP. */
460f00c4
AJ
2938 return;
2939 }
2940
2941 switch (opc) {
6af0bf9c 2942 case OPC_AND:
460f00c4
AJ
2943 if (likely(rs != 0 && rt != 0)) {
2944 tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2945 } else {
2946 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2947 }
6af0bf9c
FB
2948 break;
2949 case OPC_NOR:
460f00c4
AJ
2950 if (rs != 0 && rt != 0) {
2951 tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2952 } else if (rs == 0 && rt != 0) {
2953 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
2954 } else if (rs != 0 && rt == 0) {
2955 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
2956 } else {
2957 tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
2958 }
6af0bf9c
FB
2959 break;
2960 case OPC_OR:
460f00c4
AJ
2961 if (likely(rs != 0 && rt != 0)) {
2962 tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2963 } else if (rs == 0 && rt != 0) {
2964 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2965 } else if (rs != 0 && rt == 0) {
2966 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2967 } else {
2968 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2969 }
6af0bf9c
FB
2970 break;
2971 case OPC_XOR:
460f00c4
AJ
2972 if (likely(rs != 0 && rt != 0)) {
2973 tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2974 } else if (rs == 0 && rt != 0) {
2975 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2976 } else if (rs != 0 && rt == 0) {
2977 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2978 } else {
2979 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2980 }
6af0bf9c 2981 break;
460f00c4 2982 }
460f00c4
AJ
2983}
2984
2985/* Set on lower than */
d75c135e 2986static void gen_slt(DisasContext *ctx, uint32_t opc,
9fa77488 2987 int rd, int rs, int rt)
460f00c4 2988{
460f00c4
AJ
2989 TCGv t0, t1;
2990
2991 if (rd == 0) {
2992 /* If no destination, treat it as a NOP. */
460f00c4
AJ
2993 return;
2994 }
2995
2996 t0 = tcg_temp_new();
2997 t1 = tcg_temp_new();
2998 gen_load_gpr(t0, rs);
2999 gen_load_gpr(t1, rt);
3000 switch (opc) {
3001 case OPC_SLT:
e68dd28f 3002 tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
6af0bf9c 3003 break;
460f00c4 3004 case OPC_SLTU:
e68dd28f 3005 tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
460f00c4
AJ
3006 break;
3007 }
460f00c4
AJ
3008 tcg_temp_free(t0);
3009 tcg_temp_free(t1);
3010}
20c4c97c 3011
460f00c4 3012/* Shifts */
d75c135e
AJ
3013static void gen_shift(DisasContext *ctx, uint32_t opc,
3014 int rd, int rs, int rt)
460f00c4 3015{
460f00c4 3016 TCGv t0, t1;
20c4c97c 3017
460f00c4
AJ
3018 if (rd == 0) {
3019 /* If no destination, treat it as a NOP.
3020 For add & sub, we must generate the overflow exception when needed. */
460f00c4
AJ
3021 return;
3022 }
3023
3024 t0 = tcg_temp_new();
3025 t1 = tcg_temp_new();
3026 gen_load_gpr(t0, rs);
3027 gen_load_gpr(t1, rt);
3028 switch (opc) {
6af0bf9c 3029 case OPC_SLLV:
78723684
TS
3030 tcg_gen_andi_tl(t0, t0, 0x1f);
3031 tcg_gen_shl_tl(t0, t1, t0);
460f00c4 3032 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
6af0bf9c
FB
3033 break;
3034 case OPC_SRAV:
78723684 3035 tcg_gen_andi_tl(t0, t0, 0x1f);
460f00c4 3036 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
6af0bf9c
FB
3037 break;
3038 case OPC_SRLV:
ea63e2c3
NF
3039 tcg_gen_ext32u_tl(t1, t1);
3040 tcg_gen_andi_tl(t0, t0, 0x1f);
3041 tcg_gen_shr_tl(t0, t1, t0);
3042 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
ea63e2c3
NF
3043 break;
3044 case OPC_ROTRV:
3045 {
3046 TCGv_i32 t2 = tcg_temp_new_i32();
3047 TCGv_i32 t3 = tcg_temp_new_i32();
3048
3049 tcg_gen_trunc_tl_i32(t2, t0);
3050 tcg_gen_trunc_tl_i32(t3, t1);
3051 tcg_gen_andi_i32(t2, t2, 0x1f);
3052 tcg_gen_rotr_i32(t2, t3, t2);
3053 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3054 tcg_temp_free_i32(t2);
3055 tcg_temp_free_i32(t3);
5a63bcb2 3056 }
7a387fff 3057 break;
d26bc211 3058#if defined(TARGET_MIPS64)
7a387fff 3059 case OPC_DSLLV:
78723684 3060 tcg_gen_andi_tl(t0, t0, 0x3f);
460f00c4 3061 tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
7a387fff
TS
3062 break;
3063 case OPC_DSRAV:
78723684 3064 tcg_gen_andi_tl(t0, t0, 0x3f);
460f00c4 3065 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
7a387fff
TS
3066 break;
3067 case OPC_DSRLV:
ea63e2c3
NF
3068 tcg_gen_andi_tl(t0, t0, 0x3f);
3069 tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
ea63e2c3
NF
3070 break;
3071 case OPC_DROTRV:
3072 tcg_gen_andi_tl(t0, t0, 0x3f);
3073 tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
6af0bf9c 3074 break;
7a387fff 3075#endif
6af0bf9c 3076 }
78723684
TS
3077 tcg_temp_free(t0);
3078 tcg_temp_free(t1);
6af0bf9c
FB
3079}
3080
3081/* Arithmetic on HI/LO registers */
26135ead 3082static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg)
6af0bf9c 3083{
6af0bf9c 3084 if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
ead9360e 3085 /* Treat as NOP. */
a1f6684d 3086 return;
6af0bf9c 3087 }
4133498f 3088
4133498f
JL
3089 if (acc != 0) {
3090 check_dsp(ctx);
3091 }
3092
6af0bf9c
FB
3093 switch (opc) {
3094 case OPC_MFHI:
4133498f
JL
3095#if defined(TARGET_MIPS64)
3096 if (acc != 0) {
3097 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]);
3098 } else
3099#endif
3100 {
3101 tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]);
3102 }
6af0bf9c
FB
3103 break;
3104 case OPC_MFLO:
4133498f
JL
3105#if defined(TARGET_MIPS64)
3106 if (acc != 0) {
3107 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]);
3108 } else
3109#endif
3110 {
3111 tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]);
3112 }
6af0bf9c
FB
3113 break;
3114 case OPC_MTHI:
4133498f
JL
3115 if (reg != 0) {
3116#if defined(TARGET_MIPS64)
3117 if (acc != 0) {
3118 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_gpr[reg]);
3119 } else
3120#endif
3121 {
3122 tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]);
3123 }
3124 } else {
3125 tcg_gen_movi_tl(cpu_HI[acc], 0);
3126 }
6af0bf9c
FB
3127 break;
3128 case OPC_MTLO:
4133498f
JL
3129 if (reg != 0) {
3130#if defined(TARGET_MIPS64)
3131 if (acc != 0) {
3132 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_gpr[reg]);
3133 } else
3134#endif
3135 {
3136 tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]);
3137 }
3138 } else {
3139 tcg_gen_movi_tl(cpu_LO[acc], 0);
3140 }
6af0bf9c 3141 break;
6af0bf9c 3142 }
6af0bf9c
FB
3143}
3144
d4ea6acd
LA
3145static inline void gen_r6_ld(target_long addr, int reg, int memidx,
3146 TCGMemOp memop)
3147{
3148 TCGv t0 = tcg_const_tl(addr);
3149 tcg_gen_qemu_ld_tl(t0, t0, memidx, memop);
3150 gen_store_gpr(t0, reg);
3151 tcg_temp_free(t0);
3152}
3153
ab39ee45
YK
3154static inline void gen_pcrel(DisasContext *ctx, int opc, target_ulong pc,
3155 int rs)
d4ea6acd
LA
3156{
3157 target_long offset;
3158 target_long addr;
3159
ab39ee45 3160 switch (MASK_OPC_PCREL_TOP2BITS(opc)) {
d4ea6acd
LA
3161 case OPC_ADDIUPC:
3162 if (rs != 0) {
3163 offset = sextract32(ctx->opcode << 2, 0, 21);
ab39ee45 3164 addr = addr_add(ctx, pc, offset);
d4ea6acd
LA
3165 tcg_gen_movi_tl(cpu_gpr[rs], addr);
3166 }
3167 break;
3168 case R6_OPC_LWPC:
3169 offset = sextract32(ctx->opcode << 2, 0, 21);
ab39ee45 3170 addr = addr_add(ctx, pc, offset);
d4ea6acd
LA
3171 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TESL);
3172 break;
3173#if defined(TARGET_MIPS64)
3174 case OPC_LWUPC:
3175 check_mips_64(ctx);
3176 offset = sextract32(ctx->opcode << 2, 0, 21);
ab39ee45 3177 addr = addr_add(ctx, pc, offset);
d4ea6acd
LA
3178 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEUL);
3179 break;
3180#endif
3181 default:
ab39ee45 3182 switch (MASK_OPC_PCREL_TOP5BITS(opc)) {
d4ea6acd
LA
3183 case OPC_AUIPC:
3184 if (rs != 0) {
ab39ee45
YK
3185 offset = sextract32(ctx->opcode, 0, 16) << 16;
3186 addr = addr_add(ctx, pc, offset);
d4ea6acd
LA
3187 tcg_gen_movi_tl(cpu_gpr[rs], addr);
3188 }
3189 break;
3190 case OPC_ALUIPC:
3191 if (rs != 0) {
ab39ee45
YK
3192 offset = sextract32(ctx->opcode, 0, 16) << 16;
3193 addr = ~0xFFFF & addr_add(ctx, pc, offset);
d4ea6acd
LA
3194 tcg_gen_movi_tl(cpu_gpr[rs], addr);
3195 }
3196 break;
3197#if defined(TARGET_MIPS64)
3198 case R6_OPC_LDPC: /* bits 16 and 17 are part of immediate */
3199 case R6_OPC_LDPC + (1 << 16):
3200 case R6_OPC_LDPC + (2 << 16):
3201 case R6_OPC_LDPC + (3 << 16):
3202 check_mips_64(ctx);
3203 offset = sextract32(ctx->opcode << 3, 0, 21);
ab39ee45 3204 addr = addr_add(ctx, (pc & ~0x7), offset);
d4ea6acd
LA
3205 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEQ);
3206 break;
3207#endif
3208 default:
3209 MIPS_INVAL("OPC_PCREL");
9c708c7f 3210 generate_exception_end(ctx, EXCP_RI);
d4ea6acd
LA
3211 break;
3212 }
3213 break;
3214 }
3215}
3216
b42ee5e1
LA
3217static void gen_r6_muldiv(DisasContext *ctx, int opc, int rd, int rs, int rt)
3218{
b42ee5e1
LA
3219 TCGv t0, t1;
3220
3221 if (rd == 0) {
3222 /* Treat as NOP. */
b42ee5e1
LA
3223 return;
3224 }
3225
3226 t0 = tcg_temp_new();
3227 t1 = tcg_temp_new();
3228
3229 gen_load_gpr(t0, rs);
3230 gen_load_gpr(t1, rt);
3231
3232 switch (opc) {
3233 case R6_OPC_DIV:
3234 {
3235 TCGv t2 = tcg_temp_new();
3236 TCGv t3 = tcg_temp_new();
3237 tcg_gen_ext32s_tl(t0, t0);
3238 tcg_gen_ext32s_tl(t1, t1);
3239 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3240 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3241 tcg_gen_and_tl(t2, t2, t3);
3242 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3243 tcg_gen_or_tl(t2, t2, t3);
3244 tcg_gen_movi_tl(t3, 0);
3245 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3246 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3247 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3248 tcg_temp_free(t3);
3249 tcg_temp_free(t2);
3250 }
b42ee5e1
LA
3251 break;
3252 case R6_OPC_MOD:
3253 {
3254 TCGv t2 = tcg_temp_new();
3255 TCGv t3 = tcg_temp_new();
3256 tcg_gen_ext32s_tl(t0, t0);
3257 tcg_gen_ext32s_tl(t1, t1);
3258 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3259 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3260 tcg_gen_and_tl(t2, t2, t3);
3261 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3262 tcg_gen_or_tl(t2, t2, t3);
3263 tcg_gen_movi_tl(t3, 0);
3264 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3265 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3266 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3267 tcg_temp_free(t3);
3268 tcg_temp_free(t2);
3269 }
b42ee5e1
LA
3270 break;
3271 case R6_OPC_DIVU:
3272 {
3273 TCGv t2 = tcg_const_tl(0);
3274 TCGv t3 = tcg_const_tl(1);
3275 tcg_gen_ext32u_tl(t0, t0);
3276 tcg_gen_ext32u_tl(t1, t1);
3277 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3278 tcg_gen_divu_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_MODU:
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_remu_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_MUL:
3298 {
3299 TCGv_i32 t2 = tcg_temp_new_i32();
3300 TCGv_i32 t3 = tcg_temp_new_i32();
3301 tcg_gen_trunc_tl_i32(t2, t0);
3302 tcg_gen_trunc_tl_i32(t3, t1);
3303 tcg_gen_mul_i32(t2, t2, t3);
3304 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3305 tcg_temp_free_i32(t2);
3306 tcg_temp_free_i32(t3);
3307 }
b42ee5e1
LA
3308 break;
3309 case R6_OPC_MUH:
3310 {
3311 TCGv_i32 t2 = tcg_temp_new_i32();
3312 TCGv_i32 t3 = tcg_temp_new_i32();
3313 tcg_gen_trunc_tl_i32(t2, t0);
3314 tcg_gen_trunc_tl_i32(t3, t1);
3315 tcg_gen_muls2_i32(t2, t3, t2, t3);
3316 tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
3317 tcg_temp_free_i32(t2);
3318 tcg_temp_free_i32(t3);
3319 }
b42ee5e1
LA
3320 break;
3321 case R6_OPC_MULU:
3322 {
3323 TCGv_i32 t2 = tcg_temp_new_i32();
3324 TCGv_i32 t3 = tcg_temp_new_i32();
3325 tcg_gen_trunc_tl_i32(t2, t0);
3326 tcg_gen_trunc_tl_i32(t3, t1);
3327 tcg_gen_mul_i32(t2, t2, t3);
3328 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3329 tcg_temp_free_i32(t2);
3330 tcg_temp_free_i32(t3);
3331 }
b42ee5e1
LA
3332 break;
3333 case R6_OPC_MUHU:
3334 {
3335 TCGv_i32 t2 = tcg_temp_new_i32();
3336 TCGv_i32 t3 = tcg_temp_new_i32();
3337 tcg_gen_trunc_tl_i32(t2, t0);
3338 tcg_gen_trunc_tl_i32(t3, t1);
3339 tcg_gen_mulu2_i32(t2, t3, t2, t3);
3340 tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
3341 tcg_temp_free_i32(t2);
3342 tcg_temp_free_i32(t3);
3343 }
b42ee5e1
LA
3344 break;
3345#if defined(TARGET_MIPS64)
3346 case R6_OPC_DDIV:
3347 {
3348 TCGv t2 = tcg_temp_new();
3349 TCGv t3 = tcg_temp_new();
3350 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3351 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3352 tcg_gen_and_tl(t2, t2, t3);
3353 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3354 tcg_gen_or_tl(t2, t2, t3);
3355 tcg_gen_movi_tl(t3, 0);
3356 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3357 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3358 tcg_temp_free(t3);
3359 tcg_temp_free(t2);
3360 }
b42ee5e1
LA
3361 break;
3362 case R6_OPC_DMOD:
3363 {
3364 TCGv t2 = tcg_temp_new();
3365 TCGv t3 = tcg_temp_new();
3366 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3367 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3368 tcg_gen_and_tl(t2, t2, t3);
3369 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3370 tcg_gen_or_tl(t2, t2, t3);
3371 tcg_gen_movi_tl(t3, 0);
3372 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3373 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3374 tcg_temp_free(t3);
3375 tcg_temp_free(t2);
3376 }
b42ee5e1
LA
3377 break;
3378 case R6_OPC_DDIVU:
3379 {
3380 TCGv t2 = tcg_const_tl(0);
3381 TCGv t3 = tcg_const_tl(1);
3382 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3383 tcg_gen_divu_i64(cpu_gpr[rd], t0, t1);
3384 tcg_temp_free(t3);
3385 tcg_temp_free(t2);
3386 }
b42ee5e1
LA
3387 break;
3388 case R6_OPC_DMODU:
3389 {
3390 TCGv t2 = tcg_const_tl(0);
3391 TCGv t3 = tcg_const_tl(1);
3392 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3393 tcg_gen_remu_i64(cpu_gpr[rd], t0, t1);
3394 tcg_temp_free(t3);
3395 tcg_temp_free(t2);
3396 }
b42ee5e1
LA
3397 break;
3398 case R6_OPC_DMUL:
3399 tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
b42ee5e1
LA
3400 break;
3401 case R6_OPC_DMUH:
3402 {
3403 TCGv t2 = tcg_temp_new();
3404 tcg_gen_muls2_i64(t2, cpu_gpr[rd], t0, t1);
3405 tcg_temp_free(t2);
3406 }
b42ee5e1
LA
3407 break;
3408 case R6_OPC_DMULU:
3409 tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
b42ee5e1
LA
3410 break;
3411 case R6_OPC_DMUHU:
3412 {
3413 TCGv t2 = tcg_temp_new();
3414 tcg_gen_mulu2_i64(t2, cpu_gpr[rd], t0, t1);
3415 tcg_temp_free(t2);
3416 }
b42ee5e1
LA
3417 break;
3418#endif
3419 default:
9d68ac14 3420 MIPS_INVAL("r6 mul/div");
9c708c7f 3421 generate_exception_end(ctx, EXCP_RI);
b42ee5e1
LA
3422 goto out;
3423 }
b42ee5e1
LA
3424 out:
3425 tcg_temp_free(t0);
3426 tcg_temp_free(t1);
3427}
3428
26135ead
RS
3429static void gen_muldiv(DisasContext *ctx, uint32_t opc,
3430 int acc, int rs, int rt)
6af0bf9c 3431{
d45f89f4
AJ
3432 TCGv t0, t1;
3433
51127181
AJ
3434 t0 = tcg_temp_new();
3435 t1 = tcg_temp_new();
6af0bf9c 3436
78723684
TS
3437 gen_load_gpr(t0, rs);
3438 gen_load_gpr(t1, rt);
51127181 3439
26135ead
RS
3440 if (acc != 0) {
3441 check_dsp(ctx);
3442 }
3443
6af0bf9c
FB
3444 switch (opc) {
3445 case OPC_DIV:
48d38ca5 3446 {
51127181
AJ
3447 TCGv t2 = tcg_temp_new();
3448 TCGv t3 = tcg_temp_new();
d45f89f4
AJ
3449 tcg_gen_ext32s_tl(t0, t0);
3450 tcg_gen_ext32s_tl(t1, t1);
51127181
AJ
3451 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3452 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3453 tcg_gen_and_tl(t2, t2, t3);
3454 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3455 tcg_gen_or_tl(t2, t2, t3);
3456 tcg_gen_movi_tl(t3, 0);
3457 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
26135ead
RS
3458 tcg_gen_div_tl(cpu_LO[acc], t0, t1);
3459 tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
3460 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
3461 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
51127181
AJ
3462 tcg_temp_free(t3);
3463 tcg_temp_free(t2);
48d38ca5 3464 }
6af0bf9c
FB
3465 break;
3466 case OPC_DIVU:
48d38ca5 3467 {
51127181
AJ
3468 TCGv t2 = tcg_const_tl(0);
3469 TCGv t3 = tcg_const_tl(1);
0c0ed03b
AJ
3470 tcg_gen_ext32u_tl(t0, t0);
3471 tcg_gen_ext32u_tl(t1, t1);
51127181 3472 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
26135ead
RS
3473 tcg_gen_divu_tl(cpu_LO[acc], t0, t1);
3474 tcg_gen_remu_tl(cpu_HI[acc], t0, t1);
3475 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
3476 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
51127181
AJ
3477 tcg_temp_free(t3);
3478 tcg_temp_free(t2);
48d38ca5 3479 }
6af0bf9c
FB
3480 break;
3481 case OPC_MULT:
214c465f 3482 {
ce1dd5d1
RH
3483 TCGv_i32 t2 = tcg_temp_new_i32();
3484 TCGv_i32 t3 = tcg_temp_new_i32();
ce1dd5d1
RH
3485 tcg_gen_trunc_tl_i32(t2, t0);
3486 tcg_gen_trunc_tl_i32(t3, t1);
3487 tcg_gen_muls2_i32(t2, t3, t2, t3);
3488 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
3489 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
3490 tcg_temp_free_i32(t2);
3491 tcg_temp_free_i32(t3);
214c465f 3492 }
6af0bf9c
FB
3493 break;
3494 case OPC_MULTU:
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_mulu2_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 3506 break;
d26bc211 3507#if defined(TARGET_MIPS64)
7a387fff 3508 case OPC_DDIV:
48d38ca5 3509 {
51127181
AJ
3510 TCGv t2 = tcg_temp_new();
3511 TCGv t3 = tcg_temp_new();
3512 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3513 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3514 tcg_gen_and_tl(t2, t2, t3);
3515 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3516 tcg_gen_or_tl(t2, t2, t3);
3517 tcg_gen_movi_tl(t3, 0);
3518 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
26135ead
RS
3519 tcg_gen_div_tl(cpu_LO[acc], t0, t1);
3520 tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
51127181
AJ
3521 tcg_temp_free(t3);
3522 tcg_temp_free(t2);
48d38ca5 3523 }
7a387fff
TS
3524 break;
3525 case OPC_DDIVU:
48d38ca5 3526 {
51127181
AJ
3527 TCGv t2 = tcg_const_tl(0);
3528 TCGv t3 = tcg_const_tl(1);
3529 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
26135ead
RS
3530 tcg_gen_divu_i64(cpu_LO[acc], t0, t1);
3531 tcg_gen_remu_i64(cpu_HI[acc], t0, t1);
51127181
AJ
3532 tcg_temp_free(t3);
3533 tcg_temp_free(t2);
48d38ca5 3534 }
7a387fff
TS
3535 break;
3536 case OPC_DMULT:
26135ead 3537 tcg_gen_muls2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
7a387fff
TS
3538 break;
3539 case OPC_DMULTU:
26135ead 3540 tcg_gen_mulu2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
7a387fff
TS
3541 break;
3542#endif
6af0bf9c 3543 case OPC_MADD:
214c465f 3544 {
d45f89f4
AJ
3545 TCGv_i64 t2 = tcg_temp_new_i64();
3546 TCGv_i64 t3 = tcg_temp_new_i64();
3547
3548 tcg_gen_ext_tl_i64(t2, t0);
3549 tcg_gen_ext_tl_i64(t3, t1);
3550 tcg_gen_mul_i64(t2, t2, t3);
4133498f 3551 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
d45f89f4
AJ
3552 tcg_gen_add_i64(t2, t2, t3);
3553 tcg_temp_free_i64(t3);
71f303cd
RH
3554 gen_move_low32(cpu_LO[acc], t2);
3555 gen_move_high32(cpu_HI[acc], t2);
d45f89f4 3556 tcg_temp_free_i64(t2);
214c465f 3557 }
6af0bf9c
FB
3558 break;
3559 case OPC_MADDU:
4133498f 3560 {
d45f89f4
AJ
3561 TCGv_i64 t2 = tcg_temp_new_i64();
3562 TCGv_i64 t3 = tcg_temp_new_i64();
214c465f 3563
78723684
TS
3564 tcg_gen_ext32u_tl(t0, t0);
3565 tcg_gen_ext32u_tl(t1, t1);
d45f89f4
AJ
3566 tcg_gen_extu_tl_i64(t2, t0);
3567 tcg_gen_extu_tl_i64(t3, t1);
3568 tcg_gen_mul_i64(t2, t2, t3);
4133498f 3569 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
d45f89f4
AJ
3570 tcg_gen_add_i64(t2, t2, t3);
3571 tcg_temp_free_i64(t3);
71f303cd
RH
3572 gen_move_low32(cpu_LO[acc], t2);
3573 gen_move_high32(cpu_HI[acc], t2);
d45f89f4 3574 tcg_temp_free_i64(t2);
214c465f 3575 }
6af0bf9c
FB
3576 break;
3577 case OPC_MSUB:
214c465f 3578 {
d45f89f4
AJ
3579 TCGv_i64 t2 = tcg_temp_new_i64();
3580 TCGv_i64 t3 = tcg_temp_new_i64();
3581
3582 tcg_gen_ext_tl_i64(t2, t0);
3583 tcg_gen_ext_tl_i64(t3, t1);
3584 tcg_gen_mul_i64(t2, t2, t3);
4133498f 3585 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
98070ce0 3586 tcg_gen_sub_i64(t2, t3, t2);
d45f89f4 3587 tcg_temp_free_i64(t3);
71f303cd
RH
3588 gen_move_low32(cpu_LO[acc], t2);
3589 gen_move_high32(cpu_HI[acc], t2);
d45f89f4 3590 tcg_temp_free_i64(t2);
214c465f 3591 }
6af0bf9c
FB
3592 break;
3593 case OPC_MSUBU:
214c465f 3594 {
d45f89f4
AJ
3595 TCGv_i64 t2 = tcg_temp_new_i64();
3596 TCGv_i64 t3 = tcg_temp_new_i64();
214c465f 3597
78723684
TS
3598 tcg_gen_ext32u_tl(t0, t0);
3599 tcg_gen_ext32u_tl(t1, t1);
d45f89f4
AJ
3600 tcg_gen_extu_tl_i64(t2, t0);
3601 tcg_gen_extu_tl_i64(t3, t1);
3602 tcg_gen_mul_i64(t2, t2, t3);
4133498f 3603 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
98070ce0 3604 tcg_gen_sub_i64(t2, t3, t2);
d45f89f4 3605 tcg_temp_free_i64(t3);
71f303cd
RH
3606 gen_move_low32(cpu_LO[acc], t2);
3607 gen_move_high32(cpu_HI[acc], t2);
d45f89f4 3608 tcg_temp_free_i64(t2);
214c465f 3609 }
6af0bf9c
FB
3610 break;
3611 default:
9d68ac14 3612 MIPS_INVAL("mul/div");
9c708c7f 3613 generate_exception_end(ctx, EXCP_RI);
78723684 3614 goto out;
6af0bf9c 3615 }
78723684
TS
3616 out:
3617 tcg_temp_free(t0);
3618 tcg_temp_free(t1);
6af0bf9c
FB
3619}
3620
e9c71dd1
TS
3621static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
3622 int rd, int rs, int rt)
3623{
f157bfe1
AJ
3624 TCGv t0 = tcg_temp_new();
3625 TCGv t1 = tcg_temp_new();
e9c71dd1 3626
6c5c1e20
TS
3627 gen_load_gpr(t0, rs);
3628 gen_load_gpr(t1, rt);
e9c71dd1
TS
3629
3630 switch (opc) {
3631 case OPC_VR54XX_MULS:
895c2d04 3632 gen_helper_muls(t0, cpu_env, t0, t1);
6958549d 3633 break;
e9c71dd1 3634 case OPC_VR54XX_MULSU:
895c2d04 3635 gen_helper_mulsu(t0, cpu_env, t0, t1);
6958549d 3636 break;
e9c71dd1 3637 case OPC_VR54XX_MACC:
895c2d04 3638 gen_helper_macc(t0, cpu_env, t0, t1);
6958549d 3639 break;
e9c71dd1 3640 case OPC_VR54XX_MACCU:
895c2d04 3641 gen_helper_maccu(t0, cpu_env, t0, t1);
6958549d 3642 break;
e9c71dd1 3643 case OPC_VR54XX_MSAC:
895c2d04 3644 gen_helper_msac(t0, cpu_env, t0, t1);
6958549d 3645 break;
e9c71dd1 3646 case OPC_VR54XX_MSACU:
895c2d04 3647 gen_helper_msacu(t0, cpu_env, t0, t1);
6958549d 3648 break;
e9c71dd1 3649 case OPC_VR54XX_MULHI:
895c2d04 3650 gen_helper_mulhi(t0, cpu_env, t0, t1);
6958549d 3651 break;
e9c71dd1 3652 case OPC_VR54XX_MULHIU:
895c2d04 3653 gen_helper_mulhiu(t0, cpu_env, t0, t1);
6958549d 3654 break;
e9c71dd1 3655 case OPC_VR54XX_MULSHI:
895c2d04 3656 gen_helper_mulshi(t0, cpu_env, t0, t1);
6958549d 3657 break;
e9c71dd1 3658 case OPC_VR54XX_MULSHIU:
895c2d04 3659 gen_helper_mulshiu(t0, cpu_env, t0, t1);
6958549d 3660 break;
e9c71dd1 3661 case OPC_VR54XX_MACCHI:
895c2d04 3662 gen_helper_macchi(t0, cpu_env, t0, t1);
6958549d 3663 break;
e9c71dd1 3664 case OPC_VR54XX_MACCHIU:
895c2d04 3665 gen_helper_macchiu(t0, cpu_env, t0, t1);
6958549d 3666 break;
e9c71dd1 3667 case OPC_VR54XX_MSACHI:
895c2d04 3668 gen_helper_msachi(t0, cpu_env, t0, t1);
6958549d 3669 break;
e9c71dd1 3670 case OPC_VR54XX_MSACHIU:
895c2d04 3671 gen_helper_msachiu(t0, cpu_env, t0, t1);
6958549d 3672 break;
e9c71dd1
TS
3673 default:
3674 MIPS_INVAL("mul vr54xx");
9c708c7f 3675 generate_exception_end(ctx, EXCP_RI);
6c5c1e20 3676 goto out;
e9c71dd1 3677 }
6c5c1e20 3678 gen_store_gpr(t0, rd);
6c5c1e20
TS
3679
3680 out:
3681 tcg_temp_free(t0);
3682 tcg_temp_free(t1);
e9c71dd1
TS
3683}
3684
7a387fff 3685static void gen_cl (DisasContext *ctx, uint32_t opc,
6af0bf9c
FB
3686 int rd, int rs)
3687{
20e1fb52 3688 TCGv t0;
6c5c1e20 3689
6af0bf9c 3690 if (rd == 0) {
ead9360e 3691 /* Treat as NOP. */
20e1fb52 3692 return;
6af0bf9c 3693 }
1a0196c5 3694 t0 = cpu_gpr[rd];
6c5c1e20 3695 gen_load_gpr(t0, rs);
1a0196c5 3696
6af0bf9c
FB
3697 switch (opc) {
3698 case OPC_CLO:
4267d3e6 3699 case R6_OPC_CLO:
1a0196c5
RH
3700#if defined(TARGET_MIPS64)
3701 case OPC_DCLO:
3702 case R6_OPC_DCLO:
3703#endif
3704 tcg_gen_not_tl(t0, t0);
6af0bf9c 3705 break;
1a0196c5
RH
3706 }
3707
3708 switch (opc) {
3709 case OPC_CLO:
3710 case R6_OPC_CLO:
6af0bf9c 3711 case OPC_CLZ:
4267d3e6 3712 case R6_OPC_CLZ:
1a0196c5
RH
3713 tcg_gen_ext32u_tl(t0, t0);
3714 tcg_gen_clzi_tl(t0, t0, TARGET_LONG_BITS);
3715 tcg_gen_subi_tl(t0, t0, TARGET_LONG_BITS - 32);
6af0bf9c 3716 break;
d26bc211 3717#if defined(TARGET_MIPS64)
7a387fff 3718 case OPC_DCLO:
4267d3e6 3719 case R6_OPC_DCLO:
7a387fff 3720 case OPC_DCLZ:
4267d3e6 3721 case R6_OPC_DCLZ:
1a0196c5 3722 tcg_gen_clzi_i64(t0, t0, 64);
7a387fff
TS
3723 break;
3724#endif
6af0bf9c 3725 }
6af0bf9c
FB
3726}
3727
161f85e6 3728/* Godson integer instructions */
bd277fa1
RH
3729static void gen_loongson_integer(DisasContext *ctx, uint32_t opc,
3730 int rd, int rs, int rt)
161f85e6 3731{
161f85e6
AJ
3732 TCGv t0, t1;
3733
3734 if (rd == 0) {
3735 /* Treat as NOP. */
161f85e6
AJ
3736 return;
3737 }
3738
3739 switch (opc) {
3740 case OPC_MULT_G_2E:
3741 case OPC_MULT_G_2F:
3742 case OPC_MULTU_G_2E:
3743 case OPC_MULTU_G_2F:
3744#if defined(TARGET_MIPS64)
3745 case OPC_DMULT_G_2E:
3746 case OPC_DMULT_G_2F:
3747 case OPC_DMULTU_G_2E:
3748 case OPC_DMULTU_G_2F:
3749#endif
3750 t0 = tcg_temp_new();
3751 t1 = tcg_temp_new();
3752 break;
3753 default:
3754 t0 = tcg_temp_local_new();
3755 t1 = tcg_temp_local_new();
3756 break;
3757 }
3758
3759 gen_load_gpr(t0, rs);
3760 gen_load_gpr(t1, rt);
3761
3762 switch (opc) {
3763 case OPC_MULT_G_2E:
3764 case OPC_MULT_G_2F:
3765 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3766 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
161f85e6
AJ
3767 break;
3768 case OPC_MULTU_G_2E:
3769 case OPC_MULTU_G_2F:
3770 tcg_gen_ext32u_tl(t0, t0);
3771 tcg_gen_ext32u_tl(t1, t1);
3772 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3773 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
161f85e6
AJ
3774 break;
3775 case OPC_DIV_G_2E:
3776 case OPC_DIV_G_2F:
3777 {
42a268c2
RH
3778 TCGLabel *l1 = gen_new_label();
3779 TCGLabel *l2 = gen_new_label();
3780 TCGLabel *l3 = gen_new_label();
161f85e6
AJ
3781 tcg_gen_ext32s_tl(t0, t0);
3782 tcg_gen_ext32s_tl(t1, t1);
3783 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3784 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3785 tcg_gen_br(l3);
3786 gen_set_label(l1);
3787 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3788 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3789 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3790 tcg_gen_br(l3);
3791 gen_set_label(l2);
3792 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3793 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3794 gen_set_label(l3);
3795 }
161f85e6
AJ
3796 break;
3797 case OPC_DIVU_G_2E:
3798 case OPC_DIVU_G_2F:
3799 {
42a268c2
RH
3800 TCGLabel *l1 = gen_new_label();
3801 TCGLabel *l2 = gen_new_label();
161f85e6
AJ
3802 tcg_gen_ext32u_tl(t0, t0);
3803 tcg_gen_ext32u_tl(t1, t1);
3804 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3805 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3806 tcg_gen_br(l2);
3807 gen_set_label(l1);
3808 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3809 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3810 gen_set_label(l2);
3811 }
161f85e6
AJ
3812 break;
3813 case OPC_MOD_G_2E:
3814 case OPC_MOD_G_2F:
3815 {
42a268c2
RH
3816 TCGLabel *l1 = gen_new_label();
3817 TCGLabel *l2 = gen_new_label();
3818 TCGLabel *l3 = gen_new_label();
161f85e6
AJ
3819 tcg_gen_ext32u_tl(t0, t0);
3820 tcg_gen_ext32u_tl(t1, t1);
3821 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3822 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3823 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3824 gen_set_label(l1);
3825 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3826 tcg_gen_br(l3);
3827 gen_set_label(l2);
3828 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3829 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3830 gen_set_label(l3);
3831 }
161f85e6
AJ
3832 break;
3833 case OPC_MODU_G_2E:
3834 case OPC_MODU_G_2F:
3835 {
42a268c2
RH
3836 TCGLabel *l1 = gen_new_label();
3837 TCGLabel *l2 = gen_new_label();
161f85e6
AJ
3838 tcg_gen_ext32u_tl(t0, t0);
3839 tcg_gen_ext32u_tl(t1, t1);
3840 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3841 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3842 tcg_gen_br(l2);
3843 gen_set_label(l1);
3844 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3845 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3846 gen_set_label(l2);
3847 }
161f85e6
AJ
3848 break;
3849#if defined(TARGET_MIPS64)
3850 case OPC_DMULT_G_2E:
3851 case OPC_DMULT_G_2F:
3852 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
161f85e6
AJ
3853 break;
3854 case OPC_DMULTU_G_2E:
3855 case OPC_DMULTU_G_2F:
3856 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
161f85e6
AJ
3857 break;
3858 case OPC_DDIV_G_2E:
3859 case OPC_DDIV_G_2F:
3860 {
42a268c2
RH
3861 TCGLabel *l1 = gen_new_label();
3862 TCGLabel *l2 = gen_new_label();
3863 TCGLabel *l3 = gen_new_label();
161f85e6
AJ
3864 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3865 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3866 tcg_gen_br(l3);
3867 gen_set_label(l1);
3868 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3869 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3870 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3871 tcg_gen_br(l3);
3872 gen_set_label(l2);
3873 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3874 gen_set_label(l3);
3875 }
161f85e6
AJ
3876 break;
3877 case OPC_DDIVU_G_2E:
3878 case OPC_DDIVU_G_2F:
3879 {
42a268c2
RH
3880 TCGLabel *l1 = gen_new_label();
3881 TCGLabel *l2 = gen_new_label();
161f85e6
AJ
3882 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3883 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3884 tcg_gen_br(l2);
3885 gen_set_label(l1);
3886 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3887 gen_set_label(l2);
3888 }
161f85e6
AJ
3889 break;
3890 case OPC_DMOD_G_2E:
3891 case OPC_DMOD_G_2F:
3892 {
42a268c2
RH
3893 TCGLabel *l1 = gen_new_label();
3894 TCGLabel *l2 = gen_new_label();
3895 TCGLabel *l3 = gen_new_label();
161f85e6
AJ
3896 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3897 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3898 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3899 gen_set_label(l1);
3900 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3901 tcg_gen_br(l3);
3902 gen_set_label(l2);
3903 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3904 gen_set_label(l3);
3905 }
161f85e6
AJ
3906 break;
3907 case OPC_DMODU_G_2E:
3908 case OPC_DMODU_G_2F:
3909 {
42a268c2
RH
3910 TCGLabel *l1 = gen_new_label();
3911 TCGLabel *l2 = gen_new_label();
161f85e6
AJ
3912 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3913 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3914 tcg_gen_br(l2);
3915 gen_set_label(l1);
3916 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3917 gen_set_label(l2);
3918 }
161f85e6
AJ
3919 break;
3920#endif
3921 }
3922
161f85e6
AJ
3923 tcg_temp_free(t0);
3924 tcg_temp_free(t1);
3925}
3926
bd277fa1
RH
3927/* Loongson multimedia instructions */
3928static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt)
3929{
bd277fa1
RH
3930 uint32_t opc, shift_max;
3931 TCGv_i64 t0, t1;
3932
3933 opc = MASK_LMI(ctx->opcode);
3934 switch (opc) {
3935 case OPC_ADD_CP2:
3936 case OPC_SUB_CP2:
3937 case OPC_DADD_CP2:
3938 case OPC_DSUB_CP2:
3939 t0 = tcg_temp_local_new_i64();
3940 t1 = tcg_temp_local_new_i64();
3941 break;
3942 default:
3943 t0 = tcg_temp_new_i64();
3944 t1 = tcg_temp_new_i64();
3945 break;
3946 }
3947
b5a587b6 3948 check_cp1_enabled(ctx);
bd277fa1
RH
3949 gen_load_fpr64(ctx, t0, rs);
3950 gen_load_fpr64(ctx, t1, rt);
3951
3952#define LMI_HELPER(UP, LO) \
9d68ac14 3953 case OPC_##UP: gen_helper_##LO(t0, t0, t1); break
bd277fa1 3954#define LMI_HELPER_1(UP, LO) \
9d68ac14 3955 case OPC_##UP: gen_helper_##LO(t0, t0); break
bd277fa1 3956#define LMI_DIRECT(UP, LO, OP) \
9d68ac14 3957 case OPC_##UP: tcg_gen_##OP##_i64(t0, t0, t1); break
bd277fa1
RH
3958
3959 switch (opc) {
3960 LMI_HELPER(PADDSH, paddsh);
3961 LMI_HELPER(PADDUSH, paddush);
3962 LMI_HELPER(PADDH, paddh);
3963 LMI_HELPER(PADDW, paddw);
3964 LMI_HELPER(PADDSB, paddsb);
3965 LMI_HELPER(PADDUSB, paddusb);
3966 LMI_HELPER(PADDB, paddb);
3967
3968 LMI_HELPER(PSUBSH, psubsh);
3969 LMI_HELPER(PSUBUSH, psubush);
3970 LMI_HELPER(PSUBH, psubh);
3971 LMI_HELPER(PSUBW, psubw);
3972 LMI_HELPER(PSUBSB, psubsb);
3973 LMI_HELPER(PSUBUSB, psubusb);
3974 LMI_HELPER(PSUBB, psubb);
3975
3976 LMI_HELPER(PSHUFH, pshufh);
3977 LMI_HELPER(PACKSSWH, packsswh);
3978 LMI_HELPER(PACKSSHB, packsshb);
3979 LMI_HELPER(PACKUSHB, packushb);
3980
3981 LMI_HELPER(PUNPCKLHW, punpcklhw);
3982 LMI_HELPER(PUNPCKHHW, punpckhhw);
3983 LMI_HELPER(PUNPCKLBH, punpcklbh);
3984 LMI_HELPER(PUNPCKHBH, punpckhbh);
3985 LMI_HELPER(PUNPCKLWD, punpcklwd);
3986 LMI_HELPER(PUNPCKHWD, punpckhwd);
3987
3988 LMI_HELPER(PAVGH, pavgh);
3989 LMI_HELPER(PAVGB, pavgb);
3990 LMI_HELPER(PMAXSH, pmaxsh);
3991 LMI_HELPER(PMINSH, pminsh);
3992 LMI_HELPER(PMAXUB, pmaxub);
3993 LMI_HELPER(PMINUB, pminub);
3994
3995 LMI_HELPER(PCMPEQW, pcmpeqw);
3996 LMI_HELPER(PCMPGTW, pcmpgtw);
3997 LMI_HELPER(PCMPEQH, pcmpeqh);
3998 LMI_HELPER(PCMPGTH, pcmpgth);
3999 LMI_HELPER(PCMPEQB, pcmpeqb);
4000 LMI_HELPER(PCMPGTB, pcmpgtb);
4001
4002 LMI_HELPER(PSLLW, psllw);
4003 LMI_HELPER(PSLLH, psllh);
4004 LMI_HELPER(PSRLW, psrlw);
4005 LMI_HELPER(PSRLH, psrlh);
4006 LMI_HELPER(PSRAW, psraw);
4007 LMI_HELPER(PSRAH, psrah);
4008
4009 LMI_HELPER(PMULLH, pmullh);
4010 LMI_HELPER(PMULHH, pmulhh);
4011 LMI_HELPER(PMULHUH, pmulhuh);
4012 LMI_HELPER(PMADDHW, pmaddhw);
4013
4014 LMI_HELPER(PASUBUB, pasubub);
4015 LMI_HELPER_1(BIADD, biadd);
4016 LMI_HELPER_1(PMOVMSKB, pmovmskb);
4017
4018 LMI_DIRECT(PADDD, paddd, add);
4019 LMI_DIRECT(PSUBD, psubd, sub);
4020 LMI_DIRECT(XOR_CP2, xor, xor);
4021 LMI_DIRECT(NOR_CP2, nor, nor);
4022 LMI_DIRECT(AND_CP2, and, and);
bb7cab5f 4023 LMI_DIRECT(OR_CP2, or, or);
bd277fa1 4024
9099a36b
H
4025 case OPC_PANDN:
4026 tcg_gen_andc_i64(t0, t1, t0);
4027 break;
4028
bd277fa1
RH
4029 case OPC_PINSRH_0:
4030 tcg_gen_deposit_i64(t0, t0, t1, 0, 16);
bd277fa1
RH
4031 break;
4032 case OPC_PINSRH_1:
4033 tcg_gen_deposit_i64(t0, t0, t1, 16, 16);
bd277fa1
RH
4034 break;
4035 case OPC_PINSRH_2:
4036 tcg_gen_deposit_i64(t0, t0, t1, 32, 16);
bd277fa1
RH
4037 break;
4038 case OPC_PINSRH_3:
4039 tcg_gen_deposit_i64(t0, t0, t1, 48, 16);
bd277fa1
RH
4040 break;
4041
4042 case OPC_PEXTRH:
4043 tcg_gen_andi_i64(t1, t1, 3);
4044 tcg_gen_shli_i64(t1, t1, 4);
4045 tcg_gen_shr_i64(t0, t0, t1);
4046 tcg_gen_ext16u_i64(t0, t0);
bd277fa1
RH
4047 break;
4048
4049 case OPC_ADDU_CP2:
4050 tcg_gen_add_i64(t0, t0, t1);
4051 tcg_gen_ext32s_i64(t0, t0);
bd277fa1
RH
4052 break;
4053 case OPC_SUBU_CP2:
4054 tcg_gen_sub_i64(t0, t0, t1);
4055 tcg_gen_ext32s_i64(t0, t0);
bd277fa1
RH
4056 break;
4057
4058 case OPC_SLL_CP2:
bd277fa1
RH
4059 shift_max = 32;
4060 goto do_shift;
4061 case OPC_SRL_CP2:
bd277fa1
RH
4062 shift_max = 32;
4063 goto do_shift;
4064 case OPC_SRA_CP2:
bd277fa1
RH
4065 shift_max = 32;
4066 goto do_shift;
4067 case OPC_DSLL_CP2:
bd277fa1
RH
4068 shift_max = 64;
4069 goto do_shift;
4070 case OPC_DSRL_CP2:
bd277fa1
RH
4071 shift_max = 64;
4072 goto do_shift;
4073 case OPC_DSRA_CP2:
bd277fa1
RH
4074 shift_max = 64;
4075 goto do_shift;
4076 do_shift:
4077 /* Make sure shift count isn't TCG undefined behaviour. */
4078 tcg_gen_andi_i64(t1, t1, shift_max - 1);
4079
4080 switch (opc) {
4081 case OPC_SLL_CP2:
4082 case OPC_DSLL_CP2:
4083 tcg_gen_shl_i64(t0, t0, t1);
4084 break;
4085 case OPC_SRA_CP2:
4086 case OPC_DSRA_CP2:
4087 /* Since SRA is UndefinedResult without sign-extended inputs,
4088 we can treat SRA and DSRA the same. */
4089 tcg_gen_sar_i64(t0, t0, t1);
4090 break;
4091 case OPC_SRL_CP2:
4092 /* We want to shift in zeros for SRL; zero-extend first. */
4093 tcg_gen_ext32u_i64(t0, t0);
4094 /* FALLTHRU */
4095 case OPC_DSRL_CP2:
4096 tcg_gen_shr_i64(t0, t0, t1);
4097 break;
4098 }
4099
4100 if (shift_max == 32) {
4101 tcg_gen_ext32s_i64(t0, t0);
4102 }
4103
4104 /* Shifts larger than MAX produce zero. */
4105 tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max);
4106 tcg_gen_neg_i64(t1, t1);
4107 tcg_gen_and_i64(t0, t0, t1);
4108 break;
4109
4110 case OPC_ADD_CP2:
4111 case OPC_DADD_CP2:
4112 {
4113 TCGv_i64 t2 = tcg_temp_new_i64();
42a268c2 4114 TCGLabel *lab = gen_new_label();
bd277fa1
RH
4115
4116 tcg_gen_mov_i64(t2, t0);
4117 tcg_gen_add_i64(t0, t1, t2);
4118 if (opc == OPC_ADD_CP2) {
4119 tcg_gen_ext32s_i64(t0, t0);
4120 }
4121 tcg_gen_xor_i64(t1, t1, t2);
4122 tcg_gen_xor_i64(t2, t2, t0);
4123 tcg_gen_andc_i64(t1, t2, t1);
4124 tcg_temp_free_i64(t2);
4125 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
4126 generate_exception(ctx, EXCP_OVERFLOW);
4127 gen_set_label(lab);
bd277fa1
RH
4128 break;
4129 }
4130
4131 case OPC_SUB_CP2:
4132 case OPC_DSUB_CP2:
4133 {
4134 TCGv_i64 t2 = tcg_temp_new_i64();
42a268c2 4135 TCGLabel *lab = gen_new_label();
bd277fa1
RH
4136
4137 tcg_gen_mov_i64(t2, t0);
4138 tcg_gen_sub_i64(t0, t1, t2);
4139 if (opc == OPC_SUB_CP2) {
4140 tcg_gen_ext32s_i64(t0, t0);
4141 }
4142 tcg_gen_xor_i64(t1, t1, t2);
4143 tcg_gen_xor_i64(t2, t2, t0);
4144 tcg_gen_and_i64(t1, t1, t2);
4145 tcg_temp_free_i64(t2);
4146 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
4147 generate_exception(ctx, EXCP_OVERFLOW);
4148 gen_set_label(lab);
bd277fa1
RH
4149 break;
4150 }
4151
4152 case OPC_PMULUW:
4153 tcg_gen_ext32u_i64(t0, t0);
4154 tcg_gen_ext32u_i64(t1, t1);
4155 tcg_gen_mul_i64(t0, t0, t1);
bd277fa1
RH
4156 break;
4157
4158 case OPC_SEQU_CP2:
4159 case OPC_SEQ_CP2:
4160 case OPC_SLTU_CP2:
4161 case OPC_SLT_CP2:
4162 case OPC_SLEU_CP2:
4163 case OPC_SLE_CP2:
4164 /* ??? Document is unclear: Set FCC[CC]. Does that mean the
4165 FD field is the CC field? */
4166 default:
9d68ac14 4167 MIPS_INVAL("loongson_cp2");
9c708c7f 4168 generate_exception_end(ctx, EXCP_RI);
bd277fa1
RH
4169 return;
4170 }
4171
4172#undef LMI_HELPER
4173#undef LMI_DIRECT
4174
4175 gen_store_fpr64(ctx, t0, rd);
4176
bd277fa1
RH
4177 tcg_temp_free_i64(t0);
4178 tcg_temp_free_i64(t1);
4179}
4180
6af0bf9c 4181/* Traps */
7a387fff 4182static void gen_trap (DisasContext *ctx, uint32_t opc,
6af0bf9c
FB
4183 int rs, int rt, int16_t imm)
4184{
4185 int cond;
cdc0faa6 4186 TCGv t0 = tcg_temp_new();
1ba74fb8 4187 TCGv t1 = tcg_temp_new();
6af0bf9c
FB
4188
4189 cond = 0;
4190 /* Load needed operands */
4191 switch (opc) {
4192 case OPC_TEQ:
4193 case OPC_TGE:
4194 case OPC_TGEU:
4195 case OPC_TLT:
4196 case OPC_TLTU:
4197 case OPC_TNE:
4198 /* Compare two registers */
4199 if (rs != rt) {
be24bb4f
TS
4200 gen_load_gpr(t0, rs);
4201 gen_load_gpr(t1, rt);
6af0bf9c
FB
4202 cond = 1;
4203 }
179e32bb 4204 break;
6af0bf9c
FB
4205 case OPC_TEQI:
4206 case OPC_TGEI:
4207 case OPC_TGEIU:
4208 case OPC_TLTI:
4209 case OPC_TLTIU:
4210 case OPC_TNEI:
4211 /* Compare register to immediate */
4212 if (rs != 0 || imm != 0) {
be24bb4f
TS
4213 gen_load_gpr(t0, rs);
4214 tcg_gen_movi_tl(t1, (int32_t)imm);
6af0bf9c
FB
4215 cond = 1;
4216 }
4217 break;
4218 }
4219 if (cond == 0) {
4220 switch (opc) {
4221 case OPC_TEQ: /* rs == rs */
4222 case OPC_TEQI: /* r0 == 0 */
4223 case OPC_TGE: /* rs >= rs */
4224 case OPC_TGEI: /* r0 >= 0 */
4225 case OPC_TGEU: /* rs >= rs unsigned */
4226 case OPC_TGEIU: /* r0 >= 0 unsigned */
4227 /* Always trap */
9c708c7f 4228 generate_exception_end(ctx, EXCP_TRAP);
6af0bf9c
FB
4229 break;
4230 case OPC_TLT: /* rs < rs */
4231 case OPC_TLTI: /* r0 < 0 */
4232 case OPC_TLTU: /* rs < rs unsigned */
4233 case OPC_TLTIU: /* r0 < 0 unsigned */
4234 case OPC_TNE: /* rs != rs */
4235 case OPC_TNEI: /* r0 != 0 */
ead9360e 4236 /* Never trap: treat as NOP. */
cdc0faa6 4237 break;
6af0bf9c
FB
4238 }
4239 } else {
42a268c2 4240 TCGLabel *l1 = gen_new_label();
cdc0faa6 4241
6af0bf9c
FB
4242 switch (opc) {
4243 case OPC_TEQ:
4244 case OPC_TEQI:
cdc0faa6 4245 tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
6af0bf9c
FB
4246 break;
4247 case OPC_TGE:
4248 case OPC_TGEI:
cdc0faa6 4249 tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
6af0bf9c
FB
4250 break;
4251 case OPC_TGEU:
4252 case OPC_TGEIU:
cdc0faa6 4253 tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
6af0bf9c
FB
4254 break;
4255 case OPC_TLT:
4256 case OPC_TLTI:
cdc0faa6 4257 tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
6af0bf9c
FB
4258 break;
4259 case OPC_TLTU:
4260 case OPC_TLTIU:
cdc0faa6 4261 tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
6af0bf9c
FB
4262 break;
4263 case OPC_TNE:
4264 case OPC_TNEI:
cdc0faa6 4265 tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
6af0bf9c 4266 break;
6af0bf9c 4267 }
cdc0faa6 4268 generate_exception(ctx, EXCP_TRAP);
08ba7963
TS
4269 gen_set_label(l1);
4270 }
be24bb4f
TS
4271 tcg_temp_free(t0);
4272 tcg_temp_free(t1);
6af0bf9c
FB
4273}
4274
90aa39a1
SF
4275static inline bool use_goto_tb(DisasContext *ctx, target_ulong dest)
4276{
eeb3bba8 4277 if (unlikely(ctx->base.singlestep_enabled)) {
90aa39a1
SF
4278 return false;
4279 }
4280
4281#ifndef CONFIG_USER_ONLY
eeb3bba8 4282 return (ctx->base.tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
90aa39a1
SF
4283#else
4284 return true;
4285#endif
4286}
4287
356265ae 4288static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
c53be334 4289{
90aa39a1 4290 if (use_goto_tb(ctx, dest)) {
57fec1fe 4291 tcg_gen_goto_tb(n);
9b9e4393 4292 gen_save_pc(dest);
07ea28b4 4293 tcg_gen_exit_tb(ctx->base.tb, n);
6e256c93 4294 } else {
9b9e4393 4295 gen_save_pc(dest);
eeb3bba8 4296 if (ctx->base.singlestep_enabled) {
7b270ef2 4297 save_cpu_state(ctx, 0);
9c708c7f 4298 gen_helper_raise_exception_debug(cpu_env);
7b270ef2 4299 }
7f11636d 4300 tcg_gen_lookup_and_goto_ptr();
6e256c93 4301 }
c53be334
FB
4302}
4303
6af0bf9c 4304/* Branches (before delay slot) */
7a387fff 4305static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
7dca4ad0 4306 int insn_bytes,
b231c103
YK
4307 int rs, int rt, int32_t offset,
4308 int delayslot_size)
6af0bf9c 4309{
d077b6f7 4310 target_ulong btgt = -1;
3ad4bb2d 4311 int blink = 0;
2fdbad25 4312 int bcond_compute = 0;
1ba74fb8
AJ
4313 TCGv t0 = tcg_temp_new();
4314 TCGv t1 = tcg_temp_new();
3ad4bb2d
TS
4315
4316 if (ctx->hflags & MIPS_HFLAG_BMASK) {
923617a3 4317#ifdef MIPS_DEBUG_DISAS
339cd2a8 4318 LOG_DISAS("Branch in delay / forbidden slot at PC 0x"
eeb3bba8 4319 TARGET_FMT_lx "\n", ctx->base.pc_next);
923617a3 4320#endif
9c708c7f 4321 generate_exception_end(ctx, EXCP_RI);
6c5c1e20 4322 goto out;
3ad4bb2d 4323 }
6af0bf9c 4324
6af0bf9c
FB
4325 /* Load needed operands */
4326 switch (opc) {
4327 case OPC_BEQ:
4328 case OPC_BEQL:
4329 case OPC_BNE:
4330 case OPC_BNEL:
4331 /* Compare two registers */
4332 if (rs != rt) {
6c5c1e20
TS
4333 gen_load_gpr(t0, rs);
4334 gen_load_gpr(t1, rt);
2fdbad25 4335 bcond_compute = 1;
6af0bf9c 4336 }
eeb3bba8 4337 btgt = ctx->base.pc_next + insn_bytes + offset;
6af0bf9c
FB
4338 break;
4339 case OPC_BGEZ:
4340 case OPC_BGEZAL:
4341 case OPC_BGEZALL:
4342 case OPC_BGEZL:
4343 case OPC_BGTZ:
4344 case OPC_BGTZL:
4345 case OPC_BLEZ:
4346 case OPC_BLEZL:
4347 case OPC_BLTZ:
4348 case OPC_BLTZAL:
4349 case OPC_BLTZALL:
4350 case OPC_BLTZL:
4351 /* Compare to zero */
4352 if (rs != 0) {
6c5c1e20 4353 gen_load_gpr(t0, rs);
2fdbad25 4354 bcond_compute = 1;
6af0bf9c 4355 }
eeb3bba8 4356 btgt = ctx->base.pc_next + insn_bytes + offset;
6af0bf9c 4357 break;
e45a93e2
JL
4358 case OPC_BPOSGE32:
4359#if defined(TARGET_MIPS64)
4360 case OPC_BPOSGE64:
4361 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x7F);
4362#else
4363 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
4364#endif
4365 bcond_compute = 1;
eeb3bba8 4366 btgt = ctx->base.pc_next + insn_bytes + offset;
e45a93e2 4367 break;
6af0bf9c
FB
4368 case OPC_J:
4369 case OPC_JAL:
364d4831 4370 case OPC_JALX:
6af0bf9c 4371 /* Jump to immediate */
eeb3bba8
EC
4372 btgt = ((ctx->base.pc_next + insn_bytes) & (int32_t)0xF0000000) |
4373 (uint32_t)offset;
6af0bf9c
FB
4374 break;
4375 case OPC_JR:
4376 case OPC_JALR:
4377 /* Jump to register */
7a387fff
TS
4378 if (offset != 0 && offset != 16) {
4379 /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
cbeb0857 4380 others are reserved. */
923617a3 4381 MIPS_INVAL("jump hint");
9c708c7f 4382 generate_exception_end(ctx, EXCP_RI);
6c5c1e20 4383 goto out;
6af0bf9c 4384 }
d077b6f7 4385 gen_load_gpr(btarget, rs);
6af0bf9c
FB
4386 break;
4387 default:
4388 MIPS_INVAL("branch/jump");
9c708c7f 4389 generate_exception_end(ctx, EXCP_RI);
6c5c1e20 4390 goto out;
6af0bf9c 4391 }
2fdbad25 4392 if (bcond_compute == 0) {
6af0bf9c
FB
4393 /* No condition to be computed */
4394 switch (opc) {
4395 case OPC_BEQ: /* rx == rx */
4396 case OPC_BEQL: /* rx == rx likely */
4397 case OPC_BGEZ: /* 0 >= 0 */
4398 case OPC_BGEZL: /* 0 >= 0 likely */
4399 case OPC_BLEZ: /* 0 <= 0 */
4400 case OPC_BLEZL: /* 0 <= 0 likely */
4401 /* Always take */
4ad40f36 4402 ctx->hflags |= MIPS_HFLAG_B;
6af0bf9c
FB
4403 break;
4404 case OPC_BGEZAL: /* 0 >= 0 */
4405 case OPC_BGEZALL: /* 0 >= 0 likely */
4406 /* Always take and link */
4407 blink = 31;
4ad40f36 4408 ctx->hflags |= MIPS_HFLAG_B;
6af0bf9c
FB
4409 break;
4410 case OPC_BNE: /* rx != rx */
4411 case OPC_BGTZ: /* 0 > 0 */
4412 case OPC_BLTZ: /* 0 < 0 */
ead9360e 4413 /* Treat as NOP. */
6c5c1e20 4414 goto out;
eeef26cd 4415 case OPC_BLTZAL: /* 0 < 0 */
3c824109
NF
4416 /* Handle as an unconditional branch to get correct delay
4417 slot checking. */
4418 blink = 31;
eeb3bba8 4419 btgt = ctx->base.pc_next + insn_bytes + delayslot_size;
3c824109 4420 ctx->hflags |= MIPS_HFLAG_B;
3c824109 4421 break;
eeef26cd 4422 case OPC_BLTZALL: /* 0 < 0 likely */
eeb3bba8 4423 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 8);
9898128f 4424 /* Skip the instruction in the delay slot */
eeb3bba8 4425 ctx->base.pc_next += 4;
6c5c1e20 4426 goto out;
6af0bf9c
FB
4427 case OPC_BNEL: /* rx != rx likely */
4428 case OPC_BGTZL: /* 0 > 0 likely */
6af0bf9c
FB
4429 case OPC_BLTZL: /* 0 < 0 likely */
4430 /* Skip the instruction in the delay slot */
eeb3bba8 4431 ctx->base.pc_next += 4;
6c5c1e20 4432 goto out;
6af0bf9c 4433 case OPC_J:
4ad40f36 4434 ctx->hflags |= MIPS_HFLAG_B;
6af0bf9c 4435 break;
364d4831
NF
4436 case OPC_JALX:
4437 ctx->hflags |= MIPS_HFLAG_BX;
4438 /* Fallthrough */
6af0bf9c
FB
4439 case OPC_JAL:
4440 blink = 31;
4ad40f36 4441 ctx->hflags |= MIPS_HFLAG_B;
6af0bf9c
FB
4442 break;
4443 case OPC_JR:
4ad40f36 4444 ctx->hflags |= MIPS_HFLAG_BR;
6af0bf9c
FB
4445 break;
4446 case OPC_JALR:
4447 blink = rt;
4ad40f36 4448 ctx->hflags |= MIPS_HFLAG_BR;
6af0bf9c
FB
4449 break;
4450 default:
4451 MIPS_INVAL("branch/jump");
9c708c7f 4452 generate_exception_end(ctx, EXCP_RI);
6c5c1e20 4453 goto out;
6af0bf9c
FB
4454 }
4455 } else {
4456 switch (opc) {
4457 case OPC_BEQ:
e68dd28f 4458 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
6af0bf9c
FB
4459 goto not_likely;
4460 case OPC_BEQL:
e68dd28f 4461 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
6af0bf9c
FB
4462 goto likely;
4463 case OPC_BNE:
e68dd28f 4464 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
6af0bf9c
FB
4465 goto not_likely;
4466 case OPC_BNEL:
e68dd28f 4467 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
6af0bf9c
FB
4468 goto likely;
4469 case OPC_BGEZ:
e68dd28f 4470 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6af0bf9c
FB
4471 goto not_likely;
4472 case OPC_BGEZL:
e68dd28f 4473 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6af0bf9c
FB
4474 goto likely;
4475 case OPC_BGEZAL:
e68dd28f 4476 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6af0bf9c
FB
4477 blink = 31;
4478 goto not_likely;
4479 case OPC_BGEZALL:
e68dd28f 4480 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6af0bf9c 4481 blink = 31;
6af0bf9c
FB
4482 goto likely;
4483 case OPC_BGTZ:
e68dd28f 4484 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
6af0bf9c
FB
4485 goto not_likely;
4486 case OPC_BGTZL:
e68dd28f 4487 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
6af0bf9c
FB
4488 goto likely;
4489 case OPC_BLEZ:
e68dd28f 4490 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
6af0bf9c
FB
4491 goto not_likely;
4492 case OPC_BLEZL:
e68dd28f 4493 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
6af0bf9c
FB
4494 goto likely;
4495 case OPC_BLTZ:
e68dd28f 4496 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6af0bf9c
FB
4497 goto not_likely;
4498 case OPC_BLTZL:
e68dd28f 4499 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6af0bf9c 4500 goto likely;
e45a93e2
JL
4501 case OPC_BPOSGE32:
4502 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
e45a93e2
JL
4503 goto not_likely;
4504#if defined(TARGET_MIPS64)
4505 case OPC_BPOSGE64:
4506 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 64);
e45a93e2
JL
4507 goto not_likely;
4508#endif
6af0bf9c 4509 case OPC_BLTZAL:
e68dd28f 4510 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6af0bf9c 4511 blink = 31;
6af0bf9c 4512 not_likely:
4ad40f36 4513 ctx->hflags |= MIPS_HFLAG_BC;
6af0bf9c
FB
4514 break;
4515 case OPC_BLTZALL:
e68dd28f 4516 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6af0bf9c 4517 blink = 31;
6af0bf9c 4518 likely:
4ad40f36 4519 ctx->hflags |= MIPS_HFLAG_BL;
6af0bf9c 4520 break;
c53f4a62
TS
4521 default:
4522 MIPS_INVAL("conditional branch/jump");
9c708c7f 4523 generate_exception_end(ctx, EXCP_RI);
6c5c1e20 4524 goto out;
6af0bf9c 4525 }
6af0bf9c 4526 }
9b9e4393 4527
d077b6f7 4528 ctx->btarget = btgt;
b231c103
YK
4529
4530 switch (delayslot_size) {
4531 case 2:
4532 ctx->hflags |= MIPS_HFLAG_BDS16;
4533 break;
4534 case 4:
4535 ctx->hflags |= MIPS_HFLAG_BDS32;
4536 break;
4537 }
4538
6af0bf9c 4539 if (blink > 0) {
b231c103 4540 int post_delay = insn_bytes + delayslot_size;
364d4831
NF
4541 int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
4542
eeb3bba8
EC
4543 tcg_gen_movi_tl(cpu_gpr[blink],
4544 ctx->base.pc_next + post_delay + lowbit);
6af0bf9c 4545 }
6c5c1e20
TS
4546
4547 out:
364d4831
NF
4548 if (insn_bytes == 2)
4549 ctx->hflags |= MIPS_HFLAG_B16;
6c5c1e20
TS
4550 tcg_temp_free(t0);
4551 tcg_temp_free(t1);
6af0bf9c
FB
4552}
4553
7a387fff
TS
4554/* special3 bitfield operations */
4555static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
356265ae 4556 int rs, int lsb, int msb)
7a387fff 4557{
a7812ae4
PB
4558 TCGv t0 = tcg_temp_new();
4559 TCGv t1 = tcg_temp_new();
6c5c1e20
TS
4560
4561 gen_load_gpr(t1, rs);
7a387fff
TS
4562 switch (opc) {
4563 case OPC_EXT:
b7f26e52 4564 if (lsb + msb > 31) {
7a387fff 4565 goto fail;
b7f26e52 4566 }
505ad7c2 4567 if (msb != 31) {
6eebb7a4 4568 tcg_gen_extract_tl(t0, t1, lsb, msb + 1);
505ad7c2 4569 } else {
6eebb7a4
RH
4570 /* The two checks together imply that lsb == 0,
4571 so this is a simple sign-extension. */
4572 tcg_gen_ext32s_tl(t0, t1);
505ad7c2 4573 }
7a387fff 4574 break;
c6d6dd7c 4575#if defined(TARGET_MIPS64)
7a387fff 4576 case OPC_DEXTU:
b7f26e52
RH
4577 lsb += 32;
4578 goto do_dext;
4579 case OPC_DEXTM:
4580 msb += 32;
4581 goto do_dext;
7a387fff 4582 case OPC_DEXT:
b7f26e52
RH
4583 do_dext:
4584 if (lsb + msb > 63) {
4585 goto fail;
4586 }
6eebb7a4 4587 tcg_gen_extract_tl(t0, t1, lsb, msb + 1);
7a387fff 4588 break;
c6d6dd7c 4589#endif
7a387fff 4590 case OPC_INS:
b7f26e52 4591 if (lsb > msb) {
7a387fff 4592 goto fail;
b7f26e52 4593 }
6c5c1e20 4594 gen_load_gpr(t0, rt);
e0d002f1 4595 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
505ad7c2 4596 tcg_gen_ext32s_tl(t0, t0);
7a387fff 4597 break;
c6d6dd7c 4598#if defined(TARGET_MIPS64)
7a387fff 4599 case OPC_DINSU:
b7f26e52
RH
4600 lsb += 32;
4601 /* FALLTHRU */
4602 case OPC_DINSM:
4603 msb += 32;
4604 /* FALLTHRU */
7a387fff 4605 case OPC_DINS:
b7f26e52
RH
4606 if (lsb > msb) {
4607 goto fail;
4608 }
6c5c1e20 4609 gen_load_gpr(t0, rt);
e0d002f1 4610 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
7a387fff 4611 break;
c6d6dd7c 4612#endif
7a387fff
TS
4613 default:
4614fail:
4615 MIPS_INVAL("bitops");
9c708c7f 4616 generate_exception_end(ctx, EXCP_RI);
6c5c1e20
TS
4617 tcg_temp_free(t0);
4618 tcg_temp_free(t1);
7a387fff
TS
4619 return;
4620 }
6c5c1e20
TS
4621 gen_store_gpr(t0, rt);
4622 tcg_temp_free(t0);
4623 tcg_temp_free(t1);
7a387fff
TS
4624}
4625
49bcf33c
AJ
4626static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
4627{
3a55fa47 4628 TCGv t0;
49bcf33c 4629
3a55fa47
AJ
4630 if (rd == 0) {
4631 /* If no destination, treat it as a NOP. */
3a55fa47
AJ
4632 return;
4633 }
4634
4635 t0 = tcg_temp_new();
4636 gen_load_gpr(t0, rt);
49bcf33c
AJ
4637 switch (op2) {
4638 case OPC_WSBH:
3a55fa47
AJ
4639 {
4640 TCGv t1 = tcg_temp_new();
06a57e5c 4641 TCGv t2 = tcg_const_tl(0x00FF00FF);
3a55fa47
AJ
4642
4643 tcg_gen_shri_tl(t1, t0, 8);
06a57e5c
AJ
4644 tcg_gen_and_tl(t1, t1, t2);
4645 tcg_gen_and_tl(t0, t0, t2);
3a55fa47 4646 tcg_gen_shli_tl(t0, t0, 8);
3a55fa47 4647 tcg_gen_or_tl(t0, t0, t1);
06a57e5c 4648 tcg_temp_free(t2);
3a55fa47
AJ
4649 tcg_temp_free(t1);
4650 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
4651 }
49bcf33c
AJ
4652 break;
4653 case OPC_SEB:
3a55fa47 4654 tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
49bcf33c
AJ
4655 break;
4656 case OPC_SEH:
3a55fa47 4657 tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
49bcf33c
AJ
4658 break;
4659#if defined(TARGET_MIPS64)
4660 case OPC_DSBH:
3a55fa47
AJ
4661 {
4662 TCGv t1 = tcg_temp_new();
06a57e5c 4663 TCGv t2 = tcg_const_tl(0x00FF00FF00FF00FFULL);
3a55fa47
AJ
4664
4665 tcg_gen_shri_tl(t1, t0, 8);
06a57e5c
AJ
4666 tcg_gen_and_tl(t1, t1, t2);
4667 tcg_gen_and_tl(t0, t0, t2);
3a55fa47 4668 tcg_gen_shli_tl(t0, t0, 8);
3a55fa47 4669 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
06a57e5c 4670 tcg_temp_free(t2);
3a55fa47
AJ
4671 tcg_temp_free(t1);
4672 }
49bcf33c
AJ
4673 break;
4674 case OPC_DSHD:
3a55fa47
AJ
4675 {
4676 TCGv t1 = tcg_temp_new();
06a57e5c 4677 TCGv t2 = tcg_const_tl(0x0000FFFF0000FFFFULL);
3a55fa47
AJ
4678
4679 tcg_gen_shri_tl(t1, t0, 16);
06a57e5c
AJ
4680 tcg_gen_and_tl(t1, t1, t2);
4681 tcg_gen_and_tl(t0, t0, t2);
3a55fa47 4682 tcg_gen_shli_tl(t0, t0, 16);
3a55fa47
AJ
4683 tcg_gen_or_tl(t0, t0, t1);
4684 tcg_gen_shri_tl(t1, t0, 32);
4685 tcg_gen_shli_tl(t0, t0, 32);
4686 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
06a57e5c 4687 tcg_temp_free(t2);
3a55fa47
AJ
4688 tcg_temp_free(t1);
4689 }
49bcf33c
AJ
4690 break;
4691#endif
4692 default:
4693 MIPS_INVAL("bsfhl");
9c708c7f 4694 generate_exception_end(ctx, EXCP_RI);
49bcf33c 4695 tcg_temp_free(t0);
49bcf33c
AJ
4696 return;
4697 }
49bcf33c 4698 tcg_temp_free(t0);
49bcf33c
AJ
4699}
4700
1f1b4c00
YK
4701static void gen_lsa(DisasContext *ctx, int opc, int rd, int rs, int rt,
4702 int imm2)
4703{
4704 TCGv t0;
4705 TCGv t1;
4706 if (rd == 0) {
4707 /* Treat as NOP. */
4708 return;
4709 }
4710 t0 = tcg_temp_new();
4711 t1 = tcg_temp_new();
4712 gen_load_gpr(t0, rs);
4713 gen_load_gpr(t1, rt);
4714 tcg_gen_shli_tl(t0, t0, imm2 + 1);
4715 tcg_gen_add_tl(cpu_gpr[rd], t0, t1);
4716 if (opc == OPC_LSA) {
4717 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4718 }
4719
4720 tcg_temp_free(t1);
4721 tcg_temp_free(t0);
4722
4723 return;
4724}
4725
4726static void gen_align(DisasContext *ctx, int opc, int rd, int rs, int rt,
4727 int bp)
284b731a 4728{
1f1b4c00
YK
4729 TCGv t0;
4730 if (rd == 0) {
4731 /* Treat as NOP. */
4732 return;
4733 }
4734 t0 = tcg_temp_new();
4735 gen_load_gpr(t0, rt);
4736 if (bp == 0) {
51243852
MD
4737 switch (opc) {
4738 case OPC_ALIGN:
4739 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
4740 break;
4741#if defined(TARGET_MIPS64)
4742 case OPC_DALIGN:
4743 tcg_gen_mov_tl(cpu_gpr[rd], t0);
4744 break;
4745#endif
4746 }
1f1b4c00
YK
4747 } else {
4748 TCGv t1 = tcg_temp_new();
4749 gen_load_gpr(t1, rs);
4750 switch (opc) {
4751 case OPC_ALIGN:
4752 {
4753 TCGv_i64 t2 = tcg_temp_new_i64();
4754 tcg_gen_concat_tl_i64(t2, t1, t0);
4755 tcg_gen_shri_i64(t2, t2, 8 * (4 - bp));
4756 gen_move_low32(cpu_gpr[rd], t2);
4757 tcg_temp_free_i64(t2);
4758 }
4759 break;
284b731a 4760#if defined(TARGET_MIPS64)
1f1b4c00
YK
4761 case OPC_DALIGN:
4762 tcg_gen_shli_tl(t0, t0, 8 * bp);
4763 tcg_gen_shri_tl(t1, t1, 8 * (8 - bp));
4764 tcg_gen_or_tl(cpu_gpr[rd], t1, t0);
4765 break;
284b731a 4766#endif
1f1b4c00
YK
4767 }
4768 tcg_temp_free(t1);
4769 }
4770
4771 tcg_temp_free(t0);
4772}
4773
4774static void gen_bitswap(DisasContext *ctx, int opc, int rd, int rt)
4775{
4776 TCGv t0;
4777 if (rd == 0) {
4778 /* Treat as NOP. */
4779 return;
4780 }
4781 t0 = tcg_temp_new();
4782 gen_load_gpr(t0, rt);
4783 switch (opc) {
4784 case OPC_BITSWAP:
4785 gen_helper_bitswap(cpu_gpr[rd], t0);
4786 break;
4787#if defined(TARGET_MIPS64)
4788 case OPC_DBITSWAP:
4789 gen_helper_dbitswap(cpu_gpr[rd], t0);
4790 break;
4791#endif
4792 }
4793 tcg_temp_free(t0);
284b731a
LA
4794}
4795
1f1b4c00
YK
4796#ifndef CONFIG_USER_ONLY
4797/* CP0 (MMU and control) */
5204ea79
LA
4798static inline void gen_mthc0_entrylo(TCGv arg, target_ulong off)
4799{
4800 TCGv_i64 t0 = tcg_temp_new_i64();
4801 TCGv_i64 t1 = tcg_temp_new_i64();
4802
4803 tcg_gen_ext_tl_i64(t0, arg);
4804 tcg_gen_ld_i64(t1, cpu_env, off);
4805#if defined(TARGET_MIPS64)
4806 tcg_gen_deposit_i64(t1, t1, t0, 30, 32);
4807#else
4808 tcg_gen_concat32_i64(t1, t1, t0);
4809#endif
4810 tcg_gen_st_i64(t1, cpu_env, off);
4811 tcg_temp_free_i64(t1);
4812 tcg_temp_free_i64(t0);
4813}
4814
4815static inline void gen_mthc0_store64(TCGv arg, target_ulong off)
4816{
4817 TCGv_i64 t0 = tcg_temp_new_i64();
4818 TCGv_i64 t1 = tcg_temp_new_i64();
4819
4820 tcg_gen_ext_tl_i64(t0, arg);
4821 tcg_gen_ld_i64(t1, cpu_env, off);
4822 tcg_gen_concat32_i64(t1, t1, t0);
4823 tcg_gen_st_i64(t1, cpu_env, off);
4824 tcg_temp_free_i64(t1);
4825 tcg_temp_free_i64(t0);
4826}
4827
4828static inline void gen_mfhc0_entrylo(TCGv arg, target_ulong off)
4829{
4830 TCGv_i64 t0 = tcg_temp_new_i64();
4831
4832 tcg_gen_ld_i64(t0, cpu_env, off);
4833#if defined(TARGET_MIPS64)
4834 tcg_gen_shri_i64(t0, t0, 30);
4835#else
4836 tcg_gen_shri_i64(t0, t0, 32);
4837#endif
4838 gen_move_low32(arg, t0);
4839 tcg_temp_free_i64(t0);
4840}
4841
4842static inline void gen_mfhc0_load64(TCGv arg, target_ulong off, int shift)
4843{
4844 TCGv_i64 t0 = tcg_temp_new_i64();
4845
4846 tcg_gen_ld_i64(t0, cpu_env, off);
4847 tcg_gen_shri_i64(t0, t0, 32 + shift);
4848 gen_move_low32(arg, t0);
4849 tcg_temp_free_i64(t0);
4850}
4851
d9bea114 4852static inline void gen_mfc0_load32 (TCGv arg, target_ulong off)
4f57689a 4853{
d9bea114 4854 TCGv_i32 t0 = tcg_temp_new_i32();
4f57689a 4855
d9bea114
AJ
4856 tcg_gen_ld_i32(t0, cpu_env, off);
4857 tcg_gen_ext_i32_tl(arg, t0);
4858 tcg_temp_free_i32(t0);
4f57689a
TS
4859}
4860
d9bea114 4861static inline void gen_mfc0_load64 (TCGv arg, target_ulong off)
4f57689a 4862{
d9bea114
AJ
4863 tcg_gen_ld_tl(arg, cpu_env, off);
4864 tcg_gen_ext32s_tl(arg, arg);
4f57689a
TS
4865}
4866
d9bea114 4867static inline void gen_mtc0_store32 (TCGv arg, target_ulong off)
f1aa6320 4868{
d9bea114 4869 TCGv_i32 t0 = tcg_temp_new_i32();
f1aa6320 4870
d9bea114
AJ
4871 tcg_gen_trunc_tl_i32(t0, arg);
4872 tcg_gen_st_i32(t0, cpu_env, off);
4873 tcg_temp_free_i32(t0);
f1aa6320
TS
4874}
4875
c98d3d79
YK
4876#define CP0_CHECK(c) \
4877 do { \
4878 if (!(c)) { \
4879 goto cp0_unimplemented; \
4880 } \
4881 } while (0)
4882
5204ea79
LA
4883static void gen_mfhc0(DisasContext *ctx, TCGv arg, int reg, int sel)
4884{
4885 const char *rn = "invalid";
4886
c98d3d79 4887 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
5204ea79
LA
4888
4889 switch (reg) {
4890 case 2:
4891 switch (sel) {
4892 case 0:
4893 gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
4894 rn = "EntryLo0";
4895 break;
4896 default:
c98d3d79 4897 goto cp0_unimplemented;
5204ea79
LA
4898 }
4899 break;
4900 case 3:
4901 switch (sel) {
4902 case 0:
4903 gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
4904 rn = "EntryLo1";
4905 break;
4906 default:
c98d3d79 4907 goto cp0_unimplemented;
5204ea79
LA
4908 }
4909 break;
4910 case 17:
4911 switch (sel) {
4912 case 0:
4913 gen_mfhc0_load64(arg, offsetof(CPUMIPSState, lladdr),
4914 ctx->CP0_LLAddr_shift);
4915 rn = "LLAddr";
4916 break;
f6d4dd81
YK
4917 case 1:
4918 CP0_CHECK(ctx->mrp);
4919 gen_helper_mfhc0_maar(arg, cpu_env);
4920 rn = "MAAR";
4921 break;
5204ea79 4922 default:
c98d3d79 4923 goto cp0_unimplemented;
5204ea79
LA
4924 }
4925 break;
4926 case 28:
4927 switch (sel) {
4928 case 0:
4929 case 2:
4930 case 4:
4931 case 6:
4932 gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_TagLo), 0);
4933 rn = "TagLo";
4934 break;
4935 default:
c98d3d79 4936 goto cp0_unimplemented;
5204ea79
LA
4937 }
4938 break;
4939 default:
c98d3d79 4940 goto cp0_unimplemented;
5204ea79 4941 }
b44a7fb1 4942 trace_mips_translate_c0("mfhc0", rn, reg, sel);
5204ea79
LA
4943 return;
4944
c98d3d79 4945cp0_unimplemented:
965447ee 4946 qemu_log_mask(LOG_UNIMP, "mfhc0 %s (reg %d sel %d)\n", rn, reg, sel);
5204ea79
LA
4947 tcg_gen_movi_tl(arg, 0);
4948}
4949
4950static void gen_mthc0(DisasContext *ctx, TCGv arg, int reg, int sel)
4951{
4952 const char *rn = "invalid";
4953 uint64_t mask = ctx->PAMask >> 36;
4954
c98d3d79 4955 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
5204ea79
LA
4956
4957 switch (reg) {
4958 case 2:
4959 switch (sel) {
4960 case 0:
4961 tcg_gen_andi_tl(arg, arg, mask);
4962 gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
4963 rn = "EntryLo0";
4964 break;
4965 default:
c98d3d79 4966 goto cp0_unimplemented;
5204ea79
LA
4967 }
4968 break;
4969 case 3:
4970 switch (sel) {
4971 case 0:
4972 tcg_gen_andi_tl(arg, arg, mask);
4973 gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
4974 rn = "EntryLo1";
4975 break;
4976 default:
c98d3d79 4977 goto cp0_unimplemented;
5204ea79
LA
4978 }
4979 break;
4980 case 17:
4981 switch (sel) {
4982 case 0:
4983 /* LLAddr is read-only (the only exception is bit 0 if LLB is
4984 supported); the CP0_LLAddr_rw_bitmask does not seem to be
4985 relevant for modern MIPS cores supporting MTHC0, therefore
4986 treating MTHC0 to LLAddr as NOP. */
4987 rn = "LLAddr";
4988 break;
f6d4dd81
YK
4989 case 1:
4990 CP0_CHECK(ctx->mrp);
4991 gen_helper_mthc0_maar(cpu_env, arg);
4992 rn = "MAAR";
4993 break;
5204ea79 4994 default:
c98d3d79 4995 goto cp0_unimplemented;
5204ea79
LA
4996 }
4997 break;
4998 case 28:
4999 switch (sel) {
5000 case 0:
5001 case 2:
5002 case 4:
5003 case 6:
5004 tcg_gen_andi_tl(arg, arg, mask);
5005 gen_mthc0_store64(arg, offsetof(CPUMIPSState, CP0_TagLo));
5006 rn = "TagLo";
5007 break;
5008 default:
c98d3d79 5009 goto cp0_unimplemented;
5204ea79
LA
5010 }
5011 break;
5012 default:
c98d3d79 5013 goto cp0_unimplemented;
5204ea79 5014 }
b44a7fb1 5015 trace_mips_translate_c0("mthc0", rn, reg, sel);
5204ea79 5016
c98d3d79 5017cp0_unimplemented:
965447ee 5018 qemu_log_mask(LOG_UNIMP, "mthc0 %s (reg %d sel %d)\n", rn, reg, sel);
5204ea79
LA
5019}
5020
e98c0d17
LA
5021static inline void gen_mfc0_unimplemented(DisasContext *ctx, TCGv arg)
5022{
5023 if (ctx->insn_flags & ISA_MIPS32R6) {
5024 tcg_gen_movi_tl(arg, 0);
5025 } else {
5026 tcg_gen_movi_tl(arg, ~0);
5027 }
5028}
5029
d75c135e 5030static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
873eb012 5031{
7a387fff 5032 const char *rn = "invalid";
873eb012 5033
e189e748 5034 if (sel != 0)
d75c135e 5035 check_insn(ctx, ISA_MIPS32);
e189e748 5036
873eb012
TS
5037 switch (reg) {
5038 case 0:
7a387fff
TS
5039 switch (sel) {
5040 case 0:
7db13fae 5041 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
7a387fff
TS
5042 rn = "Index";
5043 break;
5044 case 1:
f31b035a 5045 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5046 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
7a387fff 5047 rn = "MVPControl";
ead9360e 5048 break;
7a387fff 5049 case 2:
f31b035a 5050 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5051 gen_helper_mfc0_mvpconf0(arg, cpu_env);
7a387fff 5052 rn = "MVPConf0";
ead9360e 5053 break;
7a387fff 5054 case 3:
f31b035a 5055 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5056 gen_helper_mfc0_mvpconf1(arg, cpu_env);
7a387fff 5057 rn = "MVPConf1";
ead9360e 5058 break;
01bc435b
YK
5059 case 4:
5060 CP0_CHECK(ctx->vp);
5061 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl));
5062 rn = "VPControl";
5063 break;
7a387fff 5064 default:
f31b035a 5065 goto cp0_unimplemented;
7a387fff 5066 }
873eb012
TS
5067 break;
5068 case 1:
7a387fff
TS
5069 switch (sel) {
5070 case 0:
f31b035a 5071 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
895c2d04 5072 gen_helper_mfc0_random(arg, cpu_env);
7a387fff 5073 rn = "Random";
2423f660 5074 break;
7a387fff 5075 case 1:
f31b035a 5076 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 5077 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
7a387fff 5078 rn = "VPEControl";
ead9360e 5079 break;
7a387fff 5080 case 2:
f31b035a 5081 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 5082 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
7a387fff 5083 rn = "VPEConf0";
ead9360e 5084 break;
7a387fff 5085 case 3:
f31b035a 5086 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 5087 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
7a387fff 5088 rn = "VPEConf1";
ead9360e 5089 break;
7a387fff 5090 case 4:
f31b035a 5091 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 5092 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask));
7a387fff 5093 rn = "YQMask";
ead9360e 5094 break;
7a387fff 5095 case 5:
f31b035a 5096 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 5097 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
7a387fff 5098 rn = "VPESchedule";
ead9360e 5099 break;
7a387fff 5100 case 6:
f31b035a 5101 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 5102 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
7a387fff 5103 rn = "VPEScheFBack";
ead9360e 5104 break;
7a387fff 5105 case 7:
f31b035a 5106 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 5107 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
7a387fff 5108 rn = "VPEOpt";
ead9360e 5109 break;
7a387fff 5110 default:
f31b035a 5111 goto cp0_unimplemented;
7a387fff 5112 }
873eb012
TS
5113 break;
5114 case 2:
7a387fff
TS
5115 switch (sel) {
5116 case 0:
284b731a
LA
5117 {
5118 TCGv_i64 tmp = tcg_temp_new_i64();
5119 tcg_gen_ld_i64(tmp, cpu_env,
5120 offsetof(CPUMIPSState, CP0_EntryLo0));
7207c7f9 5121#if defined(TARGET_MIPS64)
284b731a
LA
5122 if (ctx->rxi) {
5123 /* Move RI/XI fields to bits 31:30 */
5124 tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
5125 tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
5126 }
7207c7f9 5127#endif
284b731a
LA
5128 gen_move_low32(arg, tmp);
5129 tcg_temp_free_i64(tmp);
5130 }
2423f660
TS
5131 rn = "EntryLo0";
5132 break;
7a387fff 5133 case 1:
f31b035a 5134 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5135 gen_helper_mfc0_tcstatus(arg, cpu_env);
2423f660 5136 rn = "TCStatus";
ead9360e 5137 break;
7a387fff 5138 case 2:
f31b035a 5139 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5140 gen_helper_mfc0_tcbind(arg, cpu_env);
2423f660 5141 rn = "TCBind";
ead9360e 5142 break;
7a387fff 5143 case 3:
f31b035a 5144 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5145 gen_helper_mfc0_tcrestart(arg, cpu_env);
2423f660 5146 rn = "TCRestart";
ead9360e 5147 break;
7a387fff 5148 case 4:
f31b035a 5149 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5150 gen_helper_mfc0_tchalt(arg, cpu_env);
2423f660 5151 rn = "TCHalt";
ead9360e 5152 break;
7a387fff 5153 case 5:
f31b035a 5154 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5155 gen_helper_mfc0_tccontext(arg, cpu_env);
2423f660 5156 rn = "TCContext";
ead9360e 5157 break;
7a387fff 5158 case 6:
f31b035a 5159 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5160 gen_helper_mfc0_tcschedule(arg, cpu_env);
2423f660 5161 rn = "TCSchedule";
ead9360e 5162 break;
7a387fff 5163 case 7:
f31b035a 5164 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5165 gen_helper_mfc0_tcschefback(arg, cpu_env);
2423f660 5166 rn = "TCScheFBack";
ead9360e 5167 break;
7a387fff 5168 default:
f31b035a 5169 goto cp0_unimplemented;
7a387fff 5170 }
873eb012
TS
5171 break;
5172 case 3:
7a387fff
TS
5173 switch (sel) {
5174 case 0:
284b731a
LA
5175 {
5176 TCGv_i64 tmp = tcg_temp_new_i64();
5177 tcg_gen_ld_i64(tmp, cpu_env,
5178 offsetof(CPUMIPSState, CP0_EntryLo1));
7207c7f9 5179#if defined(TARGET_MIPS64)
284b731a
LA
5180 if (ctx->rxi) {
5181 /* Move RI/XI fields to bits 31:30 */
5182 tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
5183 tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
5184 }
7207c7f9 5185#endif
284b731a
LA
5186 gen_move_low32(arg, tmp);
5187 tcg_temp_free_i64(tmp);
5188 }
2423f660
TS
5189 rn = "EntryLo1";
5190 break;
01bc435b
YK
5191 case 1:
5192 CP0_CHECK(ctx->vp);
5193 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber));
5194 rn = "GlobalNumber";
5195 break;
7a387fff 5196 default:
f31b035a 5197 goto cp0_unimplemented;
1579a72e 5198 }
873eb012
TS
5199 break;
5200 case 4:
7a387fff
TS
5201 switch (sel) {
5202 case 0:
7db13fae 5203 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
d9bea114 5204 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
5205 rn = "Context";
5206 break;
7a387fff 5207 case 1:
d9bea114 5208// gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
2423f660 5209 rn = "ContextConfig";
f31b035a 5210 goto cp0_unimplemented;
d279279e 5211 case 2:
f31b035a 5212 CP0_CHECK(ctx->ulri);
e40df9a8
JH
5213 tcg_gen_ld_tl(arg, cpu_env,
5214 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
5215 tcg_gen_ext32s_tl(arg, arg);
f31b035a 5216 rn = "UserLocal";
d279279e 5217 break;
7a387fff 5218 default:
f31b035a 5219 goto cp0_unimplemented;
1579a72e 5220 }
873eb012
TS
5221 break;
5222 case 5:
7a387fff
TS
5223 switch (sel) {
5224 case 0:
7db13fae 5225 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
2423f660
TS
5226 rn = "PageMask";
5227 break;
7a387fff 5228 case 1:
d75c135e 5229 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5230 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
2423f660
TS
5231 rn = "PageGrain";
5232 break;
cec56a73
JH
5233 case 2:
5234 CP0_CHECK(ctx->sc);
5235 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl0));
5236 tcg_gen_ext32s_tl(arg, arg);
5237 rn = "SegCtl0";
5238 break;
5239 case 3:
5240 CP0_CHECK(ctx->sc);
5241 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl1));
5242 tcg_gen_ext32s_tl(arg, arg);
5243 rn = "SegCtl1";
5244 break;
5245 case 4:
5246 CP0_CHECK(ctx->sc);
5247 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl2));
5248 tcg_gen_ext32s_tl(arg, arg);
5249 rn = "SegCtl2";
5250 break;
7a387fff 5251 default:
f31b035a 5252 goto cp0_unimplemented;
1579a72e 5253 }
873eb012
TS
5254 break;
5255 case 6:
7a387fff
TS
5256 switch (sel) {
5257 case 0:
7db13fae 5258 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
2423f660
TS
5259 rn = "Wired";
5260 break;
7a387fff 5261 case 1:
d75c135e 5262 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5263 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
2423f660 5264 rn = "SRSConf0";
ead9360e 5265 break;
7a387fff 5266 case 2:
d75c135e 5267 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5268 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
2423f660 5269 rn = "SRSConf1";
ead9360e 5270 break;
7a387fff 5271 case 3:
d75c135e 5272 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5273 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
2423f660 5274 rn = "SRSConf2";
ead9360e 5275 break;
7a387fff 5276 case 4:
d75c135e 5277 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5278 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
2423f660 5279 rn = "SRSConf3";
ead9360e 5280 break;
7a387fff 5281 case 5:
d75c135e 5282 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5283 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
2423f660 5284 rn = "SRSConf4";
ead9360e 5285 break;
7a387fff 5286 default:
f31b035a 5287 goto cp0_unimplemented;
1579a72e 5288 }
873eb012 5289 break;
8c0fdd85 5290 case 7:
7a387fff
TS
5291 switch (sel) {
5292 case 0:
d75c135e 5293 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5294 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
2423f660
TS
5295 rn = "HWREna";
5296 break;
7a387fff 5297 default:
f31b035a 5298 goto cp0_unimplemented;
1579a72e 5299 }
8c0fdd85 5300 break;
873eb012 5301 case 8:
7a387fff
TS
5302 switch (sel) {
5303 case 0:
7db13fae 5304 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
d9bea114 5305 tcg_gen_ext32s_tl(arg, arg);
f0b3f3ae 5306 rn = "BadVAddr";
2423f660 5307 break;
aea14095 5308 case 1:
f31b035a
LA
5309 CP0_CHECK(ctx->bi);
5310 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
5311 rn = "BadInstr";
aea14095
LA
5312 break;
5313 case 2:
f31b035a
LA
5314 CP0_CHECK(ctx->bp);
5315 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
5316 rn = "BadInstrP";
aea14095 5317 break;
7a387fff 5318 default:
f31b035a 5319 goto cp0_unimplemented;
aea14095 5320 }
873eb012
TS
5321 break;
5322 case 9:
7a387fff
TS
5323 switch (sel) {
5324 case 0:
2e70f6ef 5325 /* Mark as an IO operation because we read the time. */
eeb3bba8 5326 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
2e70f6ef 5327 gen_io_start();
bd79255d 5328 }
895c2d04 5329 gen_helper_mfc0_count(arg, cpu_env);
eeb3bba8 5330 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
2e70f6ef 5331 gen_io_end();
2e70f6ef 5332 }
55807224 5333 /* Break the TB to be able to take timer interrupts immediately
b28425ba
EC
5334 after reading count. DISAS_STOP isn't sufficient, we need to
5335 ensure we break completely out of translated code. */
eeb3bba8
EC
5336 gen_save_pc(ctx->base.pc_next + 4);
5337 ctx->base.is_jmp = DISAS_EXIT;
2423f660
TS
5338 rn = "Count";
5339 break;
5340 /* 6,7 are implementation dependent */
7a387fff 5341 default:
f31b035a 5342 goto cp0_unimplemented;
2423f660 5343 }
873eb012
TS
5344 break;
5345 case 10:
7a387fff
TS
5346 switch (sel) {
5347 case 0:
7db13fae 5348 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
d9bea114 5349 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
5350 rn = "EntryHi";
5351 break;
7a387fff 5352 default:
f31b035a 5353 goto cp0_unimplemented;
1579a72e 5354 }
873eb012
TS
5355 break;
5356 case 11:
7a387fff
TS
5357 switch (sel) {
5358 case 0:
7db13fae 5359 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
2423f660
TS
5360 rn = "Compare";
5361 break;
5362 /* 6,7 are implementation dependent */
7a387fff 5363 default:
f31b035a 5364 goto cp0_unimplemented;
2423f660 5365 }
873eb012
TS
5366 break;
5367 case 12:
7a387fff
TS
5368 switch (sel) {
5369 case 0:
7db13fae 5370 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
2423f660
TS
5371 rn = "Status";
5372 break;
7a387fff 5373 case 1:
d75c135e 5374 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5375 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
2423f660
TS
5376 rn = "IntCtl";
5377 break;
7a387fff 5378 case 2:
d75c135e 5379 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5380 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
2423f660
TS
5381 rn = "SRSCtl";
5382 break;
7a387fff 5383 case 3:
d75c135e 5384 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5385 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
2423f660 5386 rn = "SRSMap";
fd88b6ab 5387 break;
7a387fff 5388 default:
f31b035a 5389 goto cp0_unimplemented;
7a387fff 5390 }
873eb012
TS
5391 break;
5392 case 13:
7a387fff
TS
5393 switch (sel) {
5394 case 0:
7db13fae 5395 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
2423f660
TS
5396 rn = "Cause";
5397 break;
7a387fff 5398 default:
f31b035a 5399 goto cp0_unimplemented;
7a387fff 5400 }
873eb012
TS
5401 break;
5402 case 14:
7a387fff
TS
5403 switch (sel) {
5404 case 0:
7db13fae 5405 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
d9bea114 5406 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
5407 rn = "EPC";
5408 break;
7a387fff 5409 default:
f31b035a 5410 goto cp0_unimplemented;
1579a72e 5411 }
873eb012
TS
5412 break;
5413 case 15:
7a387fff
TS
5414 switch (sel) {
5415 case 0:
7db13fae 5416 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
2423f660
TS
5417 rn = "PRid";
5418 break;
7a387fff 5419 case 1:
d75c135e 5420 check_insn(ctx, ISA_MIPS32R2);
74dbf824
JH
5421 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EBase));
5422 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
5423 rn = "EBase";
5424 break;
c870e3f5
YK
5425 case 3:
5426 check_insn(ctx, ISA_MIPS32R2);
5427 CP0_CHECK(ctx->cmgcr);
5428 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase));
5429 tcg_gen_ext32s_tl(arg, arg);
5430 rn = "CMGCRBase";
5431 break;
7a387fff 5432 default:
f31b035a 5433 goto cp0_unimplemented;
7a387fff 5434 }
873eb012
TS
5435 break;
5436 case 16:
5437 switch (sel) {
5438 case 0:
7db13fae 5439 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
873eb012
TS
5440 rn = "Config";
5441 break;
5442 case 1:
7db13fae 5443 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
873eb012
TS
5444 rn = "Config1";
5445 break;
7a387fff 5446 case 2:
7db13fae 5447 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
7a387fff
TS
5448 rn = "Config2";
5449 break;
5450 case 3:
7db13fae 5451 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
7a387fff
TS
5452 rn = "Config3";
5453 break;
b4160af1
PJ
5454 case 4:
5455 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
5456 rn = "Config4";
5457 break;
b4dd99a3
PJ
5458 case 5:
5459 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
5460 rn = "Config5";
5461 break;
e397ee33
TS
5462 /* 6,7 are implementation dependent */
5463 case 6:
7db13fae 5464 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
e397ee33
TS
5465 rn = "Config6";
5466 break;
5467 case 7:
7db13fae 5468 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
e397ee33
TS
5469 rn = "Config7";
5470 break;
873eb012 5471 default:
f31b035a 5472 goto cp0_unimplemented;
873eb012
TS
5473 }
5474 break;
5475 case 17:
7a387fff
TS
5476 switch (sel) {
5477 case 0:
895c2d04 5478 gen_helper_mfc0_lladdr(arg, cpu_env);
2423f660
TS
5479 rn = "LLAddr";
5480 break;
f6d4dd81
YK
5481 case 1:
5482 CP0_CHECK(ctx->mrp);
5483 gen_helper_mfc0_maar(arg, cpu_env);
5484 rn = "MAAR";
5485 break;
5486 case 2:
5487 CP0_CHECK(ctx->mrp);
5488 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI));
5489 rn = "MAARI";
5490 break;
7a387fff 5491 default:
f31b035a 5492 goto cp0_unimplemented;
7a387fff 5493 }
873eb012
TS
5494 break;
5495 case 18:
7a387fff 5496 switch (sel) {
c2e19f3c
AM
5497 case 0:
5498 case 1:
5499 case 2:
5500 case 3:
5501 case 4:
5502 case 5:
5503 case 6:
5504 case 7:
895c2d04 5505 gen_helper_1e0i(mfc0_watchlo, arg, sel);
2423f660
TS
5506 rn = "WatchLo";
5507 break;
7a387fff 5508 default:
f31b035a 5509 goto cp0_unimplemented;
7a387fff 5510 }
873eb012
TS
5511 break;
5512 case 19:
7a387fff 5513 switch (sel) {
c2e19f3c
AM
5514 case 0:
5515 case 1:
5516 case 2:
5517 case 3:
5518 case 4:
5519 case 5:
5520 case 6:
5521 case 7:
895c2d04 5522 gen_helper_1e0i(mfc0_watchhi, arg, sel);
2423f660
TS
5523 rn = "WatchHi";
5524 break;
7a387fff 5525 default:
f31b035a 5526 goto cp0_unimplemented;
7a387fff 5527 }
873eb012 5528 break;
8c0fdd85 5529 case 20:
7a387fff
TS
5530 switch (sel) {
5531 case 0:
d26bc211 5532#if defined(TARGET_MIPS64)
d75c135e 5533 check_insn(ctx, ISA_MIPS3);
7db13fae 5534 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
d9bea114 5535 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
5536 rn = "XContext";
5537 break;
703eaf37 5538#endif
7a387fff 5539 default:
f31b035a 5540 goto cp0_unimplemented;
7a387fff 5541 }
8c0fdd85
TS
5542 break;
5543 case 21:
7a387fff 5544 /* Officially reserved, but sel 0 is used for R1x000 framemask */
f31b035a 5545 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
7a387fff
TS
5546 switch (sel) {
5547 case 0:
7db13fae 5548 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
2423f660
TS
5549 rn = "Framemask";
5550 break;
7a387fff 5551 default:
f31b035a 5552 goto cp0_unimplemented;
7a387fff 5553 }
8c0fdd85
TS
5554 break;
5555 case 22:
d9bea114 5556 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
5557 rn = "'Diagnostic"; /* implementation dependent */
5558 break;
873eb012 5559 case 23:
7a387fff
TS
5560 switch (sel) {
5561 case 0:
895c2d04 5562 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
2423f660
TS
5563 rn = "Debug";
5564 break;
7a387fff 5565 case 1:
d9bea114 5566// gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
2423f660 5567 rn = "TraceControl";
3570d7f6 5568 goto cp0_unimplemented;
7a387fff 5569 case 2:
d9bea114 5570// gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
2423f660 5571 rn = "TraceControl2";
3570d7f6 5572 goto cp0_unimplemented;
7a387fff 5573 case 3:
d9bea114 5574// gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
2423f660 5575 rn = "UserTraceData";
3570d7f6 5576 goto cp0_unimplemented;
7a387fff 5577 case 4:
d9bea114 5578// gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
2423f660 5579 rn = "TraceBPC";
3570d7f6 5580 goto cp0_unimplemented;
7a387fff 5581 default:
f31b035a 5582 goto cp0_unimplemented;
7a387fff 5583 }
873eb012
TS
5584 break;
5585 case 24:
7a387fff
TS
5586 switch (sel) {
5587 case 0:
f0b3f3ae 5588 /* EJTAG support */
7db13fae 5589 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
d9bea114 5590 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
5591 rn = "DEPC";
5592 break;
7a387fff 5593 default:
f31b035a 5594 goto cp0_unimplemented;
7a387fff 5595 }
873eb012 5596 break;
8c0fdd85 5597 case 25:
7a387fff
TS
5598 switch (sel) {
5599 case 0:
7db13fae 5600 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
2423f660 5601 rn = "Performance0";
7a387fff
TS
5602 break;
5603 case 1:
d9bea114 5604// gen_helper_mfc0_performance1(arg);
2423f660 5605 rn = "Performance1";
3570d7f6 5606 goto cp0_unimplemented;
7a387fff 5607 case 2:
d9bea114 5608// gen_helper_mfc0_performance2(arg);
2423f660 5609 rn = "Performance2";
3570d7f6 5610 goto cp0_unimplemented;
7a387fff 5611 case 3:
d9bea114 5612// gen_helper_mfc0_performance3(arg);
2423f660 5613 rn = "Performance3";
3570d7f6 5614 goto cp0_unimplemented;
7a387fff 5615 case 4:
d9bea114 5616// gen_helper_mfc0_performance4(arg);
2423f660 5617 rn = "Performance4";
3570d7f6 5618 goto cp0_unimplemented;
7a387fff 5619 case 5:
d9bea114 5620// gen_helper_mfc0_performance5(arg);
2423f660 5621 rn = "Performance5";
3570d7f6 5622 goto cp0_unimplemented;
7a387fff 5623 case 6:
d9bea114 5624// gen_helper_mfc0_performance6(arg);
2423f660 5625 rn = "Performance6";
3570d7f6 5626 goto cp0_unimplemented;
7a387fff 5627 case 7:
d9bea114 5628// gen_helper_mfc0_performance7(arg);
2423f660 5629 rn = "Performance7";
3570d7f6 5630 goto cp0_unimplemented;
7a387fff 5631 default:
f31b035a 5632 goto cp0_unimplemented;
7a387fff 5633 }
8c0fdd85
TS
5634 break;
5635 case 26:
0d74a222
LA
5636 switch (sel) {
5637 case 0:
5638 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl));
5639 rn = "ErrCtl";
5640 break;
5641 default:
5642 goto cp0_unimplemented;
5643 }
da80682b 5644 break;
8c0fdd85 5645 case 27:
7a387fff 5646 switch (sel) {
c2e19f3c
AM
5647 case 0:
5648 case 1:
5649 case 2:
5650 case 3:
d9bea114 5651 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
5652 rn = "CacheErr";
5653 break;
7a387fff 5654 default:
f31b035a 5655 goto cp0_unimplemented;
7a387fff 5656 }
8c0fdd85 5657 break;
873eb012
TS
5658 case 28:
5659 switch (sel) {
5660 case 0:
7a387fff
TS
5661 case 2:
5662 case 4:
5663 case 6:
284b731a
LA
5664 {
5665 TCGv_i64 tmp = tcg_temp_new_i64();
5666 tcg_gen_ld_i64(tmp, cpu_env, offsetof(CPUMIPSState, CP0_TagLo));
5667 gen_move_low32(arg, tmp);
5668 tcg_temp_free_i64(tmp);
5669 }
873eb012
TS
5670 rn = "TagLo";
5671 break;
5672 case 1:
7a387fff
TS
5673 case 3:
5674 case 5:
5675 case 7:
7db13fae 5676 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
873eb012
TS
5677 rn = "DataLo";
5678 break;
5679 default:
f31b035a 5680 goto cp0_unimplemented;
873eb012
TS
5681 }
5682 break;
8c0fdd85 5683 case 29:
7a387fff
TS
5684 switch (sel) {
5685 case 0:
5686 case 2:
5687 case 4:
5688 case 6:
7db13fae 5689 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
7a387fff
TS
5690 rn = "TagHi";
5691 break;
5692 case 1:
5693 case 3:
5694 case 5:
5695 case 7:
7db13fae 5696 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
7a387fff
TS
5697 rn = "DataHi";
5698 break;
5699 default:
f31b035a 5700 goto cp0_unimplemented;
7a387fff 5701 }
8c0fdd85 5702 break;
873eb012 5703 case 30:
7a387fff
TS
5704 switch (sel) {
5705 case 0:
7db13fae 5706 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
d9bea114 5707 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
5708 rn = "ErrorEPC";
5709 break;
7a387fff 5710 default:
f31b035a 5711 goto cp0_unimplemented;
7a387fff 5712 }
873eb012
TS
5713 break;
5714 case 31:
7a387fff
TS
5715 switch (sel) {
5716 case 0:
f0b3f3ae 5717 /* EJTAG support */
7db13fae 5718 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
5719 rn = "DESAVE";
5720 break;
c2e19f3c
AM
5721 case 2:
5722 case 3:
5723 case 4:
5724 case 5:
5725 case 6:
5726 case 7:
f31b035a
LA
5727 CP0_CHECK(ctx->kscrexist & (1 << sel));
5728 tcg_gen_ld_tl(arg, cpu_env,
5729 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
5730 tcg_gen_ext32s_tl(arg, arg);
5731 rn = "KScratch";
e98c0d17 5732 break;
7a387fff 5733 default:
f31b035a 5734 goto cp0_unimplemented;
7a387fff 5735 }
873eb012
TS
5736 break;
5737 default:
f31b035a 5738 goto cp0_unimplemented;
873eb012 5739 }
b44a7fb1 5740 trace_mips_translate_c0("mfc0", rn, reg, sel);
873eb012
TS
5741 return;
5742
f31b035a 5743cp0_unimplemented:
965447ee 5744 qemu_log_mask(LOG_UNIMP, "mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
f31b035a 5745 gen_mfc0_unimplemented(ctx, arg);
873eb012
TS
5746}
5747
d75c135e 5748static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
8c0fdd85 5749{
7a387fff
TS
5750 const char *rn = "invalid";
5751
e189e748 5752 if (sel != 0)
d75c135e 5753 check_insn(ctx, ISA_MIPS32);
e189e748 5754
eeb3bba8 5755 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
2e70f6ef 5756 gen_io_start();
bd79255d 5757 }
2e70f6ef 5758
8c0fdd85
TS
5759 switch (reg) {
5760 case 0:
7a387fff
TS
5761 switch (sel) {
5762 case 0:
895c2d04 5763 gen_helper_mtc0_index(cpu_env, arg);
7a387fff
TS
5764 rn = "Index";
5765 break;
5766 case 1:
f31b035a 5767 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5768 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
7a387fff 5769 rn = "MVPControl";
ead9360e 5770 break;
7a387fff 5771 case 2:
f31b035a 5772 CP0_CHECK(ctx->insn_flags & ASE_MT);
ead9360e 5773 /* ignored */
7a387fff 5774 rn = "MVPConf0";
ead9360e 5775 break;
7a387fff 5776 case 3:
f31b035a 5777 CP0_CHECK(ctx->insn_flags & ASE_MT);
ead9360e 5778 /* ignored */
7a387fff 5779 rn = "MVPConf1";
ead9360e 5780 break;
01bc435b
YK
5781 case 4:
5782 CP0_CHECK(ctx->vp);
5783 /* ignored */
5784 rn = "VPControl";
5785 break;
7a387fff 5786 default:
f31b035a 5787 goto cp0_unimplemented;
7a387fff 5788 }
8c0fdd85
TS
5789 break;
5790 case 1:
7a387fff
TS
5791 switch (sel) {
5792 case 0:
2423f660 5793 /* ignored */
7a387fff 5794 rn = "Random";
2423f660 5795 break;
7a387fff 5796 case 1:
f31b035a 5797 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5798 gen_helper_mtc0_vpecontrol(cpu_env, arg);
7a387fff 5799 rn = "VPEControl";
ead9360e 5800 break;
7a387fff 5801 case 2:
f31b035a 5802 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5803 gen_helper_mtc0_vpeconf0(cpu_env, arg);
7a387fff 5804 rn = "VPEConf0";
ead9360e 5805 break;
7a387fff 5806 case 3:
f31b035a 5807 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5808 gen_helper_mtc0_vpeconf1(cpu_env, arg);
7a387fff 5809 rn = "VPEConf1";
ead9360e 5810 break;
7a387fff 5811 case 4:
f31b035a 5812 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5813 gen_helper_mtc0_yqmask(cpu_env, arg);
7a387fff 5814 rn = "YQMask";
ead9360e 5815 break;
7a387fff 5816 case 5:
f31b035a 5817 CP0_CHECK(ctx->insn_flags & ASE_MT);
d54a299b
LA
5818 tcg_gen_st_tl(arg, cpu_env,
5819 offsetof(CPUMIPSState, CP0_VPESchedule));
7a387fff 5820 rn = "VPESchedule";
ead9360e 5821 break;
7a387fff 5822 case 6:
f31b035a 5823 CP0_CHECK(ctx->insn_flags & ASE_MT);
d54a299b
LA
5824 tcg_gen_st_tl(arg, cpu_env,
5825 offsetof(CPUMIPSState, CP0_VPEScheFBack));
7a387fff 5826 rn = "VPEScheFBack";
ead9360e 5827 break;
7a387fff 5828 case 7:
f31b035a 5829 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5830 gen_helper_mtc0_vpeopt(cpu_env, arg);
7a387fff 5831 rn = "VPEOpt";
ead9360e 5832 break;
7a387fff 5833 default:
f31b035a 5834 goto cp0_unimplemented;
7a387fff 5835 }
8c0fdd85
TS
5836 break;
5837 case 2:
7a387fff
TS
5838 switch (sel) {
5839 case 0:
895c2d04 5840 gen_helper_mtc0_entrylo0(cpu_env, arg);
2423f660
TS
5841 rn = "EntryLo0";
5842 break;
7a387fff 5843 case 1:
f31b035a 5844 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5845 gen_helper_mtc0_tcstatus(cpu_env, arg);
2423f660 5846 rn = "TCStatus";
ead9360e 5847 break;
7a387fff 5848 case 2:
f31b035a 5849 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5850 gen_helper_mtc0_tcbind(cpu_env, arg);
2423f660 5851 rn = "TCBind";
ead9360e 5852 break;
7a387fff 5853 case 3:
f31b035a 5854 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5855 gen_helper_mtc0_tcrestart(cpu_env, arg);
2423f660 5856 rn = "TCRestart";
ead9360e 5857 break;
7a387fff 5858 case 4:
f31b035a 5859 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5860 gen_helper_mtc0_tchalt(cpu_env, arg);
2423f660 5861 rn = "TCHalt";
ead9360e 5862 break;
7a387fff 5863 case 5:
f31b035a 5864 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5865 gen_helper_mtc0_tccontext(cpu_env, arg);
2423f660 5866 rn = "TCContext";
ead9360e 5867 break;
7a387fff 5868 case 6:
f31b035a 5869 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5870 gen_helper_mtc0_tcschedule(cpu_env, arg);
2423f660 5871 rn = "TCSchedule";
ead9360e 5872 break;
7a387fff 5873 case 7:
f31b035a 5874 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5875 gen_helper_mtc0_tcschefback(cpu_env, arg);
2423f660 5876 rn = "TCScheFBack";
ead9360e 5877 break;
7a387fff 5878 default:
f31b035a 5879 goto cp0_unimplemented;
7a387fff 5880 }
8c0fdd85
TS
5881 break;
5882 case 3:
7a387fff
TS
5883 switch (sel) {
5884 case 0:
895c2d04 5885 gen_helper_mtc0_entrylo1(cpu_env, arg);
2423f660
TS
5886 rn = "EntryLo1";
5887 break;
01bc435b
YK
5888 case 1:
5889 CP0_CHECK(ctx->vp);
5890 /* ignored */
5891 rn = "GlobalNumber";
5892 break;
7a387fff 5893 default:
f31b035a 5894 goto cp0_unimplemented;
876d4b07 5895 }
8c0fdd85
TS
5896 break;
5897 case 4:
7a387fff
TS
5898 switch (sel) {
5899 case 0:
895c2d04 5900 gen_helper_mtc0_context(cpu_env, arg);
2423f660
TS
5901 rn = "Context";
5902 break;
7a387fff 5903 case 1:
895c2d04 5904// gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
2423f660 5905 rn = "ContextConfig";
f31b035a 5906 goto cp0_unimplemented;
d279279e 5907 case 2:
f31b035a
LA
5908 CP0_CHECK(ctx->ulri);
5909 tcg_gen_st_tl(arg, cpu_env,
5910 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
5911 rn = "UserLocal";
d279279e 5912 break;
7a387fff 5913 default:
f31b035a 5914 goto cp0_unimplemented;
876d4b07 5915 }
8c0fdd85
TS
5916 break;
5917 case 5:
7a387fff
TS
5918 switch (sel) {
5919 case 0:
895c2d04 5920 gen_helper_mtc0_pagemask(cpu_env, arg);
2423f660
TS
5921 rn = "PageMask";
5922 break;
7a387fff 5923 case 1:
d75c135e 5924 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5925 gen_helper_mtc0_pagegrain(cpu_env, arg);
2423f660 5926 rn = "PageGrain";
eeb3bba8 5927 ctx->base.is_jmp = DISAS_STOP;
2423f660 5928 break;
cec56a73
JH
5929 case 2:
5930 CP0_CHECK(ctx->sc);
5931 gen_helper_mtc0_segctl0(cpu_env, arg);
5932 rn = "SegCtl0";
5933 break;
5934 case 3:
5935 CP0_CHECK(ctx->sc);
5936 gen_helper_mtc0_segctl1(cpu_env, arg);
5937 rn = "SegCtl1";
5938 break;
5939 case 4:
5940 CP0_CHECK(ctx->sc);
5941 gen_helper_mtc0_segctl2(cpu_env, arg);
5942 rn = "SegCtl2";
5943 break;
7a387fff 5944 default:
f31b035a 5945 goto cp0_unimplemented;
876d4b07 5946 }
8c0fdd85
TS
5947 break;
5948 case 6:
7a387fff
TS
5949 switch (sel) {
5950 case 0:
895c2d04 5951 gen_helper_mtc0_wired(cpu_env, arg);
2423f660
TS
5952 rn = "Wired";
5953 break;
7a387fff 5954 case 1:
d75c135e 5955 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5956 gen_helper_mtc0_srsconf0(cpu_env, arg);
2423f660 5957 rn = "SRSConf0";
ead9360e 5958 break;
7a387fff 5959 case 2:
d75c135e 5960 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5961 gen_helper_mtc0_srsconf1(cpu_env, arg);
2423f660 5962 rn = "SRSConf1";
ead9360e 5963 break;
7a387fff 5964 case 3:
d75c135e 5965 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5966 gen_helper_mtc0_srsconf2(cpu_env, arg);
2423f660 5967 rn = "SRSConf2";
ead9360e 5968 break;
7a387fff 5969 case 4:
d75c135e 5970 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5971 gen_helper_mtc0_srsconf3(cpu_env, arg);
2423f660 5972 rn = "SRSConf3";
ead9360e 5973 break;
7a387fff 5974 case 5:
d75c135e 5975 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5976 gen_helper_mtc0_srsconf4(cpu_env, arg);
2423f660 5977 rn = "SRSConf4";
ead9360e 5978 break;
7a387fff 5979 default:
f31b035a 5980 goto cp0_unimplemented;
876d4b07 5981 }
8c0fdd85
TS
5982 break;
5983 case 7:
7a387fff
TS
5984 switch (sel) {
5985 case 0:
d75c135e 5986 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5987 gen_helper_mtc0_hwrena(cpu_env, arg);
eeb3bba8 5988 ctx->base.is_jmp = DISAS_STOP;
2423f660
TS
5989 rn = "HWREna";
5990 break;
7a387fff 5991 default:
f31b035a 5992 goto cp0_unimplemented;
876d4b07 5993 }
8c0fdd85
TS
5994 break;
5995 case 8:
aea14095
LA
5996 switch (sel) {
5997 case 0:
5998 /* ignored */
5999 rn = "BadVAddr";
6000 break;
6001 case 1:
6002 /* ignored */
6003 rn = "BadInstr";
6004 break;
6005 case 2:
6006 /* ignored */
6007 rn = "BadInstrP";
6008 break;
6009 default:
f31b035a 6010 goto cp0_unimplemented;
aea14095 6011 }
8c0fdd85
TS
6012 break;
6013 case 9:
7a387fff
TS
6014 switch (sel) {
6015 case 0:
895c2d04 6016 gen_helper_mtc0_count(cpu_env, arg);
2423f660
TS
6017 rn = "Count";
6018 break;
876d4b07 6019 /* 6,7 are implementation dependent */
7a387fff 6020 default:
f31b035a 6021 goto cp0_unimplemented;
876d4b07 6022 }
8c0fdd85
TS
6023 break;
6024 case 10:
7a387fff
TS
6025 switch (sel) {
6026 case 0:
895c2d04 6027 gen_helper_mtc0_entryhi(cpu_env, arg);
2423f660
TS
6028 rn = "EntryHi";
6029 break;
7a387fff 6030 default:
f31b035a 6031 goto cp0_unimplemented;
876d4b07 6032 }
8c0fdd85
TS
6033 break;
6034 case 11:
7a387fff
TS
6035 switch (sel) {
6036 case 0:
895c2d04 6037 gen_helper_mtc0_compare(cpu_env, arg);
2423f660
TS
6038 rn = "Compare";
6039 break;
6040 /* 6,7 are implementation dependent */
7a387fff 6041 default:
f31b035a 6042 goto cp0_unimplemented;
876d4b07 6043 }
8c0fdd85
TS
6044 break;
6045 case 12:
7a387fff
TS
6046 switch (sel) {
6047 case 0:
867abc7e 6048 save_cpu_state(ctx, 1);
895c2d04 6049 gen_helper_mtc0_status(cpu_env, arg);
b28425ba 6050 /* DISAS_STOP isn't good enough here, hflags may have changed. */
eeb3bba8
EC
6051 gen_save_pc(ctx->base.pc_next + 4);
6052 ctx->base.is_jmp = DISAS_EXIT;
2423f660
TS
6053 rn = "Status";
6054 break;
7a387fff 6055 case 1:
d75c135e 6056 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6057 gen_helper_mtc0_intctl(cpu_env, arg);
8487327a 6058 /* Stop translation as we may have switched the execution mode */
eeb3bba8 6059 ctx->base.is_jmp = DISAS_STOP;
2423f660
TS
6060 rn = "IntCtl";
6061 break;
7a387fff 6062 case 2:
d75c135e 6063 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6064 gen_helper_mtc0_srsctl(cpu_env, arg);
8487327a 6065 /* Stop translation as we may have switched the execution mode */
eeb3bba8 6066 ctx->base.is_jmp = DISAS_STOP;
2423f660
TS
6067 rn = "SRSCtl";
6068 break;
7a387fff 6069 case 3:
d75c135e 6070 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6071 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
8487327a 6072 /* Stop translation as we may have switched the execution mode */
eeb3bba8 6073 ctx->base.is_jmp = DISAS_STOP;
2423f660 6074 rn = "SRSMap";
fd88b6ab 6075 break;
7a387fff 6076 default:
f31b035a 6077 goto cp0_unimplemented;
876d4b07 6078 }
8c0fdd85
TS
6079 break;
6080 case 13:
7a387fff
TS
6081 switch (sel) {
6082 case 0:
867abc7e 6083 save_cpu_state(ctx, 1);
895c2d04 6084 gen_helper_mtc0_cause(cpu_env, arg);
b28425ba
EC
6085 /* Stop translation as we may have triggered an interrupt.
6086 * DISAS_STOP isn't sufficient, we need to ensure we break out of
6087 * translated code to check for pending interrupts. */
eeb3bba8
EC
6088 gen_save_pc(ctx->base.pc_next + 4);
6089 ctx->base.is_jmp = DISAS_EXIT;
2423f660
TS
6090 rn = "Cause";
6091 break;
7a387fff 6092 default:
f31b035a 6093 goto cp0_unimplemented;
876d4b07 6094 }
8c0fdd85
TS
6095 break;
6096 case 14:
7a387fff
TS
6097 switch (sel) {
6098 case 0:
d54a299b 6099 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
2423f660
TS
6100 rn = "EPC";
6101 break;
7a387fff 6102 default:
f31b035a 6103 goto cp0_unimplemented;
876d4b07 6104 }
8c0fdd85
TS
6105 break;
6106 case 15:
7a387fff
TS
6107 switch (sel) {
6108 case 0:
2423f660
TS
6109 /* ignored */
6110 rn = "PRid";
6111 break;
7a387fff 6112 case 1:
d75c135e 6113 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6114 gen_helper_mtc0_ebase(cpu_env, arg);
2423f660
TS
6115 rn = "EBase";
6116 break;
7a387fff 6117 default:
f31b035a 6118 goto cp0_unimplemented;
1579a72e 6119 }
8c0fdd85
TS
6120 break;
6121 case 16:
6122 switch (sel) {
6123 case 0:
895c2d04 6124 gen_helper_mtc0_config0(cpu_env, arg);
7a387fff 6125 rn = "Config";
2423f660 6126 /* Stop translation as we may have switched the execution mode */
eeb3bba8 6127 ctx->base.is_jmp = DISAS_STOP;
7a387fff
TS
6128 break;
6129 case 1:
e397ee33 6130 /* ignored, read only */
7a387fff
TS
6131 rn = "Config1";
6132 break;
6133 case 2:
895c2d04 6134 gen_helper_mtc0_config2(cpu_env, arg);
7a387fff 6135 rn = "Config2";
2423f660 6136 /* Stop translation as we may have switched the execution mode */
eeb3bba8 6137 ctx->base.is_jmp = DISAS_STOP;
8c0fdd85 6138 break;
7a387fff 6139 case 3:
90f12d73 6140 gen_helper_mtc0_config3(cpu_env, arg);
7a387fff 6141 rn = "Config3";
90f12d73 6142 /* Stop translation as we may have switched the execution mode */
eeb3bba8 6143 ctx->base.is_jmp = DISAS_STOP;
7a387fff 6144 break;
b4160af1
PJ
6145 case 4:
6146 gen_helper_mtc0_config4(cpu_env, arg);
6147 rn = "Config4";
eeb3bba8 6148 ctx->base.is_jmp = DISAS_STOP;
b4160af1 6149 break;
b4dd99a3
PJ
6150 case 5:
6151 gen_helper_mtc0_config5(cpu_env, arg);
6152 rn = "Config5";
6153 /* Stop translation as we may have switched the execution mode */
eeb3bba8 6154 ctx->base.is_jmp = DISAS_STOP;
b4dd99a3 6155 break;
e397ee33
TS
6156 /* 6,7 are implementation dependent */
6157 case 6:
6158 /* ignored */
6159 rn = "Config6";
6160 break;
6161 case 7:
6162 /* ignored */
6163 rn = "Config7";
6164 break;
8c0fdd85
TS
6165 default:
6166 rn = "Invalid config selector";
f31b035a 6167 goto cp0_unimplemented;
8c0fdd85
TS
6168 }
6169 break;
6170 case 17:
7a387fff
TS
6171 switch (sel) {
6172 case 0:
895c2d04 6173 gen_helper_mtc0_lladdr(cpu_env, arg);
2423f660
TS
6174 rn = "LLAddr";
6175 break;
f6d4dd81
YK
6176 case 1:
6177 CP0_CHECK(ctx->mrp);
6178 gen_helper_mtc0_maar(cpu_env, arg);
6179 rn = "MAAR";
6180 break;
6181 case 2:
6182 CP0_CHECK(ctx->mrp);
6183 gen_helper_mtc0_maari(cpu_env, arg);
6184 rn = "MAARI";
6185 break;
7a387fff 6186 default:
f31b035a 6187 goto cp0_unimplemented;
7a387fff 6188 }
8c0fdd85
TS
6189 break;
6190 case 18:
7a387fff 6191 switch (sel) {
c2e19f3c
AM
6192 case 0:
6193 case 1:
6194 case 2:
6195 case 3:
6196 case 4:
6197 case 5:
6198 case 6:
6199 case 7:
895c2d04 6200 gen_helper_0e1i(mtc0_watchlo, arg, sel);
2423f660
TS
6201 rn = "WatchLo";
6202 break;
7a387fff 6203 default:
f31b035a 6204 goto cp0_unimplemented;
7a387fff 6205 }
8c0fdd85
TS
6206 break;
6207 case 19:
7a387fff 6208 switch (sel) {
c2e19f3c
AM
6209 case 0:
6210 case 1:
6211 case 2:
6212 case 3:
6213 case 4:
6214 case 5:
6215 case 6:
6216 case 7:
895c2d04 6217 gen_helper_0e1i(mtc0_watchhi, arg, sel);
2423f660
TS
6218 rn = "WatchHi";
6219 break;
7a387fff 6220 default:
f31b035a 6221 goto cp0_unimplemented;
7a387fff 6222 }
8c0fdd85
TS
6223 break;
6224 case 20:
7a387fff
TS
6225 switch (sel) {
6226 case 0:
d26bc211 6227#if defined(TARGET_MIPS64)
d75c135e 6228 check_insn(ctx, ISA_MIPS3);
895c2d04 6229 gen_helper_mtc0_xcontext(cpu_env, arg);
2423f660
TS
6230 rn = "XContext";
6231 break;
703eaf37 6232#endif
7a387fff 6233 default:
f31b035a 6234 goto cp0_unimplemented;
7a387fff 6235 }
8c0fdd85
TS
6236 break;
6237 case 21:
7a387fff 6238 /* Officially reserved, but sel 0 is used for R1x000 framemask */
f31b035a 6239 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
7a387fff
TS
6240 switch (sel) {
6241 case 0:
895c2d04 6242 gen_helper_mtc0_framemask(cpu_env, arg);
2423f660
TS
6243 rn = "Framemask";
6244 break;
7a387fff 6245 default:
f31b035a 6246 goto cp0_unimplemented;
7a387fff
TS
6247 }
6248 break;
8c0fdd85 6249 case 22:
7a387fff
TS
6250 /* ignored */
6251 rn = "Diagnostic"; /* implementation dependent */
2423f660 6252 break;
8c0fdd85 6253 case 23:
7a387fff
TS
6254 switch (sel) {
6255 case 0:
895c2d04 6256 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
b28425ba 6257 /* DISAS_STOP isn't good enough here, hflags may have changed. */
eeb3bba8
EC
6258 gen_save_pc(ctx->base.pc_next + 4);
6259 ctx->base.is_jmp = DISAS_EXIT;
2423f660
TS
6260 rn = "Debug";
6261 break;
7a387fff 6262 case 1:
895c2d04 6263// gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
2423f660 6264 rn = "TraceControl";
8487327a 6265 /* Stop translation as we may have switched the execution mode */
eeb3bba8 6266 ctx->base.is_jmp = DISAS_STOP;
3570d7f6 6267 goto cp0_unimplemented;
7a387fff 6268 case 2:
895c2d04 6269// gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
2423f660 6270 rn = "TraceControl2";
8487327a 6271 /* Stop translation as we may have switched the execution mode */
eeb3bba8 6272 ctx->base.is_jmp = DISAS_STOP;
3570d7f6 6273 goto cp0_unimplemented;
7a387fff 6274 case 3:
8487327a 6275 /* Stop translation as we may have switched the execution mode */
eeb3bba8 6276 ctx->base.is_jmp = DISAS_STOP;
895c2d04 6277// gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
2423f660 6278 rn = "UserTraceData";
8487327a 6279 /* Stop translation as we may have switched the execution mode */
eeb3bba8 6280 ctx->base.is_jmp = DISAS_STOP;
3570d7f6 6281 goto cp0_unimplemented;
7a387fff 6282 case 4:
895c2d04 6283// gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
8487327a 6284 /* Stop translation as we may have switched the execution mode */
eeb3bba8 6285 ctx->base.is_jmp = DISAS_STOP;
2423f660 6286 rn = "TraceBPC";
3570d7f6 6287 goto cp0_unimplemented;
7a387fff 6288 default:
f31b035a 6289 goto cp0_unimplemented;
7a387fff 6290 }
8c0fdd85
TS
6291 break;
6292 case 24:
7a387fff
TS
6293 switch (sel) {
6294 case 0:
f1aa6320 6295 /* EJTAG support */
d54a299b 6296 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
2423f660
TS
6297 rn = "DEPC";
6298 break;
7a387fff 6299 default:
f31b035a 6300 goto cp0_unimplemented;
7a387fff 6301 }
8c0fdd85
TS
6302 break;
6303 case 25:
7a387fff
TS
6304 switch (sel) {
6305 case 0:
895c2d04 6306 gen_helper_mtc0_performance0(cpu_env, arg);
2423f660
TS
6307 rn = "Performance0";
6308 break;
7a387fff 6309 case 1:
d9bea114 6310// gen_helper_mtc0_performance1(arg);
2423f660 6311 rn = "Performance1";
3570d7f6 6312 goto cp0_unimplemented;
7a387fff 6313 case 2:
d9bea114 6314// gen_helper_mtc0_performance2(arg);
2423f660 6315 rn = "Performance2";
3570d7f6 6316 goto cp0_unimplemented;
7a387fff 6317 case 3:
d9bea114 6318// gen_helper_mtc0_performance3(arg);
2423f660 6319 rn = "Performance3";
3570d7f6 6320 goto cp0_unimplemented;
7a387fff 6321 case 4:
d9bea114 6322// gen_helper_mtc0_performance4(arg);
2423f660 6323 rn = "Performance4";
3570d7f6 6324 goto cp0_unimplemented;
7a387fff 6325 case 5:
d9bea114 6326// gen_helper_mtc0_performance5(arg);
2423f660 6327 rn = "Performance5";
3570d7f6 6328 goto cp0_unimplemented;
7a387fff 6329 case 6:
d9bea114 6330// gen_helper_mtc0_performance6(arg);
2423f660 6331 rn = "Performance6";
3570d7f6 6332 goto cp0_unimplemented;
7a387fff 6333 case 7:
d9bea114 6334// gen_helper_mtc0_performance7(arg);
2423f660 6335 rn = "Performance7";
3570d7f6 6336 goto cp0_unimplemented;
7a387fff 6337 default:
f31b035a 6338 goto cp0_unimplemented;
7a387fff 6339 }
8c0fdd85
TS
6340 break;
6341 case 26:
0d74a222
LA
6342 switch (sel) {
6343 case 0:
6344 gen_helper_mtc0_errctl(cpu_env, arg);
eeb3bba8 6345 ctx->base.is_jmp = DISAS_STOP;
0d74a222
LA
6346 rn = "ErrCtl";
6347 break;
6348 default:
6349 goto cp0_unimplemented;
6350 }
2423f660 6351 break;
8c0fdd85 6352 case 27:
7a387fff 6353 switch (sel) {
c2e19f3c
AM
6354 case 0:
6355 case 1:
6356 case 2:
6357 case 3:
2423f660
TS
6358 /* ignored */
6359 rn = "CacheErr";
6360 break;
7a387fff 6361 default:
f31b035a 6362 goto cp0_unimplemented;
7a387fff 6363 }
8c0fdd85
TS
6364 break;
6365 case 28:
6366 switch (sel) {
6367 case 0:
7a387fff
TS
6368 case 2:
6369 case 4:
6370 case 6:
895c2d04 6371 gen_helper_mtc0_taglo(cpu_env, arg);
8c0fdd85
TS
6372 rn = "TagLo";
6373 break;
7a387fff
TS
6374 case 1:
6375 case 3:
6376 case 5:
6377 case 7:
895c2d04 6378 gen_helper_mtc0_datalo(cpu_env, arg);
7a387fff
TS
6379 rn = "DataLo";
6380 break;
8c0fdd85 6381 default:
f31b035a 6382 goto cp0_unimplemented;
8c0fdd85
TS
6383 }
6384 break;
6385 case 29:
7a387fff
TS
6386 switch (sel) {
6387 case 0:
6388 case 2:
6389 case 4:
6390 case 6:
895c2d04 6391 gen_helper_mtc0_taghi(cpu_env, arg);
7a387fff
TS
6392 rn = "TagHi";
6393 break;
6394 case 1:
6395 case 3:
6396 case 5:
6397 case 7:
895c2d04 6398 gen_helper_mtc0_datahi(cpu_env, arg);
7a387fff
TS
6399 rn = "DataHi";
6400 break;
6401 default:
6402 rn = "invalid sel";
f31b035a 6403 goto cp0_unimplemented;
7a387fff 6404 }
8c0fdd85
TS
6405 break;
6406 case 30:
7a387fff
TS
6407 switch (sel) {
6408 case 0:
d54a299b 6409 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
2423f660
TS
6410 rn = "ErrorEPC";
6411 break;
7a387fff 6412 default:
f31b035a 6413 goto cp0_unimplemented;
7a387fff 6414 }
8c0fdd85
TS
6415 break;
6416 case 31:
7a387fff
TS
6417 switch (sel) {
6418 case 0:
f1aa6320 6419 /* EJTAG support */
7db13fae 6420 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
6421 rn = "DESAVE";
6422 break;
c2e19f3c
AM
6423 case 2:
6424 case 3:
6425 case 4:
6426 case 5:
6427 case 6:
6428 case 7:
f31b035a
LA
6429 CP0_CHECK(ctx->kscrexist & (1 << sel));
6430 tcg_gen_st_tl(arg, cpu_env,
6431 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
6432 rn = "KScratch";
e98c0d17 6433 break;
7a387fff 6434 default:
f31b035a 6435 goto cp0_unimplemented;
7a387fff 6436 }
8c0fdd85
TS
6437 break;
6438 default:
f31b035a 6439 goto cp0_unimplemented;
8c0fdd85 6440 }
b44a7fb1
PMD
6441 trace_mips_translate_c0("mtc0", rn, reg, sel);
6442
bf20dc07 6443 /* For simplicity assume that all writes can cause interrupts. */
eeb3bba8 6444 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
2e70f6ef 6445 gen_io_end();
b28425ba 6446 /* DISAS_STOP isn't sufficient, we need to ensure we break out of
b74cddcb 6447 * translated code to check for pending interrupts. */
eeb3bba8
EC
6448 gen_save_pc(ctx->base.pc_next + 4);
6449 ctx->base.is_jmp = DISAS_EXIT;
2e70f6ef 6450 }
8c0fdd85
TS
6451 return;
6452
f31b035a 6453cp0_unimplemented:
965447ee 6454 qemu_log_mask(LOG_UNIMP, "mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
8c0fdd85
TS
6455}
6456
d26bc211 6457#if defined(TARGET_MIPS64)
d75c135e 6458static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
9c2149c8
TS
6459{
6460 const char *rn = "invalid";
6461
e189e748 6462 if (sel != 0)
d75c135e 6463 check_insn(ctx, ISA_MIPS64);
e189e748 6464
9c2149c8
TS
6465 switch (reg) {
6466 case 0:
6467 switch (sel) {
6468 case 0:
7db13fae 6469 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
9c2149c8
TS
6470 rn = "Index";
6471 break;
6472 case 1:
f31b035a 6473 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6474 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
9c2149c8 6475 rn = "MVPControl";
ead9360e 6476 break;
9c2149c8 6477 case 2:
f31b035a 6478 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6479 gen_helper_mfc0_mvpconf0(arg, cpu_env);
9c2149c8 6480 rn = "MVPConf0";
ead9360e 6481 break;
9c2149c8 6482 case 3:
f31b035a 6483 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6484 gen_helper_mfc0_mvpconf1(arg, cpu_env);
9c2149c8 6485 rn = "MVPConf1";
ead9360e 6486 break;
01bc435b
YK
6487 case 4:
6488 CP0_CHECK(ctx->vp);
6489 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl));
6490 rn = "VPControl";
6491 break;
9c2149c8 6492 default:
f31b035a 6493 goto cp0_unimplemented;
9c2149c8
TS
6494 }
6495 break;
6496 case 1:
6497 switch (sel) {
6498 case 0:
f31b035a 6499 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
895c2d04 6500 gen_helper_mfc0_random(arg, cpu_env);
9c2149c8 6501 rn = "Random";
2423f660 6502 break;
9c2149c8 6503 case 1:
f31b035a 6504 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6505 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
9c2149c8 6506 rn = "VPEControl";
ead9360e 6507 break;
9c2149c8 6508 case 2:
f31b035a 6509 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6510 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
9c2149c8 6511 rn = "VPEConf0";
ead9360e 6512 break;
9c2149c8 6513 case 3:
f31b035a 6514 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6515 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
9c2149c8 6516 rn = "VPEConf1";
ead9360e 6517 break;
9c2149c8 6518 case 4:
f31b035a 6519 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6520 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_YQMask));
9c2149c8 6521 rn = "YQMask";
ead9360e 6522 break;
9c2149c8 6523 case 5:
f31b035a 6524 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6525 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
9c2149c8 6526 rn = "VPESchedule";
ead9360e 6527 break;
9c2149c8 6528 case 6:
f31b035a 6529 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6530 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
9c2149c8 6531 rn = "VPEScheFBack";
ead9360e 6532 break;
9c2149c8 6533 case 7:
f31b035a 6534 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6535 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
9c2149c8 6536 rn = "VPEOpt";
ead9360e 6537 break;
9c2149c8 6538 default:
f31b035a 6539 goto cp0_unimplemented;
9c2149c8
TS
6540 }
6541 break;
6542 case 2:
6543 switch (sel) {
6544 case 0:
7db13fae 6545 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
2423f660
TS
6546 rn = "EntryLo0";
6547 break;
9c2149c8 6548 case 1:
f31b035a 6549 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6550 gen_helper_mfc0_tcstatus(arg, cpu_env);
2423f660 6551 rn = "TCStatus";
ead9360e 6552 break;
9c2149c8 6553 case 2:
f31b035a 6554 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6555 gen_helper_mfc0_tcbind(arg, cpu_env);
2423f660 6556 rn = "TCBind";
ead9360e 6557 break;
9c2149c8 6558 case 3:
f31b035a 6559 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6560 gen_helper_dmfc0_tcrestart(arg, cpu_env);
2423f660 6561 rn = "TCRestart";
ead9360e 6562 break;
9c2149c8 6563 case 4:
f31b035a 6564 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6565 gen_helper_dmfc0_tchalt(arg, cpu_env);
2423f660 6566 rn = "TCHalt";
ead9360e 6567 break;
9c2149c8 6568 case 5:
f31b035a 6569 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6570 gen_helper_dmfc0_tccontext(arg, cpu_env);
2423f660 6571 rn = "TCContext";
ead9360e 6572 break;
9c2149c8 6573 case 6:
f31b035a 6574 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6575 gen_helper_dmfc0_tcschedule(arg, cpu_env);
2423f660 6576 rn = "TCSchedule";
ead9360e 6577 break;
9c2149c8 6578 case 7:
f31b035a 6579 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6580 gen_helper_dmfc0_tcschefback(arg, cpu_env);
2423f660 6581 rn = "TCScheFBack";
ead9360e 6582 break;
9c2149c8 6583 default:
f31b035a 6584 goto cp0_unimplemented;
9c2149c8
TS
6585 }
6586 break;
6587 case 3:
6588 switch (sel) {
6589 case 0:
7db13fae 6590 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
2423f660
TS
6591 rn = "EntryLo1";
6592 break;
01bc435b
YK
6593 case 1:
6594 CP0_CHECK(ctx->vp);
6595 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber));
6596 rn = "GlobalNumber";
6597 break;
9c2149c8 6598 default:
f31b035a 6599 goto cp0_unimplemented;
1579a72e 6600 }
9c2149c8
TS
6601 break;
6602 case 4:
6603 switch (sel) {
6604 case 0:
7db13fae 6605 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
2423f660
TS
6606 rn = "Context";
6607 break;
9c2149c8 6608 case 1:
d9bea114 6609// gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
2423f660 6610 rn = "ContextConfig";
f31b035a 6611 goto cp0_unimplemented;
d279279e 6612 case 2:
f31b035a
LA
6613 CP0_CHECK(ctx->ulri);
6614 tcg_gen_ld_tl(arg, cpu_env,
6615 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
6616 rn = "UserLocal";
d279279e 6617 break;
9c2149c8 6618 default:
f31b035a 6619 goto cp0_unimplemented;
876d4b07 6620 }
9c2149c8
TS
6621 break;
6622 case 5:
6623 switch (sel) {
6624 case 0:
7db13fae 6625 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
2423f660
TS
6626 rn = "PageMask";
6627 break;
9c2149c8 6628 case 1:
d75c135e 6629 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6630 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
2423f660
TS
6631 rn = "PageGrain";
6632 break;
cec56a73
JH
6633 case 2:
6634 CP0_CHECK(ctx->sc);
6635 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl0));
6636 rn = "SegCtl0";
6637 break;
6638 case 3:
6639 CP0_CHECK(ctx->sc);
6640 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl1));
6641 rn = "SegCtl1";
6642 break;
6643 case 4:
6644 CP0_CHECK(ctx->sc);
6645 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl2));
6646 rn = "SegCtl2";
6647 break;
9c2149c8 6648 default:
f31b035a 6649 goto cp0_unimplemented;
876d4b07 6650 }
9c2149c8
TS
6651 break;
6652 case 6:
6653 switch (sel) {
6654 case 0:
7db13fae 6655 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
2423f660
TS
6656 rn = "Wired";
6657 break;
9c2149c8 6658 case 1:
d75c135e 6659 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6660 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
2423f660 6661 rn = "SRSConf0";
ead9360e 6662 break;
9c2149c8 6663 case 2:
d75c135e 6664 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6665 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
2423f660 6666 rn = "SRSConf1";
ead9360e 6667 break;
9c2149c8 6668 case 3:
d75c135e 6669 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6670 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
2423f660 6671 rn = "SRSConf2";
ead9360e 6672 break;
9c2149c8 6673 case 4:
d75c135e 6674 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6675 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
2423f660 6676 rn = "SRSConf3";
ead9360e 6677 break;
9c2149c8 6678 case 5:
d75c135e 6679 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6680 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
2423f660 6681 rn = "SRSConf4";
ead9360e 6682 break;
9c2149c8 6683 default:
f31b035a 6684 goto cp0_unimplemented;
876d4b07 6685 }
9c2149c8
TS
6686 break;
6687 case 7:
6688 switch (sel) {
6689 case 0:
d75c135e 6690 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6691 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
2423f660
TS
6692 rn = "HWREna";
6693 break;
9c2149c8 6694 default:
f31b035a 6695 goto cp0_unimplemented;
876d4b07 6696 }
9c2149c8
TS
6697 break;
6698 case 8:
6699 switch (sel) {
6700 case 0:
7db13fae 6701 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
f0b3f3ae 6702 rn = "BadVAddr";
2423f660 6703 break;
aea14095 6704 case 1:
f31b035a
LA
6705 CP0_CHECK(ctx->bi);
6706 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
6707 rn = "BadInstr";
aea14095
LA
6708 break;
6709 case 2:
f31b035a
LA
6710 CP0_CHECK(ctx->bp);
6711 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
6712 rn = "BadInstrP";
aea14095 6713 break;
9c2149c8 6714 default:
f31b035a 6715 goto cp0_unimplemented;
876d4b07 6716 }
9c2149c8
TS
6717 break;
6718 case 9:
6719 switch (sel) {
6720 case 0:
2e70f6ef 6721 /* Mark as an IO operation because we read the time. */
eeb3bba8 6722 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
2e70f6ef 6723 gen_io_start();
bd79255d 6724 }
895c2d04 6725 gen_helper_mfc0_count(arg, cpu_env);
eeb3bba8 6726 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
2e70f6ef 6727 gen_io_end();
2e70f6ef 6728 }
55807224 6729 /* Break the TB to be able to take timer interrupts immediately
b28425ba
EC
6730 after reading count. DISAS_STOP isn't sufficient, we need to
6731 ensure we break completely out of translated code. */
eeb3bba8
EC
6732 gen_save_pc(ctx->base.pc_next + 4);
6733 ctx->base.is_jmp = DISAS_EXIT;
2423f660
TS
6734 rn = "Count";
6735 break;
6736 /* 6,7 are implementation dependent */
9c2149c8 6737 default:
f31b035a 6738 goto cp0_unimplemented;
876d4b07 6739 }
9c2149c8
TS
6740 break;
6741 case 10:
6742 switch (sel) {
6743 case 0:
7db13fae 6744 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
2423f660
TS
6745 rn = "EntryHi";
6746 break;
9c2149c8 6747 default:
f31b035a 6748 goto cp0_unimplemented;
876d4b07 6749 }
9c2149c8
TS
6750 break;
6751 case 11:
6752 switch (sel) {
6753 case 0:
7db13fae 6754 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
2423f660
TS
6755 rn = "Compare";
6756 break;
876d4b07 6757 /* 6,7 are implementation dependent */
9c2149c8 6758 default:
f31b035a 6759 goto cp0_unimplemented;
876d4b07 6760 }
9c2149c8
TS
6761 break;
6762 case 12:
6763 switch (sel) {
6764 case 0:
7db13fae 6765 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
2423f660
TS
6766 rn = "Status";
6767 break;
9c2149c8 6768 case 1:
d75c135e 6769 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6770 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
2423f660
TS
6771 rn = "IntCtl";
6772 break;
9c2149c8 6773 case 2:
d75c135e 6774 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6775 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
2423f660
TS
6776 rn = "SRSCtl";
6777 break;
9c2149c8 6778 case 3:
d75c135e 6779 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6780 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
2423f660
TS
6781 rn = "SRSMap";
6782 break;
9c2149c8 6783 default:
f31b035a 6784 goto cp0_unimplemented;
876d4b07 6785 }
9c2149c8
TS
6786 break;
6787 case 13:
6788 switch (sel) {
6789 case 0:
7db13fae 6790 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
2423f660
TS
6791 rn = "Cause";
6792 break;
9c2149c8 6793 default:
f31b035a 6794 goto cp0_unimplemented;
876d4b07 6795 }
9c2149c8
TS
6796 break;
6797 case 14:
6798 switch (sel) {
6799 case 0:
7db13fae 6800 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
2423f660
TS
6801 rn = "EPC";
6802 break;
9c2149c8 6803 default:
f31b035a 6804 goto cp0_unimplemented;
876d4b07 6805 }
9c2149c8
TS
6806 break;
6807 case 15:
6808 switch (sel) {
6809 case 0:
7db13fae 6810 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
2423f660
TS
6811 rn = "PRid";
6812 break;
9c2149c8 6813 case 1:
d75c135e 6814 check_insn(ctx, ISA_MIPS32R2);
74dbf824 6815 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EBase));
2423f660
TS
6816 rn = "EBase";
6817 break;
c870e3f5
YK
6818 case 3:
6819 check_insn(ctx, ISA_MIPS32R2);
6820 CP0_CHECK(ctx->cmgcr);
6821 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase));
6822 rn = "CMGCRBase";
6823 break;
9c2149c8 6824 default:
f31b035a 6825 goto cp0_unimplemented;
876d4b07 6826 }
9c2149c8
TS
6827 break;
6828 case 16:
6829 switch (sel) {
6830 case 0:
7db13fae 6831 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
9c2149c8
TS
6832 rn = "Config";
6833 break;
6834 case 1:
7db13fae 6835 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
9c2149c8
TS
6836 rn = "Config1";
6837 break;
6838 case 2:
7db13fae 6839 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
9c2149c8
TS
6840 rn = "Config2";
6841 break;
6842 case 3:
7db13fae 6843 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
9c2149c8
TS
6844 rn = "Config3";
6845 break;
faf1f68b
LA
6846 case 4:
6847 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
6848 rn = "Config4";
6849 break;
6850 case 5:
6851 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
6852 rn = "Config5";
6853 break;
9c2149c8 6854 /* 6,7 are implementation dependent */
f0b3f3ae 6855 case 6:
7db13fae 6856 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
f0b3f3ae
TS
6857 rn = "Config6";
6858 break;
6859 case 7:
7db13fae 6860 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
f0b3f3ae
TS
6861 rn = "Config7";
6862 break;
9c2149c8 6863 default:
f31b035a 6864 goto cp0_unimplemented;
9c2149c8
TS
6865 }
6866 break;
6867 case 17:
6868 switch (sel) {
6869 case 0:
895c2d04 6870 gen_helper_dmfc0_lladdr(arg, cpu_env);
2423f660
TS
6871 rn = "LLAddr";
6872 break;
f6d4dd81
YK
6873 case 1:
6874 CP0_CHECK(ctx->mrp);
6875 gen_helper_dmfc0_maar(arg, cpu_env);
6876 rn = "MAAR";
6877 break;
6878 case 2:
6879 CP0_CHECK(ctx->mrp);
6880 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI));
6881 rn = "MAARI";
6882 break;
9c2149c8 6883 default:
f31b035a 6884 goto cp0_unimplemented;
9c2149c8
TS
6885 }
6886 break;
6887 case 18:
6888 switch (sel) {
c2e19f3c
AM
6889 case 0:
6890 case 1:
6891 case 2:
6892 case 3:
6893 case 4:
6894 case 5:
6895 case 6:
6896 case 7:
895c2d04 6897 gen_helper_1e0i(dmfc0_watchlo, arg, sel);
2423f660
TS
6898 rn = "WatchLo";
6899 break;
9c2149c8 6900 default:
f31b035a 6901 goto cp0_unimplemented;
9c2149c8
TS
6902 }
6903 break;
6904 case 19:
6905 switch (sel) {
c2e19f3c
AM
6906 case 0:
6907 case 1:
6908 case 2:
6909 case 3:
6910 case 4:
6911 case 5:
6912 case 6:
6913 case 7:
895c2d04 6914 gen_helper_1e0i(mfc0_watchhi, arg, sel);
2423f660
TS
6915 rn = "WatchHi";
6916 break;
9c2149c8 6917 default:
f31b035a 6918 goto cp0_unimplemented;
9c2149c8
TS
6919 }
6920 break;
6921 case 20:
6922 switch (sel) {
6923 case 0:
d75c135e 6924 check_insn(ctx, ISA_MIPS3);
7db13fae 6925 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
2423f660
TS
6926 rn = "XContext";
6927 break;
9c2149c8 6928 default:
f31b035a 6929 goto cp0_unimplemented;
9c2149c8
TS
6930 }
6931 break;
6932 case 21:
6933 /* Officially reserved, but sel 0 is used for R1x000 framemask */
f31b035a 6934 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
9c2149c8
TS
6935 switch (sel) {
6936 case 0:
7db13fae 6937 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
2423f660
TS
6938 rn = "Framemask";
6939 break;
9c2149c8 6940 default:
f31b035a 6941 goto cp0_unimplemented;
9c2149c8
TS
6942 }
6943 break;
6944 case 22:
d9bea114 6945 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
6946 rn = "'Diagnostic"; /* implementation dependent */
6947 break;
9c2149c8
TS
6948 case 23:
6949 switch (sel) {
6950 case 0:
895c2d04 6951 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
2423f660
TS
6952 rn = "Debug";
6953 break;
9c2149c8 6954 case 1:
895c2d04 6955// gen_helper_dmfc0_tracecontrol(arg, cpu_env); /* PDtrace support */
2423f660 6956 rn = "TraceControl";
3570d7f6 6957 goto cp0_unimplemented;
9c2149c8 6958 case 2:
895c2d04 6959// gen_helper_dmfc0_tracecontrol2(arg, cpu_env); /* PDtrace support */
2423f660 6960 rn = "TraceControl2";
3570d7f6 6961 goto cp0_unimplemented;
9c2149c8 6962 case 3:
895c2d04 6963// gen_helper_dmfc0_usertracedata(arg, cpu_env); /* PDtrace support */
2423f660 6964 rn = "UserTraceData";
3570d7f6 6965 goto cp0_unimplemented;
9c2149c8 6966 case 4:
895c2d04 6967// gen_helper_dmfc0_tracebpc(arg, cpu_env); /* PDtrace support */
2423f660 6968 rn = "TraceBPC";
3570d7f6 6969 goto cp0_unimplemented;
9c2149c8 6970 default:
f31b035a 6971 goto cp0_unimplemented;
9c2149c8
TS
6972 }
6973 break;
6974 case 24:
6975 switch (sel) {
6976 case 0:
f0b3f3ae 6977 /* EJTAG support */
7db13fae 6978 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
2423f660
TS
6979 rn = "DEPC";
6980 break;
9c2149c8 6981 default:
f31b035a 6982 goto cp0_unimplemented;
9c2149c8
TS
6983 }
6984 break;
6985 case 25:
6986 switch (sel) {
6987 case 0:
7db13fae 6988 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
2423f660 6989 rn = "Performance0";
9c2149c8
TS
6990 break;
6991 case 1:
d9bea114 6992// gen_helper_dmfc0_performance1(arg);
2423f660 6993 rn = "Performance1";
3570d7f6 6994 goto cp0_unimplemented;
9c2149c8 6995 case 2:
d9bea114 6996// gen_helper_dmfc0_performance2(arg);
2423f660 6997 rn = "Performance2";
3570d7f6 6998 goto cp0_unimplemented;
9c2149c8 6999 case 3:
d9bea114 7000// gen_helper_dmfc0_performance3(arg);
2423f660 7001 rn = "Performance3";
3570d7f6 7002 goto cp0_unimplemented;
9c2149c8 7003 case 4:
d9bea114 7004// gen_helper_dmfc0_performance4(arg);
2423f660 7005 rn = "Performance4";
3570d7f6 7006 goto cp0_unimplemented;
9c2149c8 7007 case 5:
d9bea114 7008// gen_helper_dmfc0_performance5(arg);
2423f660 7009 rn = "Performance5";
3570d7f6 7010 goto cp0_unimplemented;
9c2149c8 7011 case 6:
d9bea114 7012// gen_helper_dmfc0_performance6(arg);
2423f660 7013 rn = "Performance6";
3570d7f6 7014 goto cp0_unimplemented;
9c2149c8 7015 case 7:
d9bea114 7016// gen_helper_dmfc0_performance7(arg);
2423f660 7017 rn = "Performance7";
3570d7f6 7018 goto cp0_unimplemented;
9c2149c8 7019 default:
f31b035a 7020 goto cp0_unimplemented;
9c2149c8
TS
7021 }
7022 break;
7023 case 26:
0d74a222
LA
7024 switch (sel) {
7025 case 0:
7026 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl));
7027 rn = "ErrCtl";
7028 break;
7029 default:
7030 goto cp0_unimplemented;
7031 }
da80682b 7032 break;
9c2149c8
TS
7033 case 27:
7034 switch (sel) {
7035 /* ignored */
c2e19f3c
AM
7036 case 0:
7037 case 1:
7038 case 2:
7039 case 3:
d9bea114 7040 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
7041 rn = "CacheErr";
7042 break;
9c2149c8 7043 default:
f31b035a 7044 goto cp0_unimplemented;
9c2149c8
TS
7045 }
7046 break;
7047 case 28:
7048 switch (sel) {
7049 case 0:
7050 case 2:
7051 case 4:
7052 case 6:
7db13fae 7053 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
9c2149c8
TS
7054 rn = "TagLo";
7055 break;
7056 case 1:
7057 case 3:
7058 case 5:
7059 case 7:
7db13fae 7060 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
9c2149c8
TS
7061 rn = "DataLo";
7062 break;
7063 default:
f31b035a 7064 goto cp0_unimplemented;
9c2149c8
TS
7065 }
7066 break;
7067 case 29:
7068 switch (sel) {
7069 case 0:
7070 case 2:
7071 case 4:
7072 case 6:
7db13fae 7073 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
9c2149c8
TS
7074 rn = "TagHi";
7075 break;
7076 case 1:
7077 case 3:
7078 case 5:
7079 case 7:
7db13fae 7080 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
9c2149c8
TS
7081 rn = "DataHi";
7082 break;
7083 default:
f31b035a 7084 goto cp0_unimplemented;
9c2149c8
TS
7085 }
7086 break;
7087 case 30:
7088 switch (sel) {
7089 case 0:
7db13fae 7090 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
2423f660
TS
7091 rn = "ErrorEPC";
7092 break;
9c2149c8 7093 default:
f31b035a 7094 goto cp0_unimplemented;
9c2149c8
TS
7095 }
7096 break;
7097 case 31:
7098 switch (sel) {
7099 case 0:
f0b3f3ae 7100 /* EJTAG support */
7db13fae 7101 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
7102 rn = "DESAVE";
7103 break;
c2e19f3c
AM
7104 case 2:
7105 case 3:
7106 case 4:
7107 case 5:
7108 case 6:
7109 case 7:
f31b035a
LA
7110 CP0_CHECK(ctx->kscrexist & (1 << sel));
7111 tcg_gen_ld_tl(arg, cpu_env,
7112 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
7113 rn = "KScratch";
e98c0d17 7114 break;
9c2149c8 7115 default:
f31b035a 7116 goto cp0_unimplemented;
9c2149c8
TS
7117 }
7118 break;
7119 default:
f31b035a 7120 goto cp0_unimplemented;
9c2149c8 7121 }
b44a7fb1 7122 trace_mips_translate_c0("dmfc0", rn, reg, sel);
9c2149c8
TS
7123 return;
7124
f31b035a 7125cp0_unimplemented:
965447ee 7126 qemu_log_mask(LOG_UNIMP, "dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
f31b035a 7127 gen_mfc0_unimplemented(ctx, arg);
9c2149c8
TS
7128}
7129
d75c135e 7130static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
9c2149c8
TS
7131{
7132 const char *rn = "invalid";
7133
e189e748 7134 if (sel != 0)
d75c135e 7135 check_insn(ctx, ISA_MIPS64);
e189e748 7136
eeb3bba8 7137 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
2e70f6ef 7138 gen_io_start();
bd79255d 7139 }
2e70f6ef 7140
9c2149c8
TS
7141 switch (reg) {
7142 case 0:
7143 switch (sel) {
7144 case 0:
895c2d04 7145 gen_helper_mtc0_index(cpu_env, arg);
9c2149c8
TS
7146 rn = "Index";
7147 break;
7148 case 1:
f31b035a 7149 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7150 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
9c2149c8 7151 rn = "MVPControl";
ead9360e 7152 break;
9c2149c8 7153 case 2:
f31b035a 7154 CP0_CHECK(ctx->insn_flags & ASE_MT);
ead9360e 7155 /* ignored */
9c2149c8 7156 rn = "MVPConf0";
ead9360e 7157 break;
9c2149c8 7158 case 3:
f31b035a 7159 CP0_CHECK(ctx->insn_flags & ASE_MT);
ead9360e 7160 /* ignored */
9c2149c8 7161 rn = "MVPConf1";
ead9360e 7162 break;
01bc435b
YK
7163 case 4:
7164 CP0_CHECK(ctx->vp);
7165 /* ignored */
7166 rn = "VPControl";
7167 break;
9c2149c8 7168 default:
f31b035a 7169 goto cp0_unimplemented;
9c2149c8
TS
7170 }
7171 break;
7172 case 1:
7173 switch (sel) {
7174 case 0:
2423f660 7175 /* ignored */
9c2149c8 7176 rn = "Random";
2423f660 7177 break;
9c2149c8 7178 case 1:
f31b035a 7179 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7180 gen_helper_mtc0_vpecontrol(cpu_env, arg);
9c2149c8 7181 rn = "VPEControl";
ead9360e 7182 break;
9c2149c8 7183 case 2:
f31b035a 7184 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7185 gen_helper_mtc0_vpeconf0(cpu_env, arg);
9c2149c8 7186 rn = "VPEConf0";
ead9360e 7187 break;
9c2149c8 7188 case 3:
f31b035a 7189 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7190 gen_helper_mtc0_vpeconf1(cpu_env, arg);
9c2149c8 7191 rn = "VPEConf1";
ead9360e 7192 break;
9c2149c8 7193 case 4:
f31b035a 7194 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7195 gen_helper_mtc0_yqmask(cpu_env, arg);
9c2149c8 7196 rn = "YQMask";
ead9360e 7197 break;
9c2149c8 7198 case 5:
f31b035a 7199 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 7200 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
9c2149c8 7201 rn = "VPESchedule";
ead9360e 7202 break;
9c2149c8 7203 case 6:
f31b035a 7204 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 7205 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
9c2149c8 7206 rn = "VPEScheFBack";
ead9360e 7207 break;
9c2149c8 7208 case 7:
f31b035a 7209 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7210 gen_helper_mtc0_vpeopt(cpu_env, arg);
9c2149c8 7211 rn = "VPEOpt";
ead9360e 7212 break;
9c2149c8 7213 default:
f31b035a 7214 goto cp0_unimplemented;
9c2149c8
TS
7215 }
7216 break;
7217 case 2:
7218 switch (sel) {
7219 case 0:
7207c7f9 7220 gen_helper_dmtc0_entrylo0(cpu_env, arg);
2423f660
TS
7221 rn = "EntryLo0";
7222 break;
9c2149c8 7223 case 1:
f31b035a 7224 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7225 gen_helper_mtc0_tcstatus(cpu_env, arg);
2423f660 7226 rn = "TCStatus";
ead9360e 7227 break;
9c2149c8 7228 case 2:
f31b035a 7229 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7230 gen_helper_mtc0_tcbind(cpu_env, arg);
2423f660 7231 rn = "TCBind";
ead9360e 7232 break;
9c2149c8 7233 case 3:
f31b035a 7234 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7235 gen_helper_mtc0_tcrestart(cpu_env, arg);
2423f660 7236 rn = "TCRestart";
ead9360e 7237 break;
9c2149c8 7238 case 4:
f31b035a 7239 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7240 gen_helper_mtc0_tchalt(cpu_env, arg);
2423f660 7241 rn = "TCHalt";
ead9360e 7242 break;
9c2149c8 7243 case 5:
f31b035a 7244 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7245 gen_helper_mtc0_tccontext(cpu_env, arg);
2423f660 7246 rn = "TCContext";
ead9360e 7247 break;
9c2149c8 7248 case 6:
f31b035a 7249 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7250 gen_helper_mtc0_tcschedule(cpu_env, arg);
2423f660 7251 rn = "TCSchedule";
ead9360e 7252 break;
9c2149c8 7253 case 7:
f31b035a 7254 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7255 gen_helper_mtc0_tcschefback(cpu_env, arg);
2423f660 7256 rn = "TCScheFBack";
ead9360e 7257 break;
9c2149c8 7258 default:
f31b035a 7259 goto cp0_unimplemented;
9c2149c8
TS
7260 }
7261 break;
7262 case 3:
7263 switch (sel) {
7264 case 0:
7207c7f9 7265 gen_helper_dmtc0_entrylo1(cpu_env, arg);
2423f660
TS
7266 rn = "EntryLo1";
7267 break;
01bc435b
YK
7268 case 1:
7269 CP0_CHECK(ctx->vp);
7270 /* ignored */
7271 rn = "GlobalNumber";
7272 break;
9c2149c8 7273 default:
f31b035a 7274 goto cp0_unimplemented;
876d4b07 7275 }
9c2149c8
TS
7276 break;
7277 case 4:
7278 switch (sel) {
7279 case 0:
895c2d04 7280 gen_helper_mtc0_context(cpu_env, arg);
2423f660
TS
7281 rn = "Context";
7282 break;
9c2149c8 7283 case 1:
895c2d04 7284// gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
2423f660 7285 rn = "ContextConfig";
f31b035a 7286 goto cp0_unimplemented;
d279279e 7287 case 2:
f31b035a
LA
7288 CP0_CHECK(ctx->ulri);
7289 tcg_gen_st_tl(arg, cpu_env,
7290 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
7291 rn = "UserLocal";
d279279e 7292 break;
9c2149c8 7293 default:
f31b035a 7294 goto cp0_unimplemented;
876d4b07 7295 }
9c2149c8
TS
7296 break;
7297 case 5:
7298 switch (sel) {
7299 case 0:
895c2d04 7300 gen_helper_mtc0_pagemask(cpu_env, arg);
2423f660
TS
7301 rn = "PageMask";
7302 break;
9c2149c8 7303 case 1:
d75c135e 7304 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7305 gen_helper_mtc0_pagegrain(cpu_env, arg);
2423f660
TS
7306 rn = "PageGrain";
7307 break;
cec56a73
JH
7308 case 2:
7309 CP0_CHECK(ctx->sc);
7310 gen_helper_mtc0_segctl0(cpu_env, arg);
7311 rn = "SegCtl0";
7312 break;
7313 case 3:
7314 CP0_CHECK(ctx->sc);
7315 gen_helper_mtc0_segctl1(cpu_env, arg);
7316 rn = "SegCtl1";
7317 break;
7318 case 4:
7319 CP0_CHECK(ctx->sc);
7320 gen_helper_mtc0_segctl2(cpu_env, arg);
7321 rn = "SegCtl2";
7322 break;
9c2149c8 7323 default:
f31b035a 7324 goto cp0_unimplemented;
876d4b07 7325 }
9c2149c8
TS
7326 break;
7327 case 6:
7328 switch (sel) {
7329 case 0:
895c2d04 7330 gen_helper_mtc0_wired(cpu_env, arg);
2423f660
TS
7331 rn = "Wired";
7332 break;
9c2149c8 7333 case 1:
d75c135e 7334 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7335 gen_helper_mtc0_srsconf0(cpu_env, arg);
2423f660 7336 rn = "SRSConf0";
ead9360e 7337 break;
9c2149c8 7338 case 2:
d75c135e 7339 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7340 gen_helper_mtc0_srsconf1(cpu_env, arg);
2423f660 7341 rn = "SRSConf1";
ead9360e 7342 break;
9c2149c8 7343 case 3:
d75c135e 7344 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7345 gen_helper_mtc0_srsconf2(cpu_env, arg);
2423f660 7346 rn = "SRSConf2";
ead9360e 7347 break;
9c2149c8 7348 case 4:
d75c135e 7349 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7350 gen_helper_mtc0_srsconf3(cpu_env, arg);
2423f660 7351 rn = "SRSConf3";
ead9360e 7352 break;
9c2149c8 7353 case 5:
d75c135e 7354 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7355 gen_helper_mtc0_srsconf4(cpu_env, arg);
2423f660 7356 rn = "SRSConf4";
ead9360e 7357 break;
9c2149c8 7358 default:
f31b035a 7359 goto cp0_unimplemented;
876d4b07 7360 }
9c2149c8
TS
7361 break;
7362 case 7:
7363 switch (sel) {
7364 case 0:
d75c135e 7365 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7366 gen_helper_mtc0_hwrena(cpu_env, arg);
eeb3bba8 7367 ctx->base.is_jmp = DISAS_STOP;
2423f660
TS
7368 rn = "HWREna";
7369 break;
9c2149c8 7370 default:
f31b035a 7371 goto cp0_unimplemented;
876d4b07 7372 }
9c2149c8
TS
7373 break;
7374 case 8:
aea14095
LA
7375 switch (sel) {
7376 case 0:
7377 /* ignored */
7378 rn = "BadVAddr";
7379 break;
7380 case 1:
7381 /* ignored */
7382 rn = "BadInstr";
7383 break;
7384 case 2:
7385 /* ignored */
7386 rn = "BadInstrP";
7387 break;
7388 default:
f31b035a 7389 goto cp0_unimplemented;
aea14095 7390 }
9c2149c8
TS
7391 break;
7392 case 9:
7393 switch (sel) {
7394 case 0:
895c2d04 7395 gen_helper_mtc0_count(cpu_env, arg);
2423f660
TS
7396 rn = "Count";
7397 break;
876d4b07 7398 /* 6,7 are implementation dependent */
9c2149c8 7399 default:
f31b035a 7400 goto cp0_unimplemented;
876d4b07
TS
7401 }
7402 /* Stop translation as we may have switched the execution mode */
eeb3bba8 7403 ctx->base.is_jmp = DISAS_STOP;
9c2149c8
TS
7404 break;
7405 case 10:
7406 switch (sel) {
7407 case 0:
895c2d04 7408 gen_helper_mtc0_entryhi(cpu_env, arg);
2423f660
TS
7409 rn = "EntryHi";
7410 break;
9c2149c8 7411 default:
f31b035a 7412 goto cp0_unimplemented;
876d4b07 7413 }
9c2149c8
TS
7414 break;
7415 case 11:
7416 switch (sel) {
7417 case 0:
895c2d04 7418 gen_helper_mtc0_compare(cpu_env, arg);
2423f660
TS
7419 rn = "Compare";
7420 break;
876d4b07 7421 /* 6,7 are implementation dependent */
9c2149c8 7422 default:
f31b035a 7423 goto cp0_unimplemented;
876d4b07 7424 }
de9a95f0 7425 /* Stop translation as we may have switched the execution mode */
eeb3bba8 7426 ctx->base.is_jmp = DISAS_STOP;
9c2149c8
TS
7427 break;
7428 case 12:
7429 switch (sel) {
7430 case 0:
867abc7e 7431 save_cpu_state(ctx, 1);
895c2d04 7432 gen_helper_mtc0_status(cpu_env, arg);
b28425ba 7433 /* DISAS_STOP isn't good enough here, hflags may have changed. */
eeb3bba8
EC
7434 gen_save_pc(ctx->base.pc_next + 4);
7435 ctx->base.is_jmp = DISAS_EXIT;
2423f660
TS
7436 rn = "Status";
7437 break;
9c2149c8 7438 case 1:
d75c135e 7439 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7440 gen_helper_mtc0_intctl(cpu_env, arg);
8487327a 7441 /* Stop translation as we may have switched the execution mode */
eeb3bba8 7442 ctx->base.is_jmp = DISAS_STOP;
2423f660
TS
7443 rn = "IntCtl";
7444 break;
9c2149c8 7445 case 2:
d75c135e 7446 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7447 gen_helper_mtc0_srsctl(cpu_env, arg);
8487327a 7448 /* Stop translation as we may have switched the execution mode */
eeb3bba8 7449 ctx->base.is_jmp = DISAS_STOP;
2423f660
TS
7450 rn = "SRSCtl";
7451 break;
9c2149c8 7452 case 3:
d75c135e 7453 check_insn(ctx, ISA_MIPS32R2);
7db13fae 7454 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
8487327a 7455 /* Stop translation as we may have switched the execution mode */
eeb3bba8 7456 ctx->base.is_jmp = DISAS_STOP;
2423f660
TS
7457 rn = "SRSMap";
7458 break;
7459 default:
f31b035a 7460 goto cp0_unimplemented;
876d4b07 7461 }
9c2149c8
TS
7462 break;
7463 case 13:
7464 switch (sel) {
7465 case 0:
867abc7e 7466 save_cpu_state(ctx, 1);
895c2d04 7467 gen_helper_mtc0_cause(cpu_env, arg);
b28425ba
EC
7468 /* Stop translation as we may have triggered an interrupt.
7469 * DISAS_STOP isn't sufficient, we need to ensure we break out of
7470 * translated code to check for pending interrupts. */
eeb3bba8
EC
7471 gen_save_pc(ctx->base.pc_next + 4);
7472 ctx->base.is_jmp = DISAS_EXIT;
2423f660
TS
7473 rn = "Cause";
7474 break;
9c2149c8 7475 default:
f31b035a 7476 goto cp0_unimplemented;
876d4b07 7477 }
9c2149c8
TS
7478 break;
7479 case 14:
7480 switch (sel) {
7481 case 0:
7db13fae 7482 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
2423f660
TS
7483 rn = "EPC";
7484 break;
9c2149c8 7485 default:
f31b035a 7486 goto cp0_unimplemented;
876d4b07 7487 }
9c2149c8
TS
7488 break;
7489 case 15:
7490 switch (sel) {
7491 case 0:
2423f660
TS
7492 /* ignored */
7493 rn = "PRid";
7494 break;
9c2149c8 7495 case 1:
d75c135e 7496 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7497 gen_helper_mtc0_ebase(cpu_env, arg);
2423f660
TS
7498 rn = "EBase";
7499 break;
9c2149c8 7500 default:
f31b035a 7501 goto cp0_unimplemented;
876d4b07 7502 }
9c2149c8
TS
7503 break;
7504 case 16:
7505 switch (sel) {
7506 case 0:
895c2d04 7507 gen_helper_mtc0_config0(cpu_env, arg);
9c2149c8 7508 rn = "Config";
2423f660 7509 /* Stop translation as we may have switched the execution mode */
eeb3bba8 7510 ctx->base.is_jmp = DISAS_STOP;
9c2149c8
TS
7511 break;
7512 case 1:
1fc7bf6e 7513 /* ignored, read only */
9c2149c8
TS
7514 rn = "Config1";
7515 break;
7516 case 2:
895c2d04 7517 gen_helper_mtc0_config2(cpu_env, arg);
9c2149c8 7518 rn = "Config2";
2423f660 7519 /* Stop translation as we may have switched the execution mode */
eeb3bba8 7520 ctx->base.is_jmp = DISAS_STOP;
9c2149c8
TS
7521 break;
7522 case 3:
90f12d73 7523 gen_helper_mtc0_config3(cpu_env, arg);
9c2149c8 7524 rn = "Config3";
90f12d73 7525 /* Stop translation as we may have switched the execution mode */
eeb3bba8 7526 ctx->base.is_jmp = DISAS_STOP;
9c2149c8 7527 break;
faf1f68b
LA
7528 case 4:
7529 /* currently ignored */
7530 rn = "Config4";
7531 break;
7532 case 5:
7533 gen_helper_mtc0_config5(cpu_env, arg);
7534 rn = "Config5";
7535 /* Stop translation as we may have switched the execution mode */
eeb3bba8 7536 ctx->base.is_jmp = DISAS_STOP;
faf1f68b 7537 break;
9c2149c8
TS
7538 /* 6,7 are implementation dependent */
7539 default:
7540 rn = "Invalid config selector";
f31b035a 7541 goto cp0_unimplemented;
9c2149c8 7542 }
9c2149c8
TS
7543 break;
7544 case 17:
7545 switch (sel) {
7546 case 0:
895c2d04 7547 gen_helper_mtc0_lladdr(cpu_env, arg);
2423f660
TS
7548 rn = "LLAddr";
7549 break;
f6d4dd81
YK
7550 case 1:
7551 CP0_CHECK(ctx->mrp);
7552 gen_helper_mtc0_maar(cpu_env, arg);
7553 rn = "MAAR";
7554 break;
7555 case 2:
7556 CP0_CHECK(ctx->mrp);
7557 gen_helper_mtc0_maari(cpu_env, arg);
7558 rn = "MAARI";
7559 break;
9c2149c8 7560 default:
f31b035a 7561 goto cp0_unimplemented;
9c2149c8
TS
7562 }
7563 break;
7564 case 18:
7565 switch (sel) {
c2e19f3c
AM
7566 case 0:
7567 case 1:
7568 case 2:
7569 case 3:
7570 case 4:
7571 case 5:
7572 case 6:
7573 case 7:
895c2d04 7574 gen_helper_0e1i(mtc0_watchlo, arg, sel);
2423f660
TS
7575 rn = "WatchLo";
7576 break;
9c2149c8 7577 default:
f31b035a 7578 goto cp0_unimplemented;
9c2149c8
TS
7579 }
7580 break;
7581 case 19:
7582 switch (sel) {
c2e19f3c
AM
7583 case 0:
7584 case 1:
7585 case 2:
7586 case 3:
7587 case 4:
7588 case 5:
7589 case 6:
7590 case 7:
895c2d04 7591 gen_helper_0e1i(mtc0_watchhi, arg, sel);
2423f660
TS
7592 rn = "WatchHi";
7593 break;
9c2149c8 7594 default:
f31b035a 7595 goto cp0_unimplemented;
9c2149c8
TS
7596 }
7597 break;
7598 case 20:
7599 switch (sel) {
7600 case 0:
d75c135e 7601 check_insn(ctx, ISA_MIPS3);
895c2d04 7602 gen_helper_mtc0_xcontext(cpu_env, arg);
2423f660
TS
7603 rn = "XContext";
7604 break;
9c2149c8 7605 default:
f31b035a 7606 goto cp0_unimplemented;
9c2149c8
TS
7607 }
7608 break;
7609 case 21:
7610 /* Officially reserved, but sel 0 is used for R1x000 framemask */
f31b035a 7611 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
9c2149c8
TS
7612 switch (sel) {
7613 case 0:
895c2d04 7614 gen_helper_mtc0_framemask(cpu_env, arg);
2423f660
TS
7615 rn = "Framemask";
7616 break;
9c2149c8 7617 default:
f31b035a 7618 goto cp0_unimplemented;
9c2149c8
TS
7619 }
7620 break;
7621 case 22:
7622 /* ignored */
7623 rn = "Diagnostic"; /* implementation dependent */
876d4b07 7624 break;
9c2149c8
TS
7625 case 23:
7626 switch (sel) {
7627 case 0:
895c2d04 7628 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
b28425ba 7629 /* DISAS_STOP isn't good enough here, hflags may have changed. */
eeb3bba8
EC
7630 gen_save_pc(ctx->base.pc_next + 4);
7631 ctx->base.is_jmp = DISAS_EXIT;
2423f660
TS
7632 rn = "Debug";
7633 break;
9c2149c8 7634 case 1:
895c2d04 7635// gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
8487327a 7636 /* Stop translation as we may have switched the execution mode */
eeb3bba8 7637 ctx->base.is_jmp = DISAS_STOP;
2423f660 7638 rn = "TraceControl";
3570d7f6 7639 goto cp0_unimplemented;
9c2149c8 7640 case 2:
895c2d04 7641// gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
8487327a 7642 /* Stop translation as we may have switched the execution mode */
eeb3bba8 7643 ctx->base.is_jmp = DISAS_STOP;
2423f660 7644 rn = "TraceControl2";
3570d7f6 7645 goto cp0_unimplemented;
9c2149c8 7646 case 3:
895c2d04 7647// gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
8487327a 7648 /* Stop translation as we may have switched the execution mode */
eeb3bba8 7649 ctx->base.is_jmp = DISAS_STOP;
2423f660 7650 rn = "UserTraceData";
3570d7f6 7651 goto cp0_unimplemented;
9c2149c8 7652 case 4:
895c2d04 7653// gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
8487327a 7654 /* Stop translation as we may have switched the execution mode */
eeb3bba8 7655 ctx->base.is_jmp = DISAS_STOP;
2423f660 7656 rn = "TraceBPC";
3570d7f6 7657 goto cp0_unimplemented;
9c2149c8 7658 default:
f31b035a 7659 goto cp0_unimplemented;
9c2149c8 7660 }
9c2149c8
TS
7661 break;
7662 case 24:
7663 switch (sel) {
7664 case 0:
f1aa6320 7665 /* EJTAG support */
7db13fae 7666 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
2423f660
TS
7667 rn = "DEPC";
7668 break;
9c2149c8 7669 default:
f31b035a 7670 goto cp0_unimplemented;
9c2149c8
TS
7671 }
7672 break;
7673 case 25:
7674 switch (sel) {
7675 case 0:
895c2d04 7676 gen_helper_mtc0_performance0(cpu_env, arg);
2423f660
TS
7677 rn = "Performance0";
7678 break;
9c2149c8 7679 case 1:
895c2d04 7680// gen_helper_mtc0_performance1(cpu_env, arg);
2423f660 7681 rn = "Performance1";
3570d7f6 7682 goto cp0_unimplemented;
9c2149c8 7683 case 2:
895c2d04 7684// gen_helper_mtc0_performance2(cpu_env, arg);
2423f660 7685 rn = "Performance2";
3570d7f6 7686 goto cp0_unimplemented;
9c2149c8 7687 case 3:
895c2d04 7688// gen_helper_mtc0_performance3(cpu_env, arg);
2423f660 7689 rn = "Performance3";
3570d7f6 7690 goto cp0_unimplemented;
9c2149c8 7691 case 4:
895c2d04 7692// gen_helper_mtc0_performance4(cpu_env, arg);
2423f660 7693 rn = "Performance4";
3570d7f6 7694 goto cp0_unimplemented;
9c2149c8 7695 case 5:
895c2d04 7696// gen_helper_mtc0_performance5(cpu_env, arg);
2423f660 7697 rn = "Performance5";
3570d7f6 7698 goto cp0_unimplemented;
9c2149c8 7699 case 6:
895c2d04 7700// gen_helper_mtc0_performance6(cpu_env, arg);
2423f660 7701 rn = "Performance6";
3570d7f6 7702 goto cp0_unimplemented;
9c2149c8 7703 case 7:
895c2d04 7704// gen_helper_mtc0_performance7(cpu_env, arg);
2423f660 7705 rn = "Performance7";
3570d7f6 7706 goto cp0_unimplemented;
9c2149c8 7707 default:
f31b035a 7708 goto cp0_unimplemented;
9c2149c8 7709 }
876d4b07 7710 break;
9c2149c8 7711 case 26:
0d74a222
LA
7712 switch (sel) {
7713 case 0:
7714 gen_helper_mtc0_errctl(cpu_env, arg);
eeb3bba8 7715 ctx->base.is_jmp = DISAS_STOP;
0d74a222
LA
7716 rn = "ErrCtl";
7717 break;
7718 default:
7719 goto cp0_unimplemented;
7720 }
876d4b07 7721 break;
9c2149c8
TS
7722 case 27:
7723 switch (sel) {
c2e19f3c
AM
7724 case 0:
7725 case 1:
7726 case 2:
7727 case 3:
2423f660
TS
7728 /* ignored */
7729 rn = "CacheErr";
7730 break;
9c2149c8 7731 default:
f31b035a 7732 goto cp0_unimplemented;
9c2149c8 7733 }
876d4b07 7734 break;
9c2149c8
TS
7735 case 28:
7736 switch (sel) {
7737 case 0:
7738 case 2:
7739 case 4:
7740 case 6:
895c2d04 7741 gen_helper_mtc0_taglo(cpu_env, arg);
9c2149c8
TS
7742 rn = "TagLo";
7743 break;
7744 case 1:
7745 case 3:
7746 case 5:
7747 case 7:
895c2d04 7748 gen_helper_mtc0_datalo(cpu_env, arg);
9c2149c8
TS
7749 rn = "DataLo";
7750 break;
7751 default:
f31b035a 7752 goto cp0_unimplemented;
9c2149c8
TS
7753 }
7754 break;
7755 case 29:
7756 switch (sel) {
7757 case 0:
7758 case 2:
7759 case 4:
7760 case 6:
895c2d04 7761 gen_helper_mtc0_taghi(cpu_env, arg);
9c2149c8
TS
7762 rn = "TagHi";
7763 break;
7764 case 1:
7765 case 3:
7766 case 5:
7767 case 7:
895c2d04 7768 gen_helper_mtc0_datahi(cpu_env, arg);
9c2149c8
TS
7769 rn = "DataHi";
7770 break;
7771 default:
7772 rn = "invalid sel";
f31b035a 7773 goto cp0_unimplemented;
9c2149c8 7774 }
876d4b07 7775 break;
9c2149c8
TS
7776 case 30:
7777 switch (sel) {
7778 case 0:
7db13fae 7779 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
2423f660
TS
7780 rn = "ErrorEPC";
7781 break;
9c2149c8 7782 default:
f31b035a 7783 goto cp0_unimplemented;
9c2149c8
TS
7784 }
7785 break;
7786 case 31:
7787 switch (sel) {
7788 case 0:
f1aa6320 7789 /* EJTAG support */
7db13fae 7790 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
7791 rn = "DESAVE";
7792 break;
c2e19f3c
AM
7793 case 2:
7794 case 3:
7795 case 4:
7796 case 5:
7797 case 6:
7798 case 7:
f31b035a
LA
7799 CP0_CHECK(ctx->kscrexist & (1 << sel));
7800 tcg_gen_st_tl(arg, cpu_env,
7801 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
7802 rn = "KScratch";
e98c0d17 7803 break;
9c2149c8 7804 default:
f31b035a 7805 goto cp0_unimplemented;
9c2149c8 7806 }
9c2149c8
TS
7807 break;
7808 default:
f31b035a 7809 goto cp0_unimplemented;
9c2149c8 7810 }
b44a7fb1
PMD
7811 trace_mips_translate_c0("dmtc0", rn, reg, sel);
7812
bf20dc07 7813 /* For simplicity assume that all writes can cause interrupts. */
eeb3bba8 7814 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
2e70f6ef 7815 gen_io_end();
b28425ba 7816 /* DISAS_STOP isn't sufficient, we need to ensure we break out of
b74cddcb 7817 * translated code to check for pending interrupts. */
eeb3bba8
EC
7818 gen_save_pc(ctx->base.pc_next + 4);
7819 ctx->base.is_jmp = DISAS_EXIT;
2e70f6ef 7820 }
9c2149c8
TS
7821 return;
7822
f31b035a 7823cp0_unimplemented:
965447ee 7824 qemu_log_mask(LOG_UNIMP, "dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
9c2149c8 7825}
d26bc211 7826#endif /* TARGET_MIPS64 */
9c2149c8 7827
7db13fae 7828static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
ead9360e
TS
7829 int u, int sel, int h)
7830{
7831 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
a7812ae4 7832 TCGv t0 = tcg_temp_local_new();
ead9360e
TS
7833
7834 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
b5dc7732
TS
7835 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
7836 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
1a3fd9c3 7837 tcg_gen_movi_tl(t0, -1);
ead9360e
TS
7838 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
7839 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
1a3fd9c3 7840 tcg_gen_movi_tl(t0, -1);
ead9360e
TS
7841 else if (u == 0) {
7842 switch (rt) {
5a25ce94
EI
7843 case 1:
7844 switch (sel) {
7845 case 1:
895c2d04 7846 gen_helper_mftc0_vpecontrol(t0, cpu_env);
5a25ce94
EI
7847 break;
7848 case 2:
895c2d04 7849 gen_helper_mftc0_vpeconf0(t0, cpu_env);
5a25ce94
EI
7850 break;
7851 default:
7852 goto die;
7853 break;
7854 }
7855 break;
ead9360e
TS
7856 case 2:
7857 switch (sel) {
7858 case 1:
895c2d04 7859 gen_helper_mftc0_tcstatus(t0, cpu_env);
ead9360e
TS
7860 break;
7861 case 2:
895c2d04 7862 gen_helper_mftc0_tcbind(t0, cpu_env);
ead9360e
TS
7863 break;
7864 case 3:
895c2d04 7865 gen_helper_mftc0_tcrestart(t0, cpu_env);
ead9360e
TS
7866 break;
7867 case 4:
895c2d04 7868 gen_helper_mftc0_tchalt(t0, cpu_env);
ead9360e
TS
7869 break;
7870 case 5:
895c2d04 7871 gen_helper_mftc0_tccontext(t0, cpu_env);
ead9360e
TS
7872 break;
7873 case 6:
895c2d04 7874 gen_helper_mftc0_tcschedule(t0, cpu_env);
ead9360e
TS
7875 break;
7876 case 7:
895c2d04 7877 gen_helper_mftc0_tcschefback(t0, cpu_env);
ead9360e
TS
7878 break;
7879 default:
d75c135e 7880 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
7881 break;
7882 }
7883 break;
7884 case 10:
7885 switch (sel) {
7886 case 0:
895c2d04 7887 gen_helper_mftc0_entryhi(t0, cpu_env);
ead9360e
TS
7888 break;
7889 default:
d75c135e 7890 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
7891 break;
7892 }
7893 case 12:
7894 switch (sel) {
7895 case 0:
895c2d04 7896 gen_helper_mftc0_status(t0, cpu_env);
ead9360e
TS
7897 break;
7898 default:
d75c135e 7899 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
7900 break;
7901 }
5a25ce94
EI
7902 case 13:
7903 switch (sel) {
7904 case 0:
895c2d04 7905 gen_helper_mftc0_cause(t0, cpu_env);
5a25ce94
EI
7906 break;
7907 default:
7908 goto die;
7909 break;
7910 }
7911 break;
7912 case 14:
7913 switch (sel) {
7914 case 0:
895c2d04 7915 gen_helper_mftc0_epc(t0, cpu_env);
5a25ce94
EI
7916 break;
7917 default:
7918 goto die;
7919 break;
7920 }
7921 break;
7922 case 15:
7923 switch (sel) {
7924 case 1:
895c2d04 7925 gen_helper_mftc0_ebase(t0, cpu_env);
5a25ce94
EI
7926 break;
7927 default:
7928 goto die;
7929 break;
7930 }
7931 break;
7932 case 16:
7933 switch (sel) {
c2e19f3c
AM
7934 case 0:
7935 case 1:
7936 case 2:
7937 case 3:
7938 case 4:
7939 case 5:
7940 case 6:
7941 case 7:
895c2d04 7942 gen_helper_mftc0_configx(t0, cpu_env, tcg_const_tl(sel));
5a25ce94
EI
7943 break;
7944 default:
7945 goto die;
7946 break;
7947 }
7948 break;
ead9360e
TS
7949 case 23:
7950 switch (sel) {
7951 case 0:
895c2d04 7952 gen_helper_mftc0_debug(t0, cpu_env);
ead9360e
TS
7953 break;
7954 default:
d75c135e 7955 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
7956 break;
7957 }
7958 break;
7959 default:
d75c135e 7960 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
7961 }
7962 } else switch (sel) {
7963 /* GPR registers. */
7964 case 0:
895c2d04 7965 gen_helper_1e0i(mftgpr, t0, rt);
ead9360e
TS
7966 break;
7967 /* Auxiliary CPU registers */
7968 case 1:
7969 switch (rt) {
7970 case 0:
895c2d04 7971 gen_helper_1e0i(mftlo, t0, 0);
ead9360e
TS
7972 break;
7973 case 1:
895c2d04 7974 gen_helper_1e0i(mfthi, t0, 0);
ead9360e
TS
7975 break;
7976 case 2:
895c2d04 7977 gen_helper_1e0i(mftacx, t0, 0);
ead9360e
TS
7978 break;
7979 case 4:
895c2d04 7980 gen_helper_1e0i(mftlo, t0, 1);
ead9360e
TS
7981 break;
7982 case 5:
895c2d04 7983 gen_helper_1e0i(mfthi, t0, 1);
ead9360e
TS
7984 break;
7985 case 6:
895c2d04 7986 gen_helper_1e0i(mftacx, t0, 1);
ead9360e
TS
7987 break;
7988 case 8:
895c2d04 7989 gen_helper_1e0i(mftlo, t0, 2);
ead9360e
TS
7990 break;
7991 case 9:
895c2d04 7992 gen_helper_1e0i(mfthi, t0, 2);
ead9360e
TS
7993 break;
7994 case 10:
895c2d04 7995 gen_helper_1e0i(mftacx, t0, 2);
ead9360e
TS
7996 break;
7997 case 12:
895c2d04 7998 gen_helper_1e0i(mftlo, t0, 3);
ead9360e
TS
7999 break;
8000 case 13:
895c2d04 8001 gen_helper_1e0i(mfthi, t0, 3);
ead9360e
TS
8002 break;
8003 case 14:
895c2d04 8004 gen_helper_1e0i(mftacx, t0, 3);
ead9360e
TS
8005 break;
8006 case 16:
895c2d04 8007 gen_helper_mftdsp(t0, cpu_env);
ead9360e
TS
8008 break;
8009 default:
8010 goto die;
8011 }
8012 break;
8013 /* Floating point (COP1). */
8014 case 2:
8015 /* XXX: For now we support only a single FPU context. */
8016 if (h == 0) {
a7812ae4 8017 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8018
7c979afd 8019 gen_load_fpr32(ctx, fp0, rt);
b6d96bed 8020 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 8021 tcg_temp_free_i32(fp0);
ead9360e 8022 } else {
a7812ae4 8023 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8024
7f6613ce 8025 gen_load_fpr32h(ctx, fp0, rt);
b6d96bed 8026 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 8027 tcg_temp_free_i32(fp0);
ead9360e
TS
8028 }
8029 break;
8030 case 3:
8031 /* XXX: For now we support only a single FPU context. */
895c2d04 8032 gen_helper_1e0i(cfc1, t0, rt);
ead9360e
TS
8033 break;
8034 /* COP2: Not implemented. */
8035 case 4:
8036 case 5:
8037 /* fall through */
8038 default:
8039 goto die;
8040 }
b44a7fb1 8041 trace_mips_translate_tr("mftr", rt, u, sel, h);
1a3fd9c3
TS
8042 gen_store_gpr(t0, rd);
8043 tcg_temp_free(t0);
ead9360e
TS
8044 return;
8045
8046die:
1a3fd9c3 8047 tcg_temp_free(t0);
d12d51d5 8048 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
9c708c7f 8049 generate_exception_end(ctx, EXCP_RI);
ead9360e
TS
8050}
8051
7db13fae 8052static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
ead9360e
TS
8053 int u, int sel, int h)
8054{
8055 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
a7812ae4 8056 TCGv t0 = tcg_temp_local_new();
ead9360e 8057
1a3fd9c3 8058 gen_load_gpr(t0, rt);
ead9360e 8059 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
b5dc7732
TS
8060 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
8061 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
ead9360e
TS
8062 /* NOP */ ;
8063 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
8064 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
8065 /* NOP */ ;
8066 else if (u == 0) {
8067 switch (rd) {
5a25ce94
EI
8068 case 1:
8069 switch (sel) {
8070 case 1:
895c2d04 8071 gen_helper_mttc0_vpecontrol(cpu_env, t0);
5a25ce94
EI
8072 break;
8073 case 2:
895c2d04 8074 gen_helper_mttc0_vpeconf0(cpu_env, t0);
5a25ce94
EI
8075 break;
8076 default:
8077 goto die;
8078 break;
8079 }
8080 break;
ead9360e
TS
8081 case 2:
8082 switch (sel) {
8083 case 1:
895c2d04 8084 gen_helper_mttc0_tcstatus(cpu_env, t0);
ead9360e
TS
8085 break;
8086 case 2:
895c2d04 8087 gen_helper_mttc0_tcbind(cpu_env, t0);
ead9360e
TS
8088 break;
8089 case 3:
895c2d04 8090 gen_helper_mttc0_tcrestart(cpu_env, t0);
ead9360e
TS
8091 break;
8092 case 4:
895c2d04 8093 gen_helper_mttc0_tchalt(cpu_env, t0);
ead9360e
TS
8094 break;
8095 case 5:
895c2d04 8096 gen_helper_mttc0_tccontext(cpu_env, t0);
ead9360e
TS
8097 break;
8098 case 6:
895c2d04 8099 gen_helper_mttc0_tcschedule(cpu_env, t0);
ead9360e
TS
8100 break;
8101 case 7:
895c2d04 8102 gen_helper_mttc0_tcschefback(cpu_env, t0);
ead9360e
TS
8103 break;
8104 default:
d75c135e 8105 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
8106 break;
8107 }
8108 break;
8109 case 10:
8110 switch (sel) {
8111 case 0:
895c2d04 8112 gen_helper_mttc0_entryhi(cpu_env, t0);
ead9360e
TS
8113 break;
8114 default:
d75c135e 8115 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
8116 break;
8117 }
8118 case 12:
8119 switch (sel) {
8120 case 0:
895c2d04 8121 gen_helper_mttc0_status(cpu_env, t0);
ead9360e
TS
8122 break;
8123 default:
d75c135e 8124 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
8125 break;
8126 }
5a25ce94
EI
8127 case 13:
8128 switch (sel) {
8129 case 0:
895c2d04 8130 gen_helper_mttc0_cause(cpu_env, t0);
5a25ce94
EI
8131 break;
8132 default:
8133 goto die;
8134 break;
8135 }
8136 break;
8137 case 15:
8138 switch (sel) {
8139 case 1:
895c2d04 8140 gen_helper_mttc0_ebase(cpu_env, t0);
5a25ce94
EI
8141 break;
8142 default:
8143 goto die;
8144 break;
8145 }
8146 break;
ead9360e
TS
8147 case 23:
8148 switch (sel) {
8149 case 0:
895c2d04 8150 gen_helper_mttc0_debug(cpu_env, t0);
ead9360e
TS
8151 break;
8152 default:
d75c135e 8153 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
8154 break;
8155 }
8156 break;
8157 default:
d75c135e 8158 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
8159 }
8160 } else switch (sel) {
8161 /* GPR registers. */
8162 case 0:
895c2d04 8163 gen_helper_0e1i(mttgpr, t0, rd);
ead9360e
TS
8164 break;
8165 /* Auxiliary CPU registers */
8166 case 1:
8167 switch (rd) {
8168 case 0:
895c2d04 8169 gen_helper_0e1i(mttlo, t0, 0);
ead9360e
TS
8170 break;
8171 case 1:
895c2d04 8172 gen_helper_0e1i(mtthi, t0, 0);
ead9360e
TS
8173 break;
8174 case 2:
895c2d04 8175 gen_helper_0e1i(mttacx, t0, 0);
ead9360e
TS
8176 break;
8177 case 4:
895c2d04 8178 gen_helper_0e1i(mttlo, t0, 1);
ead9360e
TS
8179 break;
8180 case 5:
895c2d04 8181 gen_helper_0e1i(mtthi, t0, 1);
ead9360e
TS
8182 break;
8183 case 6:
895c2d04 8184 gen_helper_0e1i(mttacx, t0, 1);
ead9360e
TS
8185 break;
8186 case 8:
895c2d04 8187 gen_helper_0e1i(mttlo, t0, 2);
ead9360e
TS
8188 break;
8189 case 9:
895c2d04 8190 gen_helper_0e1i(mtthi, t0, 2);
ead9360e
TS
8191 break;
8192 case 10:
895c2d04 8193 gen_helper_0e1i(mttacx, t0, 2);
ead9360e
TS
8194 break;
8195 case 12:
895c2d04 8196 gen_helper_0e1i(mttlo, t0, 3);
ead9360e
TS
8197 break;
8198 case 13:
895c2d04 8199 gen_helper_0e1i(mtthi, t0, 3);
ead9360e
TS
8200 break;
8201 case 14:
895c2d04 8202 gen_helper_0e1i(mttacx, t0, 3);
ead9360e
TS
8203 break;
8204 case 16:
895c2d04 8205 gen_helper_mttdsp(cpu_env, t0);
ead9360e
TS
8206 break;
8207 default:
8208 goto die;
8209 }
8210 break;
8211 /* Floating point (COP1). */
8212 case 2:
8213 /* XXX: For now we support only a single FPU context. */
8214 if (h == 0) {
a7812ae4 8215 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8216
8217 tcg_gen_trunc_tl_i32(fp0, t0);
7c979afd 8218 gen_store_fpr32(ctx, fp0, rd);
a7812ae4 8219 tcg_temp_free_i32(fp0);
ead9360e 8220 } else {
a7812ae4 8221 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8222
8223 tcg_gen_trunc_tl_i32(fp0, t0);
7f6613ce 8224 gen_store_fpr32h(ctx, fp0, rd);
a7812ae4 8225 tcg_temp_free_i32(fp0);
ead9360e
TS
8226 }
8227 break;
8228 case 3:
8229 /* XXX: For now we support only a single FPU context. */
736d120a
PJ
8230 {
8231 TCGv_i32 fs_tmp = tcg_const_i32(rd);
8232
8233 gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
8234 tcg_temp_free_i32(fs_tmp);
8235 }
4cf8a45f 8236 /* Stop translation as we may have changed hflags */
eeb3bba8 8237 ctx->base.is_jmp = DISAS_STOP;
ead9360e
TS
8238 break;
8239 /* COP2: Not implemented. */
8240 case 4:
8241 case 5:
8242 /* fall through */
8243 default:
8244 goto die;
8245 }
b44a7fb1 8246 trace_mips_translate_tr("mttr", rd, u, sel, h);
1a3fd9c3 8247 tcg_temp_free(t0);
ead9360e
TS
8248 return;
8249
8250die:
1a3fd9c3 8251 tcg_temp_free(t0);
d12d51d5 8252 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
9c708c7f 8253 generate_exception_end(ctx, EXCP_RI);
ead9360e
TS
8254}
8255
7db13fae 8256static void gen_cp0 (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
6af0bf9c 8257{
287c4b84 8258 const char *opn = "ldst";
6af0bf9c 8259
2e15497c 8260 check_cp0_enabled(ctx);
6af0bf9c
FB
8261 switch (opc) {
8262 case OPC_MFC0:
8263 if (rt == 0) {
ead9360e 8264 /* Treat as NOP. */
6af0bf9c
FB
8265 return;
8266 }
d75c135e 8267 gen_mfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
6af0bf9c
FB
8268 opn = "mfc0";
8269 break;
8270 case OPC_MTC0:
1a3fd9c3 8271 {
1fc7bf6e 8272 TCGv t0 = tcg_temp_new();
1a3fd9c3
TS
8273
8274 gen_load_gpr(t0, rt);
d75c135e 8275 gen_mtc0(ctx, t0, rd, ctx->opcode & 0x7);
1a3fd9c3
TS
8276 tcg_temp_free(t0);
8277 }
6af0bf9c
FB
8278 opn = "mtc0";
8279 break;
d26bc211 8280#if defined(TARGET_MIPS64)
9c2149c8 8281 case OPC_DMFC0:
d75c135e 8282 check_insn(ctx, ISA_MIPS3);
9c2149c8 8283 if (rt == 0) {
ead9360e 8284 /* Treat as NOP. */
9c2149c8
TS
8285 return;
8286 }
d75c135e 8287 gen_dmfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
9c2149c8
TS
8288 opn = "dmfc0";
8289 break;
8290 case OPC_DMTC0:
d75c135e 8291 check_insn(ctx, ISA_MIPS3);
1a3fd9c3 8292 {
1fc7bf6e 8293 TCGv t0 = tcg_temp_new();
1a3fd9c3
TS
8294
8295 gen_load_gpr(t0, rt);
d75c135e 8296 gen_dmtc0(ctx, t0, rd, ctx->opcode & 0x7);
1a3fd9c3
TS
8297 tcg_temp_free(t0);
8298 }
9c2149c8
TS
8299 opn = "dmtc0";
8300 break;
534ce69f 8301#endif
5204ea79
LA
8302 case OPC_MFHC0:
8303 check_mvh(ctx);
8304 if (rt == 0) {
8305 /* Treat as NOP. */
8306 return;
8307 }
8308 gen_mfhc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
8309 opn = "mfhc0";
8310 break;
8311 case OPC_MTHC0:
8312 check_mvh(ctx);
8313 {
8314 TCGv t0 = tcg_temp_new();
8315 gen_load_gpr(t0, rt);
8316 gen_mthc0(ctx, t0, rd, ctx->opcode & 0x7);
8317 tcg_temp_free(t0);
8318 }
8319 opn = "mthc0";
8320 break;
ead9360e 8321 case OPC_MFTR:
d75c135e 8322 check_insn(ctx, ASE_MT);
ead9360e
TS
8323 if (rd == 0) {
8324 /* Treat as NOP. */
8325 return;
8326 }
6c5c1e20 8327 gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
ead9360e 8328 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
ead9360e
TS
8329 opn = "mftr";
8330 break;
8331 case OPC_MTTR:
d75c135e 8332 check_insn(ctx, ASE_MT);
6c5c1e20 8333 gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
ead9360e
TS
8334 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
8335 opn = "mttr";
8336 break;
6af0bf9c 8337 case OPC_TLBWI:
6af0bf9c 8338 opn = "tlbwi";
c01fccd2 8339 if (!env->tlb->helper_tlbwi)
29929e34 8340 goto die;
895c2d04 8341 gen_helper_tlbwi(cpu_env);
6af0bf9c 8342 break;
9456c2fb
LA
8343 case OPC_TLBINV:
8344 opn = "tlbinv";
8345 if (ctx->ie >= 2) {
8346 if (!env->tlb->helper_tlbinv) {
8347 goto die;
8348 }
8349 gen_helper_tlbinv(cpu_env);
8350 } /* treat as nop if TLBINV not supported */
8351 break;
8352 case OPC_TLBINVF:
8353 opn = "tlbinvf";
8354 if (ctx->ie >= 2) {
8355 if (!env->tlb->helper_tlbinvf) {
8356 goto die;
8357 }
8358 gen_helper_tlbinvf(cpu_env);
8359 } /* treat as nop if TLBINV not supported */
8360 break;
6af0bf9c 8361 case OPC_TLBWR:
6af0bf9c 8362 opn = "tlbwr";
c01fccd2 8363 if (!env->tlb->helper_tlbwr)
29929e34 8364 goto die;
895c2d04 8365 gen_helper_tlbwr(cpu_env);
6af0bf9c
FB
8366 break;
8367 case OPC_TLBP:
6af0bf9c 8368 opn = "tlbp";
c01fccd2 8369 if (!env->tlb->helper_tlbp)
29929e34 8370 goto die;
895c2d04 8371 gen_helper_tlbp(cpu_env);
6af0bf9c
FB
8372 break;
8373 case OPC_TLBR:
6af0bf9c 8374 opn = "tlbr";
c01fccd2 8375 if (!env->tlb->helper_tlbr)
29929e34 8376 goto die;
895c2d04 8377 gen_helper_tlbr(cpu_env);
6af0bf9c 8378 break;
ce9782f4 8379 case OPC_ERET: /* OPC_ERETNC */
339cd2a8
LA
8380 if ((ctx->insn_flags & ISA_MIPS32R6) &&
8381 (ctx->hflags & MIPS_HFLAG_BMASK)) {
339cd2a8 8382 goto die;
ce9782f4
LA
8383 } else {
8384 int bit_shift = (ctx->hflags & MIPS_HFLAG_M16) ? 16 : 6;
8385 if (ctx->opcode & (1 << bit_shift)) {
8386 /* OPC_ERETNC */
8387 opn = "eretnc";
8388 check_insn(ctx, ISA_MIPS32R5);
8389 gen_helper_eretnc(cpu_env);
8390 } else {
8391 /* OPC_ERET */
8392 opn = "eret";
8393 check_insn(ctx, ISA_MIPS2);
8394 gen_helper_eret(cpu_env);
8395 }
eeb3bba8 8396 ctx->base.is_jmp = DISAS_EXIT;
339cd2a8 8397 }
6af0bf9c
FB
8398 break;
8399 case OPC_DERET:
8400 opn = "deret";
d75c135e 8401 check_insn(ctx, ISA_MIPS32);
339cd2a8
LA
8402 if ((ctx->insn_flags & ISA_MIPS32R6) &&
8403 (ctx->hflags & MIPS_HFLAG_BMASK)) {
339cd2a8
LA
8404 goto die;
8405 }
6af0bf9c 8406 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
923617a3 8407 MIPS_INVAL(opn);
9c708c7f 8408 generate_exception_end(ctx, EXCP_RI);
6af0bf9c 8409 } else {
895c2d04 8410 gen_helper_deret(cpu_env);
eeb3bba8 8411 ctx->base.is_jmp = DISAS_EXIT;
6af0bf9c
FB
8412 }
8413 break;
4ad40f36
FB
8414 case OPC_WAIT:
8415 opn = "wait";
d75c135e 8416 check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
339cd2a8
LA
8417 if ((ctx->insn_flags & ISA_MIPS32R6) &&
8418 (ctx->hflags & MIPS_HFLAG_BMASK)) {
339cd2a8
LA
8419 goto die;
8420 }
4ad40f36 8421 /* If we get an exception, we want to restart at next instruction */
eeb3bba8 8422 ctx->base.pc_next += 4;
4ad40f36 8423 save_cpu_state(ctx, 1);
eeb3bba8 8424 ctx->base.pc_next -= 4;
895c2d04 8425 gen_helper_wait(cpu_env);
eeb3bba8 8426 ctx->base.is_jmp = DISAS_NORETURN;
4ad40f36 8427 break;
6af0bf9c 8428 default:
29929e34 8429 die:
923617a3 8430 MIPS_INVAL(opn);
9c708c7f 8431 generate_exception_end(ctx, EXCP_RI);
6af0bf9c
FB
8432 return;
8433 }
2abf314d 8434 (void)opn; /* avoid a compiler warning */
6af0bf9c 8435}
f1aa6320 8436#endif /* !CONFIG_USER_ONLY */
6af0bf9c 8437
6ea83fed 8438/* CP1 Branches (before delay slot) */
d75c135e
AJ
8439static void gen_compute_branch1(DisasContext *ctx, uint32_t op,
8440 int32_t cc, int32_t offset)
6ea83fed
FB
8441{
8442 target_ulong btarget;
a7812ae4 8443 TCGv_i32 t0 = tcg_temp_new_i32();
6ea83fed 8444
339cd2a8 8445 if ((ctx->insn_flags & ISA_MIPS32R6) && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9c708c7f 8446 generate_exception_end(ctx, EXCP_RI);
339cd2a8
LA
8447 goto out;
8448 }
8449
e189e748 8450 if (cc != 0)
d75c135e 8451 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
e189e748 8452
eeb3bba8 8453 btarget = ctx->base.pc_next + 4 + offset;
6ea83fed 8454
7a387fff
TS
8455 switch (op) {
8456 case OPC_BC1F:
d94536f4
AJ
8457 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8458 tcg_gen_not_i32(t0, t0);
8459 tcg_gen_andi_i32(t0, t0, 1);
8460 tcg_gen_extu_i32_tl(bcond, t0);
6ea83fed 8461 goto not_likely;
7a387fff 8462 case OPC_BC1FL:
d94536f4
AJ
8463 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8464 tcg_gen_not_i32(t0, t0);
8465 tcg_gen_andi_i32(t0, t0, 1);
8466 tcg_gen_extu_i32_tl(bcond, t0);
6ea83fed 8467 goto likely;
7a387fff 8468 case OPC_BC1T:
d94536f4
AJ
8469 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8470 tcg_gen_andi_i32(t0, t0, 1);
8471 tcg_gen_extu_i32_tl(bcond, t0);
5a5012ec 8472 goto not_likely;
7a387fff 8473 case OPC_BC1TL:
d94536f4
AJ
8474 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8475 tcg_gen_andi_i32(t0, t0, 1);
8476 tcg_gen_extu_i32_tl(bcond, t0);
6ea83fed
FB
8477 likely:
8478 ctx->hflags |= MIPS_HFLAG_BL;
8479 break;
5a5012ec 8480 case OPC_BC1FANY2:
a16336e4 8481 {
d94536f4
AJ
8482 TCGv_i32 t1 = tcg_temp_new_i32();
8483 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8484 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
d7f66b52 8485 tcg_gen_nand_i32(t0, t0, t1);
d94536f4 8486 tcg_temp_free_i32(t1);
d94536f4
AJ
8487 tcg_gen_andi_i32(t0, t0, 1);
8488 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 8489 }
5a5012ec
TS
8490 goto not_likely;
8491 case OPC_BC1TANY2:
a16336e4 8492 {
d94536f4
AJ
8493 TCGv_i32 t1 = tcg_temp_new_i32();
8494 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8495 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
8496 tcg_gen_or_i32(t0, t0, t1);
8497 tcg_temp_free_i32(t1);
8498 tcg_gen_andi_i32(t0, t0, 1);
8499 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 8500 }
5a5012ec
TS
8501 goto not_likely;
8502 case OPC_BC1FANY4:
a16336e4 8503 {
d94536f4
AJ
8504 TCGv_i32 t1 = tcg_temp_new_i32();
8505 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8506 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
d7f66b52 8507 tcg_gen_and_i32(t0, t0, t1);
d94536f4 8508 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
d7f66b52 8509 tcg_gen_and_i32(t0, t0, t1);
d94536f4 8510 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
d7f66b52 8511 tcg_gen_nand_i32(t0, t0, t1);
d94536f4 8512 tcg_temp_free_i32(t1);
d94536f4
AJ
8513 tcg_gen_andi_i32(t0, t0, 1);
8514 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 8515 }
5a5012ec
TS
8516 goto not_likely;
8517 case OPC_BC1TANY4:
a16336e4 8518 {
d94536f4
AJ
8519 TCGv_i32 t1 = tcg_temp_new_i32();
8520 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8521 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
8522 tcg_gen_or_i32(t0, t0, t1);
8523 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
8524 tcg_gen_or_i32(t0, t0, t1);
8525 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
8526 tcg_gen_or_i32(t0, t0, t1);
8527 tcg_temp_free_i32(t1);
8528 tcg_gen_andi_i32(t0, t0, 1);
8529 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 8530 }
5a5012ec
TS
8531 not_likely:
8532 ctx->hflags |= MIPS_HFLAG_BC;
5a5012ec
TS
8533 break;
8534 default:
9d68ac14 8535 MIPS_INVAL("cp1 cond branch");
9c708c7f 8536 generate_exception_end(ctx, EXCP_RI);
6c5c1e20 8537 goto out;
6ea83fed 8538 }
6ea83fed 8539 ctx->btarget = btarget;
b231c103 8540 ctx->hflags |= MIPS_HFLAG_BDS32;
6c5c1e20 8541 out:
a7812ae4 8542 tcg_temp_free_i32(t0);
6ea83fed
FB
8543}
8544
31837be3
YK
8545/* R6 CP1 Branches */
8546static void gen_compute_branch1_r6(DisasContext *ctx, uint32_t op,
65935f07
YK
8547 int32_t ft, int32_t offset,
8548 int delayslot_size)
31837be3
YK
8549{
8550 target_ulong btarget;
31837be3
YK
8551 TCGv_i64 t0 = tcg_temp_new_i64();
8552
8553 if (ctx->hflags & MIPS_HFLAG_BMASK) {
8554#ifdef MIPS_DEBUG_DISAS
339cd2a8 8555 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
eeb3bba8 8556 "\n", ctx->base.pc_next);
31837be3 8557#endif
9c708c7f 8558 generate_exception_end(ctx, EXCP_RI);
31837be3
YK
8559 goto out;
8560 }
8561
8562 gen_load_fpr64(ctx, t0, ft);
8563 tcg_gen_andi_i64(t0, t0, 1);
8564
eeb3bba8 8565 btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
31837be3
YK
8566
8567 switch (op) {
8568 case OPC_BC1EQZ:
8569 tcg_gen_xori_i64(t0, t0, 1);
31837be3
YK
8570 ctx->hflags |= MIPS_HFLAG_BC;
8571 break;
8572 case OPC_BC1NEZ:
8573 /* t0 already set */
31837be3
YK
8574 ctx->hflags |= MIPS_HFLAG_BC;
8575 break;
8576 default:
9d68ac14 8577 MIPS_INVAL("cp1 cond branch");
9c708c7f 8578 generate_exception_end(ctx, EXCP_RI);
31837be3
YK
8579 goto out;
8580 }
8581
8582 tcg_gen_trunc_i64_tl(bcond, t0);
8583
31837be3 8584 ctx->btarget = btarget;
65935f07
YK
8585
8586 switch (delayslot_size) {
8587 case 2:
8588 ctx->hflags |= MIPS_HFLAG_BDS16;
8589 break;
8590 case 4:
8591 ctx->hflags |= MIPS_HFLAG_BDS32;
8592 break;
8593 }
31837be3
YK
8594
8595out:
8596 tcg_temp_free_i64(t0);
8597}
8598
6af0bf9c 8599/* Coprocessor 1 (FPU) */
5a5012ec 8600
5a5012ec
TS
8601#define FOP(func, fmt) (((fmt) << 21) | (func))
8602
bf4120ad
NF
8603enum fopcode {
8604 OPC_ADD_S = FOP(0, FMT_S),
8605 OPC_SUB_S = FOP(1, FMT_S),
8606 OPC_MUL_S = FOP(2, FMT_S),
8607 OPC_DIV_S = FOP(3, FMT_S),
8608 OPC_SQRT_S = FOP(4, FMT_S),
8609 OPC_ABS_S = FOP(5, FMT_S),
8610 OPC_MOV_S = FOP(6, FMT_S),
8611 OPC_NEG_S = FOP(7, FMT_S),
8612 OPC_ROUND_L_S = FOP(8, FMT_S),
8613 OPC_TRUNC_L_S = FOP(9, FMT_S),
8614 OPC_CEIL_L_S = FOP(10, FMT_S),
8615 OPC_FLOOR_L_S = FOP(11, FMT_S),
8616 OPC_ROUND_W_S = FOP(12, FMT_S),
8617 OPC_TRUNC_W_S = FOP(13, FMT_S),
8618 OPC_CEIL_W_S = FOP(14, FMT_S),
8619 OPC_FLOOR_W_S = FOP(15, FMT_S),
e7f16abb 8620 OPC_SEL_S = FOP(16, FMT_S),
bf4120ad
NF
8621 OPC_MOVCF_S = FOP(17, FMT_S),
8622 OPC_MOVZ_S = FOP(18, FMT_S),
8623 OPC_MOVN_S = FOP(19, FMT_S),
e7f16abb 8624 OPC_SELEQZ_S = FOP(20, FMT_S),
bf4120ad
NF
8625 OPC_RECIP_S = FOP(21, FMT_S),
8626 OPC_RSQRT_S = FOP(22, FMT_S),
e7f16abb
LA
8627 OPC_SELNEZ_S = FOP(23, FMT_S),
8628 OPC_MADDF_S = FOP(24, FMT_S),
8629 OPC_MSUBF_S = FOP(25, FMT_S),
8630 OPC_RINT_S = FOP(26, FMT_S),
8631 OPC_CLASS_S = FOP(27, FMT_S),
8632 OPC_MIN_S = FOP(28, FMT_S),
bf4120ad 8633 OPC_RECIP2_S = FOP(28, FMT_S),
e7f16abb 8634 OPC_MINA_S = FOP(29, FMT_S),
bf4120ad 8635 OPC_RECIP1_S = FOP(29, FMT_S),
e7f16abb 8636 OPC_MAX_S = FOP(30, FMT_S),
bf4120ad 8637 OPC_RSQRT1_S = FOP(30, FMT_S),
e7f16abb 8638 OPC_MAXA_S = FOP(31, FMT_S),
bf4120ad
NF
8639 OPC_RSQRT2_S = FOP(31, FMT_S),
8640 OPC_CVT_D_S = FOP(33, FMT_S),
8641 OPC_CVT_W_S = FOP(36, FMT_S),
8642 OPC_CVT_L_S = FOP(37, FMT_S),
8643 OPC_CVT_PS_S = FOP(38, FMT_S),
8644 OPC_CMP_F_S = FOP (48, FMT_S),
8645 OPC_CMP_UN_S = FOP (49, FMT_S),
8646 OPC_CMP_EQ_S = FOP (50, FMT_S),
8647 OPC_CMP_UEQ_S = FOP (51, FMT_S),
8648 OPC_CMP_OLT_S = FOP (52, FMT_S),
8649 OPC_CMP_ULT_S = FOP (53, FMT_S),
8650 OPC_CMP_OLE_S = FOP (54, FMT_S),
8651 OPC_CMP_ULE_S = FOP (55, FMT_S),
8652 OPC_CMP_SF_S = FOP (56, FMT_S),
8653 OPC_CMP_NGLE_S = FOP (57, FMT_S),
8654 OPC_CMP_SEQ_S = FOP (58, FMT_S),
8655 OPC_CMP_NGL_S = FOP (59, FMT_S),
8656 OPC_CMP_LT_S = FOP (60, FMT_S),
8657 OPC_CMP_NGE_S = FOP (61, FMT_S),
8658 OPC_CMP_LE_S = FOP (62, FMT_S),
8659 OPC_CMP_NGT_S = FOP (63, FMT_S),
8660
8661 OPC_ADD_D = FOP(0, FMT_D),
8662 OPC_SUB_D = FOP(1, FMT_D),
8663 OPC_MUL_D = FOP(2, FMT_D),
8664 OPC_DIV_D = FOP(3, FMT_D),
8665 OPC_SQRT_D = FOP(4, FMT_D),
8666 OPC_ABS_D = FOP(5, FMT_D),
8667 OPC_MOV_D = FOP(6, FMT_D),
8668 OPC_NEG_D = FOP(7, FMT_D),
8669 OPC_ROUND_L_D = FOP(8, FMT_D),
8670 OPC_TRUNC_L_D = FOP(9, FMT_D),
8671 OPC_CEIL_L_D = FOP(10, FMT_D),
8672 OPC_FLOOR_L_D = FOP(11, FMT_D),
8673 OPC_ROUND_W_D = FOP(12, FMT_D),
8674 OPC_TRUNC_W_D = FOP(13, FMT_D),
8675 OPC_CEIL_W_D = FOP(14, FMT_D),
8676 OPC_FLOOR_W_D = FOP(15, FMT_D),
e7f16abb 8677 OPC_SEL_D = FOP(16, FMT_D),
bf4120ad
NF
8678 OPC_MOVCF_D = FOP(17, FMT_D),
8679 OPC_MOVZ_D = FOP(18, FMT_D),
8680 OPC_MOVN_D = FOP(19, FMT_D),
e7f16abb 8681 OPC_SELEQZ_D = FOP(20, FMT_D),
bf4120ad
NF
8682 OPC_RECIP_D = FOP(21, FMT_D),
8683 OPC_RSQRT_D = FOP(22, FMT_D),
e7f16abb
LA
8684 OPC_SELNEZ_D = FOP(23, FMT_D),
8685 OPC_MADDF_D = FOP(24, FMT_D),
8686 OPC_MSUBF_D = FOP(25, FMT_D),
8687 OPC_RINT_D = FOP(26, FMT_D),
8688 OPC_CLASS_D = FOP(27, FMT_D),
8689 OPC_MIN_D = FOP(28, FMT_D),
bf4120ad 8690 OPC_RECIP2_D = FOP(28, FMT_D),
e7f16abb 8691 OPC_MINA_D = FOP(29, FMT_D),
bf4120ad 8692 OPC_RECIP1_D = FOP(29, FMT_D),
e7f16abb 8693 OPC_MAX_D = FOP(30, FMT_D),
bf4120ad 8694 OPC_RSQRT1_D = FOP(30, FMT_D),
e7f16abb 8695 OPC_MAXA_D = FOP(31, FMT_D),
bf4120ad
NF
8696 OPC_RSQRT2_D = FOP(31, FMT_D),
8697 OPC_CVT_S_D = FOP(32, FMT_D),
8698 OPC_CVT_W_D = FOP(36, FMT_D),
8699 OPC_CVT_L_D = FOP(37, FMT_D),
8700 OPC_CMP_F_D = FOP (48, FMT_D),
8701 OPC_CMP_UN_D = FOP (49, FMT_D),
8702 OPC_CMP_EQ_D = FOP (50, FMT_D),
8703 OPC_CMP_UEQ_D = FOP (51, FMT_D),
8704 OPC_CMP_OLT_D = FOP (52, FMT_D),
8705 OPC_CMP_ULT_D = FOP (53, FMT_D),
8706 OPC_CMP_OLE_D = FOP (54, FMT_D),
8707 OPC_CMP_ULE_D = FOP (55, FMT_D),
8708 OPC_CMP_SF_D = FOP (56, FMT_D),
8709 OPC_CMP_NGLE_D = FOP (57, FMT_D),
8710 OPC_CMP_SEQ_D = FOP (58, FMT_D),
8711 OPC_CMP_NGL_D = FOP (59, FMT_D),
8712 OPC_CMP_LT_D = FOP (60, FMT_D),
8713 OPC_CMP_NGE_D = FOP (61, FMT_D),
8714 OPC_CMP_LE_D = FOP (62, FMT_D),
8715 OPC_CMP_NGT_D = FOP (63, FMT_D),
8716
8717 OPC_CVT_S_W = FOP(32, FMT_W),
8718 OPC_CVT_D_W = FOP(33, FMT_W),
8719 OPC_CVT_S_L = FOP(32, FMT_L),
8720 OPC_CVT_D_L = FOP(33, FMT_L),
8721 OPC_CVT_PS_PW = FOP(38, FMT_W),
8722
8723 OPC_ADD_PS = FOP(0, FMT_PS),
8724 OPC_SUB_PS = FOP(1, FMT_PS),
8725 OPC_MUL_PS = FOP(2, FMT_PS),
8726 OPC_DIV_PS = FOP(3, FMT_PS),
8727 OPC_ABS_PS = FOP(5, FMT_PS),
8728 OPC_MOV_PS = FOP(6, FMT_PS),
8729 OPC_NEG_PS = FOP(7, FMT_PS),
8730 OPC_MOVCF_PS = FOP(17, FMT_PS),
8731 OPC_MOVZ_PS = FOP(18, FMT_PS),
8732 OPC_MOVN_PS = FOP(19, FMT_PS),
8733 OPC_ADDR_PS = FOP(24, FMT_PS),
8734 OPC_MULR_PS = FOP(26, FMT_PS),
8735 OPC_RECIP2_PS = FOP(28, FMT_PS),
8736 OPC_RECIP1_PS = FOP(29, FMT_PS),
8737 OPC_RSQRT1_PS = FOP(30, FMT_PS),
8738 OPC_RSQRT2_PS = FOP(31, FMT_PS),
8739
8740 OPC_CVT_S_PU = FOP(32, FMT_PS),
8741 OPC_CVT_PW_PS = FOP(36, FMT_PS),
8742 OPC_CVT_S_PL = FOP(40, FMT_PS),
8743 OPC_PLL_PS = FOP(44, FMT_PS),
8744 OPC_PLU_PS = FOP(45, FMT_PS),
8745 OPC_PUL_PS = FOP(46, FMT_PS),
8746 OPC_PUU_PS = FOP(47, FMT_PS),
8747 OPC_CMP_F_PS = FOP (48, FMT_PS),
8748 OPC_CMP_UN_PS = FOP (49, FMT_PS),
8749 OPC_CMP_EQ_PS = FOP (50, FMT_PS),
8750 OPC_CMP_UEQ_PS = FOP (51, FMT_PS),
8751 OPC_CMP_OLT_PS = FOP (52, FMT_PS),
8752 OPC_CMP_ULT_PS = FOP (53, FMT_PS),
8753 OPC_CMP_OLE_PS = FOP (54, FMT_PS),
8754 OPC_CMP_ULE_PS = FOP (55, FMT_PS),
8755 OPC_CMP_SF_PS = FOP (56, FMT_PS),
8756 OPC_CMP_NGLE_PS = FOP (57, FMT_PS),
8757 OPC_CMP_SEQ_PS = FOP (58, FMT_PS),
8758 OPC_CMP_NGL_PS = FOP (59, FMT_PS),
8759 OPC_CMP_LT_PS = FOP (60, FMT_PS),
8760 OPC_CMP_NGE_PS = FOP (61, FMT_PS),
8761 OPC_CMP_LE_PS = FOP (62, FMT_PS),
8762 OPC_CMP_NGT_PS = FOP (63, FMT_PS),
8763};
8764
3f493883
YK
8765enum r6_f_cmp_op {
8766 R6_OPC_CMP_AF_S = FOP(0, FMT_W),
8767 R6_OPC_CMP_UN_S = FOP(1, FMT_W),
8768 R6_OPC_CMP_EQ_S = FOP(2, FMT_W),
8769 R6_OPC_CMP_UEQ_S = FOP(3, FMT_W),
8770 R6_OPC_CMP_LT_S = FOP(4, FMT_W),
8771 R6_OPC_CMP_ULT_S = FOP(5, FMT_W),
8772 R6_OPC_CMP_LE_S = FOP(6, FMT_W),
8773 R6_OPC_CMP_ULE_S = FOP(7, FMT_W),
8774 R6_OPC_CMP_SAF_S = FOP(8, FMT_W),
8775 R6_OPC_CMP_SUN_S = FOP(9, FMT_W),
8776 R6_OPC_CMP_SEQ_S = FOP(10, FMT_W),
8777 R6_OPC_CMP_SEUQ_S = FOP(11, FMT_W),
8778 R6_OPC_CMP_SLT_S = FOP(12, FMT_W),
8779 R6_OPC_CMP_SULT_S = FOP(13, FMT_W),
8780 R6_OPC_CMP_SLE_S = FOP(14, FMT_W),
8781 R6_OPC_CMP_SULE_S = FOP(15, FMT_W),
8782 R6_OPC_CMP_OR_S = FOP(17, FMT_W),
8783 R6_OPC_CMP_UNE_S = FOP(18, FMT_W),
8784 R6_OPC_CMP_NE_S = FOP(19, FMT_W),
8785 R6_OPC_CMP_SOR_S = FOP(25, FMT_W),
8786 R6_OPC_CMP_SUNE_S = FOP(26, FMT_W),
8787 R6_OPC_CMP_SNE_S = FOP(27, FMT_W),
8788
8789 R6_OPC_CMP_AF_D = FOP(0, FMT_L),
8790 R6_OPC_CMP_UN_D = FOP(1, FMT_L),
8791 R6_OPC_CMP_EQ_D = FOP(2, FMT_L),
8792 R6_OPC_CMP_UEQ_D = FOP(3, FMT_L),
8793 R6_OPC_CMP_LT_D = FOP(4, FMT_L),
8794 R6_OPC_CMP_ULT_D = FOP(5, FMT_L),
8795 R6_OPC_CMP_LE_D = FOP(6, FMT_L),
8796 R6_OPC_CMP_ULE_D = FOP(7, FMT_L),
8797 R6_OPC_CMP_SAF_D = FOP(8, FMT_L),
8798 R6_OPC_CMP_SUN_D = FOP(9, FMT_L),
8799 R6_OPC_CMP_SEQ_D = FOP(10, FMT_L),
8800 R6_OPC_CMP_SEUQ_D = FOP(11, FMT_L),
8801 R6_OPC_CMP_SLT_D = FOP(12, FMT_L),
8802 R6_OPC_CMP_SULT_D = FOP(13, FMT_L),
8803 R6_OPC_CMP_SLE_D = FOP(14, FMT_L),
8804 R6_OPC_CMP_SULE_D = FOP(15, FMT_L),
8805 R6_OPC_CMP_OR_D = FOP(17, FMT_L),
8806 R6_OPC_CMP_UNE_D = FOP(18, FMT_L),
8807 R6_OPC_CMP_NE_D = FOP(19, FMT_L),
8808 R6_OPC_CMP_SOR_D = FOP(25, FMT_L),
8809 R6_OPC_CMP_SUNE_D = FOP(26, FMT_L),
8810 R6_OPC_CMP_SNE_D = FOP(27, FMT_L),
8811};
7a387fff 8812static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
6ea83fed 8813{
72c3a3ee 8814 TCGv t0 = tcg_temp_new();
6ea83fed
FB
8815
8816 switch (opc) {
8817 case OPC_MFC1:
b6d96bed 8818 {
a7812ae4 8819 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8820
7c979afd 8821 gen_load_fpr32(ctx, fp0, fs);
b6d96bed 8822 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 8823 tcg_temp_free_i32(fp0);
6958549d 8824 }
6c5c1e20 8825 gen_store_gpr(t0, rt);
6ea83fed
FB
8826 break;
8827 case OPC_MTC1:
6c5c1e20 8828 gen_load_gpr(t0, rt);
b6d96bed 8829 {
a7812ae4 8830 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8831
8832 tcg_gen_trunc_tl_i32(fp0, t0);
7c979afd 8833 gen_store_fpr32(ctx, fp0, fs);
a7812ae4 8834 tcg_temp_free_i32(fp0);
6958549d 8835 }
6ea83fed
FB
8836 break;
8837 case OPC_CFC1:
895c2d04 8838 gen_helper_1e0i(cfc1, t0, fs);
6c5c1e20 8839 gen_store_gpr(t0, rt);
6ea83fed
FB
8840 break;
8841 case OPC_CTC1:
6c5c1e20 8842 gen_load_gpr(t0, rt);
9c708c7f 8843 save_cpu_state(ctx, 0);
736d120a
PJ
8844 {
8845 TCGv_i32 fs_tmp = tcg_const_i32(fs);
8846
8847 gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
8848 tcg_temp_free_i32(fs_tmp);
8849 }
4cf8a45f 8850 /* Stop translation as we may have changed hflags */
eeb3bba8 8851 ctx->base.is_jmp = DISAS_STOP;
6ea83fed 8852 break;
72c3a3ee 8853#if defined(TARGET_MIPS64)
9c2149c8 8854 case OPC_DMFC1:
72c3a3ee 8855 gen_load_fpr64(ctx, t0, fs);
6c5c1e20 8856 gen_store_gpr(t0, rt);
5a5012ec 8857 break;
9c2149c8 8858 case OPC_DMTC1:
6c5c1e20 8859 gen_load_gpr(t0, rt);
72c3a3ee 8860 gen_store_fpr64(ctx, t0, fs);
5a5012ec 8861 break;
72c3a3ee 8862#endif
5a5012ec 8863 case OPC_MFHC1:
b6d96bed 8864 {
a7812ae4 8865 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8866
7f6613ce 8867 gen_load_fpr32h(ctx, fp0, fs);
b6d96bed 8868 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 8869 tcg_temp_free_i32(fp0);
6958549d 8870 }
6c5c1e20 8871 gen_store_gpr(t0, rt);
5a5012ec
TS
8872 break;
8873 case OPC_MTHC1:
6c5c1e20 8874 gen_load_gpr(t0, rt);
b6d96bed 8875 {
a7812ae4 8876 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8877
8878 tcg_gen_trunc_tl_i32(fp0, t0);
7f6613ce 8879 gen_store_fpr32h(ctx, fp0, fs);
a7812ae4 8880 tcg_temp_free_i32(fp0);
6958549d 8881 }
5a5012ec 8882 break;
6ea83fed 8883 default:
9d68ac14 8884 MIPS_INVAL("cp1 move");
9c708c7f 8885 generate_exception_end(ctx, EXCP_RI);
6c5c1e20 8886 goto out;
6ea83fed 8887 }
6c5c1e20
TS
8888
8889 out:
8890 tcg_temp_free(t0);
6ea83fed
FB
8891}
8892
5a5012ec
TS
8893static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
8894{
42a268c2 8895 TCGLabel *l1;
e214b9bb 8896 TCGCond cond;
af58f9ca
AJ
8897 TCGv_i32 t0;
8898
8899 if (rd == 0) {
8900 /* Treat as NOP. */
8901 return;
8902 }
6ea83fed 8903
e214b9bb 8904 if (tf)
e214b9bb 8905 cond = TCG_COND_EQ;
27848470
TS
8906 else
8907 cond = TCG_COND_NE;
8908
af58f9ca
AJ
8909 l1 = gen_new_label();
8910 t0 = tcg_temp_new_i32();
fa31af0e 8911 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
af58f9ca 8912 tcg_gen_brcondi_i32(cond, t0, 0, l1);
a4e8338d 8913 tcg_temp_free_i32(t0);
af58f9ca
AJ
8914 if (rs == 0) {
8915 tcg_gen_movi_tl(cpu_gpr[rd], 0);
8916 } else {
8917 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
8918 }
e214b9bb 8919 gen_set_label(l1);
5a5012ec
TS
8920}
8921
7c979afd
LA
8922static inline void gen_movcf_s(DisasContext *ctx, int fs, int fd, int cc,
8923 int tf)
a16336e4 8924{
a16336e4 8925 int cond;
cbc37b28 8926 TCGv_i32 t0 = tcg_temp_new_i32();
42a268c2 8927 TCGLabel *l1 = gen_new_label();
a16336e4 8928
a16336e4
TS
8929 if (tf)
8930 cond = TCG_COND_EQ;
8931 else
8932 cond = TCG_COND_NE;
8933
fa31af0e 8934 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
cbc37b28 8935 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7c979afd
LA
8936 gen_load_fpr32(ctx, t0, fs);
8937 gen_store_fpr32(ctx, t0, fd);
a16336e4 8938 gen_set_label(l1);
cbc37b28 8939 tcg_temp_free_i32(t0);
5a5012ec 8940}
a16336e4 8941
b6d96bed 8942static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
a16336e4 8943{
a16336e4 8944 int cond;
cbc37b28
AJ
8945 TCGv_i32 t0 = tcg_temp_new_i32();
8946 TCGv_i64 fp0;
42a268c2 8947 TCGLabel *l1 = gen_new_label();
a16336e4 8948
a16336e4
TS
8949 if (tf)
8950 cond = TCG_COND_EQ;
8951 else
8952 cond = TCG_COND_NE;
8953
fa31af0e 8954 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
cbc37b28 8955 tcg_gen_brcondi_i32(cond, t0, 0, l1);
a4e8338d 8956 tcg_temp_free_i32(t0);
11f94258 8957 fp0 = tcg_temp_new_i64();
9bf3eb2c 8958 gen_load_fpr64(ctx, fp0, fs);
9bf3eb2c 8959 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8960 tcg_temp_free_i64(fp0);
cbc37b28 8961 gen_set_label(l1);
a16336e4
TS
8962}
8963
7f6613ce
PJ
8964static inline void gen_movcf_ps(DisasContext *ctx, int fs, int fd,
8965 int cc, int tf)
a16336e4
TS
8966{
8967 int cond;
cbc37b28 8968 TCGv_i32 t0 = tcg_temp_new_i32();
42a268c2
RH
8969 TCGLabel *l1 = gen_new_label();
8970 TCGLabel *l2 = gen_new_label();
a16336e4
TS
8971
8972 if (tf)
8973 cond = TCG_COND_EQ;
8974 else
8975 cond = TCG_COND_NE;
8976
fa31af0e 8977 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
cbc37b28 8978 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7c979afd
LA
8979 gen_load_fpr32(ctx, t0, fs);
8980 gen_store_fpr32(ctx, t0, fd);
a16336e4 8981 gen_set_label(l1);
9bf3eb2c 8982
fa31af0e 8983 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc+1));
cbc37b28 8984 tcg_gen_brcondi_i32(cond, t0, 0, l2);
7f6613ce
PJ
8985 gen_load_fpr32h(ctx, t0, fs);
8986 gen_store_fpr32h(ctx, t0, fd);
52a0e9eb 8987 tcg_temp_free_i32(t0);
a16336e4 8988 gen_set_label(l2);
a16336e4
TS
8989}
8990
e7f16abb
LA
8991static void gen_sel_s(DisasContext *ctx, enum fopcode op1, int fd, int ft,
8992 int fs)
8993{
8994 TCGv_i32 t1 = tcg_const_i32(0);
8995 TCGv_i32 fp0 = tcg_temp_new_i32();
8996 TCGv_i32 fp1 = tcg_temp_new_i32();
8997 TCGv_i32 fp2 = tcg_temp_new_i32();
7c979afd
LA
8998 gen_load_fpr32(ctx, fp0, fd);
8999 gen_load_fpr32(ctx, fp1, ft);
9000 gen_load_fpr32(ctx, fp2, fs);
e7f16abb
LA
9001
9002 switch (op1) {
9003 case OPC_SEL_S:
9004 tcg_gen_andi_i32(fp0, fp0, 1);
9005 tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
9006 break;
9007 case OPC_SELEQZ_S:
9008 tcg_gen_andi_i32(fp1, fp1, 1);
9009 tcg_gen_movcond_i32(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
9010 break;
9011 case OPC_SELNEZ_S:
9012 tcg_gen_andi_i32(fp1, fp1, 1);
9013 tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
9014 break;
9015 default:
9016 MIPS_INVAL("gen_sel_s");
9c708c7f 9017 generate_exception_end(ctx, EXCP_RI);
e7f16abb
LA
9018 break;
9019 }
9020
7c979afd 9021 gen_store_fpr32(ctx, fp0, fd);
e7f16abb
LA
9022 tcg_temp_free_i32(fp2);
9023 tcg_temp_free_i32(fp1);
9024 tcg_temp_free_i32(fp0);
9025 tcg_temp_free_i32(t1);
9026}
9027
9028static void gen_sel_d(DisasContext *ctx, enum fopcode op1, int fd, int ft,
9029 int fs)
9030{
9031 TCGv_i64 t1 = tcg_const_i64(0);
9032 TCGv_i64 fp0 = tcg_temp_new_i64();
9033 TCGv_i64 fp1 = tcg_temp_new_i64();
9034 TCGv_i64 fp2 = tcg_temp_new_i64();
9035 gen_load_fpr64(ctx, fp0, fd);
9036 gen_load_fpr64(ctx, fp1, ft);
9037 gen_load_fpr64(ctx, fp2, fs);
9038
9039 switch (op1) {
9040 case OPC_SEL_D:
9041 tcg_gen_andi_i64(fp0, fp0, 1);
9042 tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
9043 break;
9044 case OPC_SELEQZ_D:
9045 tcg_gen_andi_i64(fp1, fp1, 1);
9046 tcg_gen_movcond_i64(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
9047 break;
9048 case OPC_SELNEZ_D:
9049 tcg_gen_andi_i64(fp1, fp1, 1);
9050 tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
9051 break;
9052 default:
9053 MIPS_INVAL("gen_sel_d");
9c708c7f 9054 generate_exception_end(ctx, EXCP_RI);
e7f16abb
LA
9055 break;
9056 }
9057
9058 gen_store_fpr64(ctx, fp0, fd);
9059 tcg_temp_free_i64(fp2);
9060 tcg_temp_free_i64(fp1);
9061 tcg_temp_free_i64(fp0);
9062 tcg_temp_free_i64(t1);
9063}
6ea83fed 9064
bf4120ad 9065static void gen_farith (DisasContext *ctx, enum fopcode op1,
5e755519 9066 int ft, int fs, int fd, int cc)
6ea83fed 9067{
7a387fff 9068 uint32_t func = ctx->opcode & 0x3f;
bf4120ad
NF
9069 switch (op1) {
9070 case OPC_ADD_S:
b6d96bed 9071 {
a7812ae4
PB
9072 TCGv_i32 fp0 = tcg_temp_new_i32();
9073 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 9074
7c979afd
LA
9075 gen_load_fpr32(ctx, fp0, fs);
9076 gen_load_fpr32(ctx, fp1, ft);
895c2d04 9077 gen_helper_float_add_s(fp0, cpu_env, fp0, fp1);
a7812ae4 9078 tcg_temp_free_i32(fp1);
7c979afd 9079 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9080 tcg_temp_free_i32(fp0);
b6d96bed 9081 }
5a5012ec 9082 break;
bf4120ad 9083 case OPC_SUB_S:
b6d96bed 9084 {
a7812ae4
PB
9085 TCGv_i32 fp0 = tcg_temp_new_i32();
9086 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 9087
7c979afd
LA
9088 gen_load_fpr32(ctx, fp0, fs);
9089 gen_load_fpr32(ctx, fp1, ft);
895c2d04 9090 gen_helper_float_sub_s(fp0, cpu_env, fp0, fp1);
a7812ae4 9091 tcg_temp_free_i32(fp1);
7c979afd 9092 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9093 tcg_temp_free_i32(fp0);
b6d96bed 9094 }
5a5012ec 9095 break;
bf4120ad 9096 case OPC_MUL_S:
b6d96bed 9097 {
a7812ae4
PB
9098 TCGv_i32 fp0 = tcg_temp_new_i32();
9099 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 9100
7c979afd
LA
9101 gen_load_fpr32(ctx, fp0, fs);
9102 gen_load_fpr32(ctx, fp1, ft);
895c2d04 9103 gen_helper_float_mul_s(fp0, cpu_env, fp0, fp1);
a7812ae4 9104 tcg_temp_free_i32(fp1);
7c979afd 9105 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9106 tcg_temp_free_i32(fp0);
b6d96bed 9107 }
5a5012ec 9108 break;
bf4120ad 9109 case OPC_DIV_S:
b6d96bed 9110 {
a7812ae4
PB
9111 TCGv_i32 fp0 = tcg_temp_new_i32();
9112 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 9113
7c979afd
LA
9114 gen_load_fpr32(ctx, fp0, fs);
9115 gen_load_fpr32(ctx, fp1, ft);
895c2d04 9116 gen_helper_float_div_s(fp0, cpu_env, fp0, fp1);
a7812ae4 9117 tcg_temp_free_i32(fp1);
7c979afd 9118 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9119 tcg_temp_free_i32(fp0);
b6d96bed 9120 }
5a5012ec 9121 break;
bf4120ad 9122 case OPC_SQRT_S:
b6d96bed 9123 {
a7812ae4 9124 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9125
7c979afd 9126 gen_load_fpr32(ctx, fp0, fs);
895c2d04 9127 gen_helper_float_sqrt_s(fp0, cpu_env, fp0);
7c979afd 9128 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9129 tcg_temp_free_i32(fp0);
b6d96bed 9130 }
5a5012ec 9131 break;
bf4120ad 9132 case OPC_ABS_S:
b6d96bed 9133 {
a7812ae4 9134 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9135
7c979afd 9136 gen_load_fpr32(ctx, fp0, fs);
6be77480
AM
9137 if (ctx->abs2008) {
9138 tcg_gen_andi_i32(fp0, fp0, 0x7fffffffUL);
9139 } else {
9140 gen_helper_float_abs_s(fp0, fp0);
9141 }
7c979afd 9142 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9143 tcg_temp_free_i32(fp0);
b6d96bed 9144 }
5a5012ec 9145 break;
bf4120ad 9146 case OPC_MOV_S:
b6d96bed 9147 {
a7812ae4 9148 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9149
7c979afd
LA
9150 gen_load_fpr32(ctx, fp0, fs);
9151 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9152 tcg_temp_free_i32(fp0);
b6d96bed 9153 }
5a5012ec 9154 break;
bf4120ad 9155 case OPC_NEG_S:
b6d96bed 9156 {
a7812ae4 9157 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9158
7c979afd 9159 gen_load_fpr32(ctx, fp0, fs);
6be77480
AM
9160 if (ctx->abs2008) {
9161 tcg_gen_xori_i32(fp0, fp0, 1UL << 31);
9162 } else {
9163 gen_helper_float_chs_s(fp0, fp0);
9164 }
7c979afd 9165 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9166 tcg_temp_free_i32(fp0);
b6d96bed 9167 }
5a5012ec 9168 break;
bf4120ad 9169 case OPC_ROUND_L_S:
5e755519 9170 check_cp1_64bitmode(ctx);
b6d96bed 9171 {
a7812ae4
PB
9172 TCGv_i32 fp32 = tcg_temp_new_i32();
9173 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 9174
7c979afd 9175 gen_load_fpr32(ctx, fp32, fs);
87552089
AM
9176 if (ctx->nan2008) {
9177 gen_helper_float_round_2008_l_s(fp64, cpu_env, fp32);
9178 } else {
9179 gen_helper_float_round_l_s(fp64, cpu_env, fp32);
9180 }
a7812ae4 9181 tcg_temp_free_i32(fp32);
b6d96bed 9182 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 9183 tcg_temp_free_i64(fp64);
b6d96bed 9184 }
5a5012ec 9185 break;
bf4120ad 9186 case OPC_TRUNC_L_S:
5e755519 9187 check_cp1_64bitmode(ctx);
b6d96bed 9188 {
a7812ae4
PB
9189 TCGv_i32 fp32 = tcg_temp_new_i32();
9190 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 9191
7c979afd 9192 gen_load_fpr32(ctx, fp32, fs);
87552089
AM
9193 if (ctx->nan2008) {
9194 gen_helper_float_trunc_2008_l_s(fp64, cpu_env, fp32);
9195 } else {
9196 gen_helper_float_trunc_l_s(fp64, cpu_env, fp32);
9197 }
a7812ae4 9198 tcg_temp_free_i32(fp32);
b6d96bed 9199 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 9200 tcg_temp_free_i64(fp64);
b6d96bed 9201 }
5a5012ec 9202 break;
bf4120ad 9203 case OPC_CEIL_L_S:
5e755519 9204 check_cp1_64bitmode(ctx);
b6d96bed 9205 {
a7812ae4
PB
9206 TCGv_i32 fp32 = tcg_temp_new_i32();
9207 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 9208
7c979afd 9209 gen_load_fpr32(ctx, fp32, fs);
87552089
AM
9210 if (ctx->nan2008) {
9211 gen_helper_float_ceil_2008_l_s(fp64, cpu_env, fp32);
9212 } else {
9213 gen_helper_float_ceil_l_s(fp64, cpu_env, fp32);
9214 }
a7812ae4 9215 tcg_temp_free_i32(fp32);
b6d96bed 9216 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 9217 tcg_temp_free_i64(fp64);
b6d96bed 9218 }
5a5012ec 9219 break;
bf4120ad 9220 case OPC_FLOOR_L_S:
5e755519 9221 check_cp1_64bitmode(ctx);
b6d96bed 9222 {
a7812ae4
PB
9223 TCGv_i32 fp32 = tcg_temp_new_i32();
9224 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 9225
7c979afd 9226 gen_load_fpr32(ctx, fp32, fs);
87552089
AM
9227 if (ctx->nan2008) {
9228 gen_helper_float_floor_2008_l_s(fp64, cpu_env, fp32);
9229 } else {
9230 gen_helper_float_floor_l_s(fp64, cpu_env, fp32);
9231 }
a7812ae4 9232 tcg_temp_free_i32(fp32);
b6d96bed 9233 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 9234 tcg_temp_free_i64(fp64);
b6d96bed 9235 }
5a5012ec 9236 break;
bf4120ad 9237 case OPC_ROUND_W_S:
b6d96bed 9238 {
a7812ae4 9239 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9240
7c979afd 9241 gen_load_fpr32(ctx, fp0, fs);
87552089
AM
9242 if (ctx->nan2008) {
9243 gen_helper_float_round_2008_w_s(fp0, cpu_env, fp0);
9244 } else {
9245 gen_helper_float_round_w_s(fp0, cpu_env, fp0);
9246 }
7c979afd 9247 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9248 tcg_temp_free_i32(fp0);
b6d96bed 9249 }
5a5012ec 9250 break;
bf4120ad 9251 case OPC_TRUNC_W_S:
b6d96bed 9252 {
a7812ae4 9253 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9254
7c979afd 9255 gen_load_fpr32(ctx, fp0, fs);
87552089
AM
9256 if (ctx->nan2008) {
9257 gen_helper_float_trunc_2008_w_s(fp0, cpu_env, fp0);
9258 } else {
9259 gen_helper_float_trunc_w_s(fp0, cpu_env, fp0);
9260 }
7c979afd 9261 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9262 tcg_temp_free_i32(fp0);
b6d96bed 9263 }
5a5012ec 9264 break;
bf4120ad 9265 case OPC_CEIL_W_S:
b6d96bed 9266 {
a7812ae4 9267 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9268
7c979afd 9269 gen_load_fpr32(ctx, fp0, fs);
87552089
AM
9270 if (ctx->nan2008) {
9271 gen_helper_float_ceil_2008_w_s(fp0, cpu_env, fp0);
9272 } else {
9273 gen_helper_float_ceil_w_s(fp0, cpu_env, fp0);
9274 }
7c979afd 9275 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9276 tcg_temp_free_i32(fp0);
b6d96bed 9277 }
5a5012ec 9278 break;
bf4120ad 9279 case OPC_FLOOR_W_S:
b6d96bed 9280 {
a7812ae4 9281 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9282
7c979afd 9283 gen_load_fpr32(ctx, fp0, fs);
87552089
AM
9284 if (ctx->nan2008) {
9285 gen_helper_float_floor_2008_w_s(fp0, cpu_env, fp0);
9286 } else {
9287 gen_helper_float_floor_w_s(fp0, cpu_env, fp0);
9288 }
7c979afd 9289 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9290 tcg_temp_free_i32(fp0);
b6d96bed 9291 }
5a5012ec 9292 break;
e7f16abb
LA
9293 case OPC_SEL_S:
9294 check_insn(ctx, ISA_MIPS32R6);
9295 gen_sel_s(ctx, op1, fd, ft, fs);
e7f16abb
LA
9296 break;
9297 case OPC_SELEQZ_S:
9298 check_insn(ctx, ISA_MIPS32R6);
9299 gen_sel_s(ctx, op1, fd, ft, fs);
e7f16abb
LA
9300 break;
9301 case OPC_SELNEZ_S:
9302 check_insn(ctx, ISA_MIPS32R6);
9303 gen_sel_s(ctx, op1, fd, ft, fs);
e7f16abb 9304 break;
bf4120ad 9305 case OPC_MOVCF_S:
fecd2646 9306 check_insn_opc_removed(ctx, ISA_MIPS32R6);
7c979afd 9307 gen_movcf_s(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
5a5012ec 9308 break;
bf4120ad 9309 case OPC_MOVZ_S:
fecd2646 9310 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a16336e4 9311 {
42a268c2 9312 TCGLabel *l1 = gen_new_label();
c9297f4d 9313 TCGv_i32 fp0;
a16336e4 9314
c9297f4d
AJ
9315 if (ft != 0) {
9316 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
9317 }
9318 fp0 = tcg_temp_new_i32();
7c979afd
LA
9319 gen_load_fpr32(ctx, fp0, fs);
9320 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9321 tcg_temp_free_i32(fp0);
a16336e4
TS
9322 gen_set_label(l1);
9323 }
5a5012ec 9324 break;
bf4120ad 9325 case OPC_MOVN_S:
fecd2646 9326 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a16336e4 9327 {
42a268c2 9328 TCGLabel *l1 = gen_new_label();
c9297f4d
AJ
9329 TCGv_i32 fp0;
9330
9331 if (ft != 0) {
9332 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
9333 fp0 = tcg_temp_new_i32();
7c979afd
LA
9334 gen_load_fpr32(ctx, fp0, fs);
9335 gen_store_fpr32(ctx, fp0, fd);
c9297f4d
AJ
9336 tcg_temp_free_i32(fp0);
9337 gen_set_label(l1);
9338 }
a16336e4 9339 }
5a5012ec 9340 break;
bf4120ad 9341 case OPC_RECIP_S:
b6d96bed 9342 {
a7812ae4 9343 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9344
7c979afd 9345 gen_load_fpr32(ctx, fp0, fs);
895c2d04 9346 gen_helper_float_recip_s(fp0, cpu_env, fp0);
7c979afd 9347 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9348 tcg_temp_free_i32(fp0);
b6d96bed 9349 }
57fa1fb3 9350 break;
bf4120ad 9351 case OPC_RSQRT_S:
b6d96bed 9352 {
a7812ae4 9353 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9354
7c979afd 9355 gen_load_fpr32(ctx, fp0, fs);
895c2d04 9356 gen_helper_float_rsqrt_s(fp0, cpu_env, fp0);
7c979afd 9357 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9358 tcg_temp_free_i32(fp0);
b6d96bed 9359 }
57fa1fb3 9360 break;
e7f16abb
LA
9361 case OPC_MADDF_S:
9362 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 9363 {
a7812ae4
PB
9364 TCGv_i32 fp0 = tcg_temp_new_i32();
9365 TCGv_i32 fp1 = tcg_temp_new_i32();
e7f16abb 9366 TCGv_i32 fp2 = tcg_temp_new_i32();
7c979afd
LA
9367 gen_load_fpr32(ctx, fp0, fs);
9368 gen_load_fpr32(ctx, fp1, ft);
9369 gen_load_fpr32(ctx, fp2, fd);
e7f16abb 9370 gen_helper_float_maddf_s(fp2, cpu_env, fp0, fp1, fp2);
7c979afd 9371 gen_store_fpr32(ctx, fp2, fd);
e7f16abb 9372 tcg_temp_free_i32(fp2);
a7812ae4 9373 tcg_temp_free_i32(fp1);
a7812ae4 9374 tcg_temp_free_i32(fp0);
b6d96bed 9375 }
57fa1fb3 9376 break;
e7f16abb
LA
9377 case OPC_MSUBF_S:
9378 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 9379 {
a7812ae4 9380 TCGv_i32 fp0 = tcg_temp_new_i32();
e7f16abb
LA
9381 TCGv_i32 fp1 = tcg_temp_new_i32();
9382 TCGv_i32 fp2 = tcg_temp_new_i32();
7c979afd
LA
9383 gen_load_fpr32(ctx, fp0, fs);
9384 gen_load_fpr32(ctx, fp1, ft);
9385 gen_load_fpr32(ctx, fp2, fd);
e7f16abb 9386 gen_helper_float_msubf_s(fp2, cpu_env, fp0, fp1, fp2);
7c979afd 9387 gen_store_fpr32(ctx, fp2, fd);
e7f16abb
LA
9388 tcg_temp_free_i32(fp2);
9389 tcg_temp_free_i32(fp1);
a7812ae4 9390 tcg_temp_free_i32(fp0);
b6d96bed 9391 }
57fa1fb3 9392 break;
e7f16abb
LA
9393 case OPC_RINT_S:
9394 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 9395 {
a7812ae4 9396 TCGv_i32 fp0 = tcg_temp_new_i32();
7c979afd 9397 gen_load_fpr32(ctx, fp0, fs);
e7f16abb 9398 gen_helper_float_rint_s(fp0, cpu_env, fp0);
7c979afd 9399 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9400 tcg_temp_free_i32(fp0);
b6d96bed 9401 }
57fa1fb3 9402 break;
e7f16abb
LA
9403 case OPC_CLASS_S:
9404 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 9405 {
e7f16abb 9406 TCGv_i32 fp0 = tcg_temp_new_i32();
7c979afd 9407 gen_load_fpr32(ctx, fp0, fs);
af39bc8c 9408 gen_helper_float_class_s(fp0, cpu_env, fp0);
7c979afd 9409 gen_store_fpr32(ctx, fp0, fd);
e7f16abb 9410 tcg_temp_free_i32(fp0);
e7f16abb
LA
9411 }
9412 break;
9413 case OPC_MIN_S: /* OPC_RECIP2_S */
9414 if (ctx->insn_flags & ISA_MIPS32R6) {
9415 /* OPC_MIN_S */
a7812ae4
PB
9416 TCGv_i32 fp0 = tcg_temp_new_i32();
9417 TCGv_i32 fp1 = tcg_temp_new_i32();
e7f16abb 9418 TCGv_i32 fp2 = tcg_temp_new_i32();
7c979afd
LA
9419 gen_load_fpr32(ctx, fp0, fs);
9420 gen_load_fpr32(ctx, fp1, ft);
e7f16abb 9421 gen_helper_float_min_s(fp2, cpu_env, fp0, fp1);
7c979afd 9422 gen_store_fpr32(ctx, fp2, fd);
e7f16abb
LA
9423 tcg_temp_free_i32(fp2);
9424 tcg_temp_free_i32(fp1);
9425 tcg_temp_free_i32(fp0);
e7f16abb
LA
9426 } else {
9427 /* OPC_RECIP2_S */
9428 check_cp1_64bitmode(ctx);
9429 {
9430 TCGv_i32 fp0 = tcg_temp_new_i32();
9431 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 9432
7c979afd
LA
9433 gen_load_fpr32(ctx, fp0, fs);
9434 gen_load_fpr32(ctx, fp1, ft);
e7f16abb
LA
9435 gen_helper_float_recip2_s(fp0, cpu_env, fp0, fp1);
9436 tcg_temp_free_i32(fp1);
7c979afd 9437 gen_store_fpr32(ctx, fp0, fd);
e7f16abb
LA
9438 tcg_temp_free_i32(fp0);
9439 }
e7f16abb
LA
9440 }
9441 break;
9442 case OPC_MINA_S: /* OPC_RECIP1_S */
9443 if (ctx->insn_flags & ISA_MIPS32R6) {
9444 /* OPC_MINA_S */
9445 TCGv_i32 fp0 = tcg_temp_new_i32();
9446 TCGv_i32 fp1 = tcg_temp_new_i32();
9447 TCGv_i32 fp2 = tcg_temp_new_i32();
7c979afd
LA
9448 gen_load_fpr32(ctx, fp0, fs);
9449 gen_load_fpr32(ctx, fp1, ft);
e7f16abb 9450 gen_helper_float_mina_s(fp2, cpu_env, fp0, fp1);
7c979afd 9451 gen_store_fpr32(ctx, fp2, fd);
e7f16abb
LA
9452 tcg_temp_free_i32(fp2);
9453 tcg_temp_free_i32(fp1);
9454 tcg_temp_free_i32(fp0);
e7f16abb
LA
9455 } else {
9456 /* OPC_RECIP1_S */
9457 check_cp1_64bitmode(ctx);
9458 {
9459 TCGv_i32 fp0 = tcg_temp_new_i32();
9460
7c979afd 9461 gen_load_fpr32(ctx, fp0, fs);
e7f16abb 9462 gen_helper_float_recip1_s(fp0, cpu_env, fp0);
7c979afd 9463 gen_store_fpr32(ctx, fp0, fd);
e7f16abb
LA
9464 tcg_temp_free_i32(fp0);
9465 }
e7f16abb
LA
9466 }
9467 break;
9468 case OPC_MAX_S: /* OPC_RSQRT1_S */
9469 if (ctx->insn_flags & ISA_MIPS32R6) {
9470 /* OPC_MAX_S */
9471 TCGv_i32 fp0 = tcg_temp_new_i32();
9472 TCGv_i32 fp1 = tcg_temp_new_i32();
7c979afd
LA
9473 gen_load_fpr32(ctx, fp0, fs);
9474 gen_load_fpr32(ctx, fp1, ft);
e7f16abb 9475 gen_helper_float_max_s(fp1, cpu_env, fp0, fp1);
7c979afd 9476 gen_store_fpr32(ctx, fp1, fd);
e7f16abb
LA
9477 tcg_temp_free_i32(fp1);
9478 tcg_temp_free_i32(fp0);
e7f16abb
LA
9479 } else {
9480 /* OPC_RSQRT1_S */
9481 check_cp1_64bitmode(ctx);
9482 {
9483 TCGv_i32 fp0 = tcg_temp_new_i32();
9484
7c979afd 9485 gen_load_fpr32(ctx, fp0, fs);
e7f16abb 9486 gen_helper_float_rsqrt1_s(fp0, cpu_env, fp0);
7c979afd 9487 gen_store_fpr32(ctx, fp0, fd);
e7f16abb
LA
9488 tcg_temp_free_i32(fp0);
9489 }
e7f16abb
LA
9490 }
9491 break;
9492 case OPC_MAXA_S: /* OPC_RSQRT2_S */
9493 if (ctx->insn_flags & ISA_MIPS32R6) {
9494 /* OPC_MAXA_S */
9495 TCGv_i32 fp0 = tcg_temp_new_i32();
9496 TCGv_i32 fp1 = tcg_temp_new_i32();
7c979afd
LA
9497 gen_load_fpr32(ctx, fp0, fs);
9498 gen_load_fpr32(ctx, fp1, ft);
e7f16abb 9499 gen_helper_float_maxa_s(fp1, cpu_env, fp0, fp1);
7c979afd 9500 gen_store_fpr32(ctx, fp1, fd);
a7812ae4 9501 tcg_temp_free_i32(fp1);
a7812ae4 9502 tcg_temp_free_i32(fp0);
e7f16abb
LA
9503 } else {
9504 /* OPC_RSQRT2_S */
9505 check_cp1_64bitmode(ctx);
9506 {
9507 TCGv_i32 fp0 = tcg_temp_new_i32();
9508 TCGv_i32 fp1 = tcg_temp_new_i32();
9509
7c979afd
LA
9510 gen_load_fpr32(ctx, fp0, fs);
9511 gen_load_fpr32(ctx, fp1, ft);
e7f16abb
LA
9512 gen_helper_float_rsqrt2_s(fp0, cpu_env, fp0, fp1);
9513 tcg_temp_free_i32(fp1);
7c979afd 9514 gen_store_fpr32(ctx, fp0, fd);
e7f16abb
LA
9515 tcg_temp_free_i32(fp0);
9516 }
b6d96bed 9517 }
57fa1fb3 9518 break;
bf4120ad 9519 case OPC_CVT_D_S:
5e755519 9520 check_cp1_registers(ctx, fd);
b6d96bed 9521 {
a7812ae4
PB
9522 TCGv_i32 fp32 = tcg_temp_new_i32();
9523 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 9524
7c979afd 9525 gen_load_fpr32(ctx, fp32, fs);
895c2d04 9526 gen_helper_float_cvtd_s(fp64, cpu_env, fp32);
a7812ae4 9527 tcg_temp_free_i32(fp32);
b6d96bed 9528 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 9529 tcg_temp_free_i64(fp64);
b6d96bed 9530 }
5a5012ec 9531 break;
bf4120ad 9532 case OPC_CVT_W_S:
b6d96bed 9533 {
a7812ae4 9534 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9535
7c979afd 9536 gen_load_fpr32(ctx, fp0, fs);
87552089
AM
9537 if (ctx->nan2008) {
9538 gen_helper_float_cvt_2008_w_s(fp0, cpu_env, fp0);
9539 } else {
9540 gen_helper_float_cvt_w_s(fp0, cpu_env, fp0);
9541 }
7c979afd 9542 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9543 tcg_temp_free_i32(fp0);
b6d96bed 9544 }
5a5012ec 9545 break;
bf4120ad 9546 case OPC_CVT_L_S:
5e755519 9547 check_cp1_64bitmode(ctx);
b6d96bed 9548 {
a7812ae4
PB
9549 TCGv_i32 fp32 = tcg_temp_new_i32();
9550 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 9551
7c979afd 9552 gen_load_fpr32(ctx, fp32, fs);
87552089
AM
9553 if (ctx->nan2008) {
9554 gen_helper_float_cvt_2008_l_s(fp64, cpu_env, fp32);
9555 } else {
9556 gen_helper_float_cvt_l_s(fp64, cpu_env, fp32);
9557 }
a7812ae4 9558 tcg_temp_free_i32(fp32);
b6d96bed 9559 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 9560 tcg_temp_free_i64(fp64);
b6d96bed 9561 }
5a5012ec 9562 break;
bf4120ad 9563 case OPC_CVT_PS_S:
e29c9628 9564 check_ps(ctx);
b6d96bed 9565 {
a7812ae4
PB
9566 TCGv_i64 fp64 = tcg_temp_new_i64();
9567 TCGv_i32 fp32_0 = tcg_temp_new_i32();
9568 TCGv_i32 fp32_1 = tcg_temp_new_i32();
b6d96bed 9569
7c979afd
LA
9570 gen_load_fpr32(ctx, fp32_0, fs);
9571 gen_load_fpr32(ctx, fp32_1, ft);
13d24f49 9572 tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0);
a7812ae4
PB
9573 tcg_temp_free_i32(fp32_1);
9574 tcg_temp_free_i32(fp32_0);
36aa55dc 9575 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 9576 tcg_temp_free_i64(fp64);
b6d96bed 9577 }
5a5012ec 9578 break;
bf4120ad
NF
9579 case OPC_CMP_F_S:
9580 case OPC_CMP_UN_S:
9581 case OPC_CMP_EQ_S:
9582 case OPC_CMP_UEQ_S:
9583 case OPC_CMP_OLT_S:
9584 case OPC_CMP_ULT_S:
9585 case OPC_CMP_OLE_S:
9586 case OPC_CMP_ULE_S:
9587 case OPC_CMP_SF_S:
9588 case OPC_CMP_NGLE_S:
9589 case OPC_CMP_SEQ_S:
9590 case OPC_CMP_NGL_S:
9591 case OPC_CMP_LT_S:
9592 case OPC_CMP_NGE_S:
9593 case OPC_CMP_LE_S:
9594 case OPC_CMP_NGT_S:
fecd2646 9595 check_insn_opc_removed(ctx, ISA_MIPS32R6);
8153667c
NF
9596 if (ctx->opcode & (1 << 6)) {
9597 gen_cmpabs_s(ctx, func-48, ft, fs, cc);
8153667c
NF
9598 } else {
9599 gen_cmp_s(ctx, func-48, ft, fs, cc);
5a1e8ffb 9600 }
5a5012ec 9601 break;
bf4120ad 9602 case OPC_ADD_D:
5e755519 9603 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 9604 {
a7812ae4
PB
9605 TCGv_i64 fp0 = tcg_temp_new_i64();
9606 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9607
9608 gen_load_fpr64(ctx, fp0, fs);
9609 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9610 gen_helper_float_add_d(fp0, cpu_env, fp0, fp1);
a7812ae4 9611 tcg_temp_free_i64(fp1);
b6d96bed 9612 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9613 tcg_temp_free_i64(fp0);
b6d96bed 9614 }
6ea83fed 9615 break;
bf4120ad 9616 case OPC_SUB_D:
5e755519 9617 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 9618 {
a7812ae4
PB
9619 TCGv_i64 fp0 = tcg_temp_new_i64();
9620 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9621
9622 gen_load_fpr64(ctx, fp0, fs);
9623 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9624 gen_helper_float_sub_d(fp0, cpu_env, fp0, fp1);
a7812ae4 9625 tcg_temp_free_i64(fp1);
b6d96bed 9626 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9627 tcg_temp_free_i64(fp0);
b6d96bed 9628 }
6ea83fed 9629 break;
bf4120ad 9630 case OPC_MUL_D:
5e755519 9631 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 9632 {
a7812ae4
PB
9633 TCGv_i64 fp0 = tcg_temp_new_i64();
9634 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9635
9636 gen_load_fpr64(ctx, fp0, fs);
9637 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9638 gen_helper_float_mul_d(fp0, cpu_env, fp0, fp1);
a7812ae4 9639 tcg_temp_free_i64(fp1);
b6d96bed 9640 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9641 tcg_temp_free_i64(fp0);
b6d96bed 9642 }
6ea83fed 9643 break;
bf4120ad 9644 case OPC_DIV_D:
5e755519 9645 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 9646 {
a7812ae4
PB
9647 TCGv_i64 fp0 = tcg_temp_new_i64();
9648 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9649
9650 gen_load_fpr64(ctx, fp0, fs);
9651 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9652 gen_helper_float_div_d(fp0, cpu_env, fp0, fp1);
a7812ae4 9653 tcg_temp_free_i64(fp1);
b6d96bed 9654 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9655 tcg_temp_free_i64(fp0);
b6d96bed 9656 }
6ea83fed 9657 break;
bf4120ad 9658 case OPC_SQRT_D:
5e755519 9659 check_cp1_registers(ctx, fs | fd);
b6d96bed 9660 {
a7812ae4 9661 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9662
9663 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9664 gen_helper_float_sqrt_d(fp0, cpu_env, fp0);
b6d96bed 9665 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9666 tcg_temp_free_i64(fp0);
b6d96bed 9667 }
6ea83fed 9668 break;
bf4120ad 9669 case OPC_ABS_D:
5e755519 9670 check_cp1_registers(ctx, fs | fd);
b6d96bed 9671 {
a7812ae4 9672 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9673
9674 gen_load_fpr64(ctx, fp0, fs);
6be77480
AM
9675 if (ctx->abs2008) {
9676 tcg_gen_andi_i64(fp0, fp0, 0x7fffffffffffffffULL);
9677 } else {
9678 gen_helper_float_abs_d(fp0, fp0);
9679 }
b6d96bed 9680 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9681 tcg_temp_free_i64(fp0);
b6d96bed 9682 }
6ea83fed 9683 break;
bf4120ad 9684 case OPC_MOV_D:
5e755519 9685 check_cp1_registers(ctx, fs | fd);
b6d96bed 9686 {
a7812ae4 9687 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9688
9689 gen_load_fpr64(ctx, fp0, fs);
9690 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9691 tcg_temp_free_i64(fp0);
b6d96bed 9692 }
6ea83fed 9693 break;
bf4120ad 9694 case OPC_NEG_D:
5e755519 9695 check_cp1_registers(ctx, fs | fd);
b6d96bed 9696 {
a7812ae4 9697 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9698
9699 gen_load_fpr64(ctx, fp0, fs);
6be77480
AM
9700 if (ctx->abs2008) {
9701 tcg_gen_xori_i64(fp0, fp0, 1ULL << 63);
9702 } else {
9703 gen_helper_float_chs_d(fp0, fp0);
9704 }
b6d96bed 9705 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9706 tcg_temp_free_i64(fp0);
b6d96bed 9707 }
6ea83fed 9708 break;
bf4120ad 9709 case OPC_ROUND_L_D:
5e755519 9710 check_cp1_64bitmode(ctx);
b6d96bed 9711 {
a7812ae4 9712 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9713
9714 gen_load_fpr64(ctx, fp0, fs);
87552089
AM
9715 if (ctx->nan2008) {
9716 gen_helper_float_round_2008_l_d(fp0, cpu_env, fp0);
9717 } else {
9718 gen_helper_float_round_l_d(fp0, cpu_env, fp0);
9719 }
b6d96bed 9720 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9721 tcg_temp_free_i64(fp0);
b6d96bed 9722 }
5a5012ec 9723 break;
bf4120ad 9724 case OPC_TRUNC_L_D:
5e755519 9725 check_cp1_64bitmode(ctx);
b6d96bed 9726 {
a7812ae4 9727 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9728
9729 gen_load_fpr64(ctx, fp0, fs);
87552089
AM
9730 if (ctx->nan2008) {
9731 gen_helper_float_trunc_2008_l_d(fp0, cpu_env, fp0);
9732 } else {
9733 gen_helper_float_trunc_l_d(fp0, cpu_env, fp0);
9734 }
b6d96bed 9735 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9736 tcg_temp_free_i64(fp0);
b6d96bed 9737 }
5a5012ec 9738 break;
bf4120ad 9739 case OPC_CEIL_L_D:
5e755519 9740 check_cp1_64bitmode(ctx);
b6d96bed 9741 {
a7812ae4 9742 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9743
9744 gen_load_fpr64(ctx, fp0, fs);
87552089
AM
9745 if (ctx->nan2008) {
9746 gen_helper_float_ceil_2008_l_d(fp0, cpu_env, fp0);
9747 } else {
9748 gen_helper_float_ceil_l_d(fp0, cpu_env, fp0);
9749 }
b6d96bed 9750 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9751 tcg_temp_free_i64(fp0);
b6d96bed 9752 }
5a5012ec 9753 break;
bf4120ad 9754 case OPC_FLOOR_L_D:
5e755519 9755 check_cp1_64bitmode(ctx);
b6d96bed 9756 {
a7812ae4 9757 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9758
9759 gen_load_fpr64(ctx, fp0, fs);
87552089
AM
9760 if (ctx->nan2008) {
9761 gen_helper_float_floor_2008_l_d(fp0, cpu_env, fp0);
9762 } else {
9763 gen_helper_float_floor_l_d(fp0, cpu_env, fp0);
9764 }
b6d96bed 9765 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9766 tcg_temp_free_i64(fp0);
b6d96bed 9767 }
5a5012ec 9768 break;
bf4120ad 9769 case OPC_ROUND_W_D:
5e755519 9770 check_cp1_registers(ctx, fs);
b6d96bed 9771 {
a7812ae4
PB
9772 TCGv_i32 fp32 = tcg_temp_new_i32();
9773 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
9774
9775 gen_load_fpr64(ctx, fp64, fs);
87552089
AM
9776 if (ctx->nan2008) {
9777 gen_helper_float_round_2008_w_d(fp32, cpu_env, fp64);
9778 } else {
9779 gen_helper_float_round_w_d(fp32, cpu_env, fp64);
9780 }
a7812ae4 9781 tcg_temp_free_i64(fp64);
7c979afd 9782 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 9783 tcg_temp_free_i32(fp32);
b6d96bed 9784 }
6ea83fed 9785 break;
bf4120ad 9786 case OPC_TRUNC_W_D:
5e755519 9787 check_cp1_registers(ctx, fs);
b6d96bed 9788 {
a7812ae4
PB
9789 TCGv_i32 fp32 = tcg_temp_new_i32();
9790 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
9791
9792 gen_load_fpr64(ctx, fp64, fs);
87552089
AM
9793 if (ctx->nan2008) {
9794 gen_helper_float_trunc_2008_w_d(fp32, cpu_env, fp64);
9795 } else {
9796 gen_helper_float_trunc_w_d(fp32, cpu_env, fp64);
9797 }
a7812ae4 9798 tcg_temp_free_i64(fp64);
7c979afd 9799 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 9800 tcg_temp_free_i32(fp32);
b6d96bed 9801 }
6ea83fed 9802 break;
bf4120ad 9803 case OPC_CEIL_W_D:
5e755519 9804 check_cp1_registers(ctx, fs);
b6d96bed 9805 {
a7812ae4
PB
9806 TCGv_i32 fp32 = tcg_temp_new_i32();
9807 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
9808
9809 gen_load_fpr64(ctx, fp64, fs);
87552089
AM
9810 if (ctx->nan2008) {
9811 gen_helper_float_ceil_2008_w_d(fp32, cpu_env, fp64);
9812 } else {
9813 gen_helper_float_ceil_w_d(fp32, cpu_env, fp64);
9814 }
a7812ae4 9815 tcg_temp_free_i64(fp64);
7c979afd 9816 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 9817 tcg_temp_free_i32(fp32);
b6d96bed 9818 }
6ea83fed 9819 break;
bf4120ad 9820 case OPC_FLOOR_W_D:
5e755519 9821 check_cp1_registers(ctx, fs);
b6d96bed 9822 {
a7812ae4
PB
9823 TCGv_i32 fp32 = tcg_temp_new_i32();
9824 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
9825
9826 gen_load_fpr64(ctx, fp64, fs);
87552089
AM
9827 if (ctx->nan2008) {
9828 gen_helper_float_floor_2008_w_d(fp32, cpu_env, fp64);
9829 } else {
9830 gen_helper_float_floor_w_d(fp32, cpu_env, fp64);
9831 }
a7812ae4 9832 tcg_temp_free_i64(fp64);
7c979afd 9833 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 9834 tcg_temp_free_i32(fp32);
b6d96bed 9835 }
6ea83fed 9836 break;
e7f16abb
LA
9837 case OPC_SEL_D:
9838 check_insn(ctx, ISA_MIPS32R6);
9839 gen_sel_d(ctx, op1, fd, ft, fs);
e7f16abb
LA
9840 break;
9841 case OPC_SELEQZ_D:
9842 check_insn(ctx, ISA_MIPS32R6);
9843 gen_sel_d(ctx, op1, fd, ft, fs);
e7f16abb
LA
9844 break;
9845 case OPC_SELNEZ_D:
9846 check_insn(ctx, ISA_MIPS32R6);
9847 gen_sel_d(ctx, op1, fd, ft, fs);
e7f16abb 9848 break;
bf4120ad 9849 case OPC_MOVCF_D:
fecd2646 9850 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b6d96bed 9851 gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
dd016883 9852 break;
bf4120ad 9853 case OPC_MOVZ_D:
fecd2646 9854 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a16336e4 9855 {
42a268c2 9856 TCGLabel *l1 = gen_new_label();
c9297f4d 9857 TCGv_i64 fp0;
a16336e4 9858
c9297f4d
AJ
9859 if (ft != 0) {
9860 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
9861 }
9862 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9863 gen_load_fpr64(ctx, fp0, fs);
9864 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9865 tcg_temp_free_i64(fp0);
a16336e4
TS
9866 gen_set_label(l1);
9867 }
5a5012ec 9868 break;
bf4120ad 9869 case OPC_MOVN_D:
fecd2646 9870 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a16336e4 9871 {
42a268c2 9872 TCGLabel *l1 = gen_new_label();
c9297f4d
AJ
9873 TCGv_i64 fp0;
9874
9875 if (ft != 0) {
9876 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
9877 fp0 = tcg_temp_new_i64();
9878 gen_load_fpr64(ctx, fp0, fs);
9879 gen_store_fpr64(ctx, fp0, fd);
9880 tcg_temp_free_i64(fp0);
9881 gen_set_label(l1);
9882 }
a16336e4 9883 }
6ea83fed 9884 break;
bf4120ad 9885 case OPC_RECIP_D:
ca6c7803 9886 check_cp1_registers(ctx, fs | fd);
b6d96bed 9887 {
a7812ae4 9888 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9889
9890 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9891 gen_helper_float_recip_d(fp0, cpu_env, fp0);
b6d96bed 9892 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9893 tcg_temp_free_i64(fp0);
b6d96bed 9894 }
57fa1fb3 9895 break;
bf4120ad 9896 case OPC_RSQRT_D:
ca6c7803 9897 check_cp1_registers(ctx, fs | fd);
b6d96bed 9898 {
a7812ae4 9899 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9900
9901 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9902 gen_helper_float_rsqrt_d(fp0, cpu_env, fp0);
b6d96bed 9903 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9904 tcg_temp_free_i64(fp0);
b6d96bed 9905 }
57fa1fb3 9906 break;
e7f16abb
LA
9907 case OPC_MADDF_D:
9908 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 9909 {
a7812ae4
PB
9910 TCGv_i64 fp0 = tcg_temp_new_i64();
9911 TCGv_i64 fp1 = tcg_temp_new_i64();
e7f16abb 9912 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
9913 gen_load_fpr64(ctx, fp0, fs);
9914 gen_load_fpr64(ctx, fp1, ft);
e7f16abb
LA
9915 gen_load_fpr64(ctx, fp2, fd);
9916 gen_helper_float_maddf_d(fp2, cpu_env, fp0, fp1, fp2);
9917 gen_store_fpr64(ctx, fp2, fd);
9918 tcg_temp_free_i64(fp2);
a7812ae4 9919 tcg_temp_free_i64(fp1);
a7812ae4 9920 tcg_temp_free_i64(fp0);
b6d96bed 9921 }
57fa1fb3 9922 break;
e7f16abb
LA
9923 case OPC_MSUBF_D:
9924 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 9925 {
a7812ae4 9926 TCGv_i64 fp0 = tcg_temp_new_i64();
e7f16abb
LA
9927 TCGv_i64 fp1 = tcg_temp_new_i64();
9928 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed 9929 gen_load_fpr64(ctx, fp0, fs);
e7f16abb
LA
9930 gen_load_fpr64(ctx, fp1, ft);
9931 gen_load_fpr64(ctx, fp2, fd);
9932 gen_helper_float_msubf_d(fp2, cpu_env, fp0, fp1, fp2);
9933 gen_store_fpr64(ctx, fp2, fd);
9934 tcg_temp_free_i64(fp2);
9935 tcg_temp_free_i64(fp1);
a7812ae4 9936 tcg_temp_free_i64(fp0);
b6d96bed 9937 }
57fa1fb3 9938 break;
e7f16abb
LA
9939 case OPC_RINT_D:
9940 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 9941 {
a7812ae4 9942 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 9943 gen_load_fpr64(ctx, fp0, fs);
e7f16abb 9944 gen_helper_float_rint_d(fp0, cpu_env, fp0);
b6d96bed 9945 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9946 tcg_temp_free_i64(fp0);
b6d96bed 9947 }
57fa1fb3 9948 break;
e7f16abb
LA
9949 case OPC_CLASS_D:
9950 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 9951 {
e7f16abb
LA
9952 TCGv_i64 fp0 = tcg_temp_new_i64();
9953 gen_load_fpr64(ctx, fp0, fs);
af39bc8c 9954 gen_helper_float_class_d(fp0, cpu_env, fp0);
e7f16abb
LA
9955 gen_store_fpr64(ctx, fp0, fd);
9956 tcg_temp_free_i64(fp0);
e7f16abb
LA
9957 }
9958 break;
9959 case OPC_MIN_D: /* OPC_RECIP2_D */
9960 if (ctx->insn_flags & ISA_MIPS32R6) {
9961 /* OPC_MIN_D */
a7812ae4
PB
9962 TCGv_i64 fp0 = tcg_temp_new_i64();
9963 TCGv_i64 fp1 = tcg_temp_new_i64();
e7f16abb
LA
9964 gen_load_fpr64(ctx, fp0, fs);
9965 gen_load_fpr64(ctx, fp1, ft);
9966 gen_helper_float_min_d(fp1, cpu_env, fp0, fp1);
9967 gen_store_fpr64(ctx, fp1, fd);
9968 tcg_temp_free_i64(fp1);
9969 tcg_temp_free_i64(fp0);
e7f16abb
LA
9970 } else {
9971 /* OPC_RECIP2_D */
9972 check_cp1_64bitmode(ctx);
9973 {
9974 TCGv_i64 fp0 = tcg_temp_new_i64();
9975 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed 9976
e7f16abb
LA
9977 gen_load_fpr64(ctx, fp0, fs);
9978 gen_load_fpr64(ctx, fp1, ft);
9979 gen_helper_float_recip2_d(fp0, cpu_env, fp0, fp1);
9980 tcg_temp_free_i64(fp1);
9981 gen_store_fpr64(ctx, fp0, fd);
9982 tcg_temp_free_i64(fp0);
9983 }
e7f16abb
LA
9984 }
9985 break;
9986 case OPC_MINA_D: /* OPC_RECIP1_D */
9987 if (ctx->insn_flags & ISA_MIPS32R6) {
9988 /* OPC_MINA_D */
9989 TCGv_i64 fp0 = tcg_temp_new_i64();
9990 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9991 gen_load_fpr64(ctx, fp0, fs);
9992 gen_load_fpr64(ctx, fp1, ft);
e7f16abb
LA
9993 gen_helper_float_mina_d(fp1, cpu_env, fp0, fp1);
9994 gen_store_fpr64(ctx, fp1, fd);
9995 tcg_temp_free_i64(fp1);
9996 tcg_temp_free_i64(fp0);
e7f16abb
LA
9997 } else {
9998 /* OPC_RECIP1_D */
9999 check_cp1_64bitmode(ctx);
10000 {
10001 TCGv_i64 fp0 = tcg_temp_new_i64();
10002
10003 gen_load_fpr64(ctx, fp0, fs);
10004 gen_helper_float_recip1_d(fp0, cpu_env, fp0);
10005 gen_store_fpr64(ctx, fp0, fd);
10006 tcg_temp_free_i64(fp0);
10007 }
e7f16abb
LA
10008 }
10009 break;
10010 case OPC_MAX_D: /* OPC_RSQRT1_D */
10011 if (ctx->insn_flags & ISA_MIPS32R6) {
10012 /* OPC_MAX_D */
10013 TCGv_i64 fp0 = tcg_temp_new_i64();
10014 TCGv_i64 fp1 = tcg_temp_new_i64();
10015 gen_load_fpr64(ctx, fp0, fs);
10016 gen_load_fpr64(ctx, fp1, ft);
10017 gen_helper_float_max_d(fp1, cpu_env, fp0, fp1);
10018 gen_store_fpr64(ctx, fp1, fd);
a7812ae4 10019 tcg_temp_free_i64(fp1);
a7812ae4 10020 tcg_temp_free_i64(fp0);
e7f16abb
LA
10021 } else {
10022 /* OPC_RSQRT1_D */
10023 check_cp1_64bitmode(ctx);
10024 {
10025 TCGv_i64 fp0 = tcg_temp_new_i64();
10026
10027 gen_load_fpr64(ctx, fp0, fs);
10028 gen_helper_float_rsqrt1_d(fp0, cpu_env, fp0);
10029 gen_store_fpr64(ctx, fp0, fd);
10030 tcg_temp_free_i64(fp0);
10031 }
e7f16abb
LA
10032 }
10033 break;
10034 case OPC_MAXA_D: /* OPC_RSQRT2_D */
10035 if (ctx->insn_flags & ISA_MIPS32R6) {
10036 /* OPC_MAXA_D */
10037 TCGv_i64 fp0 = tcg_temp_new_i64();
10038 TCGv_i64 fp1 = tcg_temp_new_i64();
10039 gen_load_fpr64(ctx, fp0, fs);
10040 gen_load_fpr64(ctx, fp1, ft);
10041 gen_helper_float_maxa_d(fp1, cpu_env, fp0, fp1);
10042 gen_store_fpr64(ctx, fp1, fd);
10043 tcg_temp_free_i64(fp1);
10044 tcg_temp_free_i64(fp0);
e7f16abb
LA
10045 } else {
10046 /* OPC_RSQRT2_D */
10047 check_cp1_64bitmode(ctx);
10048 {
10049 TCGv_i64 fp0 = tcg_temp_new_i64();
10050 TCGv_i64 fp1 = tcg_temp_new_i64();
10051
10052 gen_load_fpr64(ctx, fp0, fs);
10053 gen_load_fpr64(ctx, fp1, ft);
10054 gen_helper_float_rsqrt2_d(fp0, cpu_env, fp0, fp1);
10055 tcg_temp_free_i64(fp1);
10056 gen_store_fpr64(ctx, fp0, fd);
10057 tcg_temp_free_i64(fp0);
10058 }
b6d96bed 10059 }
57fa1fb3 10060 break;
bf4120ad
NF
10061 case OPC_CMP_F_D:
10062 case OPC_CMP_UN_D:
10063 case OPC_CMP_EQ_D:
10064 case OPC_CMP_UEQ_D:
10065 case OPC_CMP_OLT_D:
10066 case OPC_CMP_ULT_D:
10067 case OPC_CMP_OLE_D:
10068 case OPC_CMP_ULE_D:
10069 case OPC_CMP_SF_D:
10070 case OPC_CMP_NGLE_D:
10071 case OPC_CMP_SEQ_D:
10072 case OPC_CMP_NGL_D:
10073 case OPC_CMP_LT_D:
10074 case OPC_CMP_NGE_D:
10075 case OPC_CMP_LE_D:
10076 case OPC_CMP_NGT_D:
fecd2646 10077 check_insn_opc_removed(ctx, ISA_MIPS32R6);
8153667c
NF
10078 if (ctx->opcode & (1 << 6)) {
10079 gen_cmpabs_d(ctx, func-48, ft, fs, cc);
8153667c
NF
10080 } else {
10081 gen_cmp_d(ctx, func-48, ft, fs, cc);
5a1e8ffb 10082 }
6ea83fed 10083 break;
bf4120ad 10084 case OPC_CVT_S_D:
5e755519 10085 check_cp1_registers(ctx, fs);
b6d96bed 10086 {
a7812ae4
PB
10087 TCGv_i32 fp32 = tcg_temp_new_i32();
10088 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
10089
10090 gen_load_fpr64(ctx, fp64, fs);
895c2d04 10091 gen_helper_float_cvts_d(fp32, cpu_env, fp64);
a7812ae4 10092 tcg_temp_free_i64(fp64);
7c979afd 10093 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 10094 tcg_temp_free_i32(fp32);
b6d96bed 10095 }
5a5012ec 10096 break;
bf4120ad 10097 case OPC_CVT_W_D:
5e755519 10098 check_cp1_registers(ctx, fs);
b6d96bed 10099 {
a7812ae4
PB
10100 TCGv_i32 fp32 = tcg_temp_new_i32();
10101 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
10102
10103 gen_load_fpr64(ctx, fp64, fs);
87552089
AM
10104 if (ctx->nan2008) {
10105 gen_helper_float_cvt_2008_w_d(fp32, cpu_env, fp64);
10106 } else {
10107 gen_helper_float_cvt_w_d(fp32, cpu_env, fp64);
10108 }
a7812ae4 10109 tcg_temp_free_i64(fp64);
7c979afd 10110 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 10111 tcg_temp_free_i32(fp32);
b6d96bed 10112 }
5a5012ec 10113 break;
bf4120ad 10114 case OPC_CVT_L_D:
5e755519 10115 check_cp1_64bitmode(ctx);
b6d96bed 10116 {
a7812ae4 10117 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
10118
10119 gen_load_fpr64(ctx, fp0, fs);
87552089
AM
10120 if (ctx->nan2008) {
10121 gen_helper_float_cvt_2008_l_d(fp0, cpu_env, fp0);
10122 } else {
10123 gen_helper_float_cvt_l_d(fp0, cpu_env, fp0);
10124 }
b6d96bed 10125 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10126 tcg_temp_free_i64(fp0);
b6d96bed 10127 }
5a5012ec 10128 break;
bf4120ad 10129 case OPC_CVT_S_W:
b6d96bed 10130 {
a7812ae4 10131 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 10132
7c979afd 10133 gen_load_fpr32(ctx, fp0, fs);
895c2d04 10134 gen_helper_float_cvts_w(fp0, cpu_env, fp0);
7c979afd 10135 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 10136 tcg_temp_free_i32(fp0);
b6d96bed 10137 }
6ea83fed 10138 break;
bf4120ad 10139 case OPC_CVT_D_W:
5e755519 10140 check_cp1_registers(ctx, fd);
b6d96bed 10141 {
a7812ae4
PB
10142 TCGv_i32 fp32 = tcg_temp_new_i32();
10143 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 10144
7c979afd 10145 gen_load_fpr32(ctx, fp32, fs);
895c2d04 10146 gen_helper_float_cvtd_w(fp64, cpu_env, fp32);
a7812ae4 10147 tcg_temp_free_i32(fp32);
b6d96bed 10148 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 10149 tcg_temp_free_i64(fp64);
b6d96bed 10150 }
5a5012ec 10151 break;
bf4120ad 10152 case OPC_CVT_S_L:
5e755519 10153 check_cp1_64bitmode(ctx);
b6d96bed 10154 {
a7812ae4
PB
10155 TCGv_i32 fp32 = tcg_temp_new_i32();
10156 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
10157
10158 gen_load_fpr64(ctx, fp64, fs);
895c2d04 10159 gen_helper_float_cvts_l(fp32, cpu_env, fp64);
a7812ae4 10160 tcg_temp_free_i64(fp64);
7c979afd 10161 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 10162 tcg_temp_free_i32(fp32);
b6d96bed 10163 }
5a5012ec 10164 break;
bf4120ad 10165 case OPC_CVT_D_L:
5e755519 10166 check_cp1_64bitmode(ctx);
b6d96bed 10167 {
a7812ae4 10168 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
10169
10170 gen_load_fpr64(ctx, fp0, fs);
895c2d04 10171 gen_helper_float_cvtd_l(fp0, cpu_env, fp0);
b6d96bed 10172 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10173 tcg_temp_free_i64(fp0);
b6d96bed 10174 }
5a5012ec 10175 break;
bf4120ad 10176 case OPC_CVT_PS_PW:
e29c9628 10177 check_ps(ctx);
b6d96bed 10178 {
a7812ae4 10179 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
10180
10181 gen_load_fpr64(ctx, fp0, fs);
895c2d04 10182 gen_helper_float_cvtps_pw(fp0, cpu_env, fp0);
b6d96bed 10183 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10184 tcg_temp_free_i64(fp0);
b6d96bed 10185 }
5a5012ec 10186 break;
bf4120ad 10187 case OPC_ADD_PS:
e29c9628 10188 check_ps(ctx);
b6d96bed 10189 {
a7812ae4
PB
10190 TCGv_i64 fp0 = tcg_temp_new_i64();
10191 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
10192
10193 gen_load_fpr64(ctx, fp0, fs);
10194 gen_load_fpr64(ctx, fp1, ft);
895c2d04 10195 gen_helper_float_add_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 10196 tcg_temp_free_i64(fp1);
b6d96bed 10197 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10198 tcg_temp_free_i64(fp0);
b6d96bed 10199 }
6ea83fed 10200 break;
bf4120ad 10201 case OPC_SUB_PS:
e29c9628 10202 check_ps(ctx);
b6d96bed 10203 {
a7812ae4
PB
10204 TCGv_i64 fp0 = tcg_temp_new_i64();
10205 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
10206
10207 gen_load_fpr64(ctx, fp0, fs);
10208 gen_load_fpr64(ctx, fp1, ft);
895c2d04 10209 gen_helper_float_sub_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 10210 tcg_temp_free_i64(fp1);
b6d96bed 10211 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10212 tcg_temp_free_i64(fp0);
b6d96bed 10213 }
6ea83fed 10214 break;
bf4120ad 10215 case OPC_MUL_PS:
e29c9628 10216 check_ps(ctx);
b6d96bed 10217 {
a7812ae4
PB
10218 TCGv_i64 fp0 = tcg_temp_new_i64();
10219 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
10220
10221 gen_load_fpr64(ctx, fp0, fs);
10222 gen_load_fpr64(ctx, fp1, ft);
895c2d04 10223 gen_helper_float_mul_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 10224 tcg_temp_free_i64(fp1);
b6d96bed 10225 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10226 tcg_temp_free_i64(fp0);
b6d96bed 10227 }
6ea83fed 10228 break;
bf4120ad 10229 case OPC_ABS_PS:
e29c9628 10230 check_ps(ctx);
b6d96bed 10231 {
a7812ae4 10232 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
10233
10234 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 10235 gen_helper_float_abs_ps(fp0, fp0);
b6d96bed 10236 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10237 tcg_temp_free_i64(fp0);
b6d96bed 10238 }
6ea83fed 10239 break;
bf4120ad 10240 case OPC_MOV_PS:
e29c9628 10241 check_ps(ctx);
b6d96bed 10242 {
a7812ae4 10243 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
10244
10245 gen_load_fpr64(ctx, fp0, fs);
10246 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10247 tcg_temp_free_i64(fp0);
b6d96bed 10248 }
6ea83fed 10249 break;
bf4120ad 10250 case OPC_NEG_PS:
e29c9628 10251 check_ps(ctx);
b6d96bed 10252 {
a7812ae4 10253 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
10254
10255 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 10256 gen_helper_float_chs_ps(fp0, fp0);
b6d96bed 10257 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10258 tcg_temp_free_i64(fp0);
b6d96bed 10259 }
6ea83fed 10260 break;
bf4120ad 10261 case OPC_MOVCF_PS:
e29c9628 10262 check_ps(ctx);
7f6613ce 10263 gen_movcf_ps(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
6ea83fed 10264 break;
bf4120ad 10265 case OPC_MOVZ_PS:
e29c9628 10266 check_ps(ctx);
a16336e4 10267 {
42a268c2 10268 TCGLabel *l1 = gen_new_label();
30a3848b 10269 TCGv_i64 fp0;
a16336e4 10270
c9297f4d
AJ
10271 if (ft != 0)
10272 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
10273 fp0 = tcg_temp_new_i64();
10274 gen_load_fpr64(ctx, fp0, fs);
10275 gen_store_fpr64(ctx, fp0, fd);
10276 tcg_temp_free_i64(fp0);
a16336e4
TS
10277 gen_set_label(l1);
10278 }
6ea83fed 10279 break;
bf4120ad 10280 case OPC_MOVN_PS:
e29c9628 10281 check_ps(ctx);
a16336e4 10282 {
42a268c2 10283 TCGLabel *l1 = gen_new_label();
30a3848b 10284 TCGv_i64 fp0;
c9297f4d
AJ
10285
10286 if (ft != 0) {
10287 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
10288 fp0 = tcg_temp_new_i64();
10289 gen_load_fpr64(ctx, fp0, fs);
10290 gen_store_fpr64(ctx, fp0, fd);
10291 tcg_temp_free_i64(fp0);
10292 gen_set_label(l1);
10293 }
a16336e4 10294 }
6ea83fed 10295 break;
bf4120ad 10296 case OPC_ADDR_PS:
e29c9628 10297 check_ps(ctx);
b6d96bed 10298 {
a7812ae4
PB
10299 TCGv_i64 fp0 = tcg_temp_new_i64();
10300 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
10301
10302 gen_load_fpr64(ctx, fp0, ft);
10303 gen_load_fpr64(ctx, fp1, fs);
895c2d04 10304 gen_helper_float_addr_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 10305 tcg_temp_free_i64(fp1);
b6d96bed 10306 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10307 tcg_temp_free_i64(fp0);
b6d96bed 10308 }
fbcc6828 10309 break;
bf4120ad 10310 case OPC_MULR_PS:
e29c9628 10311 check_ps(ctx);
b6d96bed 10312 {
a7812ae4
PB
10313 TCGv_i64 fp0 = tcg_temp_new_i64();
10314 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
10315
10316 gen_load_fpr64(ctx, fp0, ft);
10317 gen_load_fpr64(ctx, fp1, fs);
895c2d04 10318 gen_helper_float_mulr_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 10319 tcg_temp_free_i64(fp1);
b6d96bed 10320 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10321 tcg_temp_free_i64(fp0);
b6d96bed 10322 }
57fa1fb3 10323 break;
bf4120ad 10324 case OPC_RECIP2_PS:
e29c9628 10325 check_ps(ctx);
b6d96bed 10326 {
a7812ae4
PB
10327 TCGv_i64 fp0 = tcg_temp_new_i64();
10328 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
10329
10330 gen_load_fpr64(ctx, fp0, fs);
d22d7289 10331 gen_load_fpr64(ctx, fp1, ft);
895c2d04 10332 gen_helper_float_recip2_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 10333 tcg_temp_free_i64(fp1);
b6d96bed 10334 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10335 tcg_temp_free_i64(fp0);
b6d96bed 10336 }
57fa1fb3 10337 break;
bf4120ad 10338 case OPC_RECIP1_PS:
e29c9628 10339 check_ps(ctx);
b6d96bed 10340 {
a7812ae4 10341 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
10342
10343 gen_load_fpr64(ctx, fp0, fs);
895c2d04 10344 gen_helper_float_recip1_ps(fp0, cpu_env, fp0);
b6d96bed 10345 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10346 tcg_temp_free_i64(fp0);
b6d96bed 10347 }
57fa1fb3 10348 break;
bf4120ad 10349 case OPC_RSQRT1_PS:
e29c9628 10350 check_ps(ctx);
b6d96bed 10351 {
a7812ae4 10352 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
10353
10354 gen_load_fpr64(ctx, fp0, fs);
895c2d04 10355 gen_helper_float_rsqrt1_ps(fp0, cpu_env, fp0);
b6d96bed 10356 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10357 tcg_temp_free_i64(fp0);
b6d96bed 10358 }
57fa1fb3 10359 break;
bf4120ad 10360 case OPC_RSQRT2_PS:
e29c9628 10361 check_ps(ctx);
b6d96bed 10362 {
a7812ae4
PB
10363 TCGv_i64 fp0 = tcg_temp_new_i64();
10364 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
10365
10366 gen_load_fpr64(ctx, fp0, fs);
10367 gen_load_fpr64(ctx, fp1, ft);
895c2d04 10368 gen_helper_float_rsqrt2_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 10369 tcg_temp_free_i64(fp1);
b6d96bed 10370 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10371 tcg_temp_free_i64(fp0);
b6d96bed 10372 }
57fa1fb3 10373 break;
bf4120ad 10374 case OPC_CVT_S_PU:
5e755519 10375 check_cp1_64bitmode(ctx);
b6d96bed 10376 {
a7812ae4 10377 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 10378
7f6613ce 10379 gen_load_fpr32h(ctx, fp0, fs);
895c2d04 10380 gen_helper_float_cvts_pu(fp0, cpu_env, fp0);
7c979afd 10381 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 10382 tcg_temp_free_i32(fp0);
b6d96bed 10383 }
dd016883 10384 break;
bf4120ad 10385 case OPC_CVT_PW_PS:
e29c9628 10386 check_ps(ctx);
b6d96bed 10387 {
a7812ae4 10388 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
10389
10390 gen_load_fpr64(ctx, fp0, fs);
895c2d04 10391 gen_helper_float_cvtpw_ps(fp0, cpu_env, fp0);
b6d96bed 10392 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10393 tcg_temp_free_i64(fp0);
b6d96bed 10394 }
6ea83fed 10395 break;
bf4120ad 10396 case OPC_CVT_S_PL:
5e755519 10397 check_cp1_64bitmode(ctx);
b6d96bed 10398 {
a7812ae4 10399 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 10400
7c979afd 10401 gen_load_fpr32(ctx, fp0, fs);
895c2d04 10402 gen_helper_float_cvts_pl(fp0, cpu_env, fp0);
7c979afd 10403 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 10404 tcg_temp_free_i32(fp0);
b6d96bed 10405 }
6ea83fed 10406 break;
bf4120ad 10407 case OPC_PLL_PS:
e29c9628 10408 check_ps(ctx);
b6d96bed 10409 {
a7812ae4
PB
10410 TCGv_i32 fp0 = tcg_temp_new_i32();
10411 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 10412
7c979afd
LA
10413 gen_load_fpr32(ctx, fp0, fs);
10414 gen_load_fpr32(ctx, fp1, ft);
7f6613ce 10415 gen_store_fpr32h(ctx, fp0, fd);
7c979afd 10416 gen_store_fpr32(ctx, fp1, fd);
a7812ae4
PB
10417 tcg_temp_free_i32(fp0);
10418 tcg_temp_free_i32(fp1);
b6d96bed 10419 }
6ea83fed 10420 break;
bf4120ad 10421 case OPC_PLU_PS:
e29c9628 10422 check_ps(ctx);
b6d96bed 10423 {
a7812ae4
PB
10424 TCGv_i32 fp0 = tcg_temp_new_i32();
10425 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 10426
7c979afd 10427 gen_load_fpr32(ctx, fp0, fs);
7f6613ce 10428 gen_load_fpr32h(ctx, fp1, ft);
7c979afd 10429 gen_store_fpr32(ctx, fp1, fd);
7f6613ce 10430 gen_store_fpr32h(ctx, fp0, fd);
a7812ae4
PB
10431 tcg_temp_free_i32(fp0);
10432 tcg_temp_free_i32(fp1);
b6d96bed 10433 }
5a5012ec 10434 break;
bf4120ad 10435 case OPC_PUL_PS:
e29c9628 10436 check_ps(ctx);
b6d96bed 10437 {
a7812ae4
PB
10438 TCGv_i32 fp0 = tcg_temp_new_i32();
10439 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 10440
7f6613ce 10441 gen_load_fpr32h(ctx, fp0, fs);
7c979afd
LA
10442 gen_load_fpr32(ctx, fp1, ft);
10443 gen_store_fpr32(ctx, fp1, fd);
7f6613ce 10444 gen_store_fpr32h(ctx, fp0, fd);
a7812ae4
PB
10445 tcg_temp_free_i32(fp0);
10446 tcg_temp_free_i32(fp1);
b6d96bed 10447 }
5a5012ec 10448 break;
bf4120ad 10449 case OPC_PUU_PS:
e29c9628 10450 check_ps(ctx);
b6d96bed 10451 {
a7812ae4
PB
10452 TCGv_i32 fp0 = tcg_temp_new_i32();
10453 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 10454
7f6613ce
PJ
10455 gen_load_fpr32h(ctx, fp0, fs);
10456 gen_load_fpr32h(ctx, fp1, ft);
7c979afd 10457 gen_store_fpr32(ctx, fp1, fd);
7f6613ce 10458 gen_store_fpr32h(ctx, fp0, fd);
a7812ae4
PB
10459 tcg_temp_free_i32(fp0);
10460 tcg_temp_free_i32(fp1);
b6d96bed 10461 }
5a5012ec 10462 break;
bf4120ad
NF
10463 case OPC_CMP_F_PS:
10464 case OPC_CMP_UN_PS:
10465 case OPC_CMP_EQ_PS:
10466 case OPC_CMP_UEQ_PS:
10467 case OPC_CMP_OLT_PS:
10468 case OPC_CMP_ULT_PS:
10469 case OPC_CMP_OLE_PS:
10470 case OPC_CMP_ULE_PS:
10471 case OPC_CMP_SF_PS:
10472 case OPC_CMP_NGLE_PS:
10473 case OPC_CMP_SEQ_PS:
10474 case OPC_CMP_NGL_PS:
10475 case OPC_CMP_LT_PS:
10476 case OPC_CMP_NGE_PS:
10477 case OPC_CMP_LE_PS:
10478 case OPC_CMP_NGT_PS:
8153667c
NF
10479 if (ctx->opcode & (1 << 6)) {
10480 gen_cmpabs_ps(ctx, func-48, ft, fs, cc);
8153667c
NF
10481 } else {
10482 gen_cmp_ps(ctx, func-48, ft, fs, cc);
5a1e8ffb 10483 }
6ea83fed 10484 break;
5a5012ec 10485 default:
9d68ac14 10486 MIPS_INVAL("farith");
9c708c7f 10487 generate_exception_end(ctx, EXCP_RI);
6ea83fed
FB
10488 return;
10489 }
6ea83fed 10490}
6af0bf9c 10491
5a5012ec 10492/* Coprocessor 3 (FPU) */
5e755519
TS
10493static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
10494 int fd, int fs, int base, int index)
7a387fff 10495{
4e2474d6 10496 TCGv t0 = tcg_temp_new();
7a387fff 10497
93b12ccc 10498 if (base == 0) {
6c5c1e20 10499 gen_load_gpr(t0, index);
93b12ccc 10500 } else if (index == 0) {
6c5c1e20 10501 gen_load_gpr(t0, base);
93b12ccc 10502 } else {
05168674 10503 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]);
93b12ccc 10504 }
5a5012ec 10505 /* Don't do NOP if destination is zero: we must perform the actual
ead9360e 10506 memory access. */
5a5012ec
TS
10507 switch (opc) {
10508 case OPC_LWXC1:
8c0ab41f 10509 check_cop1x(ctx);
b6d96bed 10510 {
a7812ae4 10511 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 10512
5f68f5ae 10513 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
585c88d5 10514 tcg_gen_trunc_tl_i32(fp0, t0);
7c979afd 10515 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 10516 tcg_temp_free_i32(fp0);
b6d96bed 10517 }
5a5012ec
TS
10518 break;
10519 case OPC_LDXC1:
8c0ab41f
AJ
10520 check_cop1x(ctx);
10521 check_cp1_registers(ctx, fd);
b6d96bed 10522 {
a7812ae4 10523 TCGv_i64 fp0 = tcg_temp_new_i64();
5f68f5ae 10524 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
b6d96bed 10525 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10526 tcg_temp_free_i64(fp0);
b6d96bed 10527 }
5a5012ec
TS
10528 break;
10529 case OPC_LUXC1:
8c0ab41f 10530 check_cp1_64bitmode(ctx);
6c5c1e20 10531 tcg_gen_andi_tl(t0, t0, ~0x7);
b6d96bed 10532 {
a7812ae4 10533 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 10534
5f68f5ae 10535 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
b6d96bed 10536 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10537 tcg_temp_free_i64(fp0);
b6d96bed 10538 }
5a5012ec
TS
10539 break;
10540 case OPC_SWXC1:
8c0ab41f 10541 check_cop1x(ctx);
b6d96bed 10542 {
a7812ae4 10543 TCGv_i32 fp0 = tcg_temp_new_i32();
7c979afd 10544 gen_load_fpr32(ctx, fp0, fs);
5f68f5ae 10545 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL);
a7812ae4 10546 tcg_temp_free_i32(fp0);
b6d96bed 10547 }
5a5012ec
TS
10548 break;
10549 case OPC_SDXC1:
8c0ab41f
AJ
10550 check_cop1x(ctx);
10551 check_cp1_registers(ctx, fs);
b6d96bed 10552 {
a7812ae4 10553 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 10554 gen_load_fpr64(ctx, fp0, fs);
5f68f5ae 10555 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
a7812ae4 10556 tcg_temp_free_i64(fp0);
b6d96bed 10557 }
5a5012ec
TS
10558 break;
10559 case OPC_SUXC1:
8c0ab41f 10560 check_cp1_64bitmode(ctx);
6c5c1e20 10561 tcg_gen_andi_tl(t0, t0, ~0x7);
b6d96bed 10562 {
a7812ae4 10563 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 10564 gen_load_fpr64(ctx, fp0, fs);
5f68f5ae 10565 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
a7812ae4 10566 tcg_temp_free_i64(fp0);
b6d96bed 10567 }
5a5012ec 10568 break;
5a5012ec 10569 }
6c5c1e20 10570 tcg_temp_free(t0);
5a5012ec
TS
10571}
10572
5e755519
TS
10573static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
10574 int fd, int fr, int fs, int ft)
5a5012ec 10575{
5a5012ec
TS
10576 switch (opc) {
10577 case OPC_ALNV_PS:
e29c9628 10578 check_ps(ctx);
a16336e4 10579 {
a7812ae4 10580 TCGv t0 = tcg_temp_local_new();
c905fdac
AJ
10581 TCGv_i32 fp = tcg_temp_new_i32();
10582 TCGv_i32 fph = tcg_temp_new_i32();
42a268c2
RH
10583 TCGLabel *l1 = gen_new_label();
10584 TCGLabel *l2 = gen_new_label();
a16336e4 10585
6c5c1e20
TS
10586 gen_load_gpr(t0, fr);
10587 tcg_gen_andi_tl(t0, t0, 0x7);
6c5c1e20
TS
10588
10589 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
7c979afd 10590 gen_load_fpr32(ctx, fp, fs);
7f6613ce 10591 gen_load_fpr32h(ctx, fph, fs);
7c979afd 10592 gen_store_fpr32(ctx, fp, fd);
7f6613ce 10593 gen_store_fpr32h(ctx, fph, fd);
a16336e4
TS
10594 tcg_gen_br(l2);
10595 gen_set_label(l1);
6c5c1e20
TS
10596 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
10597 tcg_temp_free(t0);
a16336e4 10598#ifdef TARGET_WORDS_BIGENDIAN
7c979afd 10599 gen_load_fpr32(ctx, fp, fs);
7f6613ce
PJ
10600 gen_load_fpr32h(ctx, fph, ft);
10601 gen_store_fpr32h(ctx, fp, fd);
7c979afd 10602 gen_store_fpr32(ctx, fph, fd);
a16336e4 10603#else
7f6613ce 10604 gen_load_fpr32h(ctx, fph, fs);
7c979afd
LA
10605 gen_load_fpr32(ctx, fp, ft);
10606 gen_store_fpr32(ctx, fph, fd);
7f6613ce 10607 gen_store_fpr32h(ctx, fp, fd);
a16336e4
TS
10608#endif
10609 gen_set_label(l2);
c905fdac
AJ
10610 tcg_temp_free_i32(fp);
10611 tcg_temp_free_i32(fph);
a16336e4 10612 }
5a5012ec
TS
10613 break;
10614 case OPC_MADD_S:
b8aa4598 10615 check_cop1x(ctx);
b6d96bed 10616 {
a7812ae4
PB
10617 TCGv_i32 fp0 = tcg_temp_new_i32();
10618 TCGv_i32 fp1 = tcg_temp_new_i32();
10619 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed 10620
7c979afd
LA
10621 gen_load_fpr32(ctx, fp0, fs);
10622 gen_load_fpr32(ctx, fp1, ft);
10623 gen_load_fpr32(ctx, fp2, fr);
b3d6cd44 10624 gen_helper_float_madd_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10625 tcg_temp_free_i32(fp0);
10626 tcg_temp_free_i32(fp1);
7c979afd 10627 gen_store_fpr32(ctx, fp2, fd);
a7812ae4 10628 tcg_temp_free_i32(fp2);
b6d96bed 10629 }
5a5012ec
TS
10630 break;
10631 case OPC_MADD_D:
b8aa4598
TS
10632 check_cop1x(ctx);
10633 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 10634 {
a7812ae4
PB
10635 TCGv_i64 fp0 = tcg_temp_new_i64();
10636 TCGv_i64 fp1 = tcg_temp_new_i64();
10637 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10638
10639 gen_load_fpr64(ctx, fp0, fs);
10640 gen_load_fpr64(ctx, fp1, ft);
10641 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10642 gen_helper_float_madd_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10643 tcg_temp_free_i64(fp0);
10644 tcg_temp_free_i64(fp1);
b6d96bed 10645 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10646 tcg_temp_free_i64(fp2);
b6d96bed 10647 }
5a5012ec
TS
10648 break;
10649 case OPC_MADD_PS:
e29c9628 10650 check_ps(ctx);
b6d96bed 10651 {
a7812ae4
PB
10652 TCGv_i64 fp0 = tcg_temp_new_i64();
10653 TCGv_i64 fp1 = tcg_temp_new_i64();
10654 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10655
10656 gen_load_fpr64(ctx, fp0, fs);
10657 gen_load_fpr64(ctx, fp1, ft);
10658 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10659 gen_helper_float_madd_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10660 tcg_temp_free_i64(fp0);
10661 tcg_temp_free_i64(fp1);
b6d96bed 10662 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10663 tcg_temp_free_i64(fp2);
b6d96bed 10664 }
5a5012ec
TS
10665 break;
10666 case OPC_MSUB_S:
b8aa4598 10667 check_cop1x(ctx);
b6d96bed 10668 {
a7812ae4
PB
10669 TCGv_i32 fp0 = tcg_temp_new_i32();
10670 TCGv_i32 fp1 = tcg_temp_new_i32();
10671 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed 10672
7c979afd
LA
10673 gen_load_fpr32(ctx, fp0, fs);
10674 gen_load_fpr32(ctx, fp1, ft);
10675 gen_load_fpr32(ctx, fp2, fr);
b3d6cd44 10676 gen_helper_float_msub_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10677 tcg_temp_free_i32(fp0);
10678 tcg_temp_free_i32(fp1);
7c979afd 10679 gen_store_fpr32(ctx, fp2, fd);
a7812ae4 10680 tcg_temp_free_i32(fp2);
b6d96bed 10681 }
5a5012ec
TS
10682 break;
10683 case OPC_MSUB_D:
b8aa4598
TS
10684 check_cop1x(ctx);
10685 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 10686 {
a7812ae4
PB
10687 TCGv_i64 fp0 = tcg_temp_new_i64();
10688 TCGv_i64 fp1 = tcg_temp_new_i64();
10689 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10690
10691 gen_load_fpr64(ctx, fp0, fs);
10692 gen_load_fpr64(ctx, fp1, ft);
10693 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10694 gen_helper_float_msub_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10695 tcg_temp_free_i64(fp0);
10696 tcg_temp_free_i64(fp1);
b6d96bed 10697 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10698 tcg_temp_free_i64(fp2);
b6d96bed 10699 }
5a5012ec
TS
10700 break;
10701 case OPC_MSUB_PS:
e29c9628 10702 check_ps(ctx);
b6d96bed 10703 {
a7812ae4
PB
10704 TCGv_i64 fp0 = tcg_temp_new_i64();
10705 TCGv_i64 fp1 = tcg_temp_new_i64();
10706 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10707
10708 gen_load_fpr64(ctx, fp0, fs);
10709 gen_load_fpr64(ctx, fp1, ft);
10710 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10711 gen_helper_float_msub_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10712 tcg_temp_free_i64(fp0);
10713 tcg_temp_free_i64(fp1);
b6d96bed 10714 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10715 tcg_temp_free_i64(fp2);
b6d96bed 10716 }
5a5012ec
TS
10717 break;
10718 case OPC_NMADD_S:
b8aa4598 10719 check_cop1x(ctx);
b6d96bed 10720 {
a7812ae4
PB
10721 TCGv_i32 fp0 = tcg_temp_new_i32();
10722 TCGv_i32 fp1 = tcg_temp_new_i32();
10723 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed 10724
7c979afd
LA
10725 gen_load_fpr32(ctx, fp0, fs);
10726 gen_load_fpr32(ctx, fp1, ft);
10727 gen_load_fpr32(ctx, fp2, fr);
b3d6cd44 10728 gen_helper_float_nmadd_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10729 tcg_temp_free_i32(fp0);
10730 tcg_temp_free_i32(fp1);
7c979afd 10731 gen_store_fpr32(ctx, fp2, fd);
a7812ae4 10732 tcg_temp_free_i32(fp2);
b6d96bed 10733 }
5a5012ec
TS
10734 break;
10735 case OPC_NMADD_D:
b8aa4598
TS
10736 check_cop1x(ctx);
10737 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 10738 {
a7812ae4
PB
10739 TCGv_i64 fp0 = tcg_temp_new_i64();
10740 TCGv_i64 fp1 = tcg_temp_new_i64();
10741 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10742
10743 gen_load_fpr64(ctx, fp0, fs);
10744 gen_load_fpr64(ctx, fp1, ft);
10745 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10746 gen_helper_float_nmadd_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10747 tcg_temp_free_i64(fp0);
10748 tcg_temp_free_i64(fp1);
b6d96bed 10749 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10750 tcg_temp_free_i64(fp2);
b6d96bed 10751 }
5a5012ec
TS
10752 break;
10753 case OPC_NMADD_PS:
e29c9628 10754 check_ps(ctx);
b6d96bed 10755 {
a7812ae4
PB
10756 TCGv_i64 fp0 = tcg_temp_new_i64();
10757 TCGv_i64 fp1 = tcg_temp_new_i64();
10758 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10759
10760 gen_load_fpr64(ctx, fp0, fs);
10761 gen_load_fpr64(ctx, fp1, ft);
10762 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10763 gen_helper_float_nmadd_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10764 tcg_temp_free_i64(fp0);
10765 tcg_temp_free_i64(fp1);
b6d96bed 10766 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10767 tcg_temp_free_i64(fp2);
b6d96bed 10768 }
5a5012ec
TS
10769 break;
10770 case OPC_NMSUB_S:
b8aa4598 10771 check_cop1x(ctx);
b6d96bed 10772 {
a7812ae4
PB
10773 TCGv_i32 fp0 = tcg_temp_new_i32();
10774 TCGv_i32 fp1 = tcg_temp_new_i32();
10775 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed 10776
7c979afd
LA
10777 gen_load_fpr32(ctx, fp0, fs);
10778 gen_load_fpr32(ctx, fp1, ft);
10779 gen_load_fpr32(ctx, fp2, fr);
b3d6cd44 10780 gen_helper_float_nmsub_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10781 tcg_temp_free_i32(fp0);
10782 tcg_temp_free_i32(fp1);
7c979afd 10783 gen_store_fpr32(ctx, fp2, fd);
a7812ae4 10784 tcg_temp_free_i32(fp2);
b6d96bed 10785 }
5a5012ec
TS
10786 break;
10787 case OPC_NMSUB_D:
b8aa4598
TS
10788 check_cop1x(ctx);
10789 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 10790 {
a7812ae4
PB
10791 TCGv_i64 fp0 = tcg_temp_new_i64();
10792 TCGv_i64 fp1 = tcg_temp_new_i64();
10793 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10794
10795 gen_load_fpr64(ctx, fp0, fs);
10796 gen_load_fpr64(ctx, fp1, ft);
10797 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10798 gen_helper_float_nmsub_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10799 tcg_temp_free_i64(fp0);
10800 tcg_temp_free_i64(fp1);
b6d96bed 10801 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10802 tcg_temp_free_i64(fp2);
b6d96bed 10803 }
5a5012ec
TS
10804 break;
10805 case OPC_NMSUB_PS:
e29c9628 10806 check_ps(ctx);
b6d96bed 10807 {
a7812ae4
PB
10808 TCGv_i64 fp0 = tcg_temp_new_i64();
10809 TCGv_i64 fp1 = tcg_temp_new_i64();
10810 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10811
10812 gen_load_fpr64(ctx, fp0, fs);
10813 gen_load_fpr64(ctx, fp1, ft);
10814 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10815 gen_helper_float_nmsub_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10816 tcg_temp_free_i64(fp0);
10817 tcg_temp_free_i64(fp1);
b6d96bed 10818 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10819 tcg_temp_free_i64(fp2);
b6d96bed 10820 }
5a5012ec 10821 break;
923617a3 10822 default:
9d68ac14 10823 MIPS_INVAL("flt3_arith");
9c708c7f 10824 generate_exception_end(ctx, EXCP_RI);
5a5012ec
TS
10825 return;
10826 }
7a387fff
TS
10827}
10828
b00c7218 10829static void gen_rdhwr(DisasContext *ctx, int rt, int rd, int sel)
26ebe468
NF
10830{
10831 TCGv t0;
10832
b3167288
RH
10833#if !defined(CONFIG_USER_ONLY)
10834 /* The Linux kernel will emulate rdhwr if it's not supported natively.
10835 Therefore only check the ISA in system mode. */
d75c135e 10836 check_insn(ctx, ISA_MIPS32R2);
b3167288 10837#endif
26ebe468
NF
10838 t0 = tcg_temp_new();
10839
10840 switch (rd) {
10841 case 0:
895c2d04 10842 gen_helper_rdhwr_cpunum(t0, cpu_env);
26ebe468
NF
10843 gen_store_gpr(t0, rt);
10844 break;
10845 case 1:
895c2d04 10846 gen_helper_rdhwr_synci_step(t0, cpu_env);
26ebe468
NF
10847 gen_store_gpr(t0, rt);
10848 break;
10849 case 2:
eeb3bba8 10850 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
d673a68d
JH
10851 gen_io_start();
10852 }
895c2d04 10853 gen_helper_rdhwr_cc(t0, cpu_env);
eeb3bba8 10854 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
d673a68d
JH
10855 gen_io_end();
10856 }
26ebe468 10857 gen_store_gpr(t0, rt);
d673a68d 10858 /* Break the TB to be able to take timer interrupts immediately
b28425ba 10859 after reading count. DISAS_STOP isn't sufficient, we need to ensure
d673a68d 10860 we break completely out of translated code. */
eeb3bba8
EC
10861 gen_save_pc(ctx->base.pc_next + 4);
10862 ctx->base.is_jmp = DISAS_EXIT;
26ebe468
NF
10863 break;
10864 case 3:
895c2d04 10865 gen_helper_rdhwr_ccres(t0, cpu_env);
26ebe468
NF
10866 gen_store_gpr(t0, rt);
10867 break;
b00c7218
YK
10868 case 4:
10869 check_insn(ctx, ISA_MIPS32R6);
10870 if (sel != 0) {
10871 /* Performance counter registers are not implemented other than
10872 * control register 0.
10873 */
10874 generate_exception(ctx, EXCP_RI);
10875 }
10876 gen_helper_rdhwr_performance(t0, cpu_env);
10877 gen_store_gpr(t0, rt);
10878 break;
10879 case 5:
10880 check_insn(ctx, ISA_MIPS32R6);
10881 gen_helper_rdhwr_xnp(t0, cpu_env);
10882 gen_store_gpr(t0, rt);
10883 break;
26ebe468
NF
10884 case 29:
10885#if defined(CONFIG_USER_ONLY)
d279279e
PJ
10886 tcg_gen_ld_tl(t0, cpu_env,
10887 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
26ebe468
NF
10888 gen_store_gpr(t0, rt);
10889 break;
10890#else
d279279e
PJ
10891 if ((ctx->hflags & MIPS_HFLAG_CP0) ||
10892 (ctx->hflags & MIPS_HFLAG_HWRENA_ULR)) {
10893 tcg_gen_ld_tl(t0, cpu_env,
10894 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
10895 gen_store_gpr(t0, rt);
10896 } else {
9c708c7f 10897 generate_exception_end(ctx, EXCP_RI);
d279279e
PJ
10898 }
10899 break;
26ebe468
NF
10900#endif
10901 default: /* Invalid */
10902 MIPS_INVAL("rdhwr");
9c708c7f 10903 generate_exception_end(ctx, EXCP_RI);
26ebe468
NF
10904 break;
10905 }
10906 tcg_temp_free(t0);
10907}
10908
a5f53390
LA
10909static inline void clear_branch_hflags(DisasContext *ctx)
10910{
10911 ctx->hflags &= ~MIPS_HFLAG_BMASK;
eeb3bba8 10912 if (ctx->base.is_jmp == DISAS_NEXT) {
a5f53390
LA
10913 save_cpu_state(ctx, 0);
10914 } else {
10915 /* it is not safe to save ctx->hflags as hflags may be changed
10916 in execution time by the instruction in delay / forbidden slot. */
10917 tcg_gen_andi_i32(hflags, hflags, ~MIPS_HFLAG_BMASK);
10918 }
10919}
10920
31837be3 10921static void gen_branch(DisasContext *ctx, int insn_bytes)
c9602061
NF
10922{
10923 if (ctx->hflags & MIPS_HFLAG_BMASK) {
364d4831 10924 int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
c9602061 10925 /* Branches completion */
a5f53390 10926 clear_branch_hflags(ctx);
eeb3bba8 10927 ctx->base.is_jmp = DISAS_NORETURN;
c9602061 10928 /* FIXME: Need to clear can_do_io. */
364d4831 10929 switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
339cd2a8 10930 case MIPS_HFLAG_FBNSLOT:
eeb3bba8 10931 gen_goto_tb(ctx, 0, ctx->base.pc_next + insn_bytes);
339cd2a8 10932 break;
c9602061
NF
10933 case MIPS_HFLAG_B:
10934 /* unconditional branch */
364d4831
NF
10935 if (proc_hflags & MIPS_HFLAG_BX) {
10936 tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
10937 }
c9602061
NF
10938 gen_goto_tb(ctx, 0, ctx->btarget);
10939 break;
10940 case MIPS_HFLAG_BL:
10941 /* blikely taken case */
c9602061
NF
10942 gen_goto_tb(ctx, 0, ctx->btarget);
10943 break;
10944 case MIPS_HFLAG_BC:
10945 /* Conditional branch */
c9602061 10946 {
42a268c2 10947 TCGLabel *l1 = gen_new_label();
c9602061
NF
10948
10949 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
eeb3bba8 10950 gen_goto_tb(ctx, 1, ctx->base.pc_next + insn_bytes);
c9602061
NF
10951 gen_set_label(l1);
10952 gen_goto_tb(ctx, 0, ctx->btarget);
10953 }
10954 break;
10955 case MIPS_HFLAG_BR:
10956 /* unconditional branch to register */
d75c135e 10957 if (ctx->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
364d4831
NF
10958 TCGv t0 = tcg_temp_new();
10959 TCGv_i32 t1 = tcg_temp_new_i32();
10960
10961 tcg_gen_andi_tl(t0, btarget, 0x1);
10962 tcg_gen_trunc_tl_i32(t1, t0);
10963 tcg_temp_free(t0);
10964 tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
10965 tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
10966 tcg_gen_or_i32(hflags, hflags, t1);
10967 tcg_temp_free_i32(t1);
10968
10969 tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
10970 } else {
10971 tcg_gen_mov_tl(cpu_PC, btarget);
10972 }
eeb3bba8 10973 if (ctx->base.singlestep_enabled) {
c9602061 10974 save_cpu_state(ctx, 0);
9c708c7f 10975 gen_helper_raise_exception_debug(cpu_env);
c9602061 10976 }
7f11636d 10977 tcg_gen_lookup_and_goto_ptr();
c9602061
NF
10978 break;
10979 default:
a5f53390
LA
10980 fprintf(stderr, "unknown branch 0x%x\n", proc_hflags);
10981 abort();
c9602061
NF
10982 }
10983 }
10984}
10985
6893f074
YK
10986/* Compact Branches */
10987static void gen_compute_compact_branch(DisasContext *ctx, uint32_t opc,
10988 int rs, int rt, int32_t offset)
10989{
10990 int bcond_compute = 0;
10991 TCGv t0 = tcg_temp_new();
10992 TCGv t1 = tcg_temp_new();
65935f07 10993 int m16_lowbit = (ctx->hflags & MIPS_HFLAG_M16) != 0;
6893f074
YK
10994
10995 if (ctx->hflags & MIPS_HFLAG_BMASK) {
10996#ifdef MIPS_DEBUG_DISAS
10997 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
eeb3bba8 10998 "\n", ctx->base.pc_next);
6893f074 10999#endif
9c708c7f 11000 generate_exception_end(ctx, EXCP_RI);
6893f074
YK
11001 goto out;
11002 }
11003
11004 /* Load needed operands and calculate btarget */
11005 switch (opc) {
11006 /* compact branch */
11007 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
11008 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
11009 gen_load_gpr(t0, rs);
11010 gen_load_gpr(t1, rt);
11011 bcond_compute = 1;
eeb3bba8 11012 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
6893f074
YK
11013 if (rs <= rt && rs == 0) {
11014 /* OPC_BEQZALC, OPC_BNEZALC */
eeb3bba8 11015 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
6893f074
YK
11016 }
11017 break;
11018 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
11019 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
11020 gen_load_gpr(t0, rs);
11021 gen_load_gpr(t1, rt);
11022 bcond_compute = 1;
eeb3bba8 11023 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
6893f074
YK
11024 break;
11025 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
11026 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
11027 if (rs == 0 || rs == rt) {
11028 /* OPC_BLEZALC, OPC_BGEZALC */
11029 /* OPC_BGTZALC, OPC_BLTZALC */
eeb3bba8 11030 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
6893f074
YK
11031 }
11032 gen_load_gpr(t0, rs);
11033 gen_load_gpr(t1, rt);
11034 bcond_compute = 1;
eeb3bba8 11035 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
6893f074
YK
11036 break;
11037 case OPC_BC:
11038 case OPC_BALC:
eeb3bba8 11039 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
6893f074
YK
11040 break;
11041 case OPC_BEQZC:
11042 case OPC_BNEZC:
11043 if (rs != 0) {
11044 /* OPC_BEQZC, OPC_BNEZC */
11045 gen_load_gpr(t0, rs);
11046 bcond_compute = 1;
eeb3bba8 11047 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
6893f074
YK
11048 } else {
11049 /* OPC_JIC, OPC_JIALC */
11050 TCGv tbase = tcg_temp_new();
11051 TCGv toffset = tcg_temp_new();
11052
11053 gen_load_gpr(tbase, rt);
11054 tcg_gen_movi_tl(toffset, offset);
11055 gen_op_addr_add(ctx, btarget, tbase, toffset);
11056 tcg_temp_free(tbase);
11057 tcg_temp_free(toffset);
11058 }
11059 break;
11060 default:
11061 MIPS_INVAL("Compact branch/jump");
9c708c7f 11062 generate_exception_end(ctx, EXCP_RI);
6893f074
YK
11063 goto out;
11064 }
11065
11066 if (bcond_compute == 0) {
11067 /* Uncoditional compact branch */
11068 switch (opc) {
11069 case OPC_JIALC:
eeb3bba8 11070 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
6893f074
YK
11071 /* Fallthrough */
11072 case OPC_JIC:
11073 ctx->hflags |= MIPS_HFLAG_BR;
11074 break;
11075 case OPC_BALC:
eeb3bba8 11076 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
6893f074
YK
11077 /* Fallthrough */
11078 case OPC_BC:
11079 ctx->hflags |= MIPS_HFLAG_B;
11080 break;
11081 default:
11082 MIPS_INVAL("Compact branch/jump");
9c708c7f 11083 generate_exception_end(ctx, EXCP_RI);
6893f074
YK
11084 goto out;
11085 }
11086
11087 /* Generating branch here as compact branches don't have delay slot */
11088 gen_branch(ctx, 4);
11089 } else {
11090 /* Conditional compact branch */
11091 TCGLabel *fs = gen_new_label();
11092 save_cpu_state(ctx, 0);
11093
11094 switch (opc) {
11095 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
11096 if (rs == 0 && rt != 0) {
11097 /* OPC_BLEZALC */
11098 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
11099 } else if (rs != 0 && rt != 0 && rs == rt) {
11100 /* OPC_BGEZALC */
11101 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
11102 } else {
11103 /* OPC_BGEUC */
11104 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU), t0, t1, fs);
11105 }
11106 break;
11107 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
11108 if (rs == 0 && rt != 0) {
11109 /* OPC_BGTZALC */
11110 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
11111 } else if (rs != 0 && rt != 0 && rs == rt) {
11112 /* OPC_BLTZALC */
11113 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
11114 } else {
11115 /* OPC_BLTUC */
11116 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU), t0, t1, fs);
11117 }
11118 break;
11119 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
11120 if (rs == 0 && rt != 0) {
11121 /* OPC_BLEZC */
11122 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
11123 } else if (rs != 0 && rt != 0 && rs == rt) {
11124 /* OPC_BGEZC */
11125 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
11126 } else {
11127 /* OPC_BGEC */
11128 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE), t0, t1, fs);
11129 }
11130 break;
11131 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
11132 if (rs == 0 && rt != 0) {
11133 /* OPC_BGTZC */
11134 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
11135 } else if (rs != 0 && rt != 0 && rs == rt) {
11136 /* OPC_BLTZC */
11137 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
11138 } else {
11139 /* OPC_BLTC */
11140 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT), t0, t1, fs);
11141 }
11142 break;
11143 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
11144 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
11145 if (rs >= rt) {
11146 /* OPC_BOVC, OPC_BNVC */
11147 TCGv t2 = tcg_temp_new();
11148 TCGv t3 = tcg_temp_new();
11149 TCGv t4 = tcg_temp_new();
11150 TCGv input_overflow = tcg_temp_new();
11151
11152 gen_load_gpr(t0, rs);
11153 gen_load_gpr(t1, rt);
11154 tcg_gen_ext32s_tl(t2, t0);
11155 tcg_gen_setcond_tl(TCG_COND_NE, input_overflow, t2, t0);
11156 tcg_gen_ext32s_tl(t3, t1);
11157 tcg_gen_setcond_tl(TCG_COND_NE, t4, t3, t1);
11158 tcg_gen_or_tl(input_overflow, input_overflow, t4);
11159
11160 tcg_gen_add_tl(t4, t2, t3);
11161 tcg_gen_ext32s_tl(t4, t4);
11162 tcg_gen_xor_tl(t2, t2, t3);
11163 tcg_gen_xor_tl(t3, t4, t3);
11164 tcg_gen_andc_tl(t2, t3, t2);
11165 tcg_gen_setcondi_tl(TCG_COND_LT, t4, t2, 0);
11166 tcg_gen_or_tl(t4, t4, input_overflow);
11167 if (opc == OPC_BOVC) {
11168 /* OPC_BOVC */
11169 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t4, 0, fs);
11170 } else {
11171 /* OPC_BNVC */
11172 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t4, 0, fs);
11173 }
11174 tcg_temp_free(input_overflow);
11175 tcg_temp_free(t4);
11176 tcg_temp_free(t3);
11177 tcg_temp_free(t2);
11178 } else if (rs < rt && rs == 0) {
11179 /* OPC_BEQZALC, OPC_BNEZALC */
11180 if (opc == OPC_BEQZALC) {
11181 /* OPC_BEQZALC */
11182 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t1, 0, fs);
11183 } else {
11184 /* OPC_BNEZALC */
11185 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t1, 0, fs);
11186 }
11187 } else {
11188 /* OPC_BEQC, OPC_BNEC */
11189 if (opc == OPC_BEQC) {
11190 /* OPC_BEQC */
11191 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_EQ), t0, t1, fs);
11192 } else {
11193 /* OPC_BNEC */
11194 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_NE), t0, t1, fs);
11195 }
11196 }
11197 break;
11198 case OPC_BEQZC:
11199 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t0, 0, fs);
11200 break;
11201 case OPC_BNEZC:
11202 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t0, 0, fs);
11203 break;
11204 default:
11205 MIPS_INVAL("Compact conditional branch/jump");
9c708c7f 11206 generate_exception_end(ctx, EXCP_RI);
6893f074
YK
11207 goto out;
11208 }
11209
11210 /* Generating branch here as compact branches don't have delay slot */
11211 gen_goto_tb(ctx, 1, ctx->btarget);
11212 gen_set_label(fs);
11213
11214 ctx->hflags |= MIPS_HFLAG_FBNSLOT;
6893f074
YK
11215 }
11216
11217out:
11218 tcg_temp_free(t0);
11219 tcg_temp_free(t1);
11220}
11221
7a387fff 11222/* ISA extensions (ASEs) */
6af0bf9c 11223/* MIPS16 extension to MIPS32 */
6ea219d0
NF
11224
11225/* MIPS16 major opcodes */
11226enum {
11227 M16_OPC_ADDIUSP = 0x00,
11228 M16_OPC_ADDIUPC = 0x01,
11229 M16_OPC_B = 0x02,
11230 M16_OPC_JAL = 0x03,
11231 M16_OPC_BEQZ = 0x04,
11232 M16_OPC_BNEQZ = 0x05,
11233 M16_OPC_SHIFT = 0x06,
11234 M16_OPC_LD = 0x07,
11235 M16_OPC_RRIA = 0x08,
11236 M16_OPC_ADDIU8 = 0x09,
11237 M16_OPC_SLTI = 0x0a,
11238 M16_OPC_SLTIU = 0x0b,
11239 M16_OPC_I8 = 0x0c,
11240 M16_OPC_LI = 0x0d,
11241 M16_OPC_CMPI = 0x0e,
11242 M16_OPC_SD = 0x0f,
11243 M16_OPC_LB = 0x10,
11244 M16_OPC_LH = 0x11,
11245 M16_OPC_LWSP = 0x12,
11246 M16_OPC_LW = 0x13,
11247 M16_OPC_LBU = 0x14,
11248 M16_OPC_LHU = 0x15,
11249 M16_OPC_LWPC = 0x16,
11250 M16_OPC_LWU = 0x17,
11251 M16_OPC_SB = 0x18,
11252 M16_OPC_SH = 0x19,
11253 M16_OPC_SWSP = 0x1a,
11254 M16_OPC_SW = 0x1b,
11255 M16_OPC_RRR = 0x1c,
11256 M16_OPC_RR = 0x1d,
11257 M16_OPC_EXTEND = 0x1e,
11258 M16_OPC_I64 = 0x1f
11259};
11260
11261/* I8 funct field */
11262enum {
11263 I8_BTEQZ = 0x0,
11264 I8_BTNEZ = 0x1,
11265 I8_SWRASP = 0x2,
11266 I8_ADJSP = 0x3,
11267 I8_SVRS = 0x4,
11268 I8_MOV32R = 0x5,
11269 I8_MOVR32 = 0x7
11270};
11271
11272/* RRR f field */
11273enum {
11274 RRR_DADDU = 0x0,
11275 RRR_ADDU = 0x1,
11276 RRR_DSUBU = 0x2,
11277 RRR_SUBU = 0x3
11278};
11279
11280/* RR funct field */
11281enum {
11282 RR_JR = 0x00,
11283 RR_SDBBP = 0x01,
11284 RR_SLT = 0x02,
11285 RR_SLTU = 0x03,
11286 RR_SLLV = 0x04,
11287 RR_BREAK = 0x05,
11288 RR_SRLV = 0x06,
11289 RR_SRAV = 0x07,
11290 RR_DSRL = 0x08,
11291 RR_CMP = 0x0a,
11292 RR_NEG = 0x0b,
11293 RR_AND = 0x0c,
11294 RR_OR = 0x0d,
11295 RR_XOR = 0x0e,
11296 RR_NOT = 0x0f,
11297 RR_MFHI = 0x10,
11298 RR_CNVT = 0x11,
11299 RR_MFLO = 0x12,
11300 RR_DSRA = 0x13,
11301 RR_DSLLV = 0x14,
11302 RR_DSRLV = 0x16,
11303 RR_DSRAV = 0x17,
11304 RR_MULT = 0x18,
11305 RR_MULTU = 0x19,
11306 RR_DIV = 0x1a,
11307 RR_DIVU = 0x1b,
11308 RR_DMULT = 0x1c,
11309 RR_DMULTU = 0x1d,
11310 RR_DDIV = 0x1e,
11311 RR_DDIVU = 0x1f
11312};
11313
11314/* I64 funct field */
11315enum {
11316 I64_LDSP = 0x0,
11317 I64_SDSP = 0x1,
11318 I64_SDRASP = 0x2,
11319 I64_DADJSP = 0x3,
11320 I64_LDPC = 0x4,
364d4831 11321 I64_DADDIU5 = 0x5,
6ea219d0
NF
11322 I64_DADDIUPC = 0x6,
11323 I64_DADDIUSP = 0x7
11324};
11325
11326/* RR ry field for CNVT */
11327enum {
11328 RR_RY_CNVT_ZEB = 0x0,
11329 RR_RY_CNVT_ZEH = 0x1,
11330 RR_RY_CNVT_ZEW = 0x2,
11331 RR_RY_CNVT_SEB = 0x4,
11332 RR_RY_CNVT_SEH = 0x5,
11333 RR_RY_CNVT_SEW = 0x6,
11334};
11335
364d4831
NF
11336static int xlat (int r)
11337{
11338 static int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
11339
11340 return map[r];
11341}
11342
11343static void gen_mips16_save (DisasContext *ctx,
11344 int xsregs, int aregs,
11345 int do_ra, int do_s0, int do_s1,
11346 int framesize)
11347{
11348 TCGv t0 = tcg_temp_new();
11349 TCGv t1 = tcg_temp_new();
c48245f0 11350 TCGv t2 = tcg_temp_new();
364d4831
NF
11351 int args, astatic;
11352
11353 switch (aregs) {
11354 case 0:
11355 case 1:
11356 case 2:
11357 case 3:
11358 case 11:
11359 args = 0;
11360 break;
11361 case 4:
11362 case 5:
11363 case 6:
11364 case 7:
11365 args = 1;
11366 break;
11367 case 8:
11368 case 9:
11369 case 10:
11370 args = 2;
11371 break;
11372 case 12:
11373 case 13:
11374 args = 3;
11375 break;
11376 case 14:
11377 args = 4;
11378 break;
11379 default:
9c708c7f 11380 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
11381 return;
11382 }
11383
11384 switch (args) {
11385 case 4:
11386 gen_base_offset_addr(ctx, t0, 29, 12);
11387 gen_load_gpr(t1, 7);
5f68f5ae 11388 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
364d4831
NF
11389 /* Fall through */
11390 case 3:
11391 gen_base_offset_addr(ctx, t0, 29, 8);
11392 gen_load_gpr(t1, 6);
5f68f5ae 11393 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
364d4831
NF
11394 /* Fall through */
11395 case 2:
11396 gen_base_offset_addr(ctx, t0, 29, 4);
11397 gen_load_gpr(t1, 5);
5f68f5ae 11398 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
364d4831
NF
11399 /* Fall through */
11400 case 1:
11401 gen_base_offset_addr(ctx, t0, 29, 0);
11402 gen_load_gpr(t1, 4);
5f68f5ae 11403 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
364d4831
NF
11404 }
11405
11406 gen_load_gpr(t0, 29);
11407
5f68f5ae 11408#define DECR_AND_STORE(reg) do { \
c48245f0
MR
11409 tcg_gen_movi_tl(t2, -4); \
11410 gen_op_addr_add(ctx, t0, t0, t2); \
5f68f5ae
AJ
11411 gen_load_gpr(t1, reg); \
11412 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); \
364d4831
NF
11413 } while (0)
11414
11415 if (do_ra) {
11416 DECR_AND_STORE(31);
11417 }
11418
11419 switch (xsregs) {
11420 case 7:
11421 DECR_AND_STORE(30);
11422 /* Fall through */
11423 case 6:
11424 DECR_AND_STORE(23);
11425 /* Fall through */
11426 case 5:
11427 DECR_AND_STORE(22);
11428 /* Fall through */
11429 case 4:
11430 DECR_AND_STORE(21);
11431 /* Fall through */
11432 case 3:
11433 DECR_AND_STORE(20);
11434 /* Fall through */
11435 case 2:
11436 DECR_AND_STORE(19);
11437 /* Fall through */
11438 case 1:
11439 DECR_AND_STORE(18);
11440 }
11441
11442 if (do_s1) {
11443 DECR_AND_STORE(17);
11444 }
11445 if (do_s0) {
11446 DECR_AND_STORE(16);
11447 }
11448
11449 switch (aregs) {
11450 case 0:
11451 case 4:
11452 case 8:
11453 case 12:
11454 case 14:
11455 astatic = 0;
11456 break;
11457 case 1:
11458 case 5:
11459 case 9:
11460 case 13:
11461 astatic = 1;
11462 break;
11463 case 2:
11464 case 6:
11465 case 10:
11466 astatic = 2;
11467 break;
11468 case 3:
11469 case 7:
11470 astatic = 3;
11471 break;
11472 case 11:
11473 astatic = 4;
11474 break;
11475 default:
9c708c7f 11476 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
11477 return;
11478 }
11479
11480 if (astatic > 0) {
11481 DECR_AND_STORE(7);
11482 if (astatic > 1) {
11483 DECR_AND_STORE(6);
11484 if (astatic > 2) {
11485 DECR_AND_STORE(5);
11486 if (astatic > 3) {
11487 DECR_AND_STORE(4);
11488 }
11489 }
11490 }
11491 }
11492#undef DECR_AND_STORE
11493
c48245f0
MR
11494 tcg_gen_movi_tl(t2, -framesize);
11495 gen_op_addr_add(ctx, cpu_gpr[29], cpu_gpr[29], t2);
364d4831
NF
11496 tcg_temp_free(t0);
11497 tcg_temp_free(t1);
c48245f0 11498 tcg_temp_free(t2);
364d4831
NF
11499}
11500
11501static void gen_mips16_restore (DisasContext *ctx,
11502 int xsregs, int aregs,
11503 int do_ra, int do_s0, int do_s1,
11504 int framesize)
11505{
11506 int astatic;
11507 TCGv t0 = tcg_temp_new();
11508 TCGv t1 = tcg_temp_new();
c48245f0 11509 TCGv t2 = tcg_temp_new();
364d4831 11510
c48245f0
MR
11511 tcg_gen_movi_tl(t2, framesize);
11512 gen_op_addr_add(ctx, t0, cpu_gpr[29], t2);
364d4831 11513
5f68f5ae 11514#define DECR_AND_LOAD(reg) do { \
c48245f0
MR
11515 tcg_gen_movi_tl(t2, -4); \
11516 gen_op_addr_add(ctx, t0, t0, t2); \
5f68f5ae
AJ
11517 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL); \
11518 gen_store_gpr(t1, reg); \
364d4831
NF
11519 } while (0)
11520
11521 if (do_ra) {
11522 DECR_AND_LOAD(31);
11523 }
11524
11525 switch (xsregs) {
11526 case 7:
11527 DECR_AND_LOAD(30);
11528 /* Fall through */
11529 case 6:
11530 DECR_AND_LOAD(23);
11531 /* Fall through */
11532 case 5:
11533 DECR_AND_LOAD(22);
11534 /* Fall through */
11535 case 4:
11536 DECR_AND_LOAD(21);
11537 /* Fall through */
11538 case 3:
11539 DECR_AND_LOAD(20);
11540 /* Fall through */
11541 case 2:
11542 DECR_AND_LOAD(19);
11543 /* Fall through */
11544 case 1:
11545 DECR_AND_LOAD(18);
11546 }
11547
11548 if (do_s1) {
11549 DECR_AND_LOAD(17);
11550 }
11551 if (do_s0) {
11552 DECR_AND_LOAD(16);
11553 }
11554
11555 switch (aregs) {
11556 case 0:
11557 case 4:
11558 case 8:
11559 case 12:
11560 case 14:
11561 astatic = 0;
11562 break;
11563 case 1:
11564 case 5:
11565 case 9:
11566 case 13:
11567 astatic = 1;
11568 break;
11569 case 2:
11570 case 6:
11571 case 10:
11572 astatic = 2;
11573 break;
11574 case 3:
11575 case 7:
11576 astatic = 3;
11577 break;
11578 case 11:
11579 astatic = 4;
11580 break;
11581 default:
9c708c7f 11582 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
11583 return;
11584 }
11585
11586 if (astatic > 0) {
11587 DECR_AND_LOAD(7);
11588 if (astatic > 1) {
11589 DECR_AND_LOAD(6);
11590 if (astatic > 2) {
11591 DECR_AND_LOAD(5);
11592 if (astatic > 3) {
11593 DECR_AND_LOAD(4);
11594 }
11595 }
11596 }
11597 }
11598#undef DECR_AND_LOAD
11599
c48245f0
MR
11600 tcg_gen_movi_tl(t2, framesize);
11601 gen_op_addr_add(ctx, cpu_gpr[29], cpu_gpr[29], t2);
364d4831
NF
11602 tcg_temp_free(t0);
11603 tcg_temp_free(t1);
c48245f0 11604 tcg_temp_free(t2);
364d4831
NF
11605}
11606
11607static void gen_addiupc (DisasContext *ctx, int rx, int imm,
11608 int is_64_bit, int extended)
11609{
11610 TCGv t0;
11611
11612 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9c708c7f 11613 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
11614 return;
11615 }
11616
11617 t0 = tcg_temp_new();
11618
11619 tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
11620 tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
11621 if (!is_64_bit) {
11622 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
11623 }
11624
11625 tcg_temp_free(t0);
11626}
11627
0d74a222
LA
11628static void gen_cache_operation(DisasContext *ctx, uint32_t op, int base,
11629 int16_t offset)
11630{
11631 TCGv_i32 t0 = tcg_const_i32(op);
11632 TCGv t1 = tcg_temp_new();
11633 gen_base_offset_addr(ctx, t1, base, offset);
11634 gen_helper_cache(cpu_env, t1, t0);
11635}
11636
364d4831 11637#if defined(TARGET_MIPS64)
d75c135e 11638static void decode_i64_mips16 (DisasContext *ctx,
364d4831
NF
11639 int ry, int funct, int16_t offset,
11640 int extended)
11641{
11642 switch (funct) {
11643 case I64_LDSP:
d9224450 11644 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11645 check_mips_64(ctx);
11646 offset = extended ? offset : offset << 3;
d75c135e 11647 gen_ld(ctx, OPC_LD, ry, 29, offset);
364d4831
NF
11648 break;
11649 case I64_SDSP:
d9224450 11650 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11651 check_mips_64(ctx);
11652 offset = extended ? offset : offset << 3;
5c13fdfd 11653 gen_st(ctx, OPC_SD, ry, 29, offset);
364d4831
NF
11654 break;
11655 case I64_SDRASP:
d9224450 11656 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11657 check_mips_64(ctx);
11658 offset = extended ? offset : (ctx->opcode & 0xff) << 3;
5c13fdfd 11659 gen_st(ctx, OPC_SD, 31, 29, offset);
364d4831
NF
11660 break;
11661 case I64_DADJSP:
d9224450 11662 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11663 check_mips_64(ctx);
11664 offset = extended ? offset : ((int8_t)ctx->opcode) << 3;
d75c135e 11665 gen_arith_imm(ctx, OPC_DADDIU, 29, 29, offset);
364d4831
NF
11666 break;
11667 case I64_LDPC:
d9224450
MR
11668 check_insn(ctx, ISA_MIPS3);
11669 check_mips_64(ctx);
364d4831 11670 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9c708c7f 11671 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
11672 } else {
11673 offset = extended ? offset : offset << 3;
d75c135e 11674 gen_ld(ctx, OPC_LDPC, ry, 0, offset);
364d4831
NF
11675 }
11676 break;
11677 case I64_DADDIU5:
d9224450 11678 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11679 check_mips_64(ctx);
11680 offset = extended ? offset : ((int8_t)(offset << 3)) >> 3;
d75c135e 11681 gen_arith_imm(ctx, OPC_DADDIU, ry, ry, offset);
364d4831
NF
11682 break;
11683 case I64_DADDIUPC:
d9224450 11684 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11685 check_mips_64(ctx);
11686 offset = extended ? offset : offset << 2;
11687 gen_addiupc(ctx, ry, offset, 1, extended);
11688 break;
11689 case I64_DADDIUSP:
d9224450 11690 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11691 check_mips_64(ctx);
11692 offset = extended ? offset : offset << 2;
d75c135e 11693 gen_arith_imm(ctx, OPC_DADDIU, ry, 29, offset);
364d4831
NF
11694 break;
11695 }
11696}
11697#endif
11698
240ce26a 11699static int decode_extended_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
364d4831 11700{
eeb3bba8 11701 int extend = cpu_lduw_code(env, ctx->base.pc_next + 2);
364d4831
NF
11702 int op, rx, ry, funct, sa;
11703 int16_t imm, offset;
11704
11705 ctx->opcode = (ctx->opcode << 16) | extend;
11706 op = (ctx->opcode >> 11) & 0x1f;
11707 sa = (ctx->opcode >> 22) & 0x1f;
11708 funct = (ctx->opcode >> 8) & 0x7;
11709 rx = xlat((ctx->opcode >> 8) & 0x7);
11710 ry = xlat((ctx->opcode >> 5) & 0x7);
11711 offset = imm = (int16_t) (((ctx->opcode >> 16) & 0x1f) << 11
11712 | ((ctx->opcode >> 21) & 0x3f) << 5
11713 | (ctx->opcode & 0x1f));
11714
11715 /* The extended opcodes cleverly reuse the opcodes from their 16-bit
11716 counterparts. */
11717 switch (op) {
11718 case M16_OPC_ADDIUSP:
d75c135e 11719 gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
364d4831
NF
11720 break;
11721 case M16_OPC_ADDIUPC:
11722 gen_addiupc(ctx, rx, imm, 0, 1);
11723 break;
11724 case M16_OPC_B:
b231c103 11725 gen_compute_branch(ctx, OPC_BEQ, 4, 0, 0, offset << 1, 0);
364d4831
NF
11726 /* No delay slot, so just process as a normal instruction */
11727 break;
11728 case M16_OPC_BEQZ:
b231c103 11729 gen_compute_branch(ctx, OPC_BEQ, 4, rx, 0, offset << 1, 0);
364d4831
NF
11730 /* No delay slot, so just process as a normal instruction */
11731 break;
11732 case M16_OPC_BNEQZ:
b231c103 11733 gen_compute_branch(ctx, OPC_BNE, 4, rx, 0, offset << 1, 0);
364d4831
NF
11734 /* No delay slot, so just process as a normal instruction */
11735 break;
11736 case M16_OPC_SHIFT:
11737 switch (ctx->opcode & 0x3) {
11738 case 0x0:
d75c135e 11739 gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
364d4831
NF
11740 break;
11741 case 0x1:
11742#if defined(TARGET_MIPS64)
11743 check_mips_64(ctx);
d75c135e 11744 gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
364d4831 11745#else
9c708c7f 11746 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
11747#endif
11748 break;
11749 case 0x2:
d75c135e 11750 gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
364d4831
NF
11751 break;
11752 case 0x3:
d75c135e 11753 gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
364d4831
NF
11754 break;
11755 }
11756 break;
11757#if defined(TARGET_MIPS64)
11758 case M16_OPC_LD:
d9224450 11759 check_insn(ctx, ISA_MIPS3);
d75de749 11760 check_mips_64(ctx);
d75c135e 11761 gen_ld(ctx, OPC_LD, ry, rx, offset);
364d4831
NF
11762 break;
11763#endif
11764 case M16_OPC_RRIA:
11765 imm = ctx->opcode & 0xf;
11766 imm = imm | ((ctx->opcode >> 20) & 0x7f) << 4;
11767 imm = imm | ((ctx->opcode >> 16) & 0xf) << 11;
11768 imm = (int16_t) (imm << 1) >> 1;
11769 if ((ctx->opcode >> 4) & 0x1) {
11770#if defined(TARGET_MIPS64)
11771 check_mips_64(ctx);
d75c135e 11772 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
364d4831 11773#else
9c708c7f 11774 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
11775#endif
11776 } else {
d75c135e 11777 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
364d4831
NF
11778 }
11779 break;
11780 case M16_OPC_ADDIU8:
d75c135e 11781 gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
364d4831
NF
11782 break;
11783 case M16_OPC_SLTI:
d75c135e 11784 gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
364d4831
NF
11785 break;
11786 case M16_OPC_SLTIU:
d75c135e 11787 gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
364d4831
NF
11788 break;
11789 case M16_OPC_I8:
11790 switch (funct) {
11791 case I8_BTEQZ:
b231c103 11792 gen_compute_branch(ctx, OPC_BEQ, 4, 24, 0, offset << 1, 0);
364d4831
NF
11793 break;
11794 case I8_BTNEZ:
b231c103 11795 gen_compute_branch(ctx, OPC_BNE, 4, 24, 0, offset << 1, 0);
364d4831
NF
11796 break;
11797 case I8_SWRASP:
5c13fdfd 11798 gen_st(ctx, OPC_SW, 31, 29, imm);
364d4831
NF
11799 break;
11800 case I8_ADJSP:
d75c135e 11801 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm);
364d4831
NF
11802 break;
11803 case I8_SVRS:
d9224450 11804 check_insn(ctx, ISA_MIPS32);
364d4831
NF
11805 {
11806 int xsregs = (ctx->opcode >> 24) & 0x7;
11807 int aregs = (ctx->opcode >> 16) & 0xf;
11808 int do_ra = (ctx->opcode >> 6) & 0x1;
11809 int do_s0 = (ctx->opcode >> 5) & 0x1;
11810 int do_s1 = (ctx->opcode >> 4) & 0x1;
11811 int framesize = (((ctx->opcode >> 20) & 0xf) << 4
11812 | (ctx->opcode & 0xf)) << 3;
11813
11814 if (ctx->opcode & (1 << 7)) {
11815 gen_mips16_save(ctx, xsregs, aregs,
11816 do_ra, do_s0, do_s1,
11817 framesize);
11818 } else {
11819 gen_mips16_restore(ctx, xsregs, aregs,
11820 do_ra, do_s0, do_s1,
11821 framesize);
11822 }
11823 }
11824 break;
11825 default:
9c708c7f 11826 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
11827 break;
11828 }
11829 break;
11830 case M16_OPC_LI:
11831 tcg_gen_movi_tl(cpu_gpr[rx], (uint16_t) imm);
11832 break;
11833 case M16_OPC_CMPI:
11834 tcg_gen_xori_tl(cpu_gpr[24], cpu_gpr[rx], (uint16_t) imm);
11835 break;
11836#if defined(TARGET_MIPS64)
11837 case M16_OPC_SD:
d9224450
MR
11838 check_insn(ctx, ISA_MIPS3);
11839 check_mips_64(ctx);
5c13fdfd 11840 gen_st(ctx, OPC_SD, ry, rx, offset);
364d4831
NF
11841 break;
11842#endif
11843 case M16_OPC_LB:
d75c135e 11844 gen_ld(ctx, OPC_LB, ry, rx, offset);
364d4831
NF
11845 break;
11846 case M16_OPC_LH:
d75c135e 11847 gen_ld(ctx, OPC_LH, ry, rx, offset);
364d4831
NF
11848 break;
11849 case M16_OPC_LWSP:
d75c135e 11850 gen_ld(ctx, OPC_LW, rx, 29, offset);
364d4831
NF
11851 break;
11852 case M16_OPC_LW:
d75c135e 11853 gen_ld(ctx, OPC_LW, ry, rx, offset);
364d4831
NF
11854 break;
11855 case M16_OPC_LBU:
d75c135e 11856 gen_ld(ctx, OPC_LBU, ry, rx, offset);
364d4831
NF
11857 break;
11858 case M16_OPC_LHU:
d75c135e 11859 gen_ld(ctx, OPC_LHU, ry, rx, offset);
364d4831
NF
11860 break;
11861 case M16_OPC_LWPC:
d75c135e 11862 gen_ld(ctx, OPC_LWPC, rx, 0, offset);
364d4831
NF
11863 break;
11864#if defined(TARGET_MIPS64)
11865 case M16_OPC_LWU:
d9224450
MR
11866 check_insn(ctx, ISA_MIPS3);
11867 check_mips_64(ctx);
d75c135e 11868 gen_ld(ctx, OPC_LWU, ry, rx, offset);
364d4831
NF
11869 break;
11870#endif
11871 case M16_OPC_SB:
5c13fdfd 11872 gen_st(ctx, OPC_SB, ry, rx, offset);
364d4831
NF
11873 break;
11874 case M16_OPC_SH:
5c13fdfd 11875 gen_st(ctx, OPC_SH, ry, rx, offset);
364d4831
NF
11876 break;
11877 case M16_OPC_SWSP:
5c13fdfd 11878 gen_st(ctx, OPC_SW, rx, 29, offset);
364d4831
NF
11879 break;
11880 case M16_OPC_SW:
5c13fdfd 11881 gen_st(ctx, OPC_SW, ry, rx, offset);
364d4831
NF
11882 break;
11883#if defined(TARGET_MIPS64)
11884 case M16_OPC_I64:
d75c135e 11885 decode_i64_mips16(ctx, ry, funct, offset, 1);
364d4831
NF
11886 break;
11887#endif
11888 default:
9c708c7f 11889 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
11890 break;
11891 }
11892
11893 return 4;
11894}
11895
3b3c1694
LA
11896static inline bool is_uhi(int sdbbp_code)
11897{
11898#ifdef CONFIG_USER_ONLY
11899 return false;
11900#else
11901 return semihosting_enabled() && sdbbp_code == 1;
11902#endif
11903}
11904
240ce26a 11905static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
364d4831
NF
11906{
11907 int rx, ry;
11908 int sa;
11909 int op, cnvt_op, op1, offset;
11910 int funct;
11911 int n_bytes;
11912
11913 op = (ctx->opcode >> 11) & 0x1f;
11914 sa = (ctx->opcode >> 2) & 0x7;
11915 sa = sa == 0 ? 8 : sa;
11916 rx = xlat((ctx->opcode >> 8) & 0x7);
11917 cnvt_op = (ctx->opcode >> 5) & 0x7;
11918 ry = xlat((ctx->opcode >> 5) & 0x7);
11919 op1 = offset = ctx->opcode & 0x1f;
11920
11921 n_bytes = 2;
11922
11923 switch (op) {
11924 case M16_OPC_ADDIUSP:
11925 {
11926 int16_t imm = ((uint8_t) ctx->opcode) << 2;
11927
d75c135e 11928 gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
364d4831
NF
11929 }
11930 break;
11931 case M16_OPC_ADDIUPC:
11932 gen_addiupc(ctx, rx, ((uint8_t) ctx->opcode) << 2, 0, 0);
11933 break;
11934 case M16_OPC_B:
11935 offset = (ctx->opcode & 0x7ff) << 1;
11936 offset = (int16_t)(offset << 4) >> 4;
b231c103 11937 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, offset, 0);
364d4831
NF
11938 /* No delay slot, so just process as a normal instruction */
11939 break;
11940 case M16_OPC_JAL:
eeb3bba8 11941 offset = cpu_lduw_code(env, ctx->base.pc_next + 2);
364d4831
NF
11942 offset = (((ctx->opcode & 0x1f) << 21)
11943 | ((ctx->opcode >> 5) & 0x1f) << 16
11944 | offset) << 2;
b231c103
YK
11945 op = ((ctx->opcode >> 10) & 0x1) ? OPC_JALX : OPC_JAL;
11946 gen_compute_branch(ctx, op, 4, rx, ry, offset, 2);
364d4831 11947 n_bytes = 4;
364d4831
NF
11948 break;
11949 case M16_OPC_BEQZ:
b231c103
YK
11950 gen_compute_branch(ctx, OPC_BEQ, 2, rx, 0,
11951 ((int8_t)ctx->opcode) << 1, 0);
364d4831
NF
11952 /* No delay slot, so just process as a normal instruction */
11953 break;
11954 case M16_OPC_BNEQZ:
b231c103
YK
11955 gen_compute_branch(ctx, OPC_BNE, 2, rx, 0,
11956 ((int8_t)ctx->opcode) << 1, 0);
364d4831
NF
11957 /* No delay slot, so just process as a normal instruction */
11958 break;
11959 case M16_OPC_SHIFT:
11960 switch (ctx->opcode & 0x3) {
11961 case 0x0:
d75c135e 11962 gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
364d4831
NF
11963 break;
11964 case 0x1:
11965#if defined(TARGET_MIPS64)
d9224450 11966 check_insn(ctx, ISA_MIPS3);
364d4831 11967 check_mips_64(ctx);
d75c135e 11968 gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
364d4831 11969#else
9c708c7f 11970 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
11971#endif
11972 break;
11973 case 0x2:
d75c135e 11974 gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
364d4831
NF
11975 break;
11976 case 0x3:
d75c135e 11977 gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
364d4831
NF
11978 break;
11979 }
11980 break;
11981#if defined(TARGET_MIPS64)
11982 case M16_OPC_LD:
d9224450 11983 check_insn(ctx, ISA_MIPS3);
364d4831 11984 check_mips_64(ctx);
d75c135e 11985 gen_ld(ctx, OPC_LD, ry, rx, offset << 3);
364d4831
NF
11986 break;
11987#endif
11988 case M16_OPC_RRIA:
11989 {
11990 int16_t imm = (int8_t)((ctx->opcode & 0xf) << 4) >> 4;
11991
11992 if ((ctx->opcode >> 4) & 1) {
11993#if defined(TARGET_MIPS64)
d9224450 11994 check_insn(ctx, ISA_MIPS3);
364d4831 11995 check_mips_64(ctx);
d75c135e 11996 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
364d4831 11997#else
9c708c7f 11998 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
11999#endif
12000 } else {
d75c135e 12001 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
364d4831
NF
12002 }
12003 }
12004 break;
12005 case M16_OPC_ADDIU8:
12006 {
12007 int16_t imm = (int8_t) ctx->opcode;
12008
d75c135e 12009 gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
364d4831
NF
12010 }
12011 break;
12012 case M16_OPC_SLTI:
12013 {
12014 int16_t imm = (uint8_t) ctx->opcode;
d75c135e 12015 gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
364d4831
NF
12016 }
12017 break;
12018 case M16_OPC_SLTIU:
12019 {
12020 int16_t imm = (uint8_t) ctx->opcode;
d75c135e 12021 gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
364d4831
NF
12022 }
12023 break;
12024 case M16_OPC_I8:
12025 {
12026 int reg32;
12027
12028 funct = (ctx->opcode >> 8) & 0x7;
12029 switch (funct) {
12030 case I8_BTEQZ:
12031 gen_compute_branch(ctx, OPC_BEQ, 2, 24, 0,
b231c103 12032 ((int8_t)ctx->opcode) << 1, 0);
364d4831
NF
12033 break;
12034 case I8_BTNEZ:
12035 gen_compute_branch(ctx, OPC_BNE, 2, 24, 0,
b231c103 12036 ((int8_t)ctx->opcode) << 1, 0);
364d4831
NF
12037 break;
12038 case I8_SWRASP:
5c13fdfd 12039 gen_st(ctx, OPC_SW, 31, 29, (ctx->opcode & 0xff) << 2);
364d4831
NF
12040 break;
12041 case I8_ADJSP:
d75c135e 12042 gen_arith_imm(ctx, OPC_ADDIU, 29, 29,
364d4831
NF
12043 ((int8_t)ctx->opcode) << 3);
12044 break;
12045 case I8_SVRS:
d9224450 12046 check_insn(ctx, ISA_MIPS32);
364d4831
NF
12047 {
12048 int do_ra = ctx->opcode & (1 << 6);
12049 int do_s0 = ctx->opcode & (1 << 5);
12050 int do_s1 = ctx->opcode & (1 << 4);
12051 int framesize = ctx->opcode & 0xf;
12052
12053 if (framesize == 0) {
12054 framesize = 128;
12055 } else {
12056 framesize = framesize << 3;
12057 }
12058
12059 if (ctx->opcode & (1 << 7)) {
12060 gen_mips16_save(ctx, 0, 0,
12061 do_ra, do_s0, do_s1, framesize);
12062 } else {
12063 gen_mips16_restore(ctx, 0, 0,
12064 do_ra, do_s0, do_s1, framesize);
12065 }
12066 }
12067 break;
12068 case I8_MOV32R:
12069 {
12070 int rz = xlat(ctx->opcode & 0x7);
12071
12072 reg32 = (((ctx->opcode >> 3) & 0x3) << 3) |
12073 ((ctx->opcode >> 5) & 0x7);
d75c135e 12074 gen_arith(ctx, OPC_ADDU, reg32, rz, 0);
364d4831
NF
12075 }
12076 break;
12077 case I8_MOVR32:
12078 reg32 = ctx->opcode & 0x1f;
d75c135e 12079 gen_arith(ctx, OPC_ADDU, ry, reg32, 0);
364d4831
NF
12080 break;
12081 default:
9c708c7f 12082 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
12083 break;
12084 }
12085 }
12086 break;
12087 case M16_OPC_LI:
12088 {
12089 int16_t imm = (uint8_t) ctx->opcode;
12090
d75c135e 12091 gen_arith_imm(ctx, OPC_ADDIU, rx, 0, imm);
364d4831
NF
12092 }
12093 break;
12094 case M16_OPC_CMPI:
12095 {
12096 int16_t imm = (uint8_t) ctx->opcode;
d75c135e 12097 gen_logic_imm(ctx, OPC_XORI, 24, rx, imm);
364d4831
NF
12098 }
12099 break;
12100#if defined(TARGET_MIPS64)
12101 case M16_OPC_SD:
d9224450 12102 check_insn(ctx, ISA_MIPS3);
364d4831 12103 check_mips_64(ctx);
5c13fdfd 12104 gen_st(ctx, OPC_SD, ry, rx, offset << 3);
364d4831
NF
12105 break;
12106#endif
12107 case M16_OPC_LB:
d75c135e 12108 gen_ld(ctx, OPC_LB, ry, rx, offset);
364d4831
NF
12109 break;
12110 case M16_OPC_LH:
d75c135e 12111 gen_ld(ctx, OPC_LH, ry, rx, offset << 1);
364d4831
NF
12112 break;
12113 case M16_OPC_LWSP:
d75c135e 12114 gen_ld(ctx, OPC_LW, rx, 29, ((uint8_t)ctx->opcode) << 2);
364d4831
NF
12115 break;
12116 case M16_OPC_LW:
d75c135e 12117 gen_ld(ctx, OPC_LW, ry, rx, offset << 2);
364d4831
NF
12118 break;
12119 case M16_OPC_LBU:
d75c135e 12120 gen_ld(ctx, OPC_LBU, ry, rx, offset);
364d4831
NF
12121 break;
12122 case M16_OPC_LHU:
d75c135e 12123 gen_ld(ctx, OPC_LHU, ry, rx, offset << 1);
364d4831
NF
12124 break;
12125 case M16_OPC_LWPC:
d75c135e 12126 gen_ld(ctx, OPC_LWPC, rx, 0, ((uint8_t)ctx->opcode) << 2);
364d4831
NF
12127 break;
12128#if defined (TARGET_MIPS64)
12129 case M16_OPC_LWU:
d9224450 12130 check_insn(ctx, ISA_MIPS3);
364d4831 12131 check_mips_64(ctx);
d75c135e 12132 gen_ld(ctx, OPC_LWU, ry, rx, offset << 2);
364d4831
NF
12133 break;
12134#endif
12135 case M16_OPC_SB:
5c13fdfd 12136 gen_st(ctx, OPC_SB, ry, rx, offset);
364d4831
NF
12137 break;
12138 case M16_OPC_SH:
5c13fdfd 12139 gen_st(ctx, OPC_SH, ry, rx, offset << 1);
364d4831
NF
12140 break;
12141 case M16_OPC_SWSP:
5c13fdfd 12142 gen_st(ctx, OPC_SW, rx, 29, ((uint8_t)ctx->opcode) << 2);
364d4831
NF
12143 break;
12144 case M16_OPC_SW:
5c13fdfd 12145 gen_st(ctx, OPC_SW, ry, rx, offset << 2);
364d4831
NF
12146 break;
12147 case M16_OPC_RRR:
12148 {
12149 int rz = xlat((ctx->opcode >> 2) & 0x7);
12150 int mips32_op;
12151
12152 switch (ctx->opcode & 0x3) {
12153 case RRR_ADDU:
12154 mips32_op = OPC_ADDU;
12155 break;
12156 case RRR_SUBU:
12157 mips32_op = OPC_SUBU;
12158 break;
12159#if defined(TARGET_MIPS64)
12160 case RRR_DADDU:
12161 mips32_op = OPC_DADDU;
d9224450 12162 check_insn(ctx, ISA_MIPS3);
364d4831
NF
12163 check_mips_64(ctx);
12164 break;
12165 case RRR_DSUBU:
12166 mips32_op = OPC_DSUBU;
d9224450 12167 check_insn(ctx, ISA_MIPS3);
364d4831
NF
12168 check_mips_64(ctx);
12169 break;
12170#endif
12171 default:
9c708c7f 12172 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
12173 goto done;
12174 }
12175
d75c135e 12176 gen_arith(ctx, mips32_op, rz, rx, ry);
364d4831
NF
12177 done:
12178 ;
12179 }
12180 break;
12181 case M16_OPC_RR:
12182 switch (op1) {
12183 case RR_JR:
12184 {
12185 int nd = (ctx->opcode >> 7) & 0x1;
12186 int link = (ctx->opcode >> 6) & 0x1;
12187 int ra = (ctx->opcode >> 5) & 0x1;
12188
d9224450
MR
12189 if (nd) {
12190 check_insn(ctx, ISA_MIPS32);
12191 }
12192
364d4831 12193 if (link) {
b231c103 12194 op = OPC_JALR;
364d4831
NF
12195 } else {
12196 op = OPC_JR;
12197 }
12198
b231c103
YK
12199 gen_compute_branch(ctx, op, 2, ra ? 31 : rx, 31, 0,
12200 (nd ? 0 : 2));
364d4831
NF
12201 }
12202 break;
12203 case RR_SDBBP:
3b3c1694
LA
12204 if (is_uhi(extract32(ctx->opcode, 5, 6))) {
12205 gen_helper_do_semihosting(cpu_env);
12206 } else {
12207 /* XXX: not clear which exception should be raised
12208 * when in debug mode...
12209 */
12210 check_insn(ctx, ISA_MIPS32);
9c708c7f 12211 generate_exception_end(ctx, EXCP_DBp);
3b3c1694 12212 }
364d4831
NF
12213 break;
12214 case RR_SLT:
d75c135e 12215 gen_slt(ctx, OPC_SLT, 24, rx, ry);
364d4831
NF
12216 break;
12217 case RR_SLTU:
d75c135e 12218 gen_slt(ctx, OPC_SLTU, 24, rx, ry);
364d4831
NF
12219 break;
12220 case RR_BREAK:
9c708c7f 12221 generate_exception_end(ctx, EXCP_BREAK);
364d4831
NF
12222 break;
12223 case RR_SLLV:
d75c135e 12224 gen_shift(ctx, OPC_SLLV, ry, rx, ry);
364d4831
NF
12225 break;
12226 case RR_SRLV:
d75c135e 12227 gen_shift(ctx, OPC_SRLV, ry, rx, ry);
364d4831
NF
12228 break;
12229 case RR_SRAV:
d75c135e 12230 gen_shift(ctx, OPC_SRAV, ry, rx, ry);
364d4831
NF
12231 break;
12232#if defined (TARGET_MIPS64)
12233 case RR_DSRL:
d9224450 12234 check_insn(ctx, ISA_MIPS3);
364d4831 12235 check_mips_64(ctx);
d75c135e 12236 gen_shift_imm(ctx, OPC_DSRL, ry, ry, sa);
364d4831
NF
12237 break;
12238#endif
12239 case RR_CMP:
d75c135e 12240 gen_logic(ctx, OPC_XOR, 24, rx, ry);
364d4831
NF
12241 break;
12242 case RR_NEG:
d75c135e 12243 gen_arith(ctx, OPC_SUBU, rx, 0, ry);
364d4831
NF
12244 break;
12245 case RR_AND:
d75c135e 12246 gen_logic(ctx, OPC_AND, rx, rx, ry);
364d4831
NF
12247 break;
12248 case RR_OR:
d75c135e 12249 gen_logic(ctx, OPC_OR, rx, rx, ry);
364d4831
NF
12250 break;
12251 case RR_XOR:
d75c135e 12252 gen_logic(ctx, OPC_XOR, rx, rx, ry);
364d4831
NF
12253 break;
12254 case RR_NOT:
d75c135e 12255 gen_logic(ctx, OPC_NOR, rx, ry, 0);
364d4831
NF
12256 break;
12257 case RR_MFHI:
26135ead 12258 gen_HILO(ctx, OPC_MFHI, 0, rx);
364d4831
NF
12259 break;
12260 case RR_CNVT:
d9224450 12261 check_insn(ctx, ISA_MIPS32);
364d4831
NF
12262 switch (cnvt_op) {
12263 case RR_RY_CNVT_ZEB:
12264 tcg_gen_ext8u_tl(cpu_gpr[rx], cpu_gpr[rx]);
12265 break;
12266 case RR_RY_CNVT_ZEH:
12267 tcg_gen_ext16u_tl(cpu_gpr[rx], cpu_gpr[rx]);
12268 break;
12269 case RR_RY_CNVT_SEB:
12270 tcg_gen_ext8s_tl(cpu_gpr[rx], cpu_gpr[rx]);
12271 break;
12272 case RR_RY_CNVT_SEH:
12273 tcg_gen_ext16s_tl(cpu_gpr[rx], cpu_gpr[rx]);
12274 break;
12275#if defined (TARGET_MIPS64)
12276 case RR_RY_CNVT_ZEW:
d9224450 12277 check_insn(ctx, ISA_MIPS64);
364d4831
NF
12278 check_mips_64(ctx);
12279 tcg_gen_ext32u_tl(cpu_gpr[rx], cpu_gpr[rx]);
12280 break;
12281 case RR_RY_CNVT_SEW:
d9224450 12282 check_insn(ctx, ISA_MIPS64);
364d4831
NF
12283 check_mips_64(ctx);
12284 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
12285 break;
12286#endif
12287 default:
9c708c7f 12288 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
12289 break;
12290 }
12291 break;
12292 case RR_MFLO:
26135ead 12293 gen_HILO(ctx, OPC_MFLO, 0, rx);
364d4831
NF
12294 break;
12295#if defined (TARGET_MIPS64)
12296 case RR_DSRA:
d9224450 12297 check_insn(ctx, ISA_MIPS3);
364d4831 12298 check_mips_64(ctx);
d75c135e 12299 gen_shift_imm(ctx, OPC_DSRA, ry, ry, sa);
364d4831
NF
12300 break;
12301 case RR_DSLLV:
d9224450 12302 check_insn(ctx, ISA_MIPS3);
364d4831 12303 check_mips_64(ctx);
d75c135e 12304 gen_shift(ctx, OPC_DSLLV, ry, rx, ry);
364d4831
NF
12305 break;
12306 case RR_DSRLV:
d9224450 12307 check_insn(ctx, ISA_MIPS3);
364d4831 12308 check_mips_64(ctx);
d75c135e 12309 gen_shift(ctx, OPC_DSRLV, ry, rx, ry);
364d4831
NF
12310 break;
12311 case RR_DSRAV:
d9224450 12312 check_insn(ctx, ISA_MIPS3);
364d4831 12313 check_mips_64(ctx);
d75c135e 12314 gen_shift(ctx, OPC_DSRAV, ry, rx, ry);
364d4831
NF
12315 break;
12316#endif
12317 case RR_MULT:
26135ead 12318 gen_muldiv(ctx, OPC_MULT, 0, rx, ry);
364d4831
NF
12319 break;
12320 case RR_MULTU:
26135ead 12321 gen_muldiv(ctx, OPC_MULTU, 0, rx, ry);
364d4831
NF
12322 break;
12323 case RR_DIV:
26135ead 12324 gen_muldiv(ctx, OPC_DIV, 0, rx, ry);
364d4831
NF
12325 break;
12326 case RR_DIVU:
26135ead 12327 gen_muldiv(ctx, OPC_DIVU, 0, rx, ry);
364d4831
NF
12328 break;
12329#if defined (TARGET_MIPS64)
12330 case RR_DMULT:
d9224450 12331 check_insn(ctx, ISA_MIPS3);
364d4831 12332 check_mips_64(ctx);
26135ead 12333 gen_muldiv(ctx, OPC_DMULT, 0, rx, ry);
364d4831
NF
12334 break;
12335 case RR_DMULTU:
d9224450 12336 check_insn(ctx, ISA_MIPS3);
364d4831 12337 check_mips_64(ctx);
26135ead 12338 gen_muldiv(ctx, OPC_DMULTU, 0, rx, ry);
364d4831
NF
12339 break;
12340 case RR_DDIV:
d9224450 12341 check_insn(ctx, ISA_MIPS3);
364d4831 12342 check_mips_64(ctx);
26135ead 12343 gen_muldiv(ctx, OPC_DDIV, 0, rx, ry);
364d4831
NF
12344 break;
12345 case RR_DDIVU:
d9224450 12346 check_insn(ctx, ISA_MIPS3);
364d4831 12347 check_mips_64(ctx);
26135ead 12348 gen_muldiv(ctx, OPC_DDIVU, 0, rx, ry);
364d4831
NF
12349 break;
12350#endif
12351 default:
9c708c7f 12352 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
12353 break;
12354 }
12355 break;
12356 case M16_OPC_EXTEND:
240ce26a 12357 decode_extended_mips16_opc(env, ctx);
364d4831
NF
12358 n_bytes = 4;
12359 break;
12360#if defined(TARGET_MIPS64)
12361 case M16_OPC_I64:
12362 funct = (ctx->opcode >> 8) & 0x7;
d75c135e 12363 decode_i64_mips16(ctx, ry, funct, offset, 0);
364d4831
NF
12364 break;
12365#endif
12366 default:
9c708c7f 12367 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
12368 break;
12369 }
12370
12371 return n_bytes;
12372}
12373
211da992 12374/* microMIPS extension to MIPS32/MIPS64 */
6af0bf9c 12375
211da992
CWR
12376/*
12377 * microMIPS32/microMIPS64 major opcodes
12378 *
12379 * 1. MIPS Architecture for Programmers Volume II-B:
12380 * The microMIPS32 Instruction Set (Revision 3.05)
12381 *
12382 * Table 6.2 microMIPS32 Encoding of Major Opcode Field
12383 *
12384 * 2. MIPS Architecture For Programmers Volume II-A:
12385 * The MIPS64 Instruction Set (Revision 3.51)
12386 */
6af0bf9c 12387
3c824109
NF
12388enum {
12389 POOL32A = 0x00,
12390 POOL16A = 0x01,
12391 LBU16 = 0x02,
12392 MOVE16 = 0x03,
12393 ADDI32 = 0x04,
3a1f4268
YK
12394 R6_LUI = 0x04,
12395 AUI = 0x04,
3c824109
NF
12396 LBU32 = 0x05,
12397 SB32 = 0x06,
12398 LB32 = 0x07,
12399
12400 POOL32B = 0x08,
12401 POOL16B = 0x09,
12402 LHU16 = 0x0a,
12403 ANDI16 = 0x0b,
12404 ADDIU32 = 0x0c,
12405 LHU32 = 0x0d,
12406 SH32 = 0x0e,
12407 LH32 = 0x0f,
12408
12409 POOL32I = 0x10,
12410 POOL16C = 0x11,
12411 LWSP16 = 0x12,
12412 POOL16D = 0x13,
12413 ORI32 = 0x14,
12414 POOL32F = 0x15,
211da992
CWR
12415 POOL32S = 0x16, /* MIPS64 */
12416 DADDIU32 = 0x17, /* MIPS64 */
3c824109
NF
12417
12418 POOL32C = 0x18,
12419 LWGP16 = 0x19,
12420 LW16 = 0x1a,
12421 POOL16E = 0x1b,
12422 XORI32 = 0x1c,
12423 JALS32 = 0x1d,
3a1f4268
YK
12424 BOVC = 0x1d,
12425 BEQC = 0x1d,
12426 BEQZALC = 0x1d,
3c824109 12427 ADDIUPC = 0x1e,
3a1f4268
YK
12428 PCREL = 0x1e,
12429 BNVC = 0x1f,
12430 BNEC = 0x1f,
12431 BNEZALC = 0x1f,
3c824109 12432
3a1f4268
YK
12433 R6_BEQZC = 0x20,
12434 JIC = 0x20,
3c824109
NF
12435 POOL16F = 0x21,
12436 SB16 = 0x22,
12437 BEQZ16 = 0x23,
3a1f4268 12438 BEQZC16 = 0x23,
3c824109
NF
12439 SLTI32 = 0x24,
12440 BEQ32 = 0x25,
3a1f4268 12441 BC = 0x25,
3c824109
NF
12442 SWC132 = 0x26,
12443 LWC132 = 0x27,
12444
3a1f4268 12445 /* 0x29 is reserved */
3c824109 12446 RES_29 = 0x29,
3a1f4268
YK
12447 R6_BNEZC = 0x28,
12448 JIALC = 0x28,
3c824109
NF
12449 SH16 = 0x2a,
12450 BNEZ16 = 0x2b,
3a1f4268 12451 BNEZC16 = 0x2b,
3c824109
NF
12452 SLTIU32 = 0x2c,
12453 BNE32 = 0x2d,
3a1f4268 12454 BALC = 0x2d,
3c824109
NF
12455 SDC132 = 0x2e,
12456 LDC132 = 0x2f,
12457
3a1f4268 12458 /* 0x31 is reserved */
3c824109 12459 RES_31 = 0x31,
3a1f4268
YK
12460 BLEZALC = 0x30,
12461 BGEZALC = 0x30,
12462 BGEUC = 0x30,
3c824109
NF
12463 SWSP16 = 0x32,
12464 B16 = 0x33,
3a1f4268 12465 BC16 = 0x33,
3c824109
NF
12466 ANDI32 = 0x34,
12467 J32 = 0x35,
3a1f4268
YK
12468 BGTZC = 0x35,
12469 BLTZC = 0x35,
12470 BLTC = 0x35,
211da992
CWR
12471 SD32 = 0x36, /* MIPS64 */
12472 LD32 = 0x37, /* MIPS64 */
3c824109 12473
3a1f4268 12474 /* 0x39 is reserved */
3c824109 12475 RES_39 = 0x39,
3a1f4268
YK
12476 BGTZALC = 0x38,
12477 BLTZALC = 0x38,
12478 BLTUC = 0x38,
3c824109
NF
12479 SW16 = 0x3a,
12480 LI16 = 0x3b,
12481 JALX32 = 0x3c,
12482 JAL32 = 0x3d,
3a1f4268
YK
12483 BLEZC = 0x3d,
12484 BGEZC = 0x3d,
12485 BGEC = 0x3d,
3c824109
NF
12486 SW32 = 0x3e,
12487 LW32 = 0x3f
12488};
12489
3a1f4268
YK
12490/* PCREL Instructions perform PC-Relative address calculation. bits 20..16 */
12491enum {
12492 ADDIUPC_00 = 0x00,
12493 ADDIUPC_07 = 0x07,
12494 AUIPC = 0x1e,
12495 ALUIPC = 0x1f,
12496 LWPC_08 = 0x08,
12497 LWPC_0F = 0x0F,
12498};
12499
3c824109
NF
12500/* POOL32A encoding of minor opcode field */
12501
12502enum {
12503 /* These opcodes are distinguished only by bits 9..6; those bits are
12504 * what are recorded below. */
12505 SLL32 = 0x0,
12506 SRL32 = 0x1,
12507 SRA = 0x2,
12508 ROTR = 0x3,
3a1f4268
YK
12509 SELEQZ = 0x5,
12510 SELNEZ = 0x6,
b00c7218 12511 R6_RDHWR = 0x7,
3c824109
NF
12512
12513 SLLV = 0x0,
12514 SRLV = 0x1,
12515 SRAV = 0x2,
12516 ROTRV = 0x3,
12517 ADD = 0x4,
12518 ADDU32 = 0x5,
12519 SUB = 0x6,
12520 SUBU32 = 0x7,
12521 MUL = 0x8,
12522 AND = 0x9,
12523 OR32 = 0xa,
12524 NOR = 0xb,
12525 XOR32 = 0xc,
12526 SLT = 0xd,
12527 SLTU = 0xe,
12528
12529 MOVN = 0x0,
3a1f4268 12530 R6_MUL = 0x0,
3c824109 12531 MOVZ = 0x1,
3a1f4268
YK
12532 MUH = 0x1,
12533 MULU = 0x2,
12534 MUHU = 0x3,
3c824109 12535 LWXS = 0x4,
3a1f4268
YK
12536 R6_DIV = 0x4,
12537 MOD = 0x5,
12538 R6_DIVU = 0x6,
12539 MODU = 0x7,
3c824109
NF
12540
12541 /* The following can be distinguished by their lower 6 bits. */
dbd8af98 12542 BREAK32 = 0x07,
3c824109 12543 INS = 0x0c,
3a1f4268
YK
12544 LSA = 0x0f,
12545 ALIGN = 0x1f,
3c824109 12546 EXT = 0x2c,
bb238210
YK
12547 POOL32AXF = 0x3c,
12548 SIGRIE = 0x3f
3c824109
NF
12549};
12550
12551/* POOL32AXF encoding of minor opcode field extension */
12552
d132c79f
CWR
12553/*
12554 * 1. MIPS Architecture for Programmers Volume II-B:
12555 * The microMIPS32 Instruction Set (Revision 3.05)
12556 *
12557 * Table 6.5 POOL32Axf Encoding of Minor Opcode Extension Field
12558 *
12559 * 2. MIPS Architecture for Programmers VolumeIV-e:
12560 * The MIPS DSP Application-Specific Extension
12561 * to the microMIPS32 Architecture (Revision 2.34)
12562 *
12563 * Table 5.5 POOL32Axf Encoding of Minor Opcode Extension Field
12564 */
12565
3c824109
NF
12566enum {
12567 /* bits 11..6 */
12568 TEQ = 0x00,
12569 TGE = 0x08,
12570 TGEU = 0x10,
12571 TLT = 0x20,
12572 TLTU = 0x28,
12573 TNE = 0x30,
12574
12575 MFC0 = 0x03,
12576 MTC0 = 0x0b,
12577
d132c79f
CWR
12578 /* begin of microMIPS32 DSP */
12579
3c824109
NF
12580 /* bits 13..12 for 0x01 */
12581 MFHI_ACC = 0x0,
12582 MFLO_ACC = 0x1,
12583 MTHI_ACC = 0x2,
12584 MTLO_ACC = 0x3,
12585
12586 /* bits 13..12 for 0x2a */
12587 MADD_ACC = 0x0,
12588 MADDU_ACC = 0x1,
12589 MSUB_ACC = 0x2,
12590 MSUBU_ACC = 0x3,
12591
12592 /* bits 13..12 for 0x32 */
12593 MULT_ACC = 0x0,
6801038b 12594 MULTU_ACC = 0x1,
3c824109 12595
d132c79f
CWR
12596 /* end of microMIPS32 DSP */
12597
3c824109 12598 /* bits 15..12 for 0x2c */
3a1f4268 12599 BITSWAP = 0x0,
3c824109
NF
12600 SEB = 0x2,
12601 SEH = 0x3,
12602 CLO = 0x4,
12603 CLZ = 0x5,
12604 RDHWR = 0x6,
12605 WSBH = 0x7,
12606 MULT = 0x8,
12607 MULTU = 0x9,
12608 DIV = 0xa,
12609 DIVU = 0xb,
12610 MADD = 0xc,
12611 MADDU = 0xd,
12612 MSUB = 0xe,
12613 MSUBU = 0xf,
12614
12615 /* bits 15..12 for 0x34 */
12616 MFC2 = 0x4,
12617 MTC2 = 0x5,
12618 MFHC2 = 0x8,
12619 MTHC2 = 0x9,
12620 CFC2 = 0xc,
12621 CTC2 = 0xd,
12622
12623 /* bits 15..12 for 0x3c */
12624 JALR = 0x0,
12625 JR = 0x0, /* alias */
3a1f4268
YK
12626 JALRC = 0x0,
12627 JRC = 0x0,
3c824109 12628 JALR_HB = 0x1,
3a1f4268 12629 JALRC_HB = 0x1,
3c824109
NF
12630 JALRS = 0x4,
12631 JALRS_HB = 0x5,
12632
12633 /* bits 15..12 for 0x05 */
12634 RDPGPR = 0xe,
12635 WRPGPR = 0xf,
12636
12637 /* bits 15..12 for 0x0d */
12638 TLBP = 0x0,
12639 TLBR = 0x1,
12640 TLBWI = 0x2,
12641 TLBWR = 0x3,
e60ec063
YK
12642 TLBINV = 0x4,
12643 TLBINVF = 0x5,
3c824109
NF
12644 WAIT = 0x9,
12645 IRET = 0xd,
12646 DERET = 0xe,
12647 ERET = 0xf,
12648
12649 /* bits 15..12 for 0x15 */
12650 DMT = 0x0,
12651 DVPE = 0x1,
12652 EMT = 0x2,
12653 EVPE = 0x3,
12654
12655 /* bits 15..12 for 0x1d */
12656 DI = 0x4,
12657 EI = 0x5,
12658
12659 /* bits 15..12 for 0x2d */
12660 SYNC = 0x6,
12661 SYSCALL = 0x8,
12662 SDBBP = 0xd,
12663
12664 /* bits 15..12 for 0x35 */
12665 MFHI32 = 0x0,
12666 MFLO32 = 0x1,
12667 MTHI32 = 0x2,
12668 MTLO32 = 0x3,
12669};
12670
12671/* POOL32B encoding of minor opcode field (bits 15..12) */
12672
12673enum {
12674 LWC2 = 0x0,
12675 LWP = 0x1,
12676 LDP = 0x4,
12677 LWM32 = 0x5,
12678 CACHE = 0x6,
12679 LDM = 0x7,
12680 SWC2 = 0x8,
12681 SWP = 0x9,
12682 SDP = 0xc,
12683 SWM32 = 0xd,
12684 SDM = 0xf
12685};
12686
12687/* POOL32C encoding of minor opcode field (bits 15..12) */
12688
12689enum {
12690 LWL = 0x0,
12691 SWL = 0x8,
12692 LWR = 0x1,
12693 SWR = 0x9,
12694 PREF = 0x2,
8fffc646 12695 ST_EVA = 0xa,
3c824109
NF
12696 LL = 0x3,
12697 SC = 0xb,
12698 LDL = 0x4,
12699 SDL = 0xc,
12700 LDR = 0x5,
12701 SDR = 0xd,
8fffc646 12702 LD_EVA = 0x6,
3c824109
NF
12703 LWU = 0xe,
12704 LLD = 0x7,
12705 SCD = 0xf
12706};
12707
8fffc646
JH
12708/* POOL32C LD-EVA encoding of minor opcode field (bits 11..9) */
12709
12710enum {
12711 LBUE = 0x0,
12712 LHUE = 0x1,
12713 LWLE = 0x2,
12714 LWRE = 0x3,
12715 LBE = 0x4,
12716 LHE = 0x5,
12717 LLE = 0x6,
12718 LWE = 0x7,
12719};
12720
12721/* POOL32C ST-EVA encoding of minor opcode field (bits 11..9) */
12722
12723enum {
12724 SWLE = 0x0,
12725 SWRE = 0x1,
12726 PREFE = 0x2,
12727 CACHEE = 0x3,
12728 SBE = 0x4,
12729 SHE = 0x5,
12730 SCE = 0x6,
12731 SWE = 0x7,
12732};
12733
3c824109
NF
12734/* POOL32F encoding of minor opcode field (bits 5..0) */
12735
12736enum {
12737 /* These are the bit 7..6 values */
12738 ADD_FMT = 0x0,
3c824109
NF
12739
12740 SUB_FMT = 0x1,
3c824109
NF
12741
12742 MUL_FMT = 0x2,
12743
12744 DIV_FMT = 0x3,
12745
12746 /* These are the bit 8..6 values */
3a1f4268 12747 MOVN_FMT = 0x0,
3c824109
NF
12748 RSQRT2_FMT = 0x0,
12749 MOVF_FMT = 0x0,
3a1f4268
YK
12750 RINT_FMT = 0x0,
12751 SELNEZ_FMT = 0x0,
3c824109 12752
3a1f4268 12753 MOVZ_FMT = 0x1,
3c824109
NF
12754 LWXC1 = 0x1,
12755 MOVT_FMT = 0x1,
3a1f4268
YK
12756 CLASS_FMT = 0x1,
12757 SELEQZ_FMT = 0x1,
3c824109
NF
12758
12759 PLL_PS = 0x2,
12760 SWXC1 = 0x2,
3a1f4268 12761 SEL_FMT = 0x2,
3c824109
NF
12762
12763 PLU_PS = 0x3,
12764 LDXC1 = 0x3,
12765
3a1f4268 12766 MOVN_FMT_04 = 0x4,
3c824109
NF
12767 PUL_PS = 0x4,
12768 SDXC1 = 0x4,
12769 RECIP2_FMT = 0x4,
12770
3a1f4268 12771 MOVZ_FMT_05 = 0x05,
3c824109
NF
12772 PUU_PS = 0x5,
12773 LUXC1 = 0x5,
12774
12775 CVT_PS_S = 0x6,
12776 SUXC1 = 0x6,
12777 ADDR_PS = 0x6,
12778 PREFX = 0x6,
3a1f4268 12779 MADDF_FMT = 0x6,
3c824109
NF
12780
12781 MULR_PS = 0x7,
3a1f4268 12782 MSUBF_FMT = 0x7,
3c824109
NF
12783
12784 MADD_S = 0x01,
12785 MADD_D = 0x09,
12786 MADD_PS = 0x11,
12787 ALNV_PS = 0x19,
12788 MSUB_S = 0x21,
12789 MSUB_D = 0x29,
12790 MSUB_PS = 0x31,
12791
12792 NMADD_S = 0x02,
12793 NMADD_D = 0x0a,
12794 NMADD_PS = 0x12,
12795 NMSUB_S = 0x22,
12796 NMSUB_D = 0x2a,
12797 NMSUB_PS = 0x32,
12798
3a1f4268
YK
12799 MIN_FMT = 0x3,
12800 MAX_FMT = 0xb,
12801 MINA_FMT = 0x23,
12802 MAXA_FMT = 0x2b,
3c824109
NF
12803 POOL32FXF = 0x3b,
12804
12805 CABS_COND_FMT = 0x1c, /* MIPS3D */
3a1f4268
YK
12806 C_COND_FMT = 0x3c,
12807
12808 CMP_CONDN_S = 0x5,
12809 CMP_CONDN_D = 0x15
3c824109
NF
12810};
12811
12812/* POOL32Fxf encoding of minor opcode extension field */
12813
12814enum {
12815 CVT_L = 0x04,
12816 RSQRT_FMT = 0x08,
12817 FLOOR_L = 0x0c,
12818 CVT_PW_PS = 0x1c,
12819 CVT_W = 0x24,
12820 SQRT_FMT = 0x28,
12821 FLOOR_W = 0x2c,
12822 CVT_PS_PW = 0x3c,
12823 CFC1 = 0x40,
12824 RECIP_FMT = 0x48,
12825 CEIL_L = 0x4c,
12826 CTC1 = 0x60,
12827 CEIL_W = 0x6c,
12828 MFC1 = 0x80,
12829 CVT_S_PL = 0x84,
12830 TRUNC_L = 0x8c,
12831 MTC1 = 0xa0,
12832 CVT_S_PU = 0xa4,
12833 TRUNC_W = 0xac,
12834 MFHC1 = 0xc0,
12835 ROUND_L = 0xcc,
12836 MTHC1 = 0xe0,
12837 ROUND_W = 0xec,
12838
12839 MOV_FMT = 0x01,
12840 MOVF = 0x05,
12841 ABS_FMT = 0x0d,
12842 RSQRT1_FMT = 0x1d,
12843 MOVT = 0x25,
12844 NEG_FMT = 0x2d,
12845 CVT_D = 0x4d,
12846 RECIP1_FMT = 0x5d,
12847 CVT_S = 0x6d
12848};
12849
12850/* POOL32I encoding of minor opcode field (bits 25..21) */
12851
12852enum {
12853 BLTZ = 0x00,
12854 BLTZAL = 0x01,
12855 BGEZ = 0x02,
12856 BGEZAL = 0x03,
12857 BLEZ = 0x04,
12858 BNEZC = 0x05,
12859 BGTZ = 0x06,
12860 BEQZC = 0x07,
12861 TLTI = 0x08,
3a1f4268 12862 BC1EQZC = 0x08,
3c824109 12863 TGEI = 0x09,
3a1f4268 12864 BC1NEZC = 0x09,
3c824109 12865 TLTIU = 0x0a,
3a1f4268 12866 BC2EQZC = 0x0a,
3c824109 12867 TGEIU = 0x0b,
3a1f4268 12868 BC2NEZC = 0x0a,
3c824109 12869 TNEI = 0x0c,
3a1f4268 12870 R6_SYNCI = 0x0c,
3c824109
NF
12871 LUI = 0x0d,
12872 TEQI = 0x0e,
12873 SYNCI = 0x10,
12874 BLTZALS = 0x11,
12875 BGEZALS = 0x13,
12876 BC2F = 0x14,
12877 BC2T = 0x15,
12878 BPOSGE64 = 0x1a,
12879 BPOSGE32 = 0x1b,
12880 /* These overlap and are distinguished by bit16 of the instruction */
12881 BC1F = 0x1c,
12882 BC1T = 0x1d,
12883 BC1ANY2F = 0x1c,
12884 BC1ANY2T = 0x1d,
12885 BC1ANY4F = 0x1e,
12886 BC1ANY4T = 0x1f
12887};
12888
12889/* POOL16A encoding of minor opcode field */
12890
12891enum {
12892 ADDU16 = 0x0,
12893 SUBU16 = 0x1
12894};
12895
12896/* POOL16B encoding of minor opcode field */
12897
12898enum {
12899 SLL16 = 0x0,
12900 SRL16 = 0x1
12901};
12902
12903/* POOL16C encoding of minor opcode field */
12904
12905enum {
12906 NOT16 = 0x00,
12907 XOR16 = 0x04,
12908 AND16 = 0x08,
12909 OR16 = 0x0c,
12910 LWM16 = 0x10,
12911 SWM16 = 0x14,
12912 JR16 = 0x18,
12913 JRC16 = 0x1a,
12914 JALR16 = 0x1c,
12915 JALR16S = 0x1e,
12916 MFHI16 = 0x20,
12917 MFLO16 = 0x24,
12918 BREAK16 = 0x28,
12919 SDBBP16 = 0x2c,
12920 JRADDIUSP = 0x30
12921};
12922
3a1f4268
YK
12923/* R6 POOL16C encoding of minor opcode field (bits 0..5) */
12924
12925enum {
12926 R6_NOT16 = 0x00,
12927 R6_AND16 = 0x01,
12928 R6_LWM16 = 0x02,
12929 R6_JRC16 = 0x03,
12930 MOVEP = 0x04,
12931 MOVEP_07 = 0x07,
12932 R6_XOR16 = 0x08,
12933 R6_OR16 = 0x09,
12934 R6_SWM16 = 0x0a,
12935 JALRC16 = 0x0b,
12936 MOVEP_0C = 0x0c,
12937 MOVEP_0F = 0x0f,
12938 JRCADDIUSP = 0x13,
12939 R6_BREAK16 = 0x1b,
12940 R6_SDBBP16 = 0x3b
12941};
12942
3c824109
NF
12943/* POOL16D encoding of minor opcode field */
12944
12945enum {
12946 ADDIUS5 = 0x0,
12947 ADDIUSP = 0x1
12948};
12949
12950/* POOL16E encoding of minor opcode field */
12951
12952enum {
12953 ADDIUR2 = 0x0,
12954 ADDIUR1SP = 0x1
12955};
12956
12957static int mmreg (int r)
12958{
12959 static const int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
12960
12961 return map[r];
12962}
12963
12964/* Used for 16-bit store instructions. */
12965static int mmreg2 (int r)
12966{
12967 static const int map[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
12968
12969 return map[r];
12970}
12971
12972#define uMIPS_RD(op) ((op >> 7) & 0x7)
12973#define uMIPS_RS(op) ((op >> 4) & 0x7)
12974#define uMIPS_RS2(op) uMIPS_RS(op)
12975#define uMIPS_RS1(op) ((op >> 1) & 0x7)
12976#define uMIPS_RD5(op) ((op >> 5) & 0x1f)
12977#define uMIPS_RS5(op) (op & 0x1f)
12978
12979/* Signed immediate */
12980#define SIMM(op, start, width) \
12981 ((int32_t)(((op >> start) & ((~0U) >> (32-width))) \
12982 << (32-width)) \
12983 >> (32-width))
12984/* Zero-extended immediate */
12985#define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
12986
d75c135e 12987static void gen_addiur1sp(DisasContext *ctx)
3c824109
NF
12988{
12989 int rd = mmreg(uMIPS_RD(ctx->opcode));
12990
d75c135e 12991 gen_arith_imm(ctx, OPC_ADDIU, rd, 29, ((ctx->opcode >> 1) & 0x3f) << 2);
3c824109
NF
12992}
12993
d75c135e 12994static void gen_addiur2(DisasContext *ctx)
3c824109
NF
12995{
12996 static const int decoded_imm[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
12997 int rd = mmreg(uMIPS_RD(ctx->opcode));
12998 int rs = mmreg(uMIPS_RS(ctx->opcode));
12999
d75c135e 13000 gen_arith_imm(ctx, OPC_ADDIU, rd, rs, decoded_imm[ZIMM(ctx->opcode, 1, 3)]);
3c824109
NF
13001}
13002
d75c135e 13003static void gen_addiusp(DisasContext *ctx)
3c824109
NF
13004{
13005 int encoded = ZIMM(ctx->opcode, 1, 9);
13006 int decoded;
13007
13008 if (encoded <= 1) {
13009 decoded = 256 + encoded;
13010 } else if (encoded <= 255) {
13011 decoded = encoded;
13012 } else if (encoded <= 509) {
13013 decoded = encoded - 512;
13014 } else {
13015 decoded = encoded - 768;
13016 }
13017
d75c135e 13018 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, decoded << 2);
3c824109
NF
13019}
13020
d75c135e 13021static void gen_addius5(DisasContext *ctx)
3c824109
NF
13022{
13023 int imm = SIMM(ctx->opcode, 1, 4);
13024 int rd = (ctx->opcode >> 5) & 0x1f;
13025
d75c135e 13026 gen_arith_imm(ctx, OPC_ADDIU, rd, rd, imm);
3c824109
NF
13027}
13028
d75c135e 13029static void gen_andi16(DisasContext *ctx)
3c824109
NF
13030{
13031 static const int decoded_imm[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
13032 31, 32, 63, 64, 255, 32768, 65535 };
13033 int rd = mmreg(uMIPS_RD(ctx->opcode));
13034 int rs = mmreg(uMIPS_RS(ctx->opcode));
13035 int encoded = ZIMM(ctx->opcode, 0, 4);
13036
d75c135e 13037 gen_logic_imm(ctx, OPC_ANDI, rd, rs, decoded_imm[encoded]);
3c824109
NF
13038}
13039
13040static void gen_ldst_multiple (DisasContext *ctx, uint32_t opc, int reglist,
13041 int base, int16_t offset)
13042{
13043 TCGv t0, t1;
13044 TCGv_i32 t2;
13045
13046 if (ctx->hflags & MIPS_HFLAG_BMASK) {
9c708c7f 13047 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
13048 return;
13049 }
13050
13051 t0 = tcg_temp_new();
13052
13053 gen_base_offset_addr(ctx, t0, base, offset);
13054
13055 t1 = tcg_const_tl(reglist);
13056 t2 = tcg_const_i32(ctx->mem_idx);
6af0bf9c 13057
3c824109
NF
13058 save_cpu_state(ctx, 1);
13059 switch (opc) {
13060 case LWM32:
895c2d04 13061 gen_helper_lwm(cpu_env, t0, t1, t2);
3c824109
NF
13062 break;
13063 case SWM32:
895c2d04 13064 gen_helper_swm(cpu_env, t0, t1, t2);
3c824109
NF
13065 break;
13066#ifdef TARGET_MIPS64
13067 case LDM:
895c2d04 13068 gen_helper_ldm(cpu_env, t0, t1, t2);
3c824109
NF
13069 break;
13070 case SDM:
895c2d04 13071 gen_helper_sdm(cpu_env, t0, t1, t2);
3c824109 13072 break;
6af0bf9c 13073#endif
3c824109 13074 }
3c824109 13075 tcg_temp_free(t0);
33087598 13076 tcg_temp_free(t1);
3c824109
NF
13077 tcg_temp_free_i32(t2);
13078}
6af0bf9c 13079
3c824109 13080
240ce26a 13081static void gen_pool16c_insn(DisasContext *ctx)
6af0bf9c 13082{
3c824109
NF
13083 int rd = mmreg((ctx->opcode >> 3) & 0x7);
13084 int rs = mmreg(ctx->opcode & 0x7);
6af0bf9c 13085
3c824109
NF
13086 switch (((ctx->opcode) >> 4) & 0x3f) {
13087 case NOT16 + 0:
13088 case NOT16 + 1:
13089 case NOT16 + 2:
13090 case NOT16 + 3:
d75c135e 13091 gen_logic(ctx, OPC_NOR, rd, rs, 0);
3c824109
NF
13092 break;
13093 case XOR16 + 0:
13094 case XOR16 + 1:
13095 case XOR16 + 2:
13096 case XOR16 + 3:
d75c135e 13097 gen_logic(ctx, OPC_XOR, rd, rd, rs);
3c824109
NF
13098 break;
13099 case AND16 + 0:
13100 case AND16 + 1:
13101 case AND16 + 2:
13102 case AND16 + 3:
d75c135e 13103 gen_logic(ctx, OPC_AND, rd, rd, rs);
3c824109
NF
13104 break;
13105 case OR16 + 0:
13106 case OR16 + 1:
13107 case OR16 + 2:
13108 case OR16 + 3:
d75c135e 13109 gen_logic(ctx, OPC_OR, rd, rd, rs);
3c824109
NF
13110 break;
13111 case LWM16 + 0:
13112 case LWM16 + 1:
13113 case LWM16 + 2:
13114 case LWM16 + 3:
13115 {
13116 static const int lwm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
13117 int offset = ZIMM(ctx->opcode, 0, 4);
13118
13119 gen_ldst_multiple(ctx, LWM32, lwm_convert[(ctx->opcode >> 4) & 0x3],
13120 29, offset << 2);
13121 }
13122 break;
13123 case SWM16 + 0:
13124 case SWM16 + 1:
13125 case SWM16 + 2:
13126 case SWM16 + 3:
13127 {
13128 static const int swm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
13129 int offset = ZIMM(ctx->opcode, 0, 4);
13130
13131 gen_ldst_multiple(ctx, SWM32, swm_convert[(ctx->opcode >> 4) & 0x3],
13132 29, offset << 2);
13133 }
13134 break;
13135 case JR16 + 0:
13136 case JR16 + 1:
13137 {
13138 int reg = ctx->opcode & 0x1f;
13139
b231c103 13140 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 4);
3c824109 13141 }
3c824109
NF
13142 break;
13143 case JRC16 + 0:
13144 case JRC16 + 1:
13145 {
13146 int reg = ctx->opcode & 0x1f;
b231c103 13147 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 0);
3c824109
NF
13148 /* Let normal delay slot handling in our caller take us
13149 to the branch target. */
13150 }
13151 break;
13152 case JALR16 + 0:
13153 case JALR16 + 1:
b231c103
YK
13154 gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 4);
13155 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
13156 break;
3c824109
NF
13157 case JALR16S + 0:
13158 case JALR16S + 1:
b231c103
YK
13159 gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 2);
13160 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
3c824109
NF
13161 break;
13162 case MFHI16 + 0:
13163 case MFHI16 + 1:
26135ead 13164 gen_HILO(ctx, OPC_MFHI, 0, uMIPS_RS5(ctx->opcode));
3c824109
NF
13165 break;
13166 case MFLO16 + 0:
13167 case MFLO16 + 1:
26135ead 13168 gen_HILO(ctx, OPC_MFLO, 0, uMIPS_RS5(ctx->opcode));
3c824109
NF
13169 break;
13170 case BREAK16:
9c708c7f 13171 generate_exception_end(ctx, EXCP_BREAK);
3c824109
NF
13172 break;
13173 case SDBBP16:
3b3c1694
LA
13174 if (is_uhi(extract32(ctx->opcode, 0, 4))) {
13175 gen_helper_do_semihosting(cpu_env);
13176 } else {
13177 /* XXX: not clear which exception should be raised
13178 * when in debug mode...
13179 */
13180 check_insn(ctx, ISA_MIPS32);
9c708c7f 13181 generate_exception_end(ctx, EXCP_DBp);
3b3c1694 13182 }
3c824109
NF
13183 break;
13184 case JRADDIUSP + 0:
13185 case JRADDIUSP + 1:
13186 {
13187 int imm = ZIMM(ctx->opcode, 0, 5);
b231c103 13188 gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0, 0);
d75c135e 13189 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
3c824109
NF
13190 /* Let normal delay slot handling in our caller take us
13191 to the branch target. */
13192 }
13193 break;
13194 default:
9c708c7f 13195 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
13196 break;
13197 }
13198}
13199
ed7ce6c0
YK
13200static inline void gen_movep(DisasContext *ctx, int enc_dest, int enc_rt,
13201 int enc_rs)
13202{
13203 int rd, rs, re, rt;
13204 static const int rd_enc[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
13205 static const int re_enc[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
13206 static const int rs_rt_enc[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
13207 rd = rd_enc[enc_dest];
13208 re = re_enc[enc_dest];
13209 rs = rs_rt_enc[enc_rs];
13210 rt = rs_rt_enc[enc_rt];
13211 if (rs) {
13212 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
13213 } else {
13214 tcg_gen_movi_tl(cpu_gpr[rd], 0);
13215 }
13216 if (rt) {
13217 tcg_gen_mov_tl(cpu_gpr[re], cpu_gpr[rt]);
13218 } else {
13219 tcg_gen_movi_tl(cpu_gpr[re], 0);
13220 }
13221}
13222
13223static void gen_pool16c_r6_insn(DisasContext *ctx)
13224{
13225 int rt = mmreg((ctx->opcode >> 7) & 0x7);
13226 int rs = mmreg((ctx->opcode >> 4) & 0x7);
13227
13228 switch (ctx->opcode & 0xf) {
13229 case R6_NOT16:
13230 gen_logic(ctx, OPC_NOR, rt, rs, 0);
13231 break;
13232 case R6_AND16:
13233 gen_logic(ctx, OPC_AND, rt, rt, rs);
13234 break;
13235 case R6_LWM16:
13236 {
13237 int lwm_converted = 0x11 + extract32(ctx->opcode, 8, 2);
13238 int offset = extract32(ctx->opcode, 4, 4);
13239 gen_ldst_multiple(ctx, LWM32, lwm_converted, 29, offset << 2);
13240 }
13241 break;
13242 case R6_JRC16: /* JRCADDIUSP */
13243 if ((ctx->opcode >> 4) & 1) {
13244 /* JRCADDIUSP */
13245 int imm = extract32(ctx->opcode, 5, 5);
13246 gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0, 0);
13247 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
13248 } else {
13249 /* JRC16 */
13250 int rs = extract32(ctx->opcode, 5, 5);
13251 gen_compute_branch(ctx, OPC_JR, 2, rs, 0, 0, 0);
13252 }
13253 break;
13254 case MOVEP ... MOVEP_07:
13255 case MOVEP_0C ... MOVEP_0F:
13256 {
13257 int enc_dest = uMIPS_RD(ctx->opcode);
13258 int enc_rt = uMIPS_RS2(ctx->opcode);
13259 int enc_rs = (ctx->opcode & 3) | ((ctx->opcode >> 1) & 4);
13260 gen_movep(ctx, enc_dest, enc_rt, enc_rs);
13261 }
13262 break;
13263 case R6_XOR16:
13264 gen_logic(ctx, OPC_XOR, rt, rt, rs);
13265 break;
13266 case R6_OR16:
13267 gen_logic(ctx, OPC_OR, rt, rt, rs);
13268 break;
13269 case R6_SWM16:
13270 {
13271 int swm_converted = 0x11 + extract32(ctx->opcode, 8, 2);
13272 int offset = extract32(ctx->opcode, 4, 4);
13273 gen_ldst_multiple(ctx, SWM32, swm_converted, 29, offset << 2);
13274 }
13275 break;
13276 case JALRC16: /* BREAK16, SDBBP16 */
13277 switch (ctx->opcode & 0x3f) {
13278 case JALRC16:
13279 case JALRC16 + 0x20:
13280 /* JALRC16 */
13281 gen_compute_branch(ctx, OPC_JALR, 2, (ctx->opcode >> 5) & 0x1f,
13282 31, 0, 0);
13283 break;
13284 case R6_BREAK16:
13285 /* BREAK16 */
13286 generate_exception(ctx, EXCP_BREAK);
13287 break;
13288 case R6_SDBBP16:
13289 /* SDBBP16 */
060ebfef
LA
13290 if (is_uhi(extract32(ctx->opcode, 6, 4))) {
13291 gen_helper_do_semihosting(cpu_env);
ed7ce6c0 13292 } else {
060ebfef
LA
13293 if (ctx->hflags & MIPS_HFLAG_SBRI) {
13294 generate_exception(ctx, EXCP_RI);
13295 } else {
13296 generate_exception(ctx, EXCP_DBp);
13297 }
ed7ce6c0
YK
13298 }
13299 break;
13300 }
13301 break;
13302 default:
13303 generate_exception(ctx, EXCP_RI);
13304 break;
13305 }
13306}
13307
3c824109
NF
13308static void gen_ldxs (DisasContext *ctx, int base, int index, int rd)
13309{
13310 TCGv t0 = tcg_temp_new();
13311 TCGv t1 = tcg_temp_new();
13312
13313 gen_load_gpr(t0, base);
13314
13315 if (index != 0) {
13316 gen_load_gpr(t1, index);
13317 tcg_gen_shli_tl(t1, t1, 2);
13318 gen_op_addr_add(ctx, t0, t1, t0);
13319 }
13320
5f68f5ae 13321 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
3c824109
NF
13322 gen_store_gpr(t1, rd);
13323
13324 tcg_temp_free(t0);
13325 tcg_temp_free(t1);
13326}
13327
13328static void gen_ldst_pair (DisasContext *ctx, uint32_t opc, int rd,
13329 int base, int16_t offset)
13330{
3c824109
NF
13331 TCGv t0, t1;
13332
36c6711b 13333 if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31) {
9c708c7f 13334 generate_exception_end(ctx, EXCP_RI);
d796321b
FB
13335 return;
13336 }
13337
3c824109
NF
13338 t0 = tcg_temp_new();
13339 t1 = tcg_temp_new();
8e9ade68 13340
3c824109
NF
13341 gen_base_offset_addr(ctx, t0, base, offset);
13342
13343 switch (opc) {
13344 case LWP:
36c6711b 13345 if (rd == base) {
9c708c7f 13346 generate_exception_end(ctx, EXCP_RI);
36c6711b
EJ
13347 return;
13348 }
5f68f5ae 13349 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
3c824109
NF
13350 gen_store_gpr(t1, rd);
13351 tcg_gen_movi_tl(t1, 4);
13352 gen_op_addr_add(ctx, t0, t0, t1);
5f68f5ae 13353 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
3c824109 13354 gen_store_gpr(t1, rd+1);
3c824109
NF
13355 break;
13356 case SWP:
3c824109 13357 gen_load_gpr(t1, rd);
5f68f5ae 13358 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
3c824109
NF
13359 tcg_gen_movi_tl(t1, 4);
13360 gen_op_addr_add(ctx, t0, t0, t1);
13361 gen_load_gpr(t1, rd+1);
5f68f5ae 13362 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
3c824109
NF
13363 break;
13364#ifdef TARGET_MIPS64
13365 case LDP:
36c6711b 13366 if (rd == base) {
9c708c7f 13367 generate_exception_end(ctx, EXCP_RI);
36c6711b
EJ
13368 return;
13369 }
5f68f5ae 13370 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
3c824109
NF
13371 gen_store_gpr(t1, rd);
13372 tcg_gen_movi_tl(t1, 8);
13373 gen_op_addr_add(ctx, t0, t0, t1);
5f68f5ae 13374 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
3c824109 13375 gen_store_gpr(t1, rd+1);
3c824109
NF
13376 break;
13377 case SDP:
3c824109 13378 gen_load_gpr(t1, rd);
5f68f5ae 13379 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
3c824109
NF
13380 tcg_gen_movi_tl(t1, 8);
13381 gen_op_addr_add(ctx, t0, t0, t1);
13382 gen_load_gpr(t1, rd+1);
5f68f5ae 13383 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
3c824109
NF
13384 break;
13385#endif
6af0bf9c 13386 }
3c824109
NF
13387 tcg_temp_free(t0);
13388 tcg_temp_free(t1);
13389}
618b0fe9 13390
d208ac0c
LA
13391static void gen_sync(int stype)
13392{
13393 TCGBar tcg_mo = TCG_BAR_SC;
13394
13395 switch (stype) {
13396 case 0x4: /* SYNC_WMB */
13397 tcg_mo |= TCG_MO_ST_ST;
13398 break;
13399 case 0x10: /* SYNC_MB */
13400 tcg_mo |= TCG_MO_ALL;
13401 break;
13402 case 0x11: /* SYNC_ACQUIRE */
13403 tcg_mo |= TCG_MO_LD_LD | TCG_MO_LD_ST;
13404 break;
13405 case 0x12: /* SYNC_RELEASE */
13406 tcg_mo |= TCG_MO_ST_ST | TCG_MO_LD_ST;
13407 break;
13408 case 0x13: /* SYNC_RMB */
13409 tcg_mo |= TCG_MO_LD_LD;
13410 break;
13411 default:
13412 tcg_mo |= TCG_MO_ALL;
13413 break;
13414 }
13415
13416 tcg_gen_mb(tcg_mo);
13417}
13418
240ce26a 13419static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
3c824109
NF
13420{
13421 int extension = (ctx->opcode >> 6) & 0x3f;
13422 int minor = (ctx->opcode >> 12) & 0xf;
13423 uint32_t mips32_op;
13424
13425 switch (extension) {
13426 case TEQ:
13427 mips32_op = OPC_TEQ;
13428 goto do_trap;
13429 case TGE:
13430 mips32_op = OPC_TGE;
13431 goto do_trap;
13432 case TGEU:
13433 mips32_op = OPC_TGEU;
13434 goto do_trap;
13435 case TLT:
13436 mips32_op = OPC_TLT;
13437 goto do_trap;
13438 case TLTU:
13439 mips32_op = OPC_TLTU;
13440 goto do_trap;
13441 case TNE:
13442 mips32_op = OPC_TNE;
13443 do_trap:
13444 gen_trap(ctx, mips32_op, rs, rt, -1);
13445 break;
13446#ifndef CONFIG_USER_ONLY
13447 case MFC0:
13448 case MFC0 + 32:
2e15497c 13449 check_cp0_enabled(ctx);
3c824109
NF
13450 if (rt == 0) {
13451 /* Treat as NOP. */
13452 break;
13453 }
d75c135e 13454 gen_mfc0(ctx, cpu_gpr[rt], rs, (ctx->opcode >> 11) & 0x7);
3c824109
NF
13455 break;
13456 case MTC0:
13457 case MTC0 + 32:
2e15497c 13458 check_cp0_enabled(ctx);
3c824109
NF
13459 {
13460 TCGv t0 = tcg_temp_new();
618b0fe9 13461
3c824109 13462 gen_load_gpr(t0, rt);
d75c135e 13463 gen_mtc0(ctx, t0, rs, (ctx->opcode >> 11) & 0x7);
3c824109
NF
13464 tcg_temp_free(t0);
13465 }
13466 break;
13467#endif
a1fc6246
LA
13468 case 0x2a:
13469 switch (minor & 3) {
13470 case MADD_ACC:
13471 gen_muldiv(ctx, OPC_MADD, (ctx->opcode >> 14) & 3, rs, rt);
13472 break;
13473 case MADDU_ACC:
13474 gen_muldiv(ctx, OPC_MADDU, (ctx->opcode >> 14) & 3, rs, rt);
13475 break;
13476 case MSUB_ACC:
13477 gen_muldiv(ctx, OPC_MSUB, (ctx->opcode >> 14) & 3, rs, rt);
13478 break;
13479 case MSUBU_ACC:
13480 gen_muldiv(ctx, OPC_MSUBU, (ctx->opcode >> 14) & 3, rs, rt);
13481 break;
13482 default:
13483 goto pool32axf_invalid;
13484 }
13485 break;
13486 case 0x32:
13487 switch (minor & 3) {
13488 case MULT_ACC:
13489 gen_muldiv(ctx, OPC_MULT, (ctx->opcode >> 14) & 3, rs, rt);
13490 break;
13491 case MULTU_ACC:
13492 gen_muldiv(ctx, OPC_MULTU, (ctx->opcode >> 14) & 3, rs, rt);
13493 break;
13494 default:
13495 goto pool32axf_invalid;
13496 }
13497 break;
3c824109
NF
13498 case 0x2c:
13499 switch (minor) {
e0332095
YK
13500 case BITSWAP:
13501 check_insn(ctx, ISA_MIPS32R6);
13502 gen_bitswap(ctx, OPC_BITSWAP, rs, rt);
13503 break;
3c824109
NF
13504 case SEB:
13505 gen_bshfl(ctx, OPC_SEB, rs, rt);
13506 break;
13507 case SEH:
13508 gen_bshfl(ctx, OPC_SEH, rs, rt);
13509 break;
13510 case CLO:
13511 mips32_op = OPC_CLO;
13512 goto do_cl;
13513 case CLZ:
13514 mips32_op = OPC_CLZ;
13515 do_cl:
d75c135e 13516 check_insn(ctx, ISA_MIPS32);
3c824109
NF
13517 gen_cl(ctx, mips32_op, rt, rs);
13518 break;
13519 case RDHWR:
b00c7218
YK
13520 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13521 gen_rdhwr(ctx, rt, rs, 0);
3c824109
NF
13522 break;
13523 case WSBH:
13524 gen_bshfl(ctx, OPC_WSBH, rs, rt);
13525 break;
13526 case MULT:
9e8f441a 13527 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 13528 mips32_op = OPC_MULT;
26135ead 13529 goto do_mul;
3c824109 13530 case MULTU:
9e8f441a 13531 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 13532 mips32_op = OPC_MULTU;
26135ead 13533 goto do_mul;
3c824109 13534 case DIV:
9e8f441a 13535 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 13536 mips32_op = OPC_DIV;
26135ead 13537 goto do_div;
3c824109 13538 case DIVU:
9e8f441a 13539 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 13540 mips32_op = OPC_DIVU;
26135ead
RS
13541 goto do_div;
13542 do_div:
13543 check_insn(ctx, ISA_MIPS32);
13544 gen_muldiv(ctx, mips32_op, 0, rs, rt);
13545 break;
3c824109 13546 case MADD:
9e8f441a 13547 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 13548 mips32_op = OPC_MADD;
26135ead 13549 goto do_mul;
3c824109 13550 case MADDU:
9e8f441a 13551 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 13552 mips32_op = OPC_MADDU;
26135ead 13553 goto do_mul;
3c824109 13554 case MSUB:
9e8f441a 13555 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 13556 mips32_op = OPC_MSUB;
26135ead 13557 goto do_mul;
3c824109 13558 case MSUBU:
9e8f441a 13559 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 13560 mips32_op = OPC_MSUBU;
26135ead 13561 do_mul:
d75c135e 13562 check_insn(ctx, ISA_MIPS32);
a1fc6246 13563 gen_muldiv(ctx, mips32_op, 0, rs, rt);
3c824109
NF
13564 break;
13565 default:
13566 goto pool32axf_invalid;
13567 }
13568 break;
13569 case 0x34:
13570 switch (minor) {
13571 case MFC2:
13572 case MTC2:
13573 case MFHC2:
13574 case MTHC2:
13575 case CFC2:
13576 case CTC2:
13577 generate_exception_err(ctx, EXCP_CpU, 2);
13578 break;
13579 default:
13580 goto pool32axf_invalid;
13581 }
13582 break;
13583 case 0x3c:
13584 switch (minor) {
65935f07
YK
13585 case JALR: /* JALRC */
13586 case JALR_HB: /* JALRC_HB */
13587 if (ctx->insn_flags & ISA_MIPS32R6) {
13588 /* JALRC, JALRC_HB */
13589 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 0);
13590 } else {
13591 /* JALR, JALR_HB */
13592 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 4);
13593 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
13594 }
3c824109
NF
13595 break;
13596 case JALRS:
13597 case JALRS_HB:
9e8f441a 13598 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
13599 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 2);
13600 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
3c824109
NF
13601 break;
13602 default:
13603 goto pool32axf_invalid;
13604 }
13605 break;
13606 case 0x05:
13607 switch (minor) {
13608 case RDPGPR:
2e15497c 13609 check_cp0_enabled(ctx);
d75c135e 13610 check_insn(ctx, ISA_MIPS32R2);
1bf5902d 13611 gen_load_srsgpr(rs, rt);
3c824109
NF
13612 break;
13613 case WRPGPR:
2e15497c 13614 check_cp0_enabled(ctx);
d75c135e 13615 check_insn(ctx, ISA_MIPS32R2);
1bf5902d 13616 gen_store_srsgpr(rs, rt);
3c824109
NF
13617 break;
13618 default:
13619 goto pool32axf_invalid;
13620 }
13621 break;
13622#ifndef CONFIG_USER_ONLY
13623 case 0x0d:
13624 switch (minor) {
13625 case TLBP:
13626 mips32_op = OPC_TLBP;
13627 goto do_cp0;
13628 case TLBR:
13629 mips32_op = OPC_TLBR;
13630 goto do_cp0;
13631 case TLBWI:
13632 mips32_op = OPC_TLBWI;
13633 goto do_cp0;
13634 case TLBWR:
13635 mips32_op = OPC_TLBWR;
13636 goto do_cp0;
e60ec063
YK
13637 case TLBINV:
13638 mips32_op = OPC_TLBINV;
13639 goto do_cp0;
13640 case TLBINVF:
13641 mips32_op = OPC_TLBINVF;
13642 goto do_cp0;
3c824109
NF
13643 case WAIT:
13644 mips32_op = OPC_WAIT;
13645 goto do_cp0;
13646 case DERET:
13647 mips32_op = OPC_DERET;
13648 goto do_cp0;
13649 case ERET:
13650 mips32_op = OPC_ERET;
13651 do_cp0:
13652 gen_cp0(env, ctx, mips32_op, rt, rs);
13653 break;
13654 default:
13655 goto pool32axf_invalid;
13656 }
13657 break;
13658 case 0x1d:
13659 switch (minor) {
13660 case DI:
2e15497c 13661 check_cp0_enabled(ctx);
3c824109
NF
13662 {
13663 TCGv t0 = tcg_temp_new();
13664
13665 save_cpu_state(ctx, 1);
895c2d04 13666 gen_helper_di(t0, cpu_env);
3c824109
NF
13667 gen_store_gpr(t0, rs);
13668 /* Stop translation as we may have switched the execution mode */
eeb3bba8 13669 ctx->base.is_jmp = DISAS_STOP;
3c824109
NF
13670 tcg_temp_free(t0);
13671 }
13672 break;
13673 case EI:
2e15497c 13674 check_cp0_enabled(ctx);
3c824109
NF
13675 {
13676 TCGv t0 = tcg_temp_new();
13677
13678 save_cpu_state(ctx, 1);
895c2d04 13679 gen_helper_ei(t0, cpu_env);
3c824109 13680 gen_store_gpr(t0, rs);
b28425ba 13681 /* DISAS_STOP isn't sufficient, we need to ensure we break out
b74cddcb 13682 of translated code to check for pending interrupts. */
eeb3bba8
EC
13683 gen_save_pc(ctx->base.pc_next + 4);
13684 ctx->base.is_jmp = DISAS_EXIT;
3c824109
NF
13685 tcg_temp_free(t0);
13686 }
13687 break;
13688 default:
13689 goto pool32axf_invalid;
13690 }
13691 break;
13692#endif
13693 case 0x2d:
13694 switch (minor) {
13695 case SYNC:
d208ac0c 13696 gen_sync(extract32(ctx->opcode, 16, 5));
3c824109
NF
13697 break;
13698 case SYSCALL:
9c708c7f 13699 generate_exception_end(ctx, EXCP_SYSCALL);
3c824109
NF
13700 break;
13701 case SDBBP:
3b3c1694
LA
13702 if (is_uhi(extract32(ctx->opcode, 16, 10))) {
13703 gen_helper_do_semihosting(cpu_env);
13704 } else {
13705 check_insn(ctx, ISA_MIPS32);
e0332095 13706 if (ctx->hflags & MIPS_HFLAG_SBRI) {
9c708c7f 13707 generate_exception_end(ctx, EXCP_RI);
e0332095 13708 } else {
9c708c7f 13709 generate_exception_end(ctx, EXCP_DBp);
e0332095 13710 }
3b3c1694 13711 }
3c824109
NF
13712 break;
13713 default:
13714 goto pool32axf_invalid;
13715 }
13716 break;
a1fc6246 13717 case 0x01:
26135ead 13718 switch (minor & 3) {
a1fc6246 13719 case MFHI_ACC:
26135ead 13720 gen_HILO(ctx, OPC_MFHI, minor >> 2, rs);
3c824109 13721 break;
a1fc6246 13722 case MFLO_ACC:
26135ead 13723 gen_HILO(ctx, OPC_MFLO, minor >> 2, rs);
3c824109 13724 break;
a1fc6246 13725 case MTHI_ACC:
26135ead 13726 gen_HILO(ctx, OPC_MTHI, minor >> 2, rs);
3c824109 13727 break;
a1fc6246 13728 case MTLO_ACC:
26135ead 13729 gen_HILO(ctx, OPC_MTLO, minor >> 2, rs);
3c824109
NF
13730 break;
13731 default:
13732 goto pool32axf_invalid;
13733 }
13734 break;
a1fc6246 13735 case 0x35:
9e8f441a 13736 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a1fc6246
LA
13737 switch (minor) {
13738 case MFHI32:
13739 gen_HILO(ctx, OPC_MFHI, 0, rs);
13740 break;
13741 case MFLO32:
13742 gen_HILO(ctx, OPC_MFLO, 0, rs);
13743 break;
13744 case MTHI32:
13745 gen_HILO(ctx, OPC_MTHI, 0, rs);
13746 break;
13747 case MTLO32:
13748 gen_HILO(ctx, OPC_MTLO, 0, rs);
13749 break;
13750 default:
13751 goto pool32axf_invalid;
13752 }
13753 break;
3c824109
NF
13754 default:
13755 pool32axf_invalid:
13756 MIPS_INVAL("pool32axf");
9c708c7f 13757 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
13758 break;
13759 }
13760}
13761
13762/* Values for microMIPS fmt field. Variable-width, depending on which
13763 formats the instruction supports. */
13764
13765enum {
13766 FMT_SD_S = 0,
13767 FMT_SD_D = 1,
13768
13769 FMT_SDPS_S = 0,
13770 FMT_SDPS_D = 1,
13771 FMT_SDPS_PS = 2,
13772
13773 FMT_SWL_S = 0,
13774 FMT_SWL_W = 1,
13775 FMT_SWL_L = 2,
13776
13777 FMT_DWL_D = 0,
13778 FMT_DWL_W = 1,
13779 FMT_DWL_L = 2
13780};
13781
d75c135e 13782static void gen_pool32fxf(DisasContext *ctx, int rt, int rs)
3c824109
NF
13783{
13784 int extension = (ctx->opcode >> 6) & 0x3ff;
13785 uint32_t mips32_op;
13786
13787#define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
13788#define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
13789#define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
13790
13791 switch (extension) {
13792 case FLOAT_1BIT_FMT(CFC1, 0):
13793 mips32_op = OPC_CFC1;
13794 goto do_cp1;
13795 case FLOAT_1BIT_FMT(CTC1, 0):
13796 mips32_op = OPC_CTC1;
13797 goto do_cp1;
13798 case FLOAT_1BIT_FMT(MFC1, 0):
13799 mips32_op = OPC_MFC1;
13800 goto do_cp1;
13801 case FLOAT_1BIT_FMT(MTC1, 0):
13802 mips32_op = OPC_MTC1;
13803 goto do_cp1;
13804 case FLOAT_1BIT_FMT(MFHC1, 0):
13805 mips32_op = OPC_MFHC1;
13806 goto do_cp1;
13807 case FLOAT_1BIT_FMT(MTHC1, 0):
13808 mips32_op = OPC_MTHC1;
13809 do_cp1:
13810 gen_cp1(ctx, mips32_op, rt, rs);
13811 break;
13812
13813 /* Reciprocal square root */
13814 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_S):
13815 mips32_op = OPC_RSQRT_S;
13816 goto do_unaryfp;
13817 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_D):
13818 mips32_op = OPC_RSQRT_D;
13819 goto do_unaryfp;
13820
13821 /* Square root */
13822 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_S):
13823 mips32_op = OPC_SQRT_S;
13824 goto do_unaryfp;
13825 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_D):
13826 mips32_op = OPC_SQRT_D;
13827 goto do_unaryfp;
13828
13829 /* Reciprocal */
13830 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_S):
13831 mips32_op = OPC_RECIP_S;
13832 goto do_unaryfp;
13833 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_D):
13834 mips32_op = OPC_RECIP_D;
13835 goto do_unaryfp;
13836
13837 /* Floor */
13838 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_S):
13839 mips32_op = OPC_FLOOR_L_S;
13840 goto do_unaryfp;
13841 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_D):
13842 mips32_op = OPC_FLOOR_L_D;
13843 goto do_unaryfp;
13844 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_S):
13845 mips32_op = OPC_FLOOR_W_S;
13846 goto do_unaryfp;
13847 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_D):
13848 mips32_op = OPC_FLOOR_W_D;
13849 goto do_unaryfp;
13850
13851 /* Ceiling */
13852 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_S):
13853 mips32_op = OPC_CEIL_L_S;
13854 goto do_unaryfp;
13855 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_D):
13856 mips32_op = OPC_CEIL_L_D;
13857 goto do_unaryfp;
13858 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_S):
13859 mips32_op = OPC_CEIL_W_S;
13860 goto do_unaryfp;
13861 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_D):
13862 mips32_op = OPC_CEIL_W_D;
13863 goto do_unaryfp;
13864
13865 /* Truncation */
13866 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_S):
13867 mips32_op = OPC_TRUNC_L_S;
13868 goto do_unaryfp;
13869 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_D):
13870 mips32_op = OPC_TRUNC_L_D;
13871 goto do_unaryfp;
13872 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_S):
13873 mips32_op = OPC_TRUNC_W_S;
13874 goto do_unaryfp;
13875 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_D):
13876 mips32_op = OPC_TRUNC_W_D;
13877 goto do_unaryfp;
13878
13879 /* Round */
13880 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_S):
13881 mips32_op = OPC_ROUND_L_S;
13882 goto do_unaryfp;
13883 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_D):
13884 mips32_op = OPC_ROUND_L_D;
13885 goto do_unaryfp;
13886 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_S):
13887 mips32_op = OPC_ROUND_W_S;
13888 goto do_unaryfp;
13889 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_D):
13890 mips32_op = OPC_ROUND_W_D;
13891 goto do_unaryfp;
13892
13893 /* Integer to floating-point conversion */
13894 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_S):
13895 mips32_op = OPC_CVT_L_S;
13896 goto do_unaryfp;
13897 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_D):
13898 mips32_op = OPC_CVT_L_D;
13899 goto do_unaryfp;
13900 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_S):
13901 mips32_op = OPC_CVT_W_S;
13902 goto do_unaryfp;
13903 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_D):
13904 mips32_op = OPC_CVT_W_D;
13905 goto do_unaryfp;
13906
13907 /* Paired-foo conversions */
13908 case FLOAT_1BIT_FMT(CVT_S_PL, 0):
13909 mips32_op = OPC_CVT_S_PL;
13910 goto do_unaryfp;
13911 case FLOAT_1BIT_FMT(CVT_S_PU, 0):
13912 mips32_op = OPC_CVT_S_PU;
13913 goto do_unaryfp;
13914 case FLOAT_1BIT_FMT(CVT_PW_PS, 0):
13915 mips32_op = OPC_CVT_PW_PS;
13916 goto do_unaryfp;
13917 case FLOAT_1BIT_FMT(CVT_PS_PW, 0):
13918 mips32_op = OPC_CVT_PS_PW;
13919 goto do_unaryfp;
13920
13921 /* Floating-point moves */
13922 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_S):
13923 mips32_op = OPC_MOV_S;
13924 goto do_unaryfp;
13925 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_D):
13926 mips32_op = OPC_MOV_D;
13927 goto do_unaryfp;
13928 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_PS):
13929 mips32_op = OPC_MOV_PS;
13930 goto do_unaryfp;
13931
13932 /* Absolute value */
13933 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_S):
13934 mips32_op = OPC_ABS_S;
13935 goto do_unaryfp;
13936 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_D):
13937 mips32_op = OPC_ABS_D;
13938 goto do_unaryfp;
13939 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_PS):
13940 mips32_op = OPC_ABS_PS;
13941 goto do_unaryfp;
13942
13943 /* Negation */
13944 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_S):
13945 mips32_op = OPC_NEG_S;
13946 goto do_unaryfp;
13947 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_D):
13948 mips32_op = OPC_NEG_D;
13949 goto do_unaryfp;
13950 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_PS):
13951 mips32_op = OPC_NEG_PS;
13952 goto do_unaryfp;
13953
13954 /* Reciprocal square root step */
13955 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_S):
13956 mips32_op = OPC_RSQRT1_S;
13957 goto do_unaryfp;
13958 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_D):
13959 mips32_op = OPC_RSQRT1_D;
13960 goto do_unaryfp;
13961 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_PS):
13962 mips32_op = OPC_RSQRT1_PS;
13963 goto do_unaryfp;
13964
13965 /* Reciprocal step */
13966 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_S):
13967 mips32_op = OPC_RECIP1_S;
13968 goto do_unaryfp;
13969 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_D):
13970 mips32_op = OPC_RECIP1_S;
13971 goto do_unaryfp;
13972 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_PS):
13973 mips32_op = OPC_RECIP1_PS;
13974 goto do_unaryfp;
13975
13976 /* Conversions from double */
13977 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_S):
13978 mips32_op = OPC_CVT_D_S;
13979 goto do_unaryfp;
13980 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_W):
13981 mips32_op = OPC_CVT_D_W;
13982 goto do_unaryfp;
13983 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_L):
13984 mips32_op = OPC_CVT_D_L;
13985 goto do_unaryfp;
13986
13987 /* Conversions from single */
13988 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_D):
13989 mips32_op = OPC_CVT_S_D;
13990 goto do_unaryfp;
13991 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_W):
13992 mips32_op = OPC_CVT_S_W;
13993 goto do_unaryfp;
13994 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_L):
13995 mips32_op = OPC_CVT_S_L;
13996 do_unaryfp:
13997 gen_farith(ctx, mips32_op, -1, rs, rt, 0);
13998 break;
13999
14000 /* Conditional moves on floating-point codes */
14001 case COND_FLOAT_MOV(MOVT, 0):
14002 case COND_FLOAT_MOV(MOVT, 1):
14003 case COND_FLOAT_MOV(MOVT, 2):
14004 case COND_FLOAT_MOV(MOVT, 3):
14005 case COND_FLOAT_MOV(MOVT, 4):
14006 case COND_FLOAT_MOV(MOVT, 5):
14007 case COND_FLOAT_MOV(MOVT, 6):
14008 case COND_FLOAT_MOV(MOVT, 7):
9e8f441a 14009 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14010 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 1);
14011 break;
14012 case COND_FLOAT_MOV(MOVF, 0):
14013 case COND_FLOAT_MOV(MOVF, 1):
14014 case COND_FLOAT_MOV(MOVF, 2):
14015 case COND_FLOAT_MOV(MOVF, 3):
14016 case COND_FLOAT_MOV(MOVF, 4):
14017 case COND_FLOAT_MOV(MOVF, 5):
14018 case COND_FLOAT_MOV(MOVF, 6):
14019 case COND_FLOAT_MOV(MOVF, 7):
9e8f441a 14020 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14021 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 0);
14022 break;
14023 default:
14024 MIPS_INVAL("pool32fxf");
9c708c7f 14025 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
14026 break;
14027 }
14028}
14029
f60eeb0c 14030static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx)
3c824109
NF
14031{
14032 int32_t offset;
14033 uint16_t insn;
14034 int rt, rs, rd, rr;
14035 int16_t imm;
8fffc646 14036 uint32_t op, minor, minor2, mips32_op;
3c824109
NF
14037 uint32_t cond, fmt, cc;
14038
eeb3bba8 14039 insn = cpu_lduw_code(env, ctx->base.pc_next + 2);
3c824109
NF
14040 ctx->opcode = (ctx->opcode << 16) | insn;
14041
14042 rt = (ctx->opcode >> 21) & 0x1f;
14043 rs = (ctx->opcode >> 16) & 0x1f;
14044 rd = (ctx->opcode >> 11) & 0x1f;
14045 rr = (ctx->opcode >> 6) & 0x1f;
14046 imm = (int16_t) ctx->opcode;
14047
14048 op = (ctx->opcode >> 26) & 0x3f;
14049 switch (op) {
14050 case POOL32A:
14051 minor = ctx->opcode & 0x3f;
14052 switch (minor) {
14053 case 0x00:
14054 minor = (ctx->opcode >> 6) & 0xf;
14055 switch (minor) {
14056 case SLL32:
14057 mips32_op = OPC_SLL;
14058 goto do_shifti;
14059 case SRA:
14060 mips32_op = OPC_SRA;
14061 goto do_shifti;
14062 case SRL32:
14063 mips32_op = OPC_SRL;
14064 goto do_shifti;
14065 case ROTR:
14066 mips32_op = OPC_ROTR;
14067 do_shifti:
d75c135e 14068 gen_shift_imm(ctx, mips32_op, rt, rs, rd);
3c824109 14069 break;
e0332095
YK
14070 case SELEQZ:
14071 check_insn(ctx, ISA_MIPS32R6);
14072 gen_cond_move(ctx, OPC_SELEQZ, rd, rs, rt);
14073 break;
14074 case SELNEZ:
14075 check_insn(ctx, ISA_MIPS32R6);
14076 gen_cond_move(ctx, OPC_SELNEZ, rd, rs, rt);
14077 break;
b00c7218
YK
14078 case R6_RDHWR:
14079 check_insn(ctx, ISA_MIPS32R6);
14080 gen_rdhwr(ctx, rt, rs, extract32(ctx->opcode, 11, 3));
14081 break;
3c824109
NF
14082 default:
14083 goto pool32a_invalid;
14084 }
14085 break;
14086 case 0x10:
14087 minor = (ctx->opcode >> 6) & 0xf;
14088 switch (minor) {
14089 /* Arithmetic */
14090 case ADD:
14091 mips32_op = OPC_ADD;
14092 goto do_arith;
14093 case ADDU32:
14094 mips32_op = OPC_ADDU;
14095 goto do_arith;
14096 case SUB:
14097 mips32_op = OPC_SUB;
14098 goto do_arith;
14099 case SUBU32:
14100 mips32_op = OPC_SUBU;
14101 goto do_arith;
14102 case MUL:
9e8f441a 14103 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14104 mips32_op = OPC_MUL;
14105 do_arith:
d75c135e 14106 gen_arith(ctx, mips32_op, rd, rs, rt);
3c824109
NF
14107 break;
14108 /* Shifts */
14109 case SLLV:
14110 mips32_op = OPC_SLLV;
14111 goto do_shift;
14112 case SRLV:
14113 mips32_op = OPC_SRLV;
14114 goto do_shift;
14115 case SRAV:
14116 mips32_op = OPC_SRAV;
14117 goto do_shift;
14118 case ROTRV:
14119 mips32_op = OPC_ROTRV;
14120 do_shift:
d75c135e 14121 gen_shift(ctx, mips32_op, rd, rs, rt);
3c824109
NF
14122 break;
14123 /* Logical operations */
14124 case AND:
14125 mips32_op = OPC_AND;
14126 goto do_logic;
14127 case OR32:
14128 mips32_op = OPC_OR;
14129 goto do_logic;
14130 case NOR:
14131 mips32_op = OPC_NOR;
14132 goto do_logic;
14133 case XOR32:
14134 mips32_op = OPC_XOR;
14135 do_logic:
d75c135e 14136 gen_logic(ctx, mips32_op, rd, rs, rt);
3c824109
NF
14137 break;
14138 /* Set less than */
14139 case SLT:
14140 mips32_op = OPC_SLT;
14141 goto do_slt;
14142 case SLTU:
14143 mips32_op = OPC_SLTU;
14144 do_slt:
d75c135e 14145 gen_slt(ctx, mips32_op, rd, rs, rt);
3c824109
NF
14146 break;
14147 default:
14148 goto pool32a_invalid;
14149 }
14150 break;
14151 case 0x18:
14152 minor = (ctx->opcode >> 6) & 0xf;
14153 switch (minor) {
14154 /* Conditional moves */
e0332095
YK
14155 case MOVN: /* MUL */
14156 if (ctx->insn_flags & ISA_MIPS32R6) {
14157 /* MUL */
14158 gen_r6_muldiv(ctx, R6_OPC_MUL, rd, rs, rt);
14159 } else {
14160 /* MOVN */
14161 gen_cond_move(ctx, OPC_MOVN, rd, rs, rt);
14162 }
14163 break;
14164 case MOVZ: /* MUH */
14165 if (ctx->insn_flags & ISA_MIPS32R6) {
14166 /* MUH */
14167 gen_r6_muldiv(ctx, R6_OPC_MUH, rd, rs, rt);
14168 } else {
14169 /* MOVZ */
14170 gen_cond_move(ctx, OPC_MOVZ, rd, rs, rt);
14171 }
14172 break;
14173 case MULU:
14174 check_insn(ctx, ISA_MIPS32R6);
14175 gen_r6_muldiv(ctx, R6_OPC_MULU, rd, rs, rt);
14176 break;
14177 case MUHU:
14178 check_insn(ctx, ISA_MIPS32R6);
14179 gen_r6_muldiv(ctx, R6_OPC_MUHU, rd, rs, rt);
14180 break;
14181 case LWXS: /* DIV */
14182 if (ctx->insn_flags & ISA_MIPS32R6) {
14183 /* DIV */
14184 gen_r6_muldiv(ctx, R6_OPC_DIV, rd, rs, rt);
14185 } else {
14186 /* LWXS */
14187 gen_ldxs(ctx, rs, rt, rd);
14188 }
14189 break;
14190 case MOD:
14191 check_insn(ctx, ISA_MIPS32R6);
14192 gen_r6_muldiv(ctx, R6_OPC_MOD, rd, rs, rt);
14193 break;
14194 case R6_DIVU:
14195 check_insn(ctx, ISA_MIPS32R6);
14196 gen_r6_muldiv(ctx, R6_OPC_DIVU, rd, rs, rt);
3c824109 14197 break;
e0332095
YK
14198 case MODU:
14199 check_insn(ctx, ISA_MIPS32R6);
14200 gen_r6_muldiv(ctx, R6_OPC_MODU, rd, rs, rt);
3c824109
NF
14201 break;
14202 default:
14203 goto pool32a_invalid;
14204 }
14205 break;
14206 case INS:
14207 gen_bitops(ctx, OPC_INS, rt, rs, rr, rd);
14208 return;
e0332095
YK
14209 case LSA:
14210 check_insn(ctx, ISA_MIPS32R6);
14211 gen_lsa(ctx, OPC_LSA, rd, rs, rt,
14212 extract32(ctx->opcode, 9, 2));
14213 break;
14214 case ALIGN:
14215 check_insn(ctx, ISA_MIPS32R6);
14216 gen_align(ctx, OPC_ALIGN, rd, rs, rt,
14217 extract32(ctx->opcode, 9, 2));
14218 break;
3c824109
NF
14219 case EXT:
14220 gen_bitops(ctx, OPC_EXT, rt, rs, rr, rd);
14221 return;
14222 case POOL32AXF:
240ce26a 14223 gen_pool32axf(env, ctx, rt, rs);
3c824109 14224 break;
dbd8af98 14225 case BREAK32:
9c708c7f 14226 generate_exception_end(ctx, EXCP_BREAK);
3c824109 14227 break;
bb238210
YK
14228 case SIGRIE:
14229 check_insn(ctx, ISA_MIPS32R6);
14230 generate_exception_end(ctx, EXCP_RI);
14231 break;
3c824109
NF
14232 default:
14233 pool32a_invalid:
14234 MIPS_INVAL("pool32a");
9c708c7f 14235 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
14236 break;
14237 }
14238 break;
14239 case POOL32B:
14240 minor = (ctx->opcode >> 12) & 0xf;
14241 switch (minor) {
14242 case CACHE:
2e15497c 14243 check_cp0_enabled(ctx);
0d74a222
LA
14244 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
14245 gen_cache_operation(ctx, rt, rs, imm);
14246 }
3c824109
NF
14247 break;
14248 case LWC2:
14249 case SWC2:
14250 /* COP2: Not implemented. */
14251 generate_exception_err(ctx, EXCP_CpU, 2);
14252 break;
3c824109
NF
14253#ifdef TARGET_MIPS64
14254 case LDP:
14255 case SDP:
d9224450
MR
14256 check_insn(ctx, ISA_MIPS3);
14257 check_mips_64(ctx);
14258 /* Fallthrough */
3c824109 14259#endif
d9224450
MR
14260 case LWP:
14261 case SWP:
3c824109
NF
14262 gen_ldst_pair(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
14263 break;
3c824109
NF
14264#ifdef TARGET_MIPS64
14265 case LDM:
14266 case SDM:
d9224450
MR
14267 check_insn(ctx, ISA_MIPS3);
14268 check_mips_64(ctx);
14269 /* Fallthrough */
3c824109 14270#endif
d9224450
MR
14271 case LWM32:
14272 case SWM32:
3c824109
NF
14273 gen_ldst_multiple(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
14274 break;
14275 default:
14276 MIPS_INVAL("pool32b");
9c708c7f 14277 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
14278 break;
14279 }
14280 break;
14281 case POOL32F:
5ab5c041 14282 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
3c824109
NF
14283 minor = ctx->opcode & 0x3f;
14284 check_cp1_enabled(ctx);
14285 switch (minor) {
14286 case ALNV_PS:
9e8f441a 14287 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14288 mips32_op = OPC_ALNV_PS;
14289 goto do_madd;
14290 case MADD_S:
9e8f441a 14291 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14292 mips32_op = OPC_MADD_S;
14293 goto do_madd;
14294 case MADD_D:
9e8f441a 14295 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14296 mips32_op = OPC_MADD_D;
14297 goto do_madd;
14298 case MADD_PS:
9e8f441a 14299 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14300 mips32_op = OPC_MADD_PS;
14301 goto do_madd;
14302 case MSUB_S:
9e8f441a 14303 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14304 mips32_op = OPC_MSUB_S;
14305 goto do_madd;
14306 case MSUB_D:
9e8f441a 14307 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14308 mips32_op = OPC_MSUB_D;
14309 goto do_madd;
14310 case MSUB_PS:
9e8f441a 14311 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14312 mips32_op = OPC_MSUB_PS;
14313 goto do_madd;
14314 case NMADD_S:
9e8f441a 14315 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14316 mips32_op = OPC_NMADD_S;
14317 goto do_madd;
14318 case NMADD_D:
9e8f441a 14319 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14320 mips32_op = OPC_NMADD_D;
14321 goto do_madd;
14322 case NMADD_PS:
9e8f441a 14323 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14324 mips32_op = OPC_NMADD_PS;
14325 goto do_madd;
14326 case NMSUB_S:
9e8f441a 14327 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14328 mips32_op = OPC_NMSUB_S;
14329 goto do_madd;
14330 case NMSUB_D:
9e8f441a 14331 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14332 mips32_op = OPC_NMSUB_D;
14333 goto do_madd;
14334 case NMSUB_PS:
9e8f441a 14335 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14336 mips32_op = OPC_NMSUB_PS;
14337 do_madd:
14338 gen_flt3_arith(ctx, mips32_op, rd, rr, rs, rt);
14339 break;
14340 case CABS_COND_FMT:
9e8f441a 14341 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14342 cond = (ctx->opcode >> 6) & 0xf;
14343 cc = (ctx->opcode >> 13) & 0x7;
14344 fmt = (ctx->opcode >> 10) & 0x3;
14345 switch (fmt) {
14346 case 0x0:
14347 gen_cmpabs_s(ctx, cond, rt, rs, cc);
14348 break;
14349 case 0x1:
14350 gen_cmpabs_d(ctx, cond, rt, rs, cc);
14351 break;
14352 case 0x2:
14353 gen_cmpabs_ps(ctx, cond, rt, rs, cc);
14354 break;
14355 default:
14356 goto pool32f_invalid;
14357 }
14358 break;
14359 case C_COND_FMT:
9e8f441a 14360 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14361 cond = (ctx->opcode >> 6) & 0xf;
14362 cc = (ctx->opcode >> 13) & 0x7;
14363 fmt = (ctx->opcode >> 10) & 0x3;
14364 switch (fmt) {
14365 case 0x0:
14366 gen_cmp_s(ctx, cond, rt, rs, cc);
14367 break;
14368 case 0x1:
14369 gen_cmp_d(ctx, cond, rt, rs, cc);
14370 break;
14371 case 0x2:
14372 gen_cmp_ps(ctx, cond, rt, rs, cc);
14373 break;
14374 default:
14375 goto pool32f_invalid;
14376 }
14377 break;
2a24a7ba
YK
14378 case CMP_CONDN_S:
14379 check_insn(ctx, ISA_MIPS32R6);
14380 gen_r6_cmp_s(ctx, (ctx->opcode >> 6) & 0x1f, rt, rs, rd);
14381 break;
14382 case CMP_CONDN_D:
14383 check_insn(ctx, ISA_MIPS32R6);
14384 gen_r6_cmp_d(ctx, (ctx->opcode >> 6) & 0x1f, rt, rs, rd);
14385 break;
3c824109 14386 case POOL32FXF:
d75c135e 14387 gen_pool32fxf(ctx, rt, rs);
3c824109
NF
14388 break;
14389 case 0x00:
14390 /* PLL foo */
14391 switch ((ctx->opcode >> 6) & 0x7) {
14392 case PLL_PS:
14393 mips32_op = OPC_PLL_PS;
14394 goto do_ps;
14395 case PLU_PS:
14396 mips32_op = OPC_PLU_PS;
14397 goto do_ps;
14398 case PUL_PS:
14399 mips32_op = OPC_PUL_PS;
14400 goto do_ps;
14401 case PUU_PS:
14402 mips32_op = OPC_PUU_PS;
14403 goto do_ps;
14404 case CVT_PS_S:
9e8f441a 14405 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14406 mips32_op = OPC_CVT_PS_S;
14407 do_ps:
14408 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
14409 break;
14410 default:
14411 goto pool32f_invalid;
14412 }
14413 break;
2a24a7ba
YK
14414 case MIN_FMT:
14415 check_insn(ctx, ISA_MIPS32R6);
14416 switch ((ctx->opcode >> 9) & 0x3) {
14417 case FMT_SDPS_S:
14418 gen_farith(ctx, OPC_MIN_S, rt, rs, rd, 0);
14419 break;
14420 case FMT_SDPS_D:
14421 gen_farith(ctx, OPC_MIN_D, rt, rs, rd, 0);
14422 break;
14423 default:
14424 goto pool32f_invalid;
14425 }
14426 break;
3c824109
NF
14427 case 0x08:
14428 /* [LS][WDU]XC1 */
14429 switch ((ctx->opcode >> 6) & 0x7) {
14430 case LWXC1:
9e8f441a 14431 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14432 mips32_op = OPC_LWXC1;
14433 goto do_ldst_cp1;
14434 case SWXC1:
9e8f441a 14435 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14436 mips32_op = OPC_SWXC1;
14437 goto do_ldst_cp1;
14438 case LDXC1:
9e8f441a 14439 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14440 mips32_op = OPC_LDXC1;
14441 goto do_ldst_cp1;
14442 case SDXC1:
9e8f441a 14443 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14444 mips32_op = OPC_SDXC1;
14445 goto do_ldst_cp1;
14446 case LUXC1:
9e8f441a 14447 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14448 mips32_op = OPC_LUXC1;
14449 goto do_ldst_cp1;
14450 case SUXC1:
9e8f441a 14451 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14452 mips32_op = OPC_SUXC1;
14453 do_ldst_cp1:
14454 gen_flt3_ldst(ctx, mips32_op, rd, rd, rt, rs);
14455 break;
14456 default:
14457 goto pool32f_invalid;
14458 }
14459 break;
2a24a7ba
YK
14460 case MAX_FMT:
14461 check_insn(ctx, ISA_MIPS32R6);
14462 switch ((ctx->opcode >> 9) & 0x3) {
14463 case FMT_SDPS_S:
14464 gen_farith(ctx, OPC_MAX_S, rt, rs, rd, 0);
14465 break;
14466 case FMT_SDPS_D:
14467 gen_farith(ctx, OPC_MAX_D, rt, rs, rd, 0);
14468 break;
14469 default:
14470 goto pool32f_invalid;
14471 }
14472 break;
3c824109
NF
14473 case 0x18:
14474 /* 3D insns */
9e8f441a 14475 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14476 fmt = (ctx->opcode >> 9) & 0x3;
14477 switch ((ctx->opcode >> 6) & 0x7) {
14478 case RSQRT2_FMT:
14479 switch (fmt) {
14480 case FMT_SDPS_S:
14481 mips32_op = OPC_RSQRT2_S;
14482 goto do_3d;
14483 case FMT_SDPS_D:
14484 mips32_op = OPC_RSQRT2_D;
14485 goto do_3d;
14486 case FMT_SDPS_PS:
14487 mips32_op = OPC_RSQRT2_PS;
14488 goto do_3d;
14489 default:
14490 goto pool32f_invalid;
14491 }
14492 break;
14493 case RECIP2_FMT:
14494 switch (fmt) {
14495 case FMT_SDPS_S:
14496 mips32_op = OPC_RECIP2_S;
14497 goto do_3d;
14498 case FMT_SDPS_D:
14499 mips32_op = OPC_RECIP2_D;
14500 goto do_3d;
14501 case FMT_SDPS_PS:
14502 mips32_op = OPC_RECIP2_PS;
14503 goto do_3d;
14504 default:
14505 goto pool32f_invalid;
14506 }
14507 break;
14508 case ADDR_PS:
14509 mips32_op = OPC_ADDR_PS;
14510 goto do_3d;
14511 case MULR_PS:
14512 mips32_op = OPC_MULR_PS;
14513 do_3d:
14514 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
14515 break;
14516 default:
14517 goto pool32f_invalid;
14518 }
14519 break;
14520 case 0x20:
2a24a7ba 14521 /* MOV[FT].fmt, PREFX, RINT.fmt, CLASS.fmt*/
3c824109
NF
14522 cc = (ctx->opcode >> 13) & 0x7;
14523 fmt = (ctx->opcode >> 9) & 0x3;
14524 switch ((ctx->opcode >> 6) & 0x7) {
2a24a7ba
YK
14525 case MOVF_FMT: /* RINT_FMT */
14526 if (ctx->insn_flags & ISA_MIPS32R6) {
14527 /* RINT_FMT */
14528 switch (fmt) {
14529 case FMT_SDPS_S:
14530 gen_farith(ctx, OPC_RINT_S, 0, rt, rs, 0);
14531 break;
14532 case FMT_SDPS_D:
14533 gen_farith(ctx, OPC_RINT_D, 0, rt, rs, 0);
14534 break;
14535 default:
14536 goto pool32f_invalid;
14537 }
14538 } else {
14539 /* MOVF_FMT */
14540 switch (fmt) {
14541 case FMT_SDPS_S:
14542 gen_movcf_s(ctx, rs, rt, cc, 0);
14543 break;
14544 case FMT_SDPS_D:
14545 gen_movcf_d(ctx, rs, rt, cc, 0);
14546 break;
14547 case FMT_SDPS_PS:
14548 check_ps(ctx);
14549 gen_movcf_ps(ctx, rs, rt, cc, 0);
14550 break;
14551 default:
14552 goto pool32f_invalid;
14553 }
3c824109
NF
14554 }
14555 break;
2a24a7ba
YK
14556 case MOVT_FMT: /* CLASS_FMT */
14557 if (ctx->insn_flags & ISA_MIPS32R6) {
14558 /* CLASS_FMT */
14559 switch (fmt) {
14560 case FMT_SDPS_S:
14561 gen_farith(ctx, OPC_CLASS_S, 0, rt, rs, 0);
14562 break;
14563 case FMT_SDPS_D:
14564 gen_farith(ctx, OPC_CLASS_D, 0, rt, rs, 0);
14565 break;
14566 default:
14567 goto pool32f_invalid;
14568 }
14569 } else {
14570 /* MOVT_FMT */
14571 switch (fmt) {
14572 case FMT_SDPS_S:
14573 gen_movcf_s(ctx, rs, rt, cc, 1);
14574 break;
14575 case FMT_SDPS_D:
14576 gen_movcf_d(ctx, rs, rt, cc, 1);
14577 break;
14578 case FMT_SDPS_PS:
14579 check_ps(ctx);
14580 gen_movcf_ps(ctx, rs, rt, cc, 1);
14581 break;
14582 default:
14583 goto pool32f_invalid;
14584 }
3c824109
NF
14585 }
14586 break;
14587 case PREFX:
9e8f441a 14588 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14589 break;
14590 default:
14591 goto pool32f_invalid;
14592 }
14593 break;
14594#define FINSN_3ARG_SDPS(prfx) \
14595 switch ((ctx->opcode >> 8) & 0x3) { \
14596 case FMT_SDPS_S: \
14597 mips32_op = OPC_##prfx##_S; \
14598 goto do_fpop; \
14599 case FMT_SDPS_D: \
14600 mips32_op = OPC_##prfx##_D; \
14601 goto do_fpop; \
14602 case FMT_SDPS_PS: \
e29c9628 14603 check_ps(ctx); \
3c824109
NF
14604 mips32_op = OPC_##prfx##_PS; \
14605 goto do_fpop; \
14606 default: \
14607 goto pool32f_invalid; \
14608 }
2a24a7ba
YK
14609 case MINA_FMT:
14610 check_insn(ctx, ISA_MIPS32R6);
14611 switch ((ctx->opcode >> 9) & 0x3) {
14612 case FMT_SDPS_S:
14613 gen_farith(ctx, OPC_MINA_S, rt, rs, rd, 0);
14614 break;
14615 case FMT_SDPS_D:
14616 gen_farith(ctx, OPC_MINA_D, rt, rs, rd, 0);
14617 break;
14618 default:
14619 goto pool32f_invalid;
14620 }
14621 break;
14622 case MAXA_FMT:
14623 check_insn(ctx, ISA_MIPS32R6);
14624 switch ((ctx->opcode >> 9) & 0x3) {
14625 case FMT_SDPS_S:
14626 gen_farith(ctx, OPC_MAXA_S, rt, rs, rd, 0);
14627 break;
14628 case FMT_SDPS_D:
14629 gen_farith(ctx, OPC_MAXA_D, rt, rs, rd, 0);
14630 break;
14631 default:
14632 goto pool32f_invalid;
14633 }
14634 break;
3c824109
NF
14635 case 0x30:
14636 /* regular FP ops */
14637 switch ((ctx->opcode >> 6) & 0x3) {
14638 case ADD_FMT:
14639 FINSN_3ARG_SDPS(ADD);
14640 break;
14641 case SUB_FMT:
14642 FINSN_3ARG_SDPS(SUB);
14643 break;
14644 case MUL_FMT:
14645 FINSN_3ARG_SDPS(MUL);
14646 break;
14647 case DIV_FMT:
14648 fmt = (ctx->opcode >> 8) & 0x3;
14649 if (fmt == 1) {
14650 mips32_op = OPC_DIV_D;
14651 } else if (fmt == 0) {
14652 mips32_op = OPC_DIV_S;
14653 } else {
14654 goto pool32f_invalid;
14655 }
14656 goto do_fpop;
14657 default:
14658 goto pool32f_invalid;
14659 }
14660 break;
14661 case 0x38:
14662 /* cmovs */
2a24a7ba
YK
14663 switch ((ctx->opcode >> 6) & 0x7) {
14664 case MOVN_FMT: /* SELNEZ_FMT */
14665 if (ctx->insn_flags & ISA_MIPS32R6) {
14666 /* SELNEZ_FMT */
14667 switch ((ctx->opcode >> 9) & 0x3) {
14668 case FMT_SDPS_S:
14669 gen_sel_s(ctx, OPC_SELNEZ_S, rd, rt, rs);
14670 break;
14671 case FMT_SDPS_D:
14672 gen_sel_d(ctx, OPC_SELNEZ_D, rd, rt, rs);
14673 break;
14674 default:
14675 goto pool32f_invalid;
14676 }
14677 } else {
14678 /* MOVN_FMT */
14679 FINSN_3ARG_SDPS(MOVN);
14680 }
14681 break;
14682 case MOVN_FMT_04:
14683 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14684 FINSN_3ARG_SDPS(MOVN);
14685 break;
2a24a7ba
YK
14686 case MOVZ_FMT: /* SELEQZ_FMT */
14687 if (ctx->insn_flags & ISA_MIPS32R6) {
14688 /* SELEQZ_FMT */
14689 switch ((ctx->opcode >> 9) & 0x3) {
14690 case FMT_SDPS_S:
14691 gen_sel_s(ctx, OPC_SELEQZ_S, rd, rt, rs);
14692 break;
14693 case FMT_SDPS_D:
14694 gen_sel_d(ctx, OPC_SELEQZ_D, rd, rt, rs);
14695 break;
14696 default:
14697 goto pool32f_invalid;
14698 }
14699 } else {
14700 /* MOVZ_FMT */
14701 FINSN_3ARG_SDPS(MOVZ);
14702 }
14703 break;
14704 case MOVZ_FMT_05:
14705 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14706 FINSN_3ARG_SDPS(MOVZ);
14707 break;
2a24a7ba
YK
14708 case SEL_FMT:
14709 check_insn(ctx, ISA_MIPS32R6);
14710 switch ((ctx->opcode >> 9) & 0x3) {
14711 case FMT_SDPS_S:
14712 gen_sel_s(ctx, OPC_SEL_S, rd, rt, rs);
14713 break;
14714 case FMT_SDPS_D:
14715 gen_sel_d(ctx, OPC_SEL_D, rd, rt, rs);
14716 break;
14717 default:
14718 goto pool32f_invalid;
14719 }
14720 break;
14721 case MADDF_FMT:
14722 check_insn(ctx, ISA_MIPS32R6);
14723 switch ((ctx->opcode >> 9) & 0x3) {
14724 case FMT_SDPS_S:
14725 mips32_op = OPC_MADDF_S;
14726 goto do_fpop;
14727 case FMT_SDPS_D:
14728 mips32_op = OPC_MADDF_D;
14729 goto do_fpop;
14730 default:
14731 goto pool32f_invalid;
14732 }
14733 break;
14734 case MSUBF_FMT:
14735 check_insn(ctx, ISA_MIPS32R6);
14736 switch ((ctx->opcode >> 9) & 0x3) {
14737 case FMT_SDPS_S:
14738 mips32_op = OPC_MSUBF_S;
14739 goto do_fpop;
14740 case FMT_SDPS_D:
14741 mips32_op = OPC_MSUBF_D;
14742 goto do_fpop;
14743 default:
14744 goto pool32f_invalid;
14745 }
14746 break;
3c824109
NF
14747 default:
14748 goto pool32f_invalid;
14749 }
14750 break;
14751 do_fpop:
14752 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
14753 break;
14754 default:
14755 pool32f_invalid:
14756 MIPS_INVAL("pool32f");
9c708c7f 14757 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
14758 break;
14759 }
14760 } else {
14761 generate_exception_err(ctx, EXCP_CpU, 1);
14762 }
14763 break;
14764 case POOL32I:
14765 minor = (ctx->opcode >> 21) & 0x1f;
14766 switch (minor) {
14767 case BLTZ:
9e8f441a 14768 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
14769 gen_compute_branch(ctx, OPC_BLTZ, 4, rs, -1, imm << 1, 4);
14770 break;
3c824109 14771 case BLTZAL:
9e8f441a 14772 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
14773 gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 4);
14774 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14775 break;
3c824109 14776 case BLTZALS:
9e8f441a 14777 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
14778 gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 2);
14779 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14780 break;
3c824109 14781 case BGEZ:
9e8f441a 14782 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
14783 gen_compute_branch(ctx, OPC_BGEZ, 4, rs, -1, imm << 1, 4);
14784 break;
3c824109 14785 case BGEZAL:
9e8f441a 14786 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
14787 gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 4);
14788 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14789 break;
3c824109 14790 case BGEZALS:
9e8f441a 14791 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
14792 gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 2);
14793 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14794 break;
3c824109 14795 case BLEZ:
9e8f441a 14796 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
14797 gen_compute_branch(ctx, OPC_BLEZ, 4, rs, -1, imm << 1, 4);
14798 break;
3c824109 14799 case BGTZ:
9e8f441a 14800 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103 14801 gen_compute_branch(ctx, OPC_BGTZ, 4, rs, -1, imm << 1, 4);
3c824109
NF
14802 break;
14803
14804 /* Traps */
65935f07
YK
14805 case TLTI: /* BC1EQZC */
14806 if (ctx->insn_flags & ISA_MIPS32R6) {
14807 /* BC1EQZC */
14808 check_cp1_enabled(ctx);
14809 gen_compute_branch1_r6(ctx, OPC_BC1EQZ, rs, imm << 1, 0);
14810 } else {
14811 /* TLTI */
14812 mips32_op = OPC_TLTI;
14813 goto do_trapi;
14814 }
14815 break;
14816 case TGEI: /* BC1NEZC */
14817 if (ctx->insn_flags & ISA_MIPS32R6) {
14818 /* BC1NEZC */
14819 check_cp1_enabled(ctx);
14820 gen_compute_branch1_r6(ctx, OPC_BC1NEZ, rs, imm << 1, 0);
14821 } else {
14822 /* TGEI */
14823 mips32_op = OPC_TGEI;
14824 goto do_trapi;
14825 }
14826 break;
3c824109 14827 case TLTIU:
9e8f441a 14828 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14829 mips32_op = OPC_TLTIU;
14830 goto do_trapi;
14831 case TGEIU:
9e8f441a 14832 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14833 mips32_op = OPC_TGEIU;
14834 goto do_trapi;
3b4a5489
YK
14835 case TNEI: /* SYNCI */
14836 if (ctx->insn_flags & ISA_MIPS32R6) {
14837 /* SYNCI */
14838 /* Break the TB to be able to sync copied instructions
14839 immediately */
eeb3bba8 14840 ctx->base.is_jmp = DISAS_STOP;
3b4a5489
YK
14841 } else {
14842 /* TNEI */
14843 mips32_op = OPC_TNEI;
14844 goto do_trapi;
14845 }
14846 break;
3c824109 14847 case TEQI:
9e8f441a 14848 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14849 mips32_op = OPC_TEQI;
14850 do_trapi:
14851 gen_trap(ctx, mips32_op, rs, -1, imm);
14852 break;
14853
14854 case BNEZC:
14855 case BEQZC:
9e8f441a 14856 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 14857 gen_compute_branch(ctx, minor == BNEZC ? OPC_BNE : OPC_BEQ,
b231c103 14858 4, rs, 0, imm << 1, 0);
3c824109
NF
14859 /* Compact branches don't have a delay slot, so just let
14860 the normal delay slot handling take us to the branch
14861 target. */
14862 break;
14863 case LUI:
9e8f441a 14864 check_insn_opc_removed(ctx, ISA_MIPS32R6);
5e88759a 14865 gen_logic_imm(ctx, OPC_LUI, rs, 0, imm);
3c824109
NF
14866 break;
14867 case SYNCI:
9e8f441a 14868 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a83bddd6
DZ
14869 /* Break the TB to be able to sync copied instructions
14870 immediately */
eeb3bba8 14871 ctx->base.is_jmp = DISAS_STOP;
3c824109
NF
14872 break;
14873 case BC2F:
14874 case BC2T:
9e8f441a 14875 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14876 /* COP2: Not implemented. */
14877 generate_exception_err(ctx, EXCP_CpU, 2);
14878 break;
14879 case BC1F:
9e8f441a 14880 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14881 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1FANY2 : OPC_BC1F;
14882 goto do_cp1branch;
14883 case BC1T:
9e8f441a 14884 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14885 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1TANY2 : OPC_BC1T;
14886 goto do_cp1branch;
14887 case BC1ANY4F:
9e8f441a 14888 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14889 mips32_op = OPC_BC1FANY4;
14890 goto do_cp1mips3d;
14891 case BC1ANY4T:
9e8f441a 14892 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14893 mips32_op = OPC_BC1TANY4;
14894 do_cp1mips3d:
14895 check_cop1x(ctx);
d75c135e 14896 check_insn(ctx, ASE_MIPS3D);
3c824109
NF
14897 /* Fall through */
14898 do_cp1branch:
272f458d
MR
14899 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
14900 check_cp1_enabled(ctx);
14901 gen_compute_branch1(ctx, mips32_op,
14902 (ctx->opcode >> 18) & 0x7, imm << 1);
14903 } else {
14904 generate_exception_err(ctx, EXCP_CpU, 1);
14905 }
3c824109
NF
14906 break;
14907 case BPOSGE64:
14908 case BPOSGE32:
14909 /* MIPS DSP: not implemented */
14910 /* Fall through */
14911 default:
14912 MIPS_INVAL("pool32i");
9c708c7f 14913 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
14914 break;
14915 }
14916 break;
14917 case POOL32C:
14918 minor = (ctx->opcode >> 12) & 0xf;
3b4a5489
YK
14919 offset = sextract32(ctx->opcode, 0,
14920 (ctx->insn_flags & ISA_MIPS32R6) ? 9 : 12);
3c824109
NF
14921 switch (minor) {
14922 case LWL:
9e8f441a 14923 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 14924 mips32_op = OPC_LWL;
5c13fdfd 14925 goto do_ld_lr;
3c824109 14926 case SWL:
9e8f441a 14927 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 14928 mips32_op = OPC_SWL;
5c13fdfd 14929 goto do_st_lr;
3c824109 14930 case LWR:
9e8f441a 14931 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 14932 mips32_op = OPC_LWR;
5c13fdfd 14933 goto do_ld_lr;
3c824109 14934 case SWR:
9e8f441a 14935 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 14936 mips32_op = OPC_SWR;
5c13fdfd 14937 goto do_st_lr;
3c824109
NF
14938#if defined(TARGET_MIPS64)
14939 case LDL:
d9224450
MR
14940 check_insn(ctx, ISA_MIPS3);
14941 check_mips_64(ctx);
9e8f441a 14942 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 14943 mips32_op = OPC_LDL;
5c13fdfd 14944 goto do_ld_lr;
3c824109 14945 case SDL:
d9224450
MR
14946 check_insn(ctx, ISA_MIPS3);
14947 check_mips_64(ctx);
9e8f441a 14948 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 14949 mips32_op = OPC_SDL;
5c13fdfd 14950 goto do_st_lr;
3c824109 14951 case LDR:
d9224450
MR
14952 check_insn(ctx, ISA_MIPS3);
14953 check_mips_64(ctx);
9e8f441a 14954 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 14955 mips32_op = OPC_LDR;
5c13fdfd 14956 goto do_ld_lr;
3c824109 14957 case SDR:
d9224450
MR
14958 check_insn(ctx, ISA_MIPS3);
14959 check_mips_64(ctx);
9e8f441a 14960 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 14961 mips32_op = OPC_SDR;
5c13fdfd 14962 goto do_st_lr;
3c824109 14963 case LWU:
d9224450
MR
14964 check_insn(ctx, ISA_MIPS3);
14965 check_mips_64(ctx);
3c824109 14966 mips32_op = OPC_LWU;
5c13fdfd 14967 goto do_ld_lr;
3c824109 14968 case LLD:
d9224450
MR
14969 check_insn(ctx, ISA_MIPS3);
14970 check_mips_64(ctx);
3c824109 14971 mips32_op = OPC_LLD;
5c13fdfd 14972 goto do_ld_lr;
3c824109
NF
14973#endif
14974 case LL:
14975 mips32_op = OPC_LL;
5c13fdfd
AJ
14976 goto do_ld_lr;
14977 do_ld_lr:
3b4a5489 14978 gen_ld(ctx, mips32_op, rt, rs, offset);
5c13fdfd
AJ
14979 break;
14980 do_st_lr:
8fffc646 14981 gen_st(ctx, mips32_op, rt, rs, offset);
3c824109
NF
14982 break;
14983 case SC:
3b4a5489 14984 gen_st_cond(ctx, OPC_SC, rt, rs, offset);
3c824109
NF
14985 break;
14986#if defined(TARGET_MIPS64)
14987 case SCD:
d9224450
MR
14988 check_insn(ctx, ISA_MIPS3);
14989 check_mips_64(ctx);
3b4a5489 14990 gen_st_cond(ctx, OPC_SCD, rt, rs, offset);
3c824109
NF
14991 break;
14992#endif
8fffc646
JH
14993 case LD_EVA:
14994 if (!ctx->eva) {
14995 MIPS_INVAL("pool32c ld-eva");
14996 generate_exception_end(ctx, EXCP_RI);
14997 break;
14998 }
14999 check_cp0_enabled(ctx);
15000
15001 minor2 = (ctx->opcode >> 9) & 0x7;
15002 offset = sextract32(ctx->opcode, 0, 9);
15003 switch (minor2) {
15004 case LBUE:
15005 mips32_op = OPC_LBUE;
15006 goto do_ld_lr;
15007 case LHUE:
15008 mips32_op = OPC_LHUE;
15009 goto do_ld_lr;
15010 case LWLE:
15011 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15012 mips32_op = OPC_LWLE;
15013 goto do_ld_lr;
15014 case LWRE:
15015 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15016 mips32_op = OPC_LWRE;
15017 goto do_ld_lr;
15018 case LBE:
15019 mips32_op = OPC_LBE;
15020 goto do_ld_lr;
15021 case LHE:
15022 mips32_op = OPC_LHE;
15023 goto do_ld_lr;
15024 case LLE:
15025 mips32_op = OPC_LLE;
15026 goto do_ld_lr;
15027 case LWE:
15028 mips32_op = OPC_LWE;
15029 goto do_ld_lr;
15030 };
15031 break;
15032 case ST_EVA:
15033 if (!ctx->eva) {
15034 MIPS_INVAL("pool32c st-eva");
15035 generate_exception_end(ctx, EXCP_RI);
15036 break;
15037 }
15038 check_cp0_enabled(ctx);
15039
15040 minor2 = (ctx->opcode >> 9) & 0x7;
15041 offset = sextract32(ctx->opcode, 0, 9);
15042 switch (minor2) {
15043 case SWLE:
15044 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15045 mips32_op = OPC_SWLE;
15046 goto do_st_lr;
15047 case SWRE:
15048 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15049 mips32_op = OPC_SWRE;
15050 goto do_st_lr;
15051 case PREFE:
15052 /* Treat as no-op */
15053 if ((ctx->insn_flags & ISA_MIPS32R6) && (rt >= 24)) {
15054 /* hint codes 24-31 are reserved and signal RI */
15055 generate_exception(ctx, EXCP_RI);
15056 }
15057 break;
15058 case CACHEE:
15059 /* Treat as no-op */
15060 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
15061 gen_cache_operation(ctx, rt, rs, offset);
15062 }
15063 break;
15064 case SBE:
15065 mips32_op = OPC_SBE;
15066 goto do_st_lr;
15067 case SHE:
15068 mips32_op = OPC_SHE;
15069 goto do_st_lr;
15070 case SCE:
15071 gen_st_cond(ctx, OPC_SCE, rt, rs, offset);
15072 break;
15073 case SWE:
15074 mips32_op = OPC_SWE;
15075 goto do_st_lr;
15076 };
15077 break;
3c824109
NF
15078 case PREF:
15079 /* Treat as no-op */
3b4a5489
YK
15080 if ((ctx->insn_flags & ISA_MIPS32R6) && (rt >= 24)) {
15081 /* hint codes 24-31 are reserved and signal RI */
15082 generate_exception(ctx, EXCP_RI);
15083 }
3c824109
NF
15084 break;
15085 default:
15086 MIPS_INVAL("pool32c");
9c708c7f 15087 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
15088 break;
15089 }
15090 break;
ab39ee45
YK
15091 case ADDI32: /* AUI, LUI */
15092 if (ctx->insn_flags & ISA_MIPS32R6) {
15093 /* AUI, LUI */
15094 gen_logic_imm(ctx, OPC_LUI, rt, rs, imm);
15095 } else {
15096 /* ADDI32 */
15097 mips32_op = OPC_ADDI;
15098 goto do_addi;
15099 }
15100 break;
3c824109
NF
15101 case ADDIU32:
15102 mips32_op = OPC_ADDIU;
15103 do_addi:
d75c135e 15104 gen_arith_imm(ctx, mips32_op, rt, rs, imm);
3c824109
NF
15105 break;
15106
15107 /* Logical operations */
15108 case ORI32:
15109 mips32_op = OPC_ORI;
15110 goto do_logici;
15111 case XORI32:
15112 mips32_op = OPC_XORI;
15113 goto do_logici;
15114 case ANDI32:
15115 mips32_op = OPC_ANDI;
15116 do_logici:
d75c135e 15117 gen_logic_imm(ctx, mips32_op, rt, rs, imm);
3c824109
NF
15118 break;
15119
15120 /* Set less than immediate */
15121 case SLTI32:
15122 mips32_op = OPC_SLTI;
15123 goto do_slti;
15124 case SLTIU32:
15125 mips32_op = OPC_SLTIU;
15126 do_slti:
d75c135e 15127 gen_slt_imm(ctx, mips32_op, rt, rs, imm);
3c824109
NF
15128 break;
15129 case JALX32:
9e8f441a 15130 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 15131 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
b231c103
YK
15132 gen_compute_branch(ctx, OPC_JALX, 4, rt, rs, offset, 4);
15133 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
3c824109 15134 break;
65935f07
YK
15135 case JALS32: /* BOVC, BEQC, BEQZALC */
15136 if (ctx->insn_flags & ISA_MIPS32R6) {
15137 if (rs >= rt) {
15138 /* BOVC */
15139 mips32_op = OPC_BOVC;
15140 } else if (rs < rt && rs == 0) {
15141 /* BEQZALC */
15142 mips32_op = OPC_BEQZALC;
15143 } else {
15144 /* BEQC */
15145 mips32_op = OPC_BEQC;
15146 }
15147 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
15148 } else {
15149 /* JALS32 */
15150 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 1;
15151 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs, offset, 2);
15152 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
15153 }
3c824109 15154 break;
65935f07
YK
15155 case BEQ32: /* BC */
15156 if (ctx->insn_flags & ISA_MIPS32R6) {
15157 /* BC */
15158 gen_compute_compact_branch(ctx, OPC_BC, 0, 0,
15159 sextract32(ctx->opcode << 1, 0, 27));
15160 } else {
15161 /* BEQ32 */
15162 gen_compute_branch(ctx, OPC_BEQ, 4, rt, rs, imm << 1, 4);
15163 }
3c824109 15164 break;
65935f07
YK
15165 case BNE32: /* BALC */
15166 if (ctx->insn_flags & ISA_MIPS32R6) {
15167 /* BALC */
15168 gen_compute_compact_branch(ctx, OPC_BALC, 0, 0,
15169 sextract32(ctx->opcode << 1, 0, 27));
15170 } else {
15171 /* BNE32 */
15172 gen_compute_branch(ctx, OPC_BNE, 4, rt, rs, imm << 1, 4);
15173 }
3c824109 15174 break;
65935f07
YK
15175 case J32: /* BGTZC, BLTZC, BLTC */
15176 if (ctx->insn_flags & ISA_MIPS32R6) {
15177 if (rs == 0 && rt != 0) {
15178 /* BGTZC */
15179 mips32_op = OPC_BGTZC;
15180 } else if (rs != 0 && rt != 0 && rs == rt) {
15181 /* BLTZC */
15182 mips32_op = OPC_BLTZC;
15183 } else {
15184 /* BLTC */
15185 mips32_op = OPC_BLTC;
15186 }
15187 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
15188 } else {
15189 /* J32 */
15190 gen_compute_branch(ctx, OPC_J, 4, rt, rs,
15191 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
15192 }
3c824109 15193 break;
65935f07
YK
15194 case JAL32: /* BLEZC, BGEZC, BGEC */
15195 if (ctx->insn_flags & ISA_MIPS32R6) {
15196 if (rs == 0 && rt != 0) {
15197 /* BLEZC */
15198 mips32_op = OPC_BLEZC;
15199 } else if (rs != 0 && rt != 0 && rs == rt) {
15200 /* BGEZC */
15201 mips32_op = OPC_BGEZC;
15202 } else {
15203 /* BGEC */
15204 mips32_op = OPC_BGEC;
15205 }
15206 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
15207 } else {
15208 /* JAL32 */
15209 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs,
15210 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
15211 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
15212 }
3c824109
NF
15213 break;
15214 /* Floating point (COP1) */
15215 case LWC132:
15216 mips32_op = OPC_LWC1;
15217 goto do_cop1;
15218 case LDC132:
15219 mips32_op = OPC_LDC1;
15220 goto do_cop1;
15221 case SWC132:
15222 mips32_op = OPC_SWC1;
15223 goto do_cop1;
15224 case SDC132:
15225 mips32_op = OPC_SDC1;
15226 do_cop1:
5ab5c041 15227 gen_cop1_ldst(ctx, mips32_op, rt, rs, imm);
3c824109 15228 break;
ab39ee45
YK
15229 case ADDIUPC: /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
15230 if (ctx->insn_flags & ISA_MIPS32R6) {
15231 /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
15232 switch ((ctx->opcode >> 16) & 0x1f) {
15233 case ADDIUPC_00 ... ADDIUPC_07:
eeb3bba8 15234 gen_pcrel(ctx, OPC_ADDIUPC, ctx->base.pc_next & ~0x3, rt);
ab39ee45
YK
15235 break;
15236 case AUIPC:
eeb3bba8 15237 gen_pcrel(ctx, OPC_AUIPC, ctx->base.pc_next, rt);
ab39ee45
YK
15238 break;
15239 case ALUIPC:
eeb3bba8 15240 gen_pcrel(ctx, OPC_ALUIPC, ctx->base.pc_next, rt);
ab39ee45
YK
15241 break;
15242 case LWPC_08 ... LWPC_0F:
eeb3bba8 15243 gen_pcrel(ctx, R6_OPC_LWPC, ctx->base.pc_next & ~0x3, rt);
ab39ee45
YK
15244 break;
15245 default:
15246 generate_exception(ctx, EXCP_RI);
15247 break;
15248 }
15249 } else {
15250 /* ADDIUPC */
3c824109
NF
15251 int reg = mmreg(ZIMM(ctx->opcode, 23, 3));
15252 int offset = SIMM(ctx->opcode, 0, 23) << 2;
15253
15254 gen_addiupc(ctx, reg, offset, 0, 0);
15255 }
15256 break;
65935f07
YK
15257 case BNVC: /* BNEC, BNEZALC */
15258 check_insn(ctx, ISA_MIPS32R6);
15259 if (rs >= rt) {
15260 /* BNVC */
15261 mips32_op = OPC_BNVC;
15262 } else if (rs < rt && rs == 0) {
15263 /* BNEZALC */
15264 mips32_op = OPC_BNEZALC;
15265 } else {
15266 /* BNEC */
15267 mips32_op = OPC_BNEC;
15268 }
15269 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
15270 break;
15271 case R6_BNEZC: /* JIALC */
15272 check_insn(ctx, ISA_MIPS32R6);
15273 if (rt != 0) {
15274 /* BNEZC */
15275 gen_compute_compact_branch(ctx, OPC_BNEZC, rt, 0,
15276 sextract32(ctx->opcode << 1, 0, 22));
15277 } else {
15278 /* JIALC */
15279 gen_compute_compact_branch(ctx, OPC_JIALC, 0, rs, imm);
15280 }
15281 break;
15282 case R6_BEQZC: /* JIC */
15283 check_insn(ctx, ISA_MIPS32R6);
15284 if (rt != 0) {
15285 /* BEQZC */
15286 gen_compute_compact_branch(ctx, OPC_BEQZC, rt, 0,
15287 sextract32(ctx->opcode << 1, 0, 22));
15288 } else {
15289 /* JIC */
15290 gen_compute_compact_branch(ctx, OPC_JIC, 0, rs, imm);
15291 }
15292 break;
15293 case BLEZALC: /* BGEZALC, BGEUC */
15294 check_insn(ctx, ISA_MIPS32R6);
15295 if (rs == 0 && rt != 0) {
15296 /* BLEZALC */
15297 mips32_op = OPC_BLEZALC;
15298 } else if (rs != 0 && rt != 0 && rs == rt) {
15299 /* BGEZALC */
15300 mips32_op = OPC_BGEZALC;
15301 } else {
15302 /* BGEUC */
15303 mips32_op = OPC_BGEUC;
15304 }
15305 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
15306 break;
15307 case BGTZALC: /* BLTZALC, BLTUC */
15308 check_insn(ctx, ISA_MIPS32R6);
15309 if (rs == 0 && rt != 0) {
15310 /* BGTZALC */
15311 mips32_op = OPC_BGTZALC;
15312 } else if (rs != 0 && rt != 0 && rs == rt) {
15313 /* BLTZALC */
15314 mips32_op = OPC_BLTZALC;
15315 } else {
15316 /* BLTUC */
15317 mips32_op = OPC_BLTUC;
15318 }
15319 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
15320 break;
3c824109
NF
15321 /* Loads and stores */
15322 case LB32:
15323 mips32_op = OPC_LB;
5c13fdfd 15324 goto do_ld;
3c824109
NF
15325 case LBU32:
15326 mips32_op = OPC_LBU;
5c13fdfd 15327 goto do_ld;
3c824109
NF
15328 case LH32:
15329 mips32_op = OPC_LH;
5c13fdfd 15330 goto do_ld;
3c824109
NF
15331 case LHU32:
15332 mips32_op = OPC_LHU;
5c13fdfd 15333 goto do_ld;
3c824109
NF
15334 case LW32:
15335 mips32_op = OPC_LW;
5c13fdfd 15336 goto do_ld;
3c824109
NF
15337#ifdef TARGET_MIPS64
15338 case LD32:
d9224450
MR
15339 check_insn(ctx, ISA_MIPS3);
15340 check_mips_64(ctx);
3c824109 15341 mips32_op = OPC_LD;
5c13fdfd 15342 goto do_ld;
3c824109 15343 case SD32:
d9224450
MR
15344 check_insn(ctx, ISA_MIPS3);
15345 check_mips_64(ctx);
3c824109 15346 mips32_op = OPC_SD;
5c13fdfd 15347 goto do_st;
3c824109
NF
15348#endif
15349 case SB32:
15350 mips32_op = OPC_SB;
5c13fdfd 15351 goto do_st;
3c824109
NF
15352 case SH32:
15353 mips32_op = OPC_SH;
5c13fdfd 15354 goto do_st;
3c824109
NF
15355 case SW32:
15356 mips32_op = OPC_SW;
5c13fdfd
AJ
15357 goto do_st;
15358 do_ld:
d75c135e 15359 gen_ld(ctx, mips32_op, rt, rs, imm);
5c13fdfd
AJ
15360 break;
15361 do_st:
15362 gen_st(ctx, mips32_op, rt, rs, imm);
3c824109
NF
15363 break;
15364 default:
9c708c7f 15365 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
15366 break;
15367 }
15368}
15369
240ce26a 15370static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx)
3c824109
NF
15371{
15372 uint32_t op;
15373
15374 /* make sure instructions are on a halfword boundary */
eeb3bba8
EC
15375 if (ctx->base.pc_next & 0x1) {
15376 env->CP0_BadVAddr = ctx->base.pc_next;
9c708c7f 15377 generate_exception_end(ctx, EXCP_AdEL);
3c824109
NF
15378 return 2;
15379 }
15380
15381 op = (ctx->opcode >> 10) & 0x3f;
15382 /* Enforce properly-sized instructions in a delay slot */
b231c103
YK
15383 if (ctx->hflags & MIPS_HFLAG_BDS_STRICT) {
15384 switch (op & 0x7) { /* MSB-3..MSB-5 */
15385 case 0:
15386 /* POOL32A, POOL32B, POOL32I, POOL32C */
15387 case 4:
15388 /* ADDI32, ADDIU32, ORI32, XORI32, SLTI32, SLTIU32, ANDI32, JALX32 */
15389 case 5:
15390 /* LBU32, LHU32, POOL32F, JALS32, BEQ32, BNE32, J32, JAL32 */
15391 case 6:
15392 /* SB32, SH32, ADDIUPC, SWC132, SDC132, SW32 */
15393 case 7:
15394 /* LB32, LH32, LWC132, LDC132, LW32 */
15395 if (ctx->hflags & MIPS_HFLAG_BDS16) {
9c708c7f 15396 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
15397 return 2;
15398 }
15399 break;
b231c103
YK
15400 case 1:
15401 /* POOL16A, POOL16B, POOL16C, LWGP16, POOL16F */
15402 case 2:
15403 /* LBU16, LHU16, LWSP16, LW16, SB16, SH16, SWSP16, SW16 */
15404 case 3:
15405 /* MOVE16, ANDI16, POOL16D, POOL16E, BEQZ16, BNEZ16, B16, LI16 */
15406 if (ctx->hflags & MIPS_HFLAG_BDS32) {
9c708c7f 15407 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
15408 return 2;
15409 }
15410 break;
3c824109
NF
15411 }
15412 }
b231c103 15413
3c824109
NF
15414 switch (op) {
15415 case POOL16A:
15416 {
15417 int rd = mmreg(uMIPS_RD(ctx->opcode));
15418 int rs1 = mmreg(uMIPS_RS1(ctx->opcode));
15419 int rs2 = mmreg(uMIPS_RS2(ctx->opcode));
15420 uint32_t opc = 0;
15421
15422 switch (ctx->opcode & 0x1) {
15423 case ADDU16:
15424 opc = OPC_ADDU;
15425 break;
15426 case SUBU16:
15427 opc = OPC_SUBU;
15428 break;
15429 }
ed7ce6c0
YK
15430 if (ctx->insn_flags & ISA_MIPS32R6) {
15431 /* In the Release 6 the register number location in
15432 * the instruction encoding has changed.
15433 */
15434 gen_arith(ctx, opc, rs1, rd, rs2);
15435 } else {
15436 gen_arith(ctx, opc, rd, rs1, rs2);
15437 }
3c824109
NF
15438 }
15439 break;
15440 case POOL16B:
15441 {
15442 int rd = mmreg(uMIPS_RD(ctx->opcode));
15443 int rs = mmreg(uMIPS_RS(ctx->opcode));
15444 int amount = (ctx->opcode >> 1) & 0x7;
15445 uint32_t opc = 0;
15446 amount = amount == 0 ? 8 : amount;
15447
15448 switch (ctx->opcode & 0x1) {
15449 case SLL16:
15450 opc = OPC_SLL;
15451 break;
15452 case SRL16:
15453 opc = OPC_SRL;
15454 break;
15455 }
15456
d75c135e 15457 gen_shift_imm(ctx, opc, rd, rs, amount);
3c824109
NF
15458 }
15459 break;
15460 case POOL16C:
ed7ce6c0
YK
15461 if (ctx->insn_flags & ISA_MIPS32R6) {
15462 gen_pool16c_r6_insn(ctx);
15463 } else {
15464 gen_pool16c_insn(ctx);
15465 }
3c824109
NF
15466 break;
15467 case LWGP16:
15468 {
15469 int rd = mmreg(uMIPS_RD(ctx->opcode));
15470 int rb = 28; /* GP */
15471 int16_t offset = SIMM(ctx->opcode, 0, 7) << 2;
15472
d75c135e 15473 gen_ld(ctx, OPC_LW, rd, rb, offset);
3c824109
NF
15474 }
15475 break;
15476 case POOL16F:
9e8f441a 15477 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 15478 if (ctx->opcode & 1) {
9c708c7f 15479 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
15480 } else {
15481 /* MOVEP */
15482 int enc_dest = uMIPS_RD(ctx->opcode);
15483 int enc_rt = uMIPS_RS2(ctx->opcode);
15484 int enc_rs = uMIPS_RS1(ctx->opcode);
ed7ce6c0 15485 gen_movep(ctx, enc_dest, enc_rt, enc_rs);
3c824109
NF
15486 }
15487 break;
15488 case LBU16:
15489 {
15490 int rd = mmreg(uMIPS_RD(ctx->opcode));
15491 int rb = mmreg(uMIPS_RS(ctx->opcode));
15492 int16_t offset = ZIMM(ctx->opcode, 0, 4);
15493 offset = (offset == 0xf ? -1 : offset);
15494
d75c135e 15495 gen_ld(ctx, OPC_LBU, rd, rb, offset);
3c824109
NF
15496 }
15497 break;
15498 case LHU16:
15499 {
15500 int rd = mmreg(uMIPS_RD(ctx->opcode));
15501 int rb = mmreg(uMIPS_RS(ctx->opcode));
15502 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
15503
d75c135e 15504 gen_ld(ctx, OPC_LHU, rd, rb, offset);
3c824109
NF
15505 }
15506 break;
15507 case LWSP16:
15508 {
15509 int rd = (ctx->opcode >> 5) & 0x1f;
15510 int rb = 29; /* SP */
15511 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
15512
d75c135e 15513 gen_ld(ctx, OPC_LW, rd, rb, offset);
3c824109
NF
15514 }
15515 break;
15516 case LW16:
15517 {
15518 int rd = mmreg(uMIPS_RD(ctx->opcode));
15519 int rb = mmreg(uMIPS_RS(ctx->opcode));
15520 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
15521
d75c135e 15522 gen_ld(ctx, OPC_LW, rd, rb, offset);
3c824109
NF
15523 }
15524 break;
15525 case SB16:
15526 {
15527 int rd = mmreg2(uMIPS_RD(ctx->opcode));
15528 int rb = mmreg(uMIPS_RS(ctx->opcode));
15529 int16_t offset = ZIMM(ctx->opcode, 0, 4);
15530
5c13fdfd 15531 gen_st(ctx, OPC_SB, rd, rb, offset);
3c824109
NF
15532 }
15533 break;
15534 case SH16:
15535 {
15536 int rd = mmreg2(uMIPS_RD(ctx->opcode));
15537 int rb = mmreg(uMIPS_RS(ctx->opcode));
15538 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
15539
5c13fdfd 15540 gen_st(ctx, OPC_SH, rd, rb, offset);
3c824109
NF
15541 }
15542 break;
15543 case SWSP16:
15544 {
15545 int rd = (ctx->opcode >> 5) & 0x1f;
15546 int rb = 29; /* SP */
15547 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
15548
5c13fdfd 15549 gen_st(ctx, OPC_SW, rd, rb, offset);
3c824109
NF
15550 }
15551 break;
15552 case SW16:
15553 {
15554 int rd = mmreg2(uMIPS_RD(ctx->opcode));
15555 int rb = mmreg(uMIPS_RS(ctx->opcode));
15556 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
15557
5c13fdfd 15558 gen_st(ctx, OPC_SW, rd, rb, offset);
3c824109
NF
15559 }
15560 break;
15561 case MOVE16:
15562 {
15563 int rd = uMIPS_RD5(ctx->opcode);
15564 int rs = uMIPS_RS5(ctx->opcode);
15565
7215d7e7 15566 gen_arith(ctx, OPC_ADDU, rd, rs, 0);
3c824109
NF
15567 }
15568 break;
15569 case ANDI16:
d75c135e 15570 gen_andi16(ctx);
3c824109
NF
15571 break;
15572 case POOL16D:
15573 switch (ctx->opcode & 0x1) {
15574 case ADDIUS5:
d75c135e 15575 gen_addius5(ctx);
3c824109
NF
15576 break;
15577 case ADDIUSP:
d75c135e 15578 gen_addiusp(ctx);
3c824109
NF
15579 break;
15580 }
15581 break;
15582 case POOL16E:
15583 switch (ctx->opcode & 0x1) {
15584 case ADDIUR2:
d75c135e 15585 gen_addiur2(ctx);
3c824109
NF
15586 break;
15587 case ADDIUR1SP:
d75c135e 15588 gen_addiur1sp(ctx);
3c824109
NF
15589 break;
15590 }
15591 break;
65935f07 15592 case B16: /* BC16 */
3c824109 15593 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0,
65935f07
YK
15594 sextract32(ctx->opcode, 0, 10) << 1,
15595 (ctx->insn_flags & ISA_MIPS32R6) ? 0 : 4);
3c824109 15596 break;
65935f07
YK
15597 case BNEZ16: /* BNEZC16 */
15598 case BEQZ16: /* BEQZC16 */
3c824109
NF
15599 gen_compute_branch(ctx, op == BNEZ16 ? OPC_BNE : OPC_BEQ, 2,
15600 mmreg(uMIPS_RD(ctx->opcode)),
65935f07
YK
15601 0, sextract32(ctx->opcode, 0, 7) << 1,
15602 (ctx->insn_flags & ISA_MIPS32R6) ? 0 : 4);
15603
3c824109
NF
15604 break;
15605 case LI16:
15606 {
15607 int reg = mmreg(uMIPS_RD(ctx->opcode));
15608 int imm = ZIMM(ctx->opcode, 0, 7);
15609
15610 imm = (imm == 0x7f ? -1 : imm);
15611 tcg_gen_movi_tl(cpu_gpr[reg], imm);
15612 }
15613 break;
3c824109 15614 case RES_29:
3c824109 15615 case RES_31:
3c824109 15616 case RES_39:
9c708c7f 15617 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
15618 break;
15619 default:
f60eeb0c 15620 decode_micromips32_opc(env, ctx);
3c824109
NF
15621 return 4;
15622 }
15623
15624 return 2;
15625}
15626
15627/* SmartMIPS extension to MIPS32 */
15628
15629#if defined(TARGET_MIPS64)
15630
15631/* MDMX extension to MIPS64 */
15632
15633#endif
15634
9b1a1d68 15635/* MIPSDSP functions. */
d75c135e 15636static void gen_mipsdsp_ld(DisasContext *ctx, uint32_t opc,
9b1a1d68
JL
15637 int rd, int base, int offset)
15638{
9b1a1d68
JL
15639 TCGv t0;
15640
9b1a1d68
JL
15641 check_dsp(ctx);
15642 t0 = tcg_temp_new();
15643
15644 if (base == 0) {
15645 gen_load_gpr(t0, offset);
15646 } else if (offset == 0) {
15647 gen_load_gpr(t0, base);
15648 } else {
15649 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[offset]);
15650 }
15651
9b1a1d68
JL
15652 switch (opc) {
15653 case OPC_LBUX:
5f68f5ae 15654 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB);
9b1a1d68 15655 gen_store_gpr(t0, rd);
9b1a1d68
JL
15656 break;
15657 case OPC_LHX:
5f68f5ae 15658 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW);
9b1a1d68 15659 gen_store_gpr(t0, rd);
9b1a1d68
JL
15660 break;
15661 case OPC_LWX:
5f68f5ae 15662 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
9b1a1d68 15663 gen_store_gpr(t0, rd);
9b1a1d68
JL
15664 break;
15665#if defined(TARGET_MIPS64)
15666 case OPC_LDX:
5f68f5ae 15667 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
9b1a1d68 15668 gen_store_gpr(t0, rd);
9b1a1d68
JL
15669 break;
15670#endif
15671 }
9b1a1d68
JL
15672 tcg_temp_free(t0);
15673}
15674
461c08df
JL
15675static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
15676 int ret, int v1, int v2)
15677{
461c08df
JL
15678 TCGv v1_t;
15679 TCGv v2_t;
15680
15681 if (ret == 0) {
15682 /* Treat as NOP. */
461c08df
JL
15683 return;
15684 }
15685
15686 v1_t = tcg_temp_new();
15687 v2_t = tcg_temp_new();
15688
15689 gen_load_gpr(v1_t, v1);
15690 gen_load_gpr(v2_t, v2);
15691
15692 switch (op1) {
15693 /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
15694 case OPC_MULT_G_2E:
15695 check_dspr2(ctx);
15696 switch (op2) {
15697 case OPC_ADDUH_QB:
15698 gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t);
15699 break;
15700 case OPC_ADDUH_R_QB:
15701 gen_helper_adduh_r_qb(cpu_gpr[ret], v1_t, v2_t);
15702 break;
15703 case OPC_ADDQH_PH:
15704 gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t);
15705 break;
15706 case OPC_ADDQH_R_PH:
15707 gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
15708 break;
15709 case OPC_ADDQH_W:
15710 gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t);
15711 break;
15712 case OPC_ADDQH_R_W:
15713 gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t);
15714 break;
15715 case OPC_SUBUH_QB:
15716 gen_helper_subuh_qb(cpu_gpr[ret], v1_t, v2_t);
15717 break;
15718 case OPC_SUBUH_R_QB:
15719 gen_helper_subuh_r_qb(cpu_gpr[ret], v1_t, v2_t);
15720 break;
15721 case OPC_SUBQH_PH:
15722 gen_helper_subqh_ph(cpu_gpr[ret], v1_t, v2_t);
15723 break;
15724 case OPC_SUBQH_R_PH:
15725 gen_helper_subqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
15726 break;
15727 case OPC_SUBQH_W:
15728 gen_helper_subqh_w(cpu_gpr[ret], v1_t, v2_t);
15729 break;
15730 case OPC_SUBQH_R_W:
15731 gen_helper_subqh_r_w(cpu_gpr[ret], v1_t, v2_t);
15732 break;
15733 }
15734 break;
15735 case OPC_ABSQ_S_PH_DSP:
15736 switch (op2) {
15737 case OPC_ABSQ_S_QB:
15738 check_dspr2(ctx);
15739 gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, cpu_env);
15740 break;
15741 case OPC_ABSQ_S_PH:
15742 check_dsp(ctx);
15743 gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, cpu_env);
15744 break;
15745 case OPC_ABSQ_S_W:
15746 check_dsp(ctx);
15747 gen_helper_absq_s_w(cpu_gpr[ret], v2_t, cpu_env);
15748 break;
15749 case OPC_PRECEQ_W_PHL:
15750 check_dsp(ctx);
15751 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000);
15752 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
15753 break;
15754 case OPC_PRECEQ_W_PHR:
15755 check_dsp(ctx);
15756 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF);
15757 tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16);
15758 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
15759 break;
15760 case OPC_PRECEQU_PH_QBL:
15761 check_dsp(ctx);
15762 gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t);
15763 break;
15764 case OPC_PRECEQU_PH_QBR:
15765 check_dsp(ctx);
15766 gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t);
15767 break;
15768 case OPC_PRECEQU_PH_QBLA:
15769 check_dsp(ctx);
15770 gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t);
15771 break;
15772 case OPC_PRECEQU_PH_QBRA:
15773 check_dsp(ctx);
15774 gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t);
15775 break;
15776 case OPC_PRECEU_PH_QBL:
15777 check_dsp(ctx);
15778 gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t);
15779 break;
15780 case OPC_PRECEU_PH_QBR:
15781 check_dsp(ctx);
15782 gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t);
15783 break;
15784 case OPC_PRECEU_PH_QBLA:
15785 check_dsp(ctx);
15786 gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t);
15787 break;
15788 case OPC_PRECEU_PH_QBRA:
15789 check_dsp(ctx);
15790 gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t);
15791 break;
15792 }
15793 break;
15794 case OPC_ADDU_QB_DSP:
15795 switch (op2) {
15796 case OPC_ADDQ_PH:
15797 check_dsp(ctx);
15798 gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15799 break;
15800 case OPC_ADDQ_S_PH:
15801 check_dsp(ctx);
15802 gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15803 break;
15804 case OPC_ADDQ_S_W:
15805 check_dsp(ctx);
15806 gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15807 break;
15808 case OPC_ADDU_QB:
15809 check_dsp(ctx);
15810 gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15811 break;
15812 case OPC_ADDU_S_QB:
15813 check_dsp(ctx);
15814 gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15815 break;
15816 case OPC_ADDU_PH:
15817 check_dspr2(ctx);
15818 gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15819 break;
15820 case OPC_ADDU_S_PH:
15821 check_dspr2(ctx);
15822 gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15823 break;
15824 case OPC_SUBQ_PH:
15825 check_dsp(ctx);
15826 gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15827 break;
15828 case OPC_SUBQ_S_PH:
15829 check_dsp(ctx);
15830 gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15831 break;
15832 case OPC_SUBQ_S_W:
15833 check_dsp(ctx);
15834 gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15835 break;
15836 case OPC_SUBU_QB:
15837 check_dsp(ctx);
15838 gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15839 break;
15840 case OPC_SUBU_S_QB:
15841 check_dsp(ctx);
15842 gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15843 break;
15844 case OPC_SUBU_PH:
15845 check_dspr2(ctx);
15846 gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15847 break;
15848 case OPC_SUBU_S_PH:
15849 check_dspr2(ctx);
15850 gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15851 break;
15852 case OPC_ADDSC:
15853 check_dsp(ctx);
15854 gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15855 break;
15856 case OPC_ADDWC:
15857 check_dsp(ctx);
15858 gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15859 break;
15860 case OPC_MODSUB:
15861 check_dsp(ctx);
15862 gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t);
15863 break;
15864 case OPC_RADDU_W_QB:
15865 check_dsp(ctx);
15866 gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t);
15867 break;
15868 }
15869 break;
15870 case OPC_CMPU_EQ_QB_DSP:
15871 switch (op2) {
15872 case OPC_PRECR_QB_PH:
15873 check_dspr2(ctx);
15874 gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t);
15875 break;
15876 case OPC_PRECRQ_QB_PH:
15877 check_dsp(ctx);
15878 gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t);
15879 break;
15880 case OPC_PRECR_SRA_PH_W:
15881 check_dspr2(ctx);
15882 {
15883 TCGv_i32 sa_t = tcg_const_i32(v2);
15884 gen_helper_precr_sra_ph_w(cpu_gpr[ret], sa_t, v1_t,
15885 cpu_gpr[ret]);
15886 tcg_temp_free_i32(sa_t);
15887 break;
15888 }
15889 case OPC_PRECR_SRA_R_PH_W:
15890 check_dspr2(ctx);
15891 {
15892 TCGv_i32 sa_t = tcg_const_i32(v2);
15893 gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t,
15894 cpu_gpr[ret]);
15895 tcg_temp_free_i32(sa_t);
15896 break;
15897 }
15898 case OPC_PRECRQ_PH_W:
15899 check_dsp(ctx);
15900 gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t);
15901 break;
15902 case OPC_PRECRQ_RS_PH_W:
15903 check_dsp(ctx);
15904 gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15905 break;
15906 case OPC_PRECRQU_S_QB_PH:
15907 check_dsp(ctx);
15908 gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15909 break;
15910 }
15911 break;
15912#ifdef TARGET_MIPS64
15913 case OPC_ABSQ_S_QH_DSP:
15914 switch (op2) {
15915 case OPC_PRECEQ_L_PWL:
15916 check_dsp(ctx);
15917 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull);
15918 break;
15919 case OPC_PRECEQ_L_PWR:
15920 check_dsp(ctx);
15921 tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32);
15922 break;
15923 case OPC_PRECEQ_PW_QHL:
15924 check_dsp(ctx);
15925 gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t);
15926 break;
15927 case OPC_PRECEQ_PW_QHR:
15928 check_dsp(ctx);
15929 gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t);
15930 break;
15931 case OPC_PRECEQ_PW_QHLA:
15932 check_dsp(ctx);
15933 gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t);
15934 break;
15935 case OPC_PRECEQ_PW_QHRA:
15936 check_dsp(ctx);
15937 gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t);
15938 break;
15939 case OPC_PRECEQU_QH_OBL:
15940 check_dsp(ctx);
15941 gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t);
15942 break;
15943 case OPC_PRECEQU_QH_OBR:
15944 check_dsp(ctx);
15945 gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t);
15946 break;
15947 case OPC_PRECEQU_QH_OBLA:
15948 check_dsp(ctx);
15949 gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t);
15950 break;
15951 case OPC_PRECEQU_QH_OBRA:
15952 check_dsp(ctx);
15953 gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t);
15954 break;
15955 case OPC_PRECEU_QH_OBL:
15956 check_dsp(ctx);
15957 gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t);
15958 break;
15959 case OPC_PRECEU_QH_OBR:
15960 check_dsp(ctx);
15961 gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t);
15962 break;
15963 case OPC_PRECEU_QH_OBLA:
15964 check_dsp(ctx);
15965 gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t);
15966 break;
15967 case OPC_PRECEU_QH_OBRA:
15968 check_dsp(ctx);
15969 gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t);
15970 break;
15971 case OPC_ABSQ_S_OB:
15972 check_dspr2(ctx);
15973 gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, cpu_env);
15974 break;
15975 case OPC_ABSQ_S_PW:
15976 check_dsp(ctx);
15977 gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, cpu_env);
15978 break;
15979 case OPC_ABSQ_S_QH:
15980 check_dsp(ctx);
15981 gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, cpu_env);
15982 break;
15983 }
15984 break;
15985 case OPC_ADDU_OB_DSP:
15986 switch (op2) {
15987 case OPC_RADDU_L_OB:
15988 check_dsp(ctx);
15989 gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t);
15990 break;
15991 case OPC_SUBQ_PW:
15992 check_dsp(ctx);
15993 gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15994 break;
15995 case OPC_SUBQ_S_PW:
15996 check_dsp(ctx);
15997 gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15998 break;
15999 case OPC_SUBQ_QH:
16000 check_dsp(ctx);
16001 gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16002 break;
16003 case OPC_SUBQ_S_QH:
16004 check_dsp(ctx);
16005 gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16006 break;
16007 case OPC_SUBU_OB:
16008 check_dsp(ctx);
16009 gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16010 break;
16011 case OPC_SUBU_S_OB:
16012 check_dsp(ctx);
16013 gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16014 break;
16015 case OPC_SUBU_QH:
16016 check_dspr2(ctx);
16017 gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16018 break;
16019 case OPC_SUBU_S_QH:
16020 check_dspr2(ctx);
16021 gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16022 break;
16023 case OPC_SUBUH_OB:
16024 check_dspr2(ctx);
16025 gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t);
16026 break;
16027 case OPC_SUBUH_R_OB:
16028 check_dspr2(ctx);
16029 gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t);
16030 break;
16031 case OPC_ADDQ_PW:
16032 check_dsp(ctx);
16033 gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16034 break;
16035 case OPC_ADDQ_S_PW:
16036 check_dsp(ctx);
16037 gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16038 break;
16039 case OPC_ADDQ_QH:
16040 check_dsp(ctx);
16041 gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16042 break;
16043 case OPC_ADDQ_S_QH:
16044 check_dsp(ctx);
16045 gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16046 break;
16047 case OPC_ADDU_OB:
16048 check_dsp(ctx);
16049 gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16050 break;
16051 case OPC_ADDU_S_OB:
16052 check_dsp(ctx);
16053 gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16054 break;
16055 case OPC_ADDU_QH:
16056 check_dspr2(ctx);
16057 gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16058 break;
16059 case OPC_ADDU_S_QH:
16060 check_dspr2(ctx);
16061 gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16062 break;
16063 case OPC_ADDUH_OB:
16064 check_dspr2(ctx);
16065 gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t);
16066 break;
16067 case OPC_ADDUH_R_OB:
16068 check_dspr2(ctx);
16069 gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t);
16070 break;
16071 }
16072 break;
16073 case OPC_CMPU_EQ_OB_DSP:
16074 switch (op2) {
16075 case OPC_PRECR_OB_QH:
16076 check_dspr2(ctx);
16077 gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t);
16078 break;
16079 case OPC_PRECR_SRA_QH_PW:
16080 check_dspr2(ctx);
16081 {
16082 TCGv_i32 ret_t = tcg_const_i32(ret);
16083 gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t);
16084 tcg_temp_free_i32(ret_t);
16085 break;
16086 }
16087 case OPC_PRECR_SRA_R_QH_PW:
16088 check_dspr2(ctx);
16089 {
16090 TCGv_i32 sa_v = tcg_const_i32(ret);
16091 gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v);
16092 tcg_temp_free_i32(sa_v);
16093 break;
16094 }
16095 case OPC_PRECRQ_OB_QH:
16096 check_dsp(ctx);
16097 gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t);
16098 break;
16099 case OPC_PRECRQ_PW_L:
16100 check_dsp(ctx);
16101 gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t);
16102 break;
16103 case OPC_PRECRQ_QH_PW:
16104 check_dsp(ctx);
16105 gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t);
16106 break;
16107 case OPC_PRECRQ_RS_QH_PW:
16108 check_dsp(ctx);
16109 gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16110 break;
16111 case OPC_PRECRQU_S_OB_QH:
16112 check_dsp(ctx);
16113 gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16114 break;
16115 }
16116 break;
16117#endif
16118 }
16119
16120 tcg_temp_free(v1_t);
16121 tcg_temp_free(v2_t);
461c08df 16122}
9b1a1d68 16123
77c5fa8b
JL
16124static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc,
16125 int ret, int v1, int v2)
16126{
16127 uint32_t op2;
77c5fa8b
JL
16128 TCGv t0;
16129 TCGv v1_t;
16130 TCGv v2_t;
16131
16132 if (ret == 0) {
16133 /* Treat as NOP. */
77c5fa8b
JL
16134 return;
16135 }
16136
16137 t0 = tcg_temp_new();
16138 v1_t = tcg_temp_new();
16139 v2_t = tcg_temp_new();
16140
16141 tcg_gen_movi_tl(t0, v1);
16142 gen_load_gpr(v1_t, v1);
16143 gen_load_gpr(v2_t, v2);
16144
16145 switch (opc) {
16146 case OPC_SHLL_QB_DSP:
16147 {
16148 op2 = MASK_SHLL_QB(ctx->opcode);
16149 switch (op2) {
16150 case OPC_SHLL_QB:
16151 check_dsp(ctx);
16152 gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, cpu_env);
16153 break;
16154 case OPC_SHLLV_QB:
16155 check_dsp(ctx);
16156 gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16157 break;
16158 case OPC_SHLL_PH:
16159 check_dsp(ctx);
16160 gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
16161 break;
16162 case OPC_SHLLV_PH:
16163 check_dsp(ctx);
16164 gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16165 break;
16166 case OPC_SHLL_S_PH:
16167 check_dsp(ctx);
16168 gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
16169 break;
16170 case OPC_SHLLV_S_PH:
16171 check_dsp(ctx);
16172 gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16173 break;
16174 case OPC_SHLL_S_W:
16175 check_dsp(ctx);
16176 gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, cpu_env);
16177 break;
16178 case OPC_SHLLV_S_W:
16179 check_dsp(ctx);
16180 gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16181 break;
16182 case OPC_SHRL_QB:
16183 check_dsp(ctx);
16184 gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t);
16185 break;
16186 case OPC_SHRLV_QB:
16187 check_dsp(ctx);
16188 gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t);
16189 break;
16190 case OPC_SHRL_PH:
16191 check_dspr2(ctx);
16192 gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t);
16193 break;
16194 case OPC_SHRLV_PH:
16195 check_dspr2(ctx);
16196 gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t);
16197 break;
16198 case OPC_SHRA_QB:
16199 check_dspr2(ctx);
16200 gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t);
16201 break;
16202 case OPC_SHRA_R_QB:
16203 check_dspr2(ctx);
16204 gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t);
16205 break;
16206 case OPC_SHRAV_QB:
16207 check_dspr2(ctx);
16208 gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t);
16209 break;
16210 case OPC_SHRAV_R_QB:
16211 check_dspr2(ctx);
16212 gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t);
16213 break;
16214 case OPC_SHRA_PH:
16215 check_dsp(ctx);
16216 gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t);
16217 break;
16218 case OPC_SHRA_R_PH:
16219 check_dsp(ctx);
16220 gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t);
16221 break;
16222 case OPC_SHRAV_PH:
16223 check_dsp(ctx);
16224 gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t);
16225 break;
16226 case OPC_SHRAV_R_PH:
16227 check_dsp(ctx);
16228 gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t);
16229 break;
16230 case OPC_SHRA_R_W:
16231 check_dsp(ctx);
16232 gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t);
16233 break;
16234 case OPC_SHRAV_R_W:
16235 check_dsp(ctx);
16236 gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t);
16237 break;
16238 default: /* Invalid */
16239 MIPS_INVAL("MASK SHLL.QB");
9c708c7f 16240 generate_exception_end(ctx, EXCP_RI);
77c5fa8b
JL
16241 break;
16242 }
16243 break;
16244 }
16245#ifdef TARGET_MIPS64
16246 case OPC_SHLL_OB_DSP:
16247 op2 = MASK_SHLL_OB(ctx->opcode);
16248 switch (op2) {
16249 case OPC_SHLL_PW:
16250 check_dsp(ctx);
16251 gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
16252 break;
16253 case OPC_SHLLV_PW:
16254 check_dsp(ctx);
16255 gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
16256 break;
16257 case OPC_SHLL_S_PW:
16258 check_dsp(ctx);
16259 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
16260 break;
16261 case OPC_SHLLV_S_PW:
16262 check_dsp(ctx);
16263 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
16264 break;
16265 case OPC_SHLL_OB:
16266 check_dsp(ctx);
16267 gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, cpu_env);
16268 break;
16269 case OPC_SHLLV_OB:
16270 check_dsp(ctx);
16271 gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, cpu_env);
16272 break;
16273 case OPC_SHLL_QH:
16274 check_dsp(ctx);
16275 gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
16276 break;
16277 case OPC_SHLLV_QH:
16278 check_dsp(ctx);
16279 gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
16280 break;
16281 case OPC_SHLL_S_QH:
16282 check_dsp(ctx);
16283 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
16284 break;
16285 case OPC_SHLLV_S_QH:
16286 check_dsp(ctx);
16287 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
16288 break;
16289 case OPC_SHRA_OB:
16290 check_dspr2(ctx);
16291 gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0);
16292 break;
16293 case OPC_SHRAV_OB:
16294 check_dspr2(ctx);
16295 gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t);
16296 break;
16297 case OPC_SHRA_R_OB:
16298 check_dspr2(ctx);
16299 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0);
16300 break;
16301 case OPC_SHRAV_R_OB:
16302 check_dspr2(ctx);
16303 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t);
16304 break;
16305 case OPC_SHRA_PW:
16306 check_dsp(ctx);
16307 gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0);
16308 break;
16309 case OPC_SHRAV_PW:
16310 check_dsp(ctx);
16311 gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t);
16312 break;
16313 case OPC_SHRA_R_PW:
16314 check_dsp(ctx);
16315 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0);
16316 break;
16317 case OPC_SHRAV_R_PW:
16318 check_dsp(ctx);
16319 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t);
16320 break;
16321 case OPC_SHRA_QH:
16322 check_dsp(ctx);
16323 gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0);
16324 break;
16325 case OPC_SHRAV_QH:
16326 check_dsp(ctx);
16327 gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t);
16328 break;
16329 case OPC_SHRA_R_QH:
16330 check_dsp(ctx);
16331 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0);
16332 break;
16333 case OPC_SHRAV_R_QH:
16334 check_dsp(ctx);
16335 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t);
16336 break;
16337 case OPC_SHRL_OB:
16338 check_dsp(ctx);
16339 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0);
16340 break;
16341 case OPC_SHRLV_OB:
16342 check_dsp(ctx);
16343 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t);
16344 break;
16345 case OPC_SHRL_QH:
16346 check_dspr2(ctx);
16347 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0);
16348 break;
16349 case OPC_SHRLV_QH:
16350 check_dspr2(ctx);
16351 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t);
16352 break;
16353 default: /* Invalid */
16354 MIPS_INVAL("MASK SHLL.OB");
9c708c7f 16355 generate_exception_end(ctx, EXCP_RI);
77c5fa8b
JL
16356 break;
16357 }
16358 break;
16359#endif
16360 }
16361
16362 tcg_temp_free(t0);
16363 tcg_temp_free(v1_t);
16364 tcg_temp_free(v2_t);
77c5fa8b
JL
16365}
16366
a22260ae
JL
16367static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2,
16368 int ret, int v1, int v2, int check_ret)
16369{
a22260ae
JL
16370 TCGv_i32 t0;
16371 TCGv v1_t;
16372 TCGv v2_t;
16373
16374 if ((ret == 0) && (check_ret == 1)) {
16375 /* Treat as NOP. */
a22260ae
JL
16376 return;
16377 }
16378
16379 t0 = tcg_temp_new_i32();
16380 v1_t = tcg_temp_new();
16381 v2_t = tcg_temp_new();
16382
16383 tcg_gen_movi_i32(t0, ret);
16384 gen_load_gpr(v1_t, v1);
16385 gen_load_gpr(v2_t, v2);
16386
16387 switch (op1) {
16388 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
16389 * the same mask and op1. */
16390 case OPC_MULT_G_2E:
639eadb9 16391 check_dspr2(ctx);
a22260ae
JL
16392 switch (op2) {
16393 case OPC_MUL_PH:
16394 gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16395 break;
16396 case OPC_MUL_S_PH:
16397 gen_helper_mul_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16398 break;
16399 case OPC_MULQ_S_W:
16400 gen_helper_mulq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16401 break;
16402 case OPC_MULQ_RS_W:
16403 gen_helper_mulq_rs_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16404 break;
16405 }
16406 break;
16407 case OPC_DPA_W_PH_DSP:
16408 switch (op2) {
16409 case OPC_DPAU_H_QBL:
16410 check_dsp(ctx);
16411 gen_helper_dpau_h_qbl(t0, v1_t, v2_t, cpu_env);
16412 break;
16413 case OPC_DPAU_H_QBR:
16414 check_dsp(ctx);
16415 gen_helper_dpau_h_qbr(t0, v1_t, v2_t, cpu_env);
16416 break;
16417 case OPC_DPSU_H_QBL:
16418 check_dsp(ctx);
16419 gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, cpu_env);
16420 break;
16421 case OPC_DPSU_H_QBR:
16422 check_dsp(ctx);
16423 gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, cpu_env);
16424 break;
16425 case OPC_DPA_W_PH:
16426 check_dspr2(ctx);
16427 gen_helper_dpa_w_ph(t0, v1_t, v2_t, cpu_env);
16428 break;
16429 case OPC_DPAX_W_PH:
16430 check_dspr2(ctx);
16431 gen_helper_dpax_w_ph(t0, v1_t, v2_t, cpu_env);
16432 break;
16433 case OPC_DPAQ_S_W_PH:
16434 check_dsp(ctx);
16435 gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
16436 break;
16437 case OPC_DPAQX_S_W_PH:
16438 check_dspr2(ctx);
16439 gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
16440 break;
16441 case OPC_DPAQX_SA_W_PH:
16442 check_dspr2(ctx);
16443 gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
16444 break;
16445 case OPC_DPS_W_PH:
16446 check_dspr2(ctx);
16447 gen_helper_dps_w_ph(t0, v1_t, v2_t, cpu_env);
16448 break;
16449 case OPC_DPSX_W_PH:
16450 check_dspr2(ctx);
16451 gen_helper_dpsx_w_ph(t0, v1_t, v2_t, cpu_env);
16452 break;
16453 case OPC_DPSQ_S_W_PH:
16454 check_dsp(ctx);
16455 gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, cpu_env);
16456 break;
16457 case OPC_DPSQX_S_W_PH:
16458 check_dspr2(ctx);
16459 gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
16460 break;
16461 case OPC_DPSQX_SA_W_PH:
16462 check_dspr2(ctx);
16463 gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
16464 break;
16465 case OPC_MULSAQ_S_W_PH:
16466 check_dsp(ctx);
16467 gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
16468 break;
16469 case OPC_DPAQ_SA_L_W:
16470 check_dsp(ctx);
16471 gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, cpu_env);
16472 break;
16473 case OPC_DPSQ_SA_L_W:
16474 check_dsp(ctx);
16475 gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, cpu_env);
16476 break;
16477 case OPC_MAQ_S_W_PHL:
16478 check_dsp(ctx);
16479 gen_helper_maq_s_w_phl(t0, v1_t, v2_t, cpu_env);
16480 break;
16481 case OPC_MAQ_S_W_PHR:
16482 check_dsp(ctx);
16483 gen_helper_maq_s_w_phr(t0, v1_t, v2_t, cpu_env);
16484 break;
16485 case OPC_MAQ_SA_W_PHL:
16486 check_dsp(ctx);
16487 gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, cpu_env);
16488 break;
16489 case OPC_MAQ_SA_W_PHR:
16490 check_dsp(ctx);
16491 gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, cpu_env);
16492 break;
16493 case OPC_MULSA_W_PH:
16494 check_dspr2(ctx);
16495 gen_helper_mulsa_w_ph(t0, v1_t, v2_t, cpu_env);
16496 break;
16497 }
16498 break;
16499#ifdef TARGET_MIPS64
16500 case OPC_DPAQ_W_QH_DSP:
16501 {
16502 int ac = ret & 0x03;
16503 tcg_gen_movi_i32(t0, ac);
16504
16505 switch (op2) {
16506 case OPC_DMADD:
16507 check_dsp(ctx);
16508 gen_helper_dmadd(v1_t, v2_t, t0, cpu_env);
16509 break;
16510 case OPC_DMADDU:
16511 check_dsp(ctx);
16512 gen_helper_dmaddu(v1_t, v2_t, t0, cpu_env);
16513 break;
16514 case OPC_DMSUB:
16515 check_dsp(ctx);
16516 gen_helper_dmsub(v1_t, v2_t, t0, cpu_env);
16517 break;
16518 case OPC_DMSUBU:
16519 check_dsp(ctx);
16520 gen_helper_dmsubu(v1_t, v2_t, t0, cpu_env);
16521 break;
16522 case OPC_DPA_W_QH:
16523 check_dspr2(ctx);
16524 gen_helper_dpa_w_qh(v1_t, v2_t, t0, cpu_env);
16525 break;
16526 case OPC_DPAQ_S_W_QH:
16527 check_dsp(ctx);
16528 gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
16529 break;
16530 case OPC_DPAQ_SA_L_PW:
16531 check_dsp(ctx);
16532 gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
16533 break;
16534 case OPC_DPAU_H_OBL:
16535 check_dsp(ctx);
16536 gen_helper_dpau_h_obl(v1_t, v2_t, t0, cpu_env);
16537 break;
16538 case OPC_DPAU_H_OBR:
16539 check_dsp(ctx);
16540 gen_helper_dpau_h_obr(v1_t, v2_t, t0, cpu_env);
16541 break;
16542 case OPC_DPS_W_QH:
16543 check_dspr2(ctx);
16544 gen_helper_dps_w_qh(v1_t, v2_t, t0, cpu_env);
16545 break;
16546 case OPC_DPSQ_S_W_QH:
16547 check_dsp(ctx);
16548 gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, cpu_env);
16549 break;
16550 case OPC_DPSQ_SA_L_PW:
16551 check_dsp(ctx);
16552 gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
16553 break;
16554 case OPC_DPSU_H_OBL:
16555 check_dsp(ctx);
16556 gen_helper_dpsu_h_obl(v1_t, v2_t, t0, cpu_env);
16557 break;
16558 case OPC_DPSU_H_OBR:
16559 check_dsp(ctx);
16560 gen_helper_dpsu_h_obr(v1_t, v2_t, t0, cpu_env);
16561 break;
16562 case OPC_MAQ_S_L_PWL:
16563 check_dsp(ctx);
16564 gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, cpu_env);
16565 break;
16566 case OPC_MAQ_S_L_PWR:
16567 check_dsp(ctx);
16568 gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, cpu_env);
16569 break;
16570 case OPC_MAQ_S_W_QHLL:
16571 check_dsp(ctx);
16572 gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, cpu_env);
16573 break;
16574 case OPC_MAQ_SA_W_QHLL:
16575 check_dsp(ctx);
16576 gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, cpu_env);
16577 break;
16578 case OPC_MAQ_S_W_QHLR:
16579 check_dsp(ctx);
16580 gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, cpu_env);
16581 break;
16582 case OPC_MAQ_SA_W_QHLR:
16583 check_dsp(ctx);
16584 gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, cpu_env);
16585 break;
16586 case OPC_MAQ_S_W_QHRL:
16587 check_dsp(ctx);
16588 gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, cpu_env);
16589 break;
16590 case OPC_MAQ_SA_W_QHRL:
16591 check_dsp(ctx);
16592 gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, cpu_env);
16593 break;
16594 case OPC_MAQ_S_W_QHRR:
16595 check_dsp(ctx);
16596 gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, cpu_env);
16597 break;
16598 case OPC_MAQ_SA_W_QHRR:
16599 check_dsp(ctx);
16600 gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, cpu_env);
16601 break;
16602 case OPC_MULSAQ_S_L_PW:
16603 check_dsp(ctx);
16604 gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, cpu_env);
16605 break;
16606 case OPC_MULSAQ_S_W_QH:
16607 check_dsp(ctx);
16608 gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
16609 break;
16610 }
16611 }
16612 break;
16613#endif
16614 case OPC_ADDU_QB_DSP:
16615 switch (op2) {
16616 case OPC_MULEU_S_PH_QBL:
16617 check_dsp(ctx);
16618 gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16619 break;
16620 case OPC_MULEU_S_PH_QBR:
16621 check_dsp(ctx);
16622 gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16623 break;
16624 case OPC_MULQ_RS_PH:
16625 check_dsp(ctx);
16626 gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16627 break;
16628 case OPC_MULEQ_S_W_PHL:
16629 check_dsp(ctx);
16630 gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16631 break;
16632 case OPC_MULEQ_S_W_PHR:
16633 check_dsp(ctx);
16634 gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16635 break;
16636 case OPC_MULQ_S_PH:
16637 check_dspr2(ctx);
16638 gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16639 break;
16640 }
16641 break;
16642#ifdef TARGET_MIPS64
16643 case OPC_ADDU_OB_DSP:
16644 switch (op2) {
16645 case OPC_MULEQ_S_PW_QHL:
16646 check_dsp(ctx);
16647 gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16648 break;
16649 case OPC_MULEQ_S_PW_QHR:
16650 check_dsp(ctx);
16651 gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16652 break;
16653 case OPC_MULEU_S_QH_OBL:
16654 check_dsp(ctx);
16655 gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16656 break;
16657 case OPC_MULEU_S_QH_OBR:
16658 check_dsp(ctx);
16659 gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16660 break;
16661 case OPC_MULQ_RS_QH:
16662 check_dsp(ctx);
16663 gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16664 break;
16665 }
16666 break;
16667#endif
16668 }
16669
16670 tcg_temp_free_i32(t0);
16671 tcg_temp_free(v1_t);
16672 tcg_temp_free(v2_t);
a22260ae
JL
16673}
16674
d75c135e 16675static void gen_mipsdsp_bitinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
1cb6686c
JL
16676 int ret, int val)
16677{
1cb6686c
JL
16678 int16_t imm;
16679 TCGv t0;
16680 TCGv val_t;
16681
16682 if (ret == 0) {
16683 /* Treat as NOP. */
1cb6686c
JL
16684 return;
16685 }
16686
16687 t0 = tcg_temp_new();
16688 val_t = tcg_temp_new();
16689 gen_load_gpr(val_t, val);
16690
16691 switch (op1) {
16692 case OPC_ABSQ_S_PH_DSP:
16693 switch (op2) {
16694 case OPC_BITREV:
16695 check_dsp(ctx);
16696 gen_helper_bitrev(cpu_gpr[ret], val_t);
16697 break;
16698 case OPC_REPL_QB:
16699 check_dsp(ctx);
16700 {
16701 target_long result;
16702 imm = (ctx->opcode >> 16) & 0xFF;
16703 result = (uint32_t)imm << 24 |
16704 (uint32_t)imm << 16 |
16705 (uint32_t)imm << 8 |
16706 (uint32_t)imm;
16707 result = (int32_t)result;
16708 tcg_gen_movi_tl(cpu_gpr[ret], result);
16709 }
16710 break;
16711 case OPC_REPLV_QB:
16712 check_dsp(ctx);
16713 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
16714 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
16715 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16716 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
16717 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16718 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
16719 break;
16720 case OPC_REPL_PH:
16721 check_dsp(ctx);
16722 {
16723 imm = (ctx->opcode >> 16) & 0x03FF;
c4aaba92 16724 imm = (int16_t)(imm << 6) >> 6;
1cb6686c
JL
16725 tcg_gen_movi_tl(cpu_gpr[ret], \
16726 (target_long)((int32_t)imm << 16 | \
c4aaba92 16727 (uint16_t)imm));
1cb6686c
JL
16728 }
16729 break;
16730 case OPC_REPLV_PH:
16731 check_dsp(ctx);
16732 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
16733 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
16734 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16735 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
16736 break;
16737 }
16738 break;
16739#ifdef TARGET_MIPS64
16740 case OPC_ABSQ_S_QH_DSP:
16741 switch (op2) {
16742 case OPC_REPL_OB:
16743 check_dsp(ctx);
16744 {
16745 target_long temp;
16746
16747 imm = (ctx->opcode >> 16) & 0xFF;
16748 temp = ((uint64_t)imm << 8) | (uint64_t)imm;
16749 temp = (temp << 16) | temp;
16750 temp = (temp << 32) | temp;
16751 tcg_gen_movi_tl(cpu_gpr[ret], temp);
16752 break;
16753 }
16754 case OPC_REPL_PW:
16755 check_dsp(ctx);
16756 {
16757 target_long temp;
16758
16759 imm = (ctx->opcode >> 16) & 0x03FF;
16760 imm = (int16_t)(imm << 6) >> 6;
16761 temp = ((target_long)imm << 32) \
16762 | ((target_long)imm & 0xFFFFFFFF);
16763 tcg_gen_movi_tl(cpu_gpr[ret], temp);
16764 break;
16765 }
16766 case OPC_REPL_QH:
16767 check_dsp(ctx);
16768 {
16769 target_long temp;
16770
16771 imm = (ctx->opcode >> 16) & 0x03FF;
16772 imm = (int16_t)(imm << 6) >> 6;
16773
16774 temp = ((uint64_t)(uint16_t)imm << 48) |
16775 ((uint64_t)(uint16_t)imm << 32) |
16776 ((uint64_t)(uint16_t)imm << 16) |
16777 (uint64_t)(uint16_t)imm;
16778 tcg_gen_movi_tl(cpu_gpr[ret], temp);
16779 break;
16780 }
16781 case OPC_REPLV_OB:
16782 check_dsp(ctx);
16783 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
16784 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
16785 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16786 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
16787 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16788 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
16789 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16790 break;
16791 case OPC_REPLV_PW:
16792 check_dsp(ctx);
16793 tcg_gen_ext32u_i64(cpu_gpr[ret], val_t);
16794 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
16795 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16796 break;
16797 case OPC_REPLV_QH:
16798 check_dsp(ctx);
16799 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
16800 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
16801 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16802 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
16803 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16804 break;
16805 }
16806 break;
16807#endif
16808 }
16809 tcg_temp_free(t0);
16810 tcg_temp_free(val_t);
1cb6686c
JL
16811}
16812
26690560
JL
16813static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx,
16814 uint32_t op1, uint32_t op2,
16815 int ret, int v1, int v2, int check_ret)
16816{
26690560
JL
16817 TCGv t1;
16818 TCGv v1_t;
16819 TCGv v2_t;
16820
16821 if ((ret == 0) && (check_ret == 1)) {
16822 /* Treat as NOP. */
26690560
JL
16823 return;
16824 }
16825
26690560
JL
16826 t1 = tcg_temp_new();
16827 v1_t = tcg_temp_new();
16828 v2_t = tcg_temp_new();
16829
16830 gen_load_gpr(v1_t, v1);
16831 gen_load_gpr(v2_t, v2);
16832
16833 switch (op1) {
26690560
JL
16834 case OPC_CMPU_EQ_QB_DSP:
16835 switch (op2) {
16836 case OPC_CMPU_EQ_QB:
16837 check_dsp(ctx);
16838 gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
16839 break;
16840 case OPC_CMPU_LT_QB:
16841 check_dsp(ctx);
16842 gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
16843 break;
16844 case OPC_CMPU_LE_QB:
16845 check_dsp(ctx);
16846 gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
16847 break;
16848 case OPC_CMPGU_EQ_QB:
16849 check_dsp(ctx);
16850 gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t);
16851 break;
16852 case OPC_CMPGU_LT_QB:
16853 check_dsp(ctx);
16854 gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t);
16855 break;
16856 case OPC_CMPGU_LE_QB:
16857 check_dsp(ctx);
16858 gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t);
16859 break;
16860 case OPC_CMPGDU_EQ_QB:
16861 check_dspr2(ctx);
16862 gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t);
16863 tcg_gen_mov_tl(cpu_gpr[ret], t1);
16864 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
16865 tcg_gen_shli_tl(t1, t1, 24);
16866 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
16867 break;
16868 case OPC_CMPGDU_LT_QB:
16869 check_dspr2(ctx);
16870 gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t);
16871 tcg_gen_mov_tl(cpu_gpr[ret], t1);
16872 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
16873 tcg_gen_shli_tl(t1, t1, 24);
16874 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
16875 break;
16876 case OPC_CMPGDU_LE_QB:
16877 check_dspr2(ctx);
16878 gen_helper_cmpgu_le_qb(t1, v1_t, v2_t);
16879 tcg_gen_mov_tl(cpu_gpr[ret], t1);
16880 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
16881 tcg_gen_shli_tl(t1, t1, 24);
16882 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
16883 break;
16884 case OPC_CMP_EQ_PH:
16885 check_dsp(ctx);
16886 gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
16887 break;
16888 case OPC_CMP_LT_PH:
16889 check_dsp(ctx);
16890 gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
16891 break;
16892 case OPC_CMP_LE_PH:
16893 check_dsp(ctx);
16894 gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
16895 break;
16896 case OPC_PICK_QB:
16897 check_dsp(ctx);
16898 gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16899 break;
16900 case OPC_PICK_PH:
16901 check_dsp(ctx);
16902 gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16903 break;
16904 case OPC_PACKRL_PH:
16905 check_dsp(ctx);
16906 gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t);
16907 break;
16908 }
16909 break;
16910#ifdef TARGET_MIPS64
16911 case OPC_CMPU_EQ_OB_DSP:
16912 switch (op2) {
16913 case OPC_CMP_EQ_PW:
16914 check_dsp(ctx);
16915 gen_helper_cmp_eq_pw(v1_t, v2_t, cpu_env);
16916 break;
16917 case OPC_CMP_LT_PW:
16918 check_dsp(ctx);
16919 gen_helper_cmp_lt_pw(v1_t, v2_t, cpu_env);
16920 break;
16921 case OPC_CMP_LE_PW:
16922 check_dsp(ctx);
16923 gen_helper_cmp_le_pw(v1_t, v2_t, cpu_env);
16924 break;
16925 case OPC_CMP_EQ_QH:
16926 check_dsp(ctx);
16927 gen_helper_cmp_eq_qh(v1_t, v2_t, cpu_env);
16928 break;
16929 case OPC_CMP_LT_QH:
16930 check_dsp(ctx);
16931 gen_helper_cmp_lt_qh(v1_t, v2_t, cpu_env);
16932 break;
16933 case OPC_CMP_LE_QH:
16934 check_dsp(ctx);
16935 gen_helper_cmp_le_qh(v1_t, v2_t, cpu_env);
16936 break;
16937 case OPC_CMPGDU_EQ_OB:
16938 check_dspr2(ctx);
16939 gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16940 break;
16941 case OPC_CMPGDU_LT_OB:
16942 check_dspr2(ctx);
16943 gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16944 break;
16945 case OPC_CMPGDU_LE_OB:
16946 check_dspr2(ctx);
16947 gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16948 break;
16949 case OPC_CMPGU_EQ_OB:
16950 check_dsp(ctx);
16951 gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t);
16952 break;
16953 case OPC_CMPGU_LT_OB:
16954 check_dsp(ctx);
16955 gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t);
16956 break;
16957 case OPC_CMPGU_LE_OB:
16958 check_dsp(ctx);
16959 gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t);
16960 break;
16961 case OPC_CMPU_EQ_OB:
16962 check_dsp(ctx);
16963 gen_helper_cmpu_eq_ob(v1_t, v2_t, cpu_env);
16964 break;
16965 case OPC_CMPU_LT_OB:
16966 check_dsp(ctx);
16967 gen_helper_cmpu_lt_ob(v1_t, v2_t, cpu_env);
16968 break;
16969 case OPC_CMPU_LE_OB:
16970 check_dsp(ctx);
16971 gen_helper_cmpu_le_ob(v1_t, v2_t, cpu_env);
16972 break;
16973 case OPC_PACKRL_PW:
16974 check_dsp(ctx);
16975 gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t);
16976 break;
16977 case OPC_PICK_OB:
16978 check_dsp(ctx);
16979 gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16980 break;
16981 case OPC_PICK_PW:
16982 check_dsp(ctx);
16983 gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16984 break;
16985 case OPC_PICK_QH:
16986 check_dsp(ctx);
16987 gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16988 break;
16989 }
16990 break;
df6126a7
AJ
16991#endif
16992 }
16993
16994 tcg_temp_free(t1);
16995 tcg_temp_free(v1_t);
16996 tcg_temp_free(v2_t);
df6126a7
AJ
16997}
16998
16999static void gen_mipsdsp_append(CPUMIPSState *env, DisasContext *ctx,
17000 uint32_t op1, int rt, int rs, int sa)
17001{
df6126a7
AJ
17002 TCGv t0;
17003
17004 check_dspr2(ctx);
17005
17006 if (rt == 0) {
17007 /* Treat as NOP. */
df6126a7
AJ
17008 return;
17009 }
17010
17011 t0 = tcg_temp_new();
17012 gen_load_gpr(t0, rs);
17013
17014 switch (op1) {
17015 case OPC_APPEND_DSP:
17016 switch (MASK_APPEND(ctx->opcode)) {
17017 case OPC_APPEND:
17018 if (sa != 0) {
17019 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 32 - sa);
17020 }
17021 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
17022 break;
17023 case OPC_PREPEND:
17024 if (sa != 0) {
17025 tcg_gen_ext32u_tl(cpu_gpr[rt], cpu_gpr[rt]);
17026 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
17027 tcg_gen_shli_tl(t0, t0, 32 - sa);
17028 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
17029 }
17030 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
17031 break;
17032 case OPC_BALIGN:
17033 sa &= 3;
17034 if (sa != 0 && sa != 2) {
17035 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
17036 tcg_gen_ext32u_tl(t0, t0);
17037 tcg_gen_shri_tl(t0, t0, 8 * (4 - sa));
17038 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
17039 }
17040 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
17041 break;
17042 default: /* Invalid */
17043 MIPS_INVAL("MASK APPEND");
9c708c7f 17044 generate_exception_end(ctx, EXCP_RI);
df6126a7
AJ
17045 break;
17046 }
17047 break;
17048#ifdef TARGET_MIPS64
26690560 17049 case OPC_DAPPEND_DSP:
df6126a7 17050 switch (MASK_DAPPEND(ctx->opcode)) {
26690560 17051 case OPC_DAPPEND:
df6126a7
AJ
17052 if (sa != 0) {
17053 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 64 - sa);
17054 }
26690560
JL
17055 break;
17056 case OPC_PREPENDD:
df6126a7
AJ
17057 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], 0x20 | sa);
17058 tcg_gen_shli_tl(t0, t0, 64 - (0x20 | sa));
17059 tcg_gen_or_tl(cpu_gpr[rt], t0, t0);
26690560
JL
17060 break;
17061 case OPC_PREPENDW:
df6126a7
AJ
17062 if (sa != 0) {
17063 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
17064 tcg_gen_shli_tl(t0, t0, 64 - sa);
17065 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
17066 }
26690560
JL
17067 break;
17068 case OPC_DBALIGN:
df6126a7
AJ
17069 sa &= 7;
17070 if (sa != 0 && sa != 2 && sa != 4) {
17071 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
17072 tcg_gen_shri_tl(t0, t0, 8 * (8 - sa));
17073 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
17074 }
26690560
JL
17075 break;
17076 default: /* Invalid */
17077 MIPS_INVAL("MASK DAPPEND");
9c708c7f 17078 generate_exception_end(ctx, EXCP_RI);
26690560
JL
17079 break;
17080 }
17081 break;
17082#endif
17083 }
df6126a7 17084 tcg_temp_free(t0);
26690560
JL
17085}
17086
b53371ed
JL
17087static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
17088 int ret, int v1, int v2, int check_ret)
17089
17090{
b53371ed
JL
17091 TCGv t0;
17092 TCGv t1;
17093 TCGv v1_t;
17094 TCGv v2_t;
17095 int16_t imm;
17096
17097 if ((ret == 0) && (check_ret == 1)) {
17098 /* Treat as NOP. */
b53371ed
JL
17099 return;
17100 }
17101
17102 t0 = tcg_temp_new();
17103 t1 = tcg_temp_new();
17104 v1_t = tcg_temp_new();
17105 v2_t = tcg_temp_new();
17106
17107 gen_load_gpr(v1_t, v1);
17108 gen_load_gpr(v2_t, v2);
17109
17110 switch (op1) {
17111 case OPC_EXTR_W_DSP:
17112 check_dsp(ctx);
17113 switch (op2) {
17114 case OPC_EXTR_W:
17115 tcg_gen_movi_tl(t0, v2);
17116 tcg_gen_movi_tl(t1, v1);
17117 gen_helper_extr_w(cpu_gpr[ret], t0, t1, cpu_env);
17118 break;
17119 case OPC_EXTR_R_W:
17120 tcg_gen_movi_tl(t0, v2);
17121 tcg_gen_movi_tl(t1, v1);
17122 gen_helper_extr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
17123 break;
17124 case OPC_EXTR_RS_W:
17125 tcg_gen_movi_tl(t0, v2);
17126 tcg_gen_movi_tl(t1, v1);
17127 gen_helper_extr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
17128 break;
17129 case OPC_EXTR_S_H:
17130 tcg_gen_movi_tl(t0, v2);
17131 tcg_gen_movi_tl(t1, v1);
17132 gen_helper_extr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
17133 break;
17134 case OPC_EXTRV_S_H:
17135 tcg_gen_movi_tl(t0, v2);
17136 gen_helper_extr_s_h(cpu_gpr[ret], t0, v1_t, cpu_env);
17137 break;
17138 case OPC_EXTRV_W:
17139 tcg_gen_movi_tl(t0, v2);
17140 gen_helper_extr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
17141 break;
17142 case OPC_EXTRV_R_W:
17143 tcg_gen_movi_tl(t0, v2);
17144 gen_helper_extr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
17145 break;
17146 case OPC_EXTRV_RS_W:
17147 tcg_gen_movi_tl(t0, v2);
17148 gen_helper_extr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
17149 break;
17150 case OPC_EXTP:
17151 tcg_gen_movi_tl(t0, v2);
17152 tcg_gen_movi_tl(t1, v1);
17153 gen_helper_extp(cpu_gpr[ret], t0, t1, cpu_env);
17154 break;
17155 case OPC_EXTPV:
17156 tcg_gen_movi_tl(t0, v2);
17157 gen_helper_extp(cpu_gpr[ret], t0, v1_t, cpu_env);
17158 break;
17159 case OPC_EXTPDP:
17160 tcg_gen_movi_tl(t0, v2);
17161 tcg_gen_movi_tl(t1, v1);
17162 gen_helper_extpdp(cpu_gpr[ret], t0, t1, cpu_env);
17163 break;
17164 case OPC_EXTPDPV:
17165 tcg_gen_movi_tl(t0, v2);
17166 gen_helper_extpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
17167 break;
17168 case OPC_SHILO:
17169 imm = (ctx->opcode >> 20) & 0x3F;
17170 tcg_gen_movi_tl(t0, ret);
17171 tcg_gen_movi_tl(t1, imm);
17172 gen_helper_shilo(t0, t1, cpu_env);
17173 break;
17174 case OPC_SHILOV:
17175 tcg_gen_movi_tl(t0, ret);
17176 gen_helper_shilo(t0, v1_t, cpu_env);
17177 break;
17178 case OPC_MTHLIP:
17179 tcg_gen_movi_tl(t0, ret);
17180 gen_helper_mthlip(t0, v1_t, cpu_env);
17181 break;
17182 case OPC_WRDSP:
17183 imm = (ctx->opcode >> 11) & 0x3FF;
17184 tcg_gen_movi_tl(t0, imm);
17185 gen_helper_wrdsp(v1_t, t0, cpu_env);
17186 break;
17187 case OPC_RDDSP:
17188 imm = (ctx->opcode >> 16) & 0x03FF;
17189 tcg_gen_movi_tl(t0, imm);
17190 gen_helper_rddsp(cpu_gpr[ret], t0, cpu_env);
17191 break;
17192 }
17193 break;
17194#ifdef TARGET_MIPS64
17195 case OPC_DEXTR_W_DSP:
17196 check_dsp(ctx);
17197 switch (op2) {
17198 case OPC_DMTHLIP:
17199 tcg_gen_movi_tl(t0, ret);
17200 gen_helper_dmthlip(v1_t, t0, cpu_env);
17201 break;
17202 case OPC_DSHILO:
17203 {
17204 int shift = (ctx->opcode >> 19) & 0x7F;
17205 int ac = (ctx->opcode >> 11) & 0x03;
17206 tcg_gen_movi_tl(t0, shift);
17207 tcg_gen_movi_tl(t1, ac);
17208 gen_helper_dshilo(t0, t1, cpu_env);
17209 break;
17210 }
17211 case OPC_DSHILOV:
17212 {
17213 int ac = (ctx->opcode >> 11) & 0x03;
17214 tcg_gen_movi_tl(t0, ac);
17215 gen_helper_dshilo(v1_t, t0, cpu_env);
17216 break;
17217 }
17218 case OPC_DEXTP:
17219 tcg_gen_movi_tl(t0, v2);
17220 tcg_gen_movi_tl(t1, v1);
17221
17222 gen_helper_dextp(cpu_gpr[ret], t0, t1, cpu_env);
17223 break;
17224 case OPC_DEXTPV:
17225 tcg_gen_movi_tl(t0, v2);
17226 gen_helper_dextp(cpu_gpr[ret], t0, v1_t, cpu_env);
17227 break;
17228 case OPC_DEXTPDP:
17229 tcg_gen_movi_tl(t0, v2);
17230 tcg_gen_movi_tl(t1, v1);
17231 gen_helper_dextpdp(cpu_gpr[ret], t0, t1, cpu_env);
17232 break;
17233 case OPC_DEXTPDPV:
17234 tcg_gen_movi_tl(t0, v2);
17235 gen_helper_dextpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
17236 break;
17237 case OPC_DEXTR_L:
17238 tcg_gen_movi_tl(t0, v2);
17239 tcg_gen_movi_tl(t1, v1);
17240 gen_helper_dextr_l(cpu_gpr[ret], t0, t1, cpu_env);
17241 break;
17242 case OPC_DEXTR_R_L:
17243 tcg_gen_movi_tl(t0, v2);
17244 tcg_gen_movi_tl(t1, v1);
17245 gen_helper_dextr_r_l(cpu_gpr[ret], t0, t1, cpu_env);
17246 break;
17247 case OPC_DEXTR_RS_L:
17248 tcg_gen_movi_tl(t0, v2);
17249 tcg_gen_movi_tl(t1, v1);
17250 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, t1, cpu_env);
17251 break;
17252 case OPC_DEXTR_W:
17253 tcg_gen_movi_tl(t0, v2);
17254 tcg_gen_movi_tl(t1, v1);
17255 gen_helper_dextr_w(cpu_gpr[ret], t0, t1, cpu_env);
17256 break;
17257 case OPC_DEXTR_R_W:
17258 tcg_gen_movi_tl(t0, v2);
17259 tcg_gen_movi_tl(t1, v1);
17260 gen_helper_dextr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
17261 break;
17262 case OPC_DEXTR_RS_W:
17263 tcg_gen_movi_tl(t0, v2);
17264 tcg_gen_movi_tl(t1, v1);
17265 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
17266 break;
17267 case OPC_DEXTR_S_H:
17268 tcg_gen_movi_tl(t0, v2);
17269 tcg_gen_movi_tl(t1, v1);
17270 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
17271 break;
17272 case OPC_DEXTRV_S_H:
17273 tcg_gen_movi_tl(t0, v2);
17274 tcg_gen_movi_tl(t1, v1);
17275 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
17276 break;
17277 case OPC_DEXTRV_L:
17278 tcg_gen_movi_tl(t0, v2);
17279 gen_helper_dextr_l(cpu_gpr[ret], t0, v1_t, cpu_env);
17280 break;
17281 case OPC_DEXTRV_R_L:
17282 tcg_gen_movi_tl(t0, v2);
17283 gen_helper_dextr_r_l(cpu_gpr[ret], t0, v1_t, cpu_env);
17284 break;
17285 case OPC_DEXTRV_RS_L:
17286 tcg_gen_movi_tl(t0, v2);
17287 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, v1_t, cpu_env);
17288 break;
17289 case OPC_DEXTRV_W:
17290 tcg_gen_movi_tl(t0, v2);
17291 gen_helper_dextr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
17292 break;
17293 case OPC_DEXTRV_R_W:
17294 tcg_gen_movi_tl(t0, v2);
17295 gen_helper_dextr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
17296 break;
17297 case OPC_DEXTRV_RS_W:
17298 tcg_gen_movi_tl(t0, v2);
17299 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
17300 break;
17301 }
17302 break;
17303#endif
17304 }
17305
17306 tcg_temp_free(t0);
17307 tcg_temp_free(t1);
17308 tcg_temp_free(v1_t);
17309 tcg_temp_free(v2_t);
b53371ed
JL
17310}
17311
9b1a1d68
JL
17312/* End MIPSDSP functions. */
17313
10dc65db
LA
17314static void decode_opc_special_r6(CPUMIPSState *env, DisasContext *ctx)
17315{
4267d3e6 17316 int rs, rt, rd, sa;
b42ee5e1 17317 uint32_t op1, op2;
10dc65db
LA
17318
17319 rs = (ctx->opcode >> 21) & 0x1f;
17320 rt = (ctx->opcode >> 16) & 0x1f;
17321 rd = (ctx->opcode >> 11) & 0x1f;
4267d3e6 17322 sa = (ctx->opcode >> 6) & 0x1f;
10dc65db
LA
17323
17324 op1 = MASK_SPECIAL(ctx->opcode);
17325 switch (op1) {
d4ea6acd 17326 case OPC_LSA:
1f1b4c00 17327 gen_lsa(ctx, op1, rd, rs, rt, extract32(ctx->opcode, 6, 2));
d4ea6acd 17328 break;
c2e19f3c
AM
17329 case OPC_MULT:
17330 case OPC_MULTU:
17331 case OPC_DIV:
17332 case OPC_DIVU:
b42ee5e1
LA
17333 op2 = MASK_R6_MULDIV(ctx->opcode);
17334 switch (op2) {
17335 case R6_OPC_MUL:
17336 case R6_OPC_MUH:
17337 case R6_OPC_MULU:
17338 case R6_OPC_MUHU:
17339 case R6_OPC_DIV:
17340 case R6_OPC_MOD:
17341 case R6_OPC_DIVU:
17342 case R6_OPC_MODU:
17343 gen_r6_muldiv(ctx, op2, rd, rs, rt);
17344 break;
17345 default:
17346 MIPS_INVAL("special_r6 muldiv");
9c708c7f 17347 generate_exception_end(ctx, EXCP_RI);
b42ee5e1
LA
17348 break;
17349 }
17350 break;
10dc65db
LA
17351 case OPC_SELEQZ:
17352 case OPC_SELNEZ:
17353 gen_cond_move(ctx, op1, rd, rs, rt);
17354 break;
4267d3e6
LA
17355 case R6_OPC_CLO:
17356 case R6_OPC_CLZ:
17357 if (rt == 0 && sa == 1) {
17358 /* Major opcode and function field is shared with preR6 MFHI/MTHI.
17359 We need additionally to check other fields */
17360 gen_cl(ctx, op1, rd, rs);
17361 } else {
9c708c7f 17362 generate_exception_end(ctx, EXCP_RI);
4267d3e6
LA
17363 }
17364 break;
17365 case R6_OPC_SDBBP:
3b3c1694
LA
17366 if (is_uhi(extract32(ctx->opcode, 6, 20))) {
17367 gen_helper_do_semihosting(cpu_env);
faf1f68b 17368 } else {
3b3c1694 17369 if (ctx->hflags & MIPS_HFLAG_SBRI) {
9c708c7f 17370 generate_exception_end(ctx, EXCP_RI);
3b3c1694 17371 } else {
9c708c7f 17372 generate_exception_end(ctx, EXCP_DBp);
3b3c1694 17373 }
faf1f68b 17374 }
4267d3e6 17375 break;
b42ee5e1 17376#if defined(TARGET_MIPS64)
d4ea6acd
LA
17377 case OPC_DLSA:
17378 check_mips_64(ctx);
1f1b4c00 17379 gen_lsa(ctx, op1, rd, rs, rt, extract32(ctx->opcode, 6, 2));
d4ea6acd 17380 break;
4267d3e6
LA
17381 case R6_OPC_DCLO:
17382 case R6_OPC_DCLZ:
17383 if (rt == 0 && sa == 1) {
17384 /* Major opcode and function field is shared with preR6 MFHI/MTHI.
17385 We need additionally to check other fields */
17386 check_mips_64(ctx);
17387 gen_cl(ctx, op1, rd, rs);
17388 } else {
9c708c7f 17389 generate_exception_end(ctx, EXCP_RI);
4267d3e6
LA
17390 }
17391 break;
c2e19f3c
AM
17392 case OPC_DMULT:
17393 case OPC_DMULTU:
17394 case OPC_DDIV:
17395 case OPC_DDIVU:
17396
b42ee5e1
LA
17397 op2 = MASK_R6_MULDIV(ctx->opcode);
17398 switch (op2) {
17399 case R6_OPC_DMUL:
17400 case R6_OPC_DMUH:
17401 case R6_OPC_DMULU:
17402 case R6_OPC_DMUHU:
17403 case R6_OPC_DDIV:
17404 case R6_OPC_DMOD:
17405 case R6_OPC_DDIVU:
17406 case R6_OPC_DMODU:
17407 check_mips_64(ctx);
17408 gen_r6_muldiv(ctx, op2, rd, rs, rt);
17409 break;
17410 default:
17411 MIPS_INVAL("special_r6 muldiv");
9c708c7f 17412 generate_exception_end(ctx, EXCP_RI);
b42ee5e1
LA
17413 break;
17414 }
17415 break;
17416#endif
10dc65db
LA
17417 default: /* Invalid */
17418 MIPS_INVAL("special_r6");
9c708c7f 17419 generate_exception_end(ctx, EXCP_RI);
10dc65db
LA
17420 break;
17421 }
17422}
17423
17424static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx)
17425{
b42ee5e1 17426 int rs, rt, rd, sa;
10dc65db
LA
17427 uint32_t op1;
17428
17429 rs = (ctx->opcode >> 21) & 0x1f;
17430 rt = (ctx->opcode >> 16) & 0x1f;
17431 rd = (ctx->opcode >> 11) & 0x1f;
b42ee5e1 17432 sa = (ctx->opcode >> 6) & 0x1f;
10dc65db
LA
17433
17434 op1 = MASK_SPECIAL(ctx->opcode);
17435 switch (op1) {
17436 case OPC_MOVN: /* Conditional move */
17437 case OPC_MOVZ:
17438 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32 |
17439 INSN_LOONGSON2E | INSN_LOONGSON2F);
17440 gen_cond_move(ctx, op1, rd, rs, rt);
17441 break;
17442 case OPC_MFHI: /* Move from HI/LO */
17443 case OPC_MFLO:
17444 gen_HILO(ctx, op1, rs & 3, rd);
17445 break;
17446 case OPC_MTHI:
17447 case OPC_MTLO: /* Move to HI/LO */
17448 gen_HILO(ctx, op1, rd & 3, rs);
17449 break;
17450 case OPC_MOVCI:
17451 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
17452 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
17453 check_cp1_enabled(ctx);
17454 gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
17455 (ctx->opcode >> 16) & 1);
17456 } else {
17457 generate_exception_err(ctx, EXCP_CpU, 1);
17458 }
17459 break;
b42ee5e1
LA
17460 case OPC_MULT:
17461 case OPC_MULTU:
17462 if (sa) {
17463 check_insn(ctx, INSN_VR54XX);
17464 op1 = MASK_MUL_VR54XX(ctx->opcode);
17465 gen_mul_vr54xx(ctx, op1, rd, rs, rt);
17466 } else {
17467 gen_muldiv(ctx, op1, rd & 3, rs, rt);
17468 }
17469 break;
17470 case OPC_DIV:
17471 case OPC_DIVU:
17472 gen_muldiv(ctx, op1, 0, rs, rt);
17473 break;
17474#if defined(TARGET_MIPS64)
c2e19f3c
AM
17475 case OPC_DMULT:
17476 case OPC_DMULTU:
17477 case OPC_DDIV:
17478 case OPC_DDIVU:
b42ee5e1
LA
17479 check_insn(ctx, ISA_MIPS3);
17480 check_mips_64(ctx);
17481 gen_muldiv(ctx, op1, 0, rs, rt);
17482 break;
17483#endif
0aefa333 17484 case OPC_JR:
b231c103 17485 gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
0aefa333 17486 break;
4267d3e6
LA
17487 case OPC_SPIM:
17488#ifdef MIPS_STRICT_STANDARD
17489 MIPS_INVAL("SPIM");
9c708c7f 17490 generate_exception_end(ctx, EXCP_RI);
4267d3e6
LA
17491#else
17492 /* Implemented as RI exception for now. */
17493 MIPS_INVAL("spim (unofficial)");
9c708c7f 17494 generate_exception_end(ctx, EXCP_RI);
4267d3e6
LA
17495#endif
17496 break;
10dc65db
LA
17497 default: /* Invalid */
17498 MIPS_INVAL("special_legacy");
9c708c7f 17499 generate_exception_end(ctx, EXCP_RI);
10dc65db
LA
17500 break;
17501 }
17502}
17503
099e5b4d 17504static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx)
3c824109 17505{
3c824109 17506 int rs, rt, rd, sa;
099e5b4d 17507 uint32_t op1;
3c824109 17508
3c824109
NF
17509 rs = (ctx->opcode >> 21) & 0x1f;
17510 rt = (ctx->opcode >> 16) & 0x1f;
17511 rd = (ctx->opcode >> 11) & 0x1f;
17512 sa = (ctx->opcode >> 6) & 0x1f;
099e5b4d
LA
17513
17514 op1 = MASK_SPECIAL(ctx->opcode);
17515 switch (op1) {
17516 case OPC_SLL: /* Shift with immediate */
339cd2a8
LA
17517 if (sa == 5 && rd == 0 &&
17518 rs == 0 && rt == 0) { /* PAUSE */
17519 if ((ctx->insn_flags & ISA_MIPS32R6) &&
17520 (ctx->hflags & MIPS_HFLAG_BMASK)) {
9c708c7f 17521 generate_exception_end(ctx, EXCP_RI);
339cd2a8
LA
17522 break;
17523 }
17524 }
17525 /* Fallthrough */
099e5b4d
LA
17526 case OPC_SRA:
17527 gen_shift_imm(ctx, op1, rd, rt, sa);
17528 break;
17529 case OPC_SRL:
17530 switch ((ctx->opcode >> 21) & 0x1f) {
17531 case 1:
17532 /* rotr is decoded as srl on non-R2 CPUs */
17533 if (ctx->insn_flags & ISA_MIPS32R2) {
17534 op1 = OPC_ROTR;
ea63e2c3 17535 }
099e5b4d
LA
17536 /* Fallthrough */
17537 case 0:
17538 gen_shift_imm(ctx, op1, rd, rt, sa);
ea63e2c3 17539 break;
099e5b4d 17540 default:
9c708c7f 17541 generate_exception_end(ctx, EXCP_RI);
ea63e2c3 17542 break;
099e5b4d
LA
17543 }
17544 break;
c2e19f3c
AM
17545 case OPC_ADD:
17546 case OPC_ADDU:
17547 case OPC_SUB:
17548 case OPC_SUBU:
099e5b4d
LA
17549 gen_arith(ctx, op1, rd, rs, rt);
17550 break;
17551 case OPC_SLLV: /* Shifts */
17552 case OPC_SRAV:
17553 gen_shift(ctx, op1, rd, rs, rt);
17554 break;
17555 case OPC_SRLV:
17556 switch ((ctx->opcode >> 6) & 0x1f) {
17557 case 1:
17558 /* rotrv is decoded as srlv on non-R2 CPUs */
17559 if (ctx->insn_flags & ISA_MIPS32R2) {
17560 op1 = OPC_ROTRV;
26135ead 17561 }
099e5b4d
LA
17562 /* Fallthrough */
17563 case 0:
17564 gen_shift(ctx, op1, rd, rs, rt);
26135ead 17565 break;
099e5b4d 17566 default:
9c708c7f 17567 generate_exception_end(ctx, EXCP_RI);
6af0bf9c 17568 break;
099e5b4d
LA
17569 }
17570 break;
17571 case OPC_SLT: /* Set on less than */
17572 case OPC_SLTU:
17573 gen_slt(ctx, op1, rd, rs, rt);
17574 break;
17575 case OPC_AND: /* Logic*/
17576 case OPC_OR:
17577 case OPC_NOR:
17578 case OPC_XOR:
17579 gen_logic(ctx, op1, rd, rs, rt);
17580 break;
0aefa333 17581 case OPC_JALR:
b231c103 17582 gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
099e5b4d 17583 break;
c2e19f3c
AM
17584 case OPC_TGE: /* Traps */
17585 case OPC_TGEU:
17586 case OPC_TLT:
17587 case OPC_TLTU:
17588 case OPC_TEQ:
099e5b4d 17589 case OPC_TNE:
d9224450 17590 check_insn(ctx, ISA_MIPS2);
099e5b4d
LA
17591 gen_trap(ctx, op1, rs, rt, -1);
17592 break;
d4ea6acd 17593 case OPC_LSA: /* OPC_PMON */
f7685877
YK
17594 if ((ctx->insn_flags & ISA_MIPS32R6) ||
17595 (env->CP0_Config3 & (1 << CP0C3_MSAP))) {
d4ea6acd
LA
17596 decode_opc_special_r6(env, ctx);
17597 } else {
17598 /* Pmon entry point, also R4010 selsl */
b48cfdff 17599#ifdef MIPS_STRICT_STANDARD
d4ea6acd 17600 MIPS_INVAL("PMON / selsl");
9c708c7f 17601 generate_exception_end(ctx, EXCP_RI);
b48cfdff 17602#else
d4ea6acd 17603 gen_helper_0e0i(pmon, sa);
b48cfdff 17604#endif
d4ea6acd 17605 }
099e5b4d
LA
17606 break;
17607 case OPC_SYSCALL:
9c708c7f 17608 generate_exception_end(ctx, EXCP_SYSCALL);
099e5b4d
LA
17609 break;
17610 case OPC_BREAK:
9c708c7f 17611 generate_exception_end(ctx, EXCP_BREAK);
099e5b4d 17612 break;
099e5b4d 17613 case OPC_SYNC:
d9224450 17614 check_insn(ctx, ISA_MIPS2);
d208ac0c 17615 gen_sync(extract32(ctx->opcode, 6, 5));
099e5b4d 17616 break;
4ad40f36 17617
d26bc211 17618#if defined(TARGET_MIPS64)
099e5b4d
LA
17619 /* MIPS64 specific opcodes */
17620 case OPC_DSLL:
17621 case OPC_DSRA:
17622 case OPC_DSLL32:
17623 case OPC_DSRA32:
17624 check_insn(ctx, ISA_MIPS3);
17625 check_mips_64(ctx);
17626 gen_shift_imm(ctx, op1, rd, rt, sa);
17627 break;
17628 case OPC_DSRL:
17629 switch ((ctx->opcode >> 21) & 0x1f) {
17630 case 1:
17631 /* drotr is decoded as dsrl on non-R2 CPUs */
17632 if (ctx->insn_flags & ISA_MIPS32R2) {
17633 op1 = OPC_DROTR;
ea63e2c3 17634 }
099e5b4d
LA
17635 /* Fallthrough */
17636 case 0:
d75c135e 17637 check_insn(ctx, ISA_MIPS3);
e189e748 17638 check_mips_64(ctx);
099e5b4d 17639 gen_shift_imm(ctx, op1, rd, rt, sa);
7a387fff 17640 break;
099e5b4d 17641 default:
9c708c7f 17642 generate_exception_end(ctx, EXCP_RI);
460f00c4 17643 break;
099e5b4d
LA
17644 }
17645 break;
17646 case OPC_DSRL32:
17647 switch ((ctx->opcode >> 21) & 0x1f) {
17648 case 1:
17649 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
17650 if (ctx->insn_flags & ISA_MIPS32R2) {
17651 op1 = OPC_DROTR32;
ea63e2c3 17652 }
099e5b4d
LA
17653 /* Fallthrough */
17654 case 0:
d75c135e 17655 check_insn(ctx, ISA_MIPS3);
e189e748 17656 check_mips_64(ctx);
099e5b4d 17657 gen_shift_imm(ctx, op1, rd, rt, sa);
7a387fff 17658 break;
099e5b4d 17659 default:
9c708c7f 17660 generate_exception_end(ctx, EXCP_RI);
6af0bf9c
FB
17661 break;
17662 }
17663 break;
c2e19f3c
AM
17664 case OPC_DADD:
17665 case OPC_DADDU:
17666 case OPC_DSUB:
17667 case OPC_DSUBU:
099e5b4d
LA
17668 check_insn(ctx, ISA_MIPS3);
17669 check_mips_64(ctx);
17670 gen_arith(ctx, op1, rd, rs, rt);
17671 break;
17672 case OPC_DSLLV:
17673 case OPC_DSRAV:
17674 check_insn(ctx, ISA_MIPS3);
17675 check_mips_64(ctx);
17676 gen_shift(ctx, op1, rd, rs, rt);
17677 break;
17678 case OPC_DSRLV:
17679 switch ((ctx->opcode >> 6) & 0x1f) {
17680 case 1:
17681 /* drotrv is decoded as dsrlv on non-R2 CPUs */
17682 if (ctx->insn_flags & ISA_MIPS32R2) {
17683 op1 = OPC_DROTRV;
6af0bf9c 17684 }
099e5b4d
LA
17685 /* Fallthrough */
17686 case 0:
17687 check_insn(ctx, ISA_MIPS3);
e189e748 17688 check_mips_64(ctx);
099e5b4d 17689 gen_shift(ctx, op1, rd, rs, rt);
161f85e6 17690 break;
099e5b4d 17691 default:
9c708c7f 17692 generate_exception_end(ctx, EXCP_RI);
6af0bf9c
FB
17693 break;
17694 }
17695 break;
f7685877
YK
17696 case OPC_DLSA:
17697 if ((ctx->insn_flags & ISA_MIPS32R6) ||
17698 (env->CP0_Config3 & (1 << CP0C3_MSAP))) {
17699 decode_opc_special_r6(env, ctx);
17700 }
17701 break;
099e5b4d 17702#endif
10dc65db
LA
17703 default:
17704 if (ctx->insn_flags & ISA_MIPS32R6) {
17705 decode_opc_special_r6(env, ctx);
17706 } else {
17707 decode_opc_special_legacy(env, ctx);
17708 }
17709 }
17710}
17711
10dc65db 17712static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx)
099e5b4d
LA
17713{
17714 int rs, rt, rd;
17715 uint32_t op1;
6c5c1e20 17716
4267d3e6
LA
17717 check_insn_opc_removed(ctx, ISA_MIPS32R6);
17718
099e5b4d
LA
17719 rs = (ctx->opcode >> 21) & 0x1f;
17720 rt = (ctx->opcode >> 16) & 0x1f;
17721 rd = (ctx->opcode >> 11) & 0x1f;
17722
17723 op1 = MASK_SPECIAL2(ctx->opcode);
17724 switch (op1) {
c2e19f3c
AM
17725 case OPC_MADD: /* Multiply and add/sub */
17726 case OPC_MADDU:
17727 case OPC_MSUB:
17728 case OPC_MSUBU:
099e5b4d
LA
17729 check_insn(ctx, ISA_MIPS32);
17730 gen_muldiv(ctx, op1, rd & 3, rs, rt);
17731 break;
17732 case OPC_MUL:
099e5b4d
LA
17733 gen_arith(ctx, op1, rd, rs, rt);
17734 break;
fac5a073
LA
17735 case OPC_DIV_G_2F:
17736 case OPC_DIVU_G_2F:
17737 case OPC_MULT_G_2F:
17738 case OPC_MULTU_G_2F:
17739 case OPC_MOD_G_2F:
17740 case OPC_MODU_G_2F:
17741 check_insn(ctx, INSN_LOONGSON2F);
17742 gen_loongson_integer(ctx, op1, rd, rs, rt);
17743 break;
099e5b4d
LA
17744 case OPC_CLO:
17745 case OPC_CLZ:
17746 check_insn(ctx, ISA_MIPS32);
17747 gen_cl(ctx, op1, rd, rs);
17748 break;
17749 case OPC_SDBBP:
3b3c1694
LA
17750 if (is_uhi(extract32(ctx->opcode, 6, 20))) {
17751 gen_helper_do_semihosting(cpu_env);
17752 } else {
17753 /* XXX: not clear which exception should be raised
17754 * when in debug mode...
17755 */
17756 check_insn(ctx, ISA_MIPS32);
9c708c7f 17757 generate_exception_end(ctx, EXCP_DBp);
3b3c1694 17758 }
099e5b4d 17759 break;
9b1a1d68 17760#if defined(TARGET_MIPS64)
099e5b4d
LA
17761 case OPC_DCLO:
17762 case OPC_DCLZ:
17763 check_insn(ctx, ISA_MIPS64);
17764 check_mips_64(ctx);
17765 gen_cl(ctx, op1, rd, rs);
17766 break;
4267d3e6
LA
17767 case OPC_DMULT_G_2F:
17768 case OPC_DMULTU_G_2F:
17769 case OPC_DDIV_G_2F:
17770 case OPC_DDIVU_G_2F:
17771 case OPC_DMOD_G_2F:
17772 case OPC_DMODU_G_2F:
17773 check_insn(ctx, INSN_LOONGSON2F);
17774 gen_loongson_integer(ctx, op1, rd, rs, rt);
17775 break;
10dc65db 17776#endif
4267d3e6
LA
17777 default: /* Invalid */
17778 MIPS_INVAL("special2_legacy");
9c708c7f 17779 generate_exception_end(ctx, EXCP_RI);
4267d3e6 17780 break;
10dc65db
LA
17781 }
17782}
17783
17784static void decode_opc_special3_r6(CPUMIPSState *env, DisasContext *ctx)
17785{
15eacb9b
YK
17786 int rs, rt, rd, sa;
17787 uint32_t op1, op2;
10dc65db
LA
17788 int16_t imm;
17789
17790 rs = (ctx->opcode >> 21) & 0x1f;
17791 rt = (ctx->opcode >> 16) & 0x1f;
15eacb9b
YK
17792 rd = (ctx->opcode >> 11) & 0x1f;
17793 sa = (ctx->opcode >> 6) & 0x1f;
10dc65db
LA
17794 imm = (int16_t)ctx->opcode >> 7;
17795
17796 op1 = MASK_SPECIAL3(ctx->opcode);
17797 switch (op1) {
bf7910c6
LA
17798 case R6_OPC_PREF:
17799 if (rt >= 24) {
17800 /* hint codes 24-31 are reserved and signal RI */
9c708c7f 17801 generate_exception_end(ctx, EXCP_RI);
bf7910c6
LA
17802 }
17803 /* Treat as NOP. */
17804 break;
17805 case R6_OPC_CACHE:
40d48212 17806 check_cp0_enabled(ctx);
0d74a222
LA
17807 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
17808 gen_cache_operation(ctx, rt, rs, imm);
17809 }
bf7910c6 17810 break;
10dc65db
LA
17811 case R6_OPC_SC:
17812 gen_st_cond(ctx, op1, rt, rs, imm);
17813 break;
17814 case R6_OPC_LL:
17815 gen_ld(ctx, op1, rt, rs, imm);
17816 break;
15eacb9b
YK
17817 case OPC_BSHFL:
17818 {
17819 if (rd == 0) {
17820 /* Treat as NOP. */
17821 break;
17822 }
15eacb9b
YK
17823 op2 = MASK_BSHFL(ctx->opcode);
17824 switch (op2) {
c2e19f3c
AM
17825 case OPC_ALIGN:
17826 case OPC_ALIGN_END:
1f1b4c00 17827 gen_align(ctx, OPC_ALIGN, rd, rs, rt, sa & 3);
15eacb9b
YK
17828 break;
17829 case OPC_BITSWAP:
1f1b4c00 17830 gen_bitswap(ctx, op2, rd, rt);
15eacb9b
YK
17831 break;
17832 }
15eacb9b
YK
17833 }
17834 break;
bf7910c6
LA
17835#if defined(TARGET_MIPS64)
17836 case R6_OPC_SCD:
17837 gen_st_cond(ctx, op1, rt, rs, imm);
17838 break;
17839 case R6_OPC_LLD:
17840 gen_ld(ctx, op1, rt, rs, imm);
17841 break;
15eacb9b
YK
17842 case OPC_DBSHFL:
17843 check_mips_64(ctx);
17844 {
17845 if (rd == 0) {
17846 /* Treat as NOP. */
17847 break;
17848 }
15eacb9b
YK
17849 op2 = MASK_DBSHFL(ctx->opcode);
17850 switch (op2) {
c2e19f3c
AM
17851 case OPC_DALIGN:
17852 case OPC_DALIGN_END:
1f1b4c00 17853 gen_align(ctx, OPC_DALIGN, rd, rs, rt, sa & 7);
15eacb9b
YK
17854 break;
17855 case OPC_DBITSWAP:
1f1b4c00 17856 gen_bitswap(ctx, op2, rd, rt);
15eacb9b
YK
17857 break;
17858 }
1f1b4c00 17859
15eacb9b
YK
17860 }
17861 break;
bf7910c6 17862#endif
10dc65db
LA
17863 default: /* Invalid */
17864 MIPS_INVAL("special3_r6");
9c708c7f 17865 generate_exception_end(ctx, EXCP_RI);
10dc65db
LA
17866 break;
17867 }
17868}
17869
17870static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx)
17871{
fac5a073 17872 int rs, rt, rd;
099e5b4d 17873 uint32_t op1, op2;
099e5b4d
LA
17874
17875 rs = (ctx->opcode >> 21) & 0x1f;
17876 rt = (ctx->opcode >> 16) & 0x1f;
17877 rd = (ctx->opcode >> 11) & 0x1f;
099e5b4d
LA
17878
17879 op1 = MASK_SPECIAL3(ctx->opcode);
17880 switch (op1) {
c2e19f3c
AM
17881 case OPC_DIV_G_2E:
17882 case OPC_DIVU_G_2E:
17883 case OPC_MOD_G_2E:
17884 case OPC_MODU_G_2E:
17885 case OPC_MULT_G_2E:
17886 case OPC_MULTU_G_2E:
099e5b4d
LA
17887 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
17888 * the same mask and op1. */
17889 if ((ctx->insn_flags & ASE_DSPR2) && (op1 == OPC_MULT_G_2E)) {
17890 op2 = MASK_ADDUH_QB(ctx->opcode);
461c08df 17891 switch (op2) {
099e5b4d
LA
17892 case OPC_ADDUH_QB:
17893 case OPC_ADDUH_R_QB:
17894 case OPC_ADDQH_PH:
17895 case OPC_ADDQH_R_PH:
17896 case OPC_ADDQH_W:
17897 case OPC_ADDQH_R_W:
17898 case OPC_SUBUH_QB:
17899 case OPC_SUBUH_R_QB:
17900 case OPC_SUBQH_PH:
17901 case OPC_SUBQH_R_PH:
17902 case OPC_SUBQH_W:
17903 case OPC_SUBQH_R_W:
461c08df
JL
17904 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
17905 break;
099e5b4d
LA
17906 case OPC_MUL_PH:
17907 case OPC_MUL_S_PH:
17908 case OPC_MULQ_S_W:
17909 case OPC_MULQ_RS_W:
17910 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
1cb6686c 17911 break;
461c08df 17912 default:
099e5b4d 17913 MIPS_INVAL("MASK ADDUH.QB");
9c708c7f 17914 generate_exception_end(ctx, EXCP_RI);
461c08df
JL
17915 break;
17916 }
099e5b4d
LA
17917 } else if (ctx->insn_flags & INSN_LOONGSON2E) {
17918 gen_loongson_integer(ctx, op1, rd, rs, rt);
17919 } else {
9c708c7f 17920 generate_exception_end(ctx, EXCP_RI);
099e5b4d
LA
17921 }
17922 break;
17923 case OPC_LX_DSP:
17924 op2 = MASK_LX(ctx->opcode);
17925 switch (op2) {
17926#if defined(TARGET_MIPS64)
17927 case OPC_LDX:
17928#endif
17929 case OPC_LBUX:
17930 case OPC_LHX:
17931 case OPC_LWX:
17932 gen_mipsdsp_ld(ctx, op2, rd, rs, rt);
17933 break;
17934 default: /* Invalid */
17935 MIPS_INVAL("MASK LX");
9c708c7f 17936 generate_exception_end(ctx, EXCP_RI);
099e5b4d
LA
17937 break;
17938 }
17939 break;
17940 case OPC_ABSQ_S_PH_DSP:
17941 op2 = MASK_ABSQ_S_PH(ctx->opcode);
17942 switch (op2) {
17943 case OPC_ABSQ_S_QB:
17944 case OPC_ABSQ_S_PH:
17945 case OPC_ABSQ_S_W:
17946 case OPC_PRECEQ_W_PHL:
17947 case OPC_PRECEQ_W_PHR:
17948 case OPC_PRECEQU_PH_QBL:
17949 case OPC_PRECEQU_PH_QBR:
17950 case OPC_PRECEQU_PH_QBLA:
17951 case OPC_PRECEQU_PH_QBRA:
17952 case OPC_PRECEU_PH_QBL:
17953 case OPC_PRECEU_PH_QBR:
17954 case OPC_PRECEU_PH_QBLA:
17955 case OPC_PRECEU_PH_QBRA:
17956 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
17957 break;
17958 case OPC_BITREV:
17959 case OPC_REPL_QB:
17960 case OPC_REPLV_QB:
17961 case OPC_REPL_PH:
17962 case OPC_REPLV_PH:
17963 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
17964 break;
17965 default:
17966 MIPS_INVAL("MASK ABSQ_S.PH");
9c708c7f 17967 generate_exception_end(ctx, EXCP_RI);
099e5b4d
LA
17968 break;
17969 }
17970 break;
17971 case OPC_ADDU_QB_DSP:
17972 op2 = MASK_ADDU_QB(ctx->opcode);
17973 switch (op2) {
17974 case OPC_ADDQ_PH:
17975 case OPC_ADDQ_S_PH:
17976 case OPC_ADDQ_S_W:
17977 case OPC_ADDU_QB:
17978 case OPC_ADDU_S_QB:
17979 case OPC_ADDU_PH:
17980 case OPC_ADDU_S_PH:
17981 case OPC_SUBQ_PH:
17982 case OPC_SUBQ_S_PH:
17983 case OPC_SUBQ_S_W:
17984 case OPC_SUBU_QB:
17985 case OPC_SUBU_S_QB:
17986 case OPC_SUBU_PH:
17987 case OPC_SUBU_S_PH:
17988 case OPC_ADDSC:
17989 case OPC_ADDWC:
17990 case OPC_MODSUB:
17991 case OPC_RADDU_W_QB:
17992 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
17993 break;
17994 case OPC_MULEU_S_PH_QBL:
17995 case OPC_MULEU_S_PH_QBR:
17996 case OPC_MULQ_RS_PH:
17997 case OPC_MULEQ_S_W_PHL:
17998 case OPC_MULEQ_S_W_PHR:
17999 case OPC_MULQ_S_PH:
18000 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
18001 break;
18002 default: /* Invalid */
18003 MIPS_INVAL("MASK ADDU.QB");
9c708c7f 18004 generate_exception_end(ctx, EXCP_RI);
461c08df 18005 break;
461c08df 18006
099e5b4d
LA
18007 }
18008 break;
18009 case OPC_CMPU_EQ_QB_DSP:
18010 op2 = MASK_CMPU_EQ_QB(ctx->opcode);
18011 switch (op2) {
18012 case OPC_PRECR_SRA_PH_W:
18013 case OPC_PRECR_SRA_R_PH_W:
18014 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
461c08df 18015 break;
099e5b4d
LA
18016 case OPC_PRECR_QB_PH:
18017 case OPC_PRECRQ_QB_PH:
18018 case OPC_PRECRQ_PH_W:
18019 case OPC_PRECRQ_RS_PH_W:
18020 case OPC_PRECRQU_S_QB_PH:
18021 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
461c08df 18022 break;
099e5b4d
LA
18023 case OPC_CMPU_EQ_QB:
18024 case OPC_CMPU_LT_QB:
18025 case OPC_CMPU_LE_QB:
18026 case OPC_CMP_EQ_PH:
18027 case OPC_CMP_LT_PH:
18028 case OPC_CMP_LE_PH:
18029 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
77c5fa8b 18030 break;
099e5b4d
LA
18031 case OPC_CMPGU_EQ_QB:
18032 case OPC_CMPGU_LT_QB:
18033 case OPC_CMPGU_LE_QB:
18034 case OPC_CMPGDU_EQ_QB:
18035 case OPC_CMPGDU_LT_QB:
18036 case OPC_CMPGDU_LE_QB:
18037 case OPC_PICK_QB:
18038 case OPC_PICK_PH:
18039 case OPC_PACKRL_PH:
18040 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
18041 break;
18042 default: /* Invalid */
18043 MIPS_INVAL("MASK CMPU.EQ.QB");
9c708c7f 18044 generate_exception_end(ctx, EXCP_RI);
099e5b4d
LA
18045 break;
18046 }
18047 break;
18048 case OPC_SHLL_QB_DSP:
18049 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
18050 break;
18051 case OPC_DPA_W_PH_DSP:
18052 op2 = MASK_DPA_W_PH(ctx->opcode);
18053 switch (op2) {
18054 case OPC_DPAU_H_QBL:
18055 case OPC_DPAU_H_QBR:
18056 case OPC_DPSU_H_QBL:
18057 case OPC_DPSU_H_QBR:
18058 case OPC_DPA_W_PH:
18059 case OPC_DPAX_W_PH:
18060 case OPC_DPAQ_S_W_PH:
18061 case OPC_DPAQX_S_W_PH:
18062 case OPC_DPAQX_SA_W_PH:
18063 case OPC_DPS_W_PH:
18064 case OPC_DPSX_W_PH:
18065 case OPC_DPSQ_S_W_PH:
18066 case OPC_DPSQX_S_W_PH:
18067 case OPC_DPSQX_SA_W_PH:
18068 case OPC_MULSAQ_S_W_PH:
18069 case OPC_DPAQ_SA_L_W:
18070 case OPC_DPSQ_SA_L_W:
18071 case OPC_MAQ_S_W_PHL:
18072 case OPC_MAQ_S_W_PHR:
18073 case OPC_MAQ_SA_W_PHL:
18074 case OPC_MAQ_SA_W_PHR:
18075 case OPC_MULSA_W_PH:
18076 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
18077 break;
18078 default: /* Invalid */
18079 MIPS_INVAL("MASK DPAW.PH");
9c708c7f 18080 generate_exception_end(ctx, EXCP_RI);
099e5b4d
LA
18081 break;
18082 }
18083 break;
18084 case OPC_INSV_DSP:
18085 op2 = MASK_INSV(ctx->opcode);
18086 switch (op2) {
18087 case OPC_INSV:
18088 check_dsp(ctx);
18089 {
18090 TCGv t0, t1;
18091
18092 if (rt == 0) {
099e5b4d
LA
18093 break;
18094 }
18095
18096 t0 = tcg_temp_new();
18097 t1 = tcg_temp_new();
18098
18099 gen_load_gpr(t0, rt);
18100 gen_load_gpr(t1, rs);
18101
18102 gen_helper_insv(cpu_gpr[rt], cpu_env, t1, t0);
18103
18104 tcg_temp_free(t0);
18105 tcg_temp_free(t1);
a22260ae
JL
18106 break;
18107 }
099e5b4d
LA
18108 default: /* Invalid */
18109 MIPS_INVAL("MASK INSV");
9c708c7f 18110 generate_exception_end(ctx, EXCP_RI);
099e5b4d
LA
18111 break;
18112 }
18113 break;
18114 case OPC_APPEND_DSP:
18115 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
18116 break;
18117 case OPC_EXTR_W_DSP:
18118 op2 = MASK_EXTR_W(ctx->opcode);
18119 switch (op2) {
18120 case OPC_EXTR_W:
18121 case OPC_EXTR_R_W:
18122 case OPC_EXTR_RS_W:
18123 case OPC_EXTR_S_H:
18124 case OPC_EXTRV_S_H:
18125 case OPC_EXTRV_W:
18126 case OPC_EXTRV_R_W:
18127 case OPC_EXTRV_RS_W:
18128 case OPC_EXTP:
18129 case OPC_EXTPV:
18130 case OPC_EXTPDP:
18131 case OPC_EXTPDPV:
18132 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
18133 break;
18134 case OPC_RDDSP:
18135 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 1);
18136 break;
18137 case OPC_SHILO:
18138 case OPC_SHILOV:
18139 case OPC_MTHLIP:
18140 case OPC_WRDSP:
18141 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
18142 break;
18143 default: /* Invalid */
18144 MIPS_INVAL("MASK EXTR.W");
9c708c7f 18145 generate_exception_end(ctx, EXCP_RI);
099e5b4d
LA
18146 break;
18147 }
18148 break;
099e5b4d 18149#if defined(TARGET_MIPS64)
c2e19f3c
AM
18150 case OPC_DDIV_G_2E:
18151 case OPC_DDIVU_G_2E:
18152 case OPC_DMULT_G_2E:
18153 case OPC_DMULTU_G_2E:
18154 case OPC_DMOD_G_2E:
18155 case OPC_DMODU_G_2E:
fac5a073
LA
18156 check_insn(ctx, INSN_LOONGSON2E);
18157 gen_loongson_integer(ctx, op1, rd, rs, rt);
099e5b4d 18158 break;
099e5b4d
LA
18159 case OPC_ABSQ_S_QH_DSP:
18160 op2 = MASK_ABSQ_S_QH(ctx->opcode);
18161 switch (op2) {
18162 case OPC_PRECEQ_L_PWL:
18163 case OPC_PRECEQ_L_PWR:
18164 case OPC_PRECEQ_PW_QHL:
18165 case OPC_PRECEQ_PW_QHR:
18166 case OPC_PRECEQ_PW_QHLA:
18167 case OPC_PRECEQ_PW_QHRA:
18168 case OPC_PRECEQU_QH_OBL:
18169 case OPC_PRECEQU_QH_OBR:
18170 case OPC_PRECEQU_QH_OBLA:
18171 case OPC_PRECEQU_QH_OBRA:
18172 case OPC_PRECEU_QH_OBL:
18173 case OPC_PRECEU_QH_OBR:
18174 case OPC_PRECEU_QH_OBLA:
18175 case OPC_PRECEU_QH_OBRA:
18176 case OPC_ABSQ_S_OB:
18177 case OPC_ABSQ_S_PW:
18178 case OPC_ABSQ_S_QH:
18179 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
18180 break;
18181 case OPC_REPL_OB:
18182 case OPC_REPL_PW:
18183 case OPC_REPL_QH:
18184 case OPC_REPLV_OB:
18185 case OPC_REPLV_PW:
18186 case OPC_REPLV_QH:
18187 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
18188 break;
18189 default: /* Invalid */
18190 MIPS_INVAL("MASK ABSQ_S.QH");
9c708c7f 18191 generate_exception_end(ctx, EXCP_RI);
099e5b4d
LA
18192 break;
18193 }
18194 break;
18195 case OPC_ADDU_OB_DSP:
18196 op2 = MASK_ADDU_OB(ctx->opcode);
18197 switch (op2) {
18198 case OPC_RADDU_L_OB:
18199 case OPC_SUBQ_PW:
18200 case OPC_SUBQ_S_PW:
18201 case OPC_SUBQ_QH:
18202 case OPC_SUBQ_S_QH:
18203 case OPC_SUBU_OB:
18204 case OPC_SUBU_S_OB:
18205 case OPC_SUBU_QH:
18206 case OPC_SUBU_S_QH:
18207 case OPC_SUBUH_OB:
18208 case OPC_SUBUH_R_OB:
18209 case OPC_ADDQ_PW:
18210 case OPC_ADDQ_S_PW:
18211 case OPC_ADDQ_QH:
18212 case OPC_ADDQ_S_QH:
18213 case OPC_ADDU_OB:
18214 case OPC_ADDU_S_OB:
18215 case OPC_ADDU_QH:
18216 case OPC_ADDU_S_QH:
18217 case OPC_ADDUH_OB:
18218 case OPC_ADDUH_R_OB:
18219 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
a22260ae 18220 break;
099e5b4d
LA
18221 case OPC_MULEQ_S_PW_QHL:
18222 case OPC_MULEQ_S_PW_QHR:
18223 case OPC_MULEU_S_QH_OBL:
18224 case OPC_MULEU_S_QH_OBR:
18225 case OPC_MULQ_RS_QH:
18226 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
1cb6686c 18227 break;
099e5b4d
LA
18228 default: /* Invalid */
18229 MIPS_INVAL("MASK ADDU.OB");
9c708c7f 18230 generate_exception_end(ctx, EXCP_RI);
26690560 18231 break;
099e5b4d
LA
18232 }
18233 break;
18234 case OPC_CMPU_EQ_OB_DSP:
18235 op2 = MASK_CMPU_EQ_OB(ctx->opcode);
18236 switch (op2) {
18237 case OPC_PRECR_SRA_QH_PW:
18238 case OPC_PRECR_SRA_R_QH_PW:
18239 /* Return value is rt. */
18240 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
b53371ed 18241 break;
099e5b4d
LA
18242 case OPC_PRECR_OB_QH:
18243 case OPC_PRECRQ_OB_QH:
18244 case OPC_PRECRQ_PW_L:
18245 case OPC_PRECRQ_QH_PW:
18246 case OPC_PRECRQ_RS_QH_PW:
18247 case OPC_PRECRQU_S_OB_QH:
18248 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
4368b29a 18249 break;
099e5b4d
LA
18250 case OPC_CMPU_EQ_OB:
18251 case OPC_CMPU_LT_OB:
18252 case OPC_CMPU_LE_OB:
18253 case OPC_CMP_EQ_QH:
18254 case OPC_CMP_LT_QH:
18255 case OPC_CMP_LE_QH:
18256 case OPC_CMP_EQ_PW:
18257 case OPC_CMP_LT_PW:
18258 case OPC_CMP_LE_PW:
18259 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
7a387fff 18260 break;
099e5b4d
LA
18261 case OPC_CMPGDU_EQ_OB:
18262 case OPC_CMPGDU_LT_OB:
18263 case OPC_CMPGDU_LE_OB:
18264 case OPC_CMPGU_EQ_OB:
18265 case OPC_CMPGU_LT_OB:
18266 case OPC_CMPGU_LE_OB:
18267 case OPC_PACKRL_PW:
18268 case OPC_PICK_OB:
18269 case OPC_PICK_PW:
18270 case OPC_PICK_QH:
18271 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
c6d6dd7c 18272 break;
099e5b4d
LA
18273 default: /* Invalid */
18274 MIPS_INVAL("MASK CMPU_EQ.OB");
9c708c7f 18275 generate_exception_end(ctx, EXCP_RI);
161f85e6 18276 break;
099e5b4d
LA
18277 }
18278 break;
18279 case OPC_DAPPEND_DSP:
18280 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
18281 break;
18282 case OPC_DEXTR_W_DSP:
18283 op2 = MASK_DEXTR_W(ctx->opcode);
18284 switch (op2) {
18285 case OPC_DEXTP:
18286 case OPC_DEXTPDP:
18287 case OPC_DEXTPDPV:
18288 case OPC_DEXTPV:
18289 case OPC_DEXTR_L:
18290 case OPC_DEXTR_R_L:
18291 case OPC_DEXTR_RS_L:
18292 case OPC_DEXTR_W:
18293 case OPC_DEXTR_R_W:
18294 case OPC_DEXTR_RS_W:
18295 case OPC_DEXTR_S_H:
18296 case OPC_DEXTRV_L:
18297 case OPC_DEXTRV_R_L:
18298 case OPC_DEXTRV_RS_L:
18299 case OPC_DEXTRV_S_H:
18300 case OPC_DEXTRV_W:
18301 case OPC_DEXTRV_R_W:
18302 case OPC_DEXTRV_RS_W:
18303 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
461c08df 18304 break;
099e5b4d
LA
18305 case OPC_DMTHLIP:
18306 case OPC_DSHILO:
18307 case OPC_DSHILOV:
18308 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
461c08df 18309 break;
099e5b4d
LA
18310 default: /* Invalid */
18311 MIPS_INVAL("MASK EXTR.W");
9c708c7f 18312 generate_exception_end(ctx, EXCP_RI);
461c08df 18313 break;
099e5b4d
LA
18314 }
18315 break;
18316 case OPC_DPAQ_W_QH_DSP:
18317 op2 = MASK_DPAQ_W_QH(ctx->opcode);
18318 switch (op2) {
18319 case OPC_DPAU_H_OBL:
18320 case OPC_DPAU_H_OBR:
18321 case OPC_DPSU_H_OBL:
18322 case OPC_DPSU_H_OBR:
18323 case OPC_DPA_W_QH:
18324 case OPC_DPAQ_S_W_QH:
18325 case OPC_DPS_W_QH:
18326 case OPC_DPSQ_S_W_QH:
18327 case OPC_MULSAQ_S_W_QH:
18328 case OPC_DPAQ_SA_L_PW:
18329 case OPC_DPSQ_SA_L_PW:
18330 case OPC_MULSAQ_S_L_PW:
18331 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
18332 break;
18333 case OPC_MAQ_S_W_QHLL:
18334 case OPC_MAQ_S_W_QHLR:
18335 case OPC_MAQ_S_W_QHRL:
18336 case OPC_MAQ_S_W_QHRR:
18337 case OPC_MAQ_SA_W_QHLL:
18338 case OPC_MAQ_SA_W_QHLR:
18339 case OPC_MAQ_SA_W_QHRL:
18340 case OPC_MAQ_SA_W_QHRR:
18341 case OPC_MAQ_S_L_PWL:
18342 case OPC_MAQ_S_L_PWR:
18343 case OPC_DMADD:
18344 case OPC_DMADDU:
18345 case OPC_DMSUB:
18346 case OPC_DMSUBU:
18347 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
26690560 18348 break;
099e5b4d
LA
18349 default: /* Invalid */
18350 MIPS_INVAL("MASK DPAQ.W.QH");
9c708c7f 18351 generate_exception_end(ctx, EXCP_RI);
b53371ed 18352 break;
099e5b4d
LA
18353 }
18354 break;
18355 case OPC_DINSV_DSP:
18356 op2 = MASK_INSV(ctx->opcode);
18357 switch (op2) {
18358 case OPC_DINSV:
18359 {
18360 TCGv t0, t1;
18361
18362 if (rt == 0) {
a22260ae
JL
18363 break;
18364 }
099e5b4d 18365 check_dsp(ctx);
1cb6686c 18366
099e5b4d
LA
18367 t0 = tcg_temp_new();
18368 t1 = tcg_temp_new();
1cb6686c 18369
099e5b4d
LA
18370 gen_load_gpr(t0, rt);
18371 gen_load_gpr(t1, rs);
1cb6686c 18372
099e5b4d 18373 gen_helper_dinsv(cpu_gpr[rt], cpu_env, t1, t0);
62eb3b9a 18374
099e5b4d
LA
18375 tcg_temp_free(t0);
18376 tcg_temp_free(t1);
77c5fa8b 18377 break;
099e5b4d 18378 }
7a387fff 18379 default: /* Invalid */
099e5b4d 18380 MIPS_INVAL("MASK DINSV");
9c708c7f 18381 generate_exception_end(ctx, EXCP_RI);
7a387fff
TS
18382 break;
18383 }
18384 break;
099e5b4d
LA
18385 case OPC_SHLL_OB_DSP:
18386 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
18387 break;
18388#endif
fac5a073
LA
18389 default: /* Invalid */
18390 MIPS_INVAL("special3_legacy");
9c708c7f 18391 generate_exception_end(ctx, EXCP_RI);
fac5a073
LA
18392 break;
18393 }
18394}
18395
18396static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx)
18397{
18398 int rs, rt, rd, sa;
18399 uint32_t op1, op2;
76964147 18400 int16_t imm;
fac5a073
LA
18401
18402 rs = (ctx->opcode >> 21) & 0x1f;
18403 rt = (ctx->opcode >> 16) & 0x1f;
18404 rd = (ctx->opcode >> 11) & 0x1f;
18405 sa = (ctx->opcode >> 6) & 0x1f;
76964147 18406 imm = sextract32(ctx->opcode, 7, 9);
fac5a073
LA
18407
18408 op1 = MASK_SPECIAL3(ctx->opcode);
76964147
JH
18409
18410 /*
18411 * EVA loads and stores overlap Loongson 2E instructions decoded by
18412 * decode_opc_special3_legacy(), so be careful to allow their decoding when
18413 * EVA is absent.
18414 */
18415 if (ctx->eva) {
18416 switch (op1) {
c2e19f3c
AM
18417 case OPC_LWLE:
18418 case OPC_LWRE:
76964147
JH
18419 check_insn_opc_removed(ctx, ISA_MIPS32R6);
18420 /* fall through */
c2e19f3c
AM
18421 case OPC_LBUE:
18422 case OPC_LHUE:
18423 case OPC_LBE:
18424 case OPC_LHE:
18425 case OPC_LLE:
18426 case OPC_LWE:
76964147
JH
18427 check_cp0_enabled(ctx);
18428 gen_ld(ctx, op1, rt, rs, imm);
18429 return;
c2e19f3c
AM
18430 case OPC_SWLE:
18431 case OPC_SWRE:
76964147
JH
18432 check_insn_opc_removed(ctx, ISA_MIPS32R6);
18433 /* fall through */
c2e19f3c
AM
18434 case OPC_SBE:
18435 case OPC_SHE:
76964147
JH
18436 case OPC_SWE:
18437 check_cp0_enabled(ctx);
18438 gen_st(ctx, op1, rt, rs, imm);
18439 return;
18440 case OPC_SCE:
18441 check_cp0_enabled(ctx);
18442 gen_st_cond(ctx, op1, rt, rs, imm);
18443 return;
18444 case OPC_CACHEE:
18445 check_cp0_enabled(ctx);
18446 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
18447 gen_cache_operation(ctx, rt, rs, imm);
18448 }
18449 /* Treat as NOP. */
18450 return;
18451 case OPC_PREFE:
18452 check_cp0_enabled(ctx);
18453 /* Treat as NOP. */
18454 return;
18455 }
18456 }
18457
fac5a073
LA
18458 switch (op1) {
18459 case OPC_EXT:
18460 case OPC_INS:
18461 check_insn(ctx, ISA_MIPS32R2);
18462 gen_bitops(ctx, op1, rt, rs, sa, rd);
18463 break;
18464 case OPC_BSHFL:
fac5a073 18465 op2 = MASK_BSHFL(ctx->opcode);
15eacb9b 18466 switch (op2) {
c2e19f3c
AM
18467 case OPC_ALIGN:
18468 case OPC_ALIGN_END:
15eacb9b
YK
18469 case OPC_BITSWAP:
18470 check_insn(ctx, ISA_MIPS32R6);
18471 decode_opc_special3_r6(env, ctx);
18472 break;
18473 default:
18474 check_insn(ctx, ISA_MIPS32R2);
18475 gen_bshfl(ctx, op2, rt, rd);
18476 break;
18477 }
fac5a073
LA
18478 break;
18479#if defined(TARGET_MIPS64)
c2e19f3c
AM
18480 case OPC_DEXTM:
18481 case OPC_DEXTU:
18482 case OPC_DEXT:
18483 case OPC_DINSM:
18484 case OPC_DINSU:
18485 case OPC_DINS:
fac5a073
LA
18486 check_insn(ctx, ISA_MIPS64R2);
18487 check_mips_64(ctx);
18488 gen_bitops(ctx, op1, rt, rs, sa, rd);
18489 break;
18490 case OPC_DBSHFL:
fac5a073 18491 op2 = MASK_DBSHFL(ctx->opcode);
15eacb9b 18492 switch (op2) {
c2e19f3c
AM
18493 case OPC_DALIGN:
18494 case OPC_DALIGN_END:
15eacb9b
YK
18495 case OPC_DBITSWAP:
18496 check_insn(ctx, ISA_MIPS32R6);
18497 decode_opc_special3_r6(env, ctx);
18498 break;
18499 default:
18500 check_insn(ctx, ISA_MIPS64R2);
18501 check_mips_64(ctx);
18502 op2 = MASK_DBSHFL(ctx->opcode);
18503 gen_bshfl(ctx, op2, rt, rd);
18504 break;
18505 }
fac5a073
LA
18506 break;
18507#endif
18508 case OPC_RDHWR:
b00c7218 18509 gen_rdhwr(ctx, rt, rd, extract32(ctx->opcode, 6, 3));
fac5a073
LA
18510 break;
18511 case OPC_FORK:
18512 check_insn(ctx, ASE_MT);
18513 {
18514 TCGv t0 = tcg_temp_new();
18515 TCGv t1 = tcg_temp_new();
18516
18517 gen_load_gpr(t0, rt);
18518 gen_load_gpr(t1, rs);
18519 gen_helper_fork(t0, t1);
18520 tcg_temp_free(t0);
18521 tcg_temp_free(t1);
18522 }
18523 break;
18524 case OPC_YIELD:
18525 check_insn(ctx, ASE_MT);
18526 {
18527 TCGv t0 = tcg_temp_new();
18528
fac5a073
LA
18529 gen_load_gpr(t0, rs);
18530 gen_helper_yield(t0, cpu_env, t0);
18531 gen_store_gpr(t0, rd);
18532 tcg_temp_free(t0);
18533 }
18534 break;
10dc65db
LA
18535 default:
18536 if (ctx->insn_flags & ISA_MIPS32R6) {
18537 decode_opc_special3_r6(env, ctx);
18538 } else {
18539 decode_opc_special3_legacy(env, ctx);
18540 }
099e5b4d
LA
18541 }
18542}
18543
863f264d
YK
18544/* MIPS SIMD Architecture (MSA) */
18545static inline int check_msa_access(DisasContext *ctx)
18546{
18547 if (unlikely((ctx->hflags & MIPS_HFLAG_FPU) &&
18548 !(ctx->hflags & MIPS_HFLAG_F64))) {
9c708c7f 18549 generate_exception_end(ctx, EXCP_RI);
863f264d
YK
18550 return 0;
18551 }
18552
18553 if (unlikely(!(ctx->hflags & MIPS_HFLAG_MSA))) {
18554 if (ctx->insn_flags & ASE_MSA) {
9c708c7f 18555 generate_exception_end(ctx, EXCP_MSADIS);
863f264d
YK
18556 return 0;
18557 } else {
9c708c7f 18558 generate_exception_end(ctx, EXCP_RI);
863f264d
YK
18559 return 0;
18560 }
18561 }
18562 return 1;
18563}
18564
5692c6e1
YK
18565static void gen_check_zero_element(TCGv tresult, uint8_t df, uint8_t wt)
18566{
18567 /* generates tcg ops to check if any element is 0 */
18568 /* Note this function only works with MSA_WRLEN = 128 */
18569 uint64_t eval_zero_or_big = 0;
18570 uint64_t eval_big = 0;
18571 TCGv_i64 t0 = tcg_temp_new_i64();
18572 TCGv_i64 t1 = tcg_temp_new_i64();
18573 switch (df) {
18574 case DF_BYTE:
18575 eval_zero_or_big = 0x0101010101010101ULL;
18576 eval_big = 0x8080808080808080ULL;
18577 break;
18578 case DF_HALF:
18579 eval_zero_or_big = 0x0001000100010001ULL;
18580 eval_big = 0x8000800080008000ULL;
18581 break;
18582 case DF_WORD:
18583 eval_zero_or_big = 0x0000000100000001ULL;
18584 eval_big = 0x8000000080000000ULL;
18585 break;
18586 case DF_DOUBLE:
18587 eval_zero_or_big = 0x0000000000000001ULL;
18588 eval_big = 0x8000000000000000ULL;
18589 break;
18590 }
18591 tcg_gen_subi_i64(t0, msa_wr_d[wt<<1], eval_zero_or_big);
18592 tcg_gen_andc_i64(t0, t0, msa_wr_d[wt<<1]);
18593 tcg_gen_andi_i64(t0, t0, eval_big);
18594 tcg_gen_subi_i64(t1, msa_wr_d[(wt<<1)+1], eval_zero_or_big);
18595 tcg_gen_andc_i64(t1, t1, msa_wr_d[(wt<<1)+1]);
18596 tcg_gen_andi_i64(t1, t1, eval_big);
18597 tcg_gen_or_i64(t0, t0, t1);
18598 /* if all bits are zero then all elements are not zero */
18599 /* if some bit is non-zero then some element is zero */
18600 tcg_gen_setcondi_i64(TCG_COND_NE, t0, t0, 0);
18601 tcg_gen_trunc_i64_tl(tresult, t0);
18602 tcg_temp_free_i64(t0);
18603 tcg_temp_free_i64(t1);
18604}
18605
18606static void gen_msa_branch(CPUMIPSState *env, DisasContext *ctx, uint32_t op1)
18607{
18608 uint8_t df = (ctx->opcode >> 21) & 0x3;
18609 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
18610 int64_t s16 = (int16_t)ctx->opcode;
18611
18612 check_msa_access(ctx);
18613
075a1fe7 18614 if (ctx->hflags & MIPS_HFLAG_BMASK) {
9c708c7f 18615 generate_exception_end(ctx, EXCP_RI);
5692c6e1
YK
18616 return;
18617 }
18618 switch (op1) {
18619 case OPC_BZ_V:
18620 case OPC_BNZ_V:
18621 {
18622 TCGv_i64 t0 = tcg_temp_new_i64();
18623 tcg_gen_or_i64(t0, msa_wr_d[wt<<1], msa_wr_d[(wt<<1)+1]);
18624 tcg_gen_setcondi_i64((op1 == OPC_BZ_V) ?
18625 TCG_COND_EQ : TCG_COND_NE, t0, t0, 0);
18626 tcg_gen_trunc_i64_tl(bcond, t0);
18627 tcg_temp_free_i64(t0);
18628 }
18629 break;
18630 case OPC_BZ_B:
18631 case OPC_BZ_H:
18632 case OPC_BZ_W:
18633 case OPC_BZ_D:
18634 gen_check_zero_element(bcond, df, wt);
18635 break;
18636 case OPC_BNZ_B:
18637 case OPC_BNZ_H:
18638 case OPC_BNZ_W:
18639 case OPC_BNZ_D:
18640 gen_check_zero_element(bcond, df, wt);
18641 tcg_gen_setcondi_tl(TCG_COND_EQ, bcond, bcond, 0);
18642 break;
18643 }
18644
eeb3bba8 18645 ctx->btarget = ctx->base.pc_next + (s16 << 2) + 4;
5692c6e1
YK
18646
18647 ctx->hflags |= MIPS_HFLAG_BC;
18648 ctx->hflags |= MIPS_HFLAG_BDS32;
18649}
18650
4c789546
YK
18651static void gen_msa_i8(CPUMIPSState *env, DisasContext *ctx)
18652{
18653#define MASK_MSA_I8(op) (MASK_MSA_MINOR(op) | (op & (0x03 << 24)))
18654 uint8_t i8 = (ctx->opcode >> 16) & 0xff;
18655 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18656 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18657
18658 TCGv_i32 twd = tcg_const_i32(wd);
18659 TCGv_i32 tws = tcg_const_i32(ws);
18660 TCGv_i32 ti8 = tcg_const_i32(i8);
18661
18662 switch (MASK_MSA_I8(ctx->opcode)) {
18663 case OPC_ANDI_B:
18664 gen_helper_msa_andi_b(cpu_env, twd, tws, ti8);
18665 break;
18666 case OPC_ORI_B:
18667 gen_helper_msa_ori_b(cpu_env, twd, tws, ti8);
18668 break;
18669 case OPC_NORI_B:
18670 gen_helper_msa_nori_b(cpu_env, twd, tws, ti8);
18671 break;
18672 case OPC_XORI_B:
18673 gen_helper_msa_xori_b(cpu_env, twd, tws, ti8);
18674 break;
18675 case OPC_BMNZI_B:
18676 gen_helper_msa_bmnzi_b(cpu_env, twd, tws, ti8);
18677 break;
18678 case OPC_BMZI_B:
18679 gen_helper_msa_bmzi_b(cpu_env, twd, tws, ti8);
18680 break;
18681 case OPC_BSELI_B:
18682 gen_helper_msa_bseli_b(cpu_env, twd, tws, ti8);
18683 break;
18684 case OPC_SHF_B:
18685 case OPC_SHF_H:
18686 case OPC_SHF_W:
18687 {
18688 uint8_t df = (ctx->opcode >> 24) & 0x3;
18689 if (df == DF_DOUBLE) {
9c708c7f 18690 generate_exception_end(ctx, EXCP_RI);
4c789546
YK
18691 } else {
18692 TCGv_i32 tdf = tcg_const_i32(df);
18693 gen_helper_msa_shf_df(cpu_env, tdf, twd, tws, ti8);
18694 tcg_temp_free_i32(tdf);
18695 }
18696 }
18697 break;
18698 default:
18699 MIPS_INVAL("MSA instruction");
9c708c7f 18700 generate_exception_end(ctx, EXCP_RI);
4c789546
YK
18701 break;
18702 }
18703
18704 tcg_temp_free_i32(twd);
18705 tcg_temp_free_i32(tws);
18706 tcg_temp_free_i32(ti8);
18707}
18708
80e71591
YK
18709static void gen_msa_i5(CPUMIPSState *env, DisasContext *ctx)
18710{
18711#define MASK_MSA_I5(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
18712 uint8_t df = (ctx->opcode >> 21) & 0x3;
18713 int8_t s5 = (int8_t) sextract32(ctx->opcode, 16, 5);
18714 uint8_t u5 = (ctx->opcode >> 16) & 0x1f;
18715 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18716 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18717
18718 TCGv_i32 tdf = tcg_const_i32(df);
18719 TCGv_i32 twd = tcg_const_i32(wd);
18720 TCGv_i32 tws = tcg_const_i32(ws);
18721 TCGv_i32 timm = tcg_temp_new_i32();
18722 tcg_gen_movi_i32(timm, u5);
18723
18724 switch (MASK_MSA_I5(ctx->opcode)) {
18725 case OPC_ADDVI_df:
18726 gen_helper_msa_addvi_df(cpu_env, tdf, twd, tws, timm);
18727 break;
18728 case OPC_SUBVI_df:
18729 gen_helper_msa_subvi_df(cpu_env, tdf, twd, tws, timm);
18730 break;
18731 case OPC_MAXI_S_df:
18732 tcg_gen_movi_i32(timm, s5);
18733 gen_helper_msa_maxi_s_df(cpu_env, tdf, twd, tws, timm);
18734 break;
18735 case OPC_MAXI_U_df:
18736 gen_helper_msa_maxi_u_df(cpu_env, tdf, twd, tws, timm);
18737 break;
18738 case OPC_MINI_S_df:
18739 tcg_gen_movi_i32(timm, s5);
18740 gen_helper_msa_mini_s_df(cpu_env, tdf, twd, tws, timm);
18741 break;
18742 case OPC_MINI_U_df:
18743 gen_helper_msa_mini_u_df(cpu_env, tdf, twd, tws, timm);
18744 break;
18745 case OPC_CEQI_df:
18746 tcg_gen_movi_i32(timm, s5);
18747 gen_helper_msa_ceqi_df(cpu_env, tdf, twd, tws, timm);
18748 break;
18749 case OPC_CLTI_S_df:
18750 tcg_gen_movi_i32(timm, s5);
18751 gen_helper_msa_clti_s_df(cpu_env, tdf, twd, tws, timm);
18752 break;
18753 case OPC_CLTI_U_df:
18754 gen_helper_msa_clti_u_df(cpu_env, tdf, twd, tws, timm);
18755 break;
18756 case OPC_CLEI_S_df:
18757 tcg_gen_movi_i32(timm, s5);
18758 gen_helper_msa_clei_s_df(cpu_env, tdf, twd, tws, timm);
18759 break;
18760 case OPC_CLEI_U_df:
18761 gen_helper_msa_clei_u_df(cpu_env, tdf, twd, tws, timm);
18762 break;
18763 case OPC_LDI_df:
18764 {
18765 int32_t s10 = sextract32(ctx->opcode, 11, 10);
18766 tcg_gen_movi_i32(timm, s10);
18767 gen_helper_msa_ldi_df(cpu_env, tdf, twd, timm);
18768 }
18769 break;
18770 default:
18771 MIPS_INVAL("MSA instruction");
9c708c7f 18772 generate_exception_end(ctx, EXCP_RI);
80e71591
YK
18773 break;
18774 }
18775
18776 tcg_temp_free_i32(tdf);
18777 tcg_temp_free_i32(twd);
18778 tcg_temp_free_i32(tws);
18779 tcg_temp_free_i32(timm);
18780}
18781
d4cf28de
YK
18782static void gen_msa_bit(CPUMIPSState *env, DisasContext *ctx)
18783{
18784#define MASK_MSA_BIT(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
18785 uint8_t dfm = (ctx->opcode >> 16) & 0x7f;
18786 uint32_t df = 0, m = 0;
18787 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18788 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18789
18790 TCGv_i32 tdf;
18791 TCGv_i32 tm;
18792 TCGv_i32 twd;
18793 TCGv_i32 tws;
18794
18795 if ((dfm & 0x40) == 0x00) {
18796 m = dfm & 0x3f;
18797 df = DF_DOUBLE;
18798 } else if ((dfm & 0x60) == 0x40) {
18799 m = dfm & 0x1f;
18800 df = DF_WORD;
18801 } else if ((dfm & 0x70) == 0x60) {
18802 m = dfm & 0x0f;
18803 df = DF_HALF;
18804 } else if ((dfm & 0x78) == 0x70) {
18805 m = dfm & 0x7;
18806 df = DF_BYTE;
18807 } else {
9c708c7f 18808 generate_exception_end(ctx, EXCP_RI);
d4cf28de
YK
18809 return;
18810 }
18811
18812 tdf = tcg_const_i32(df);
18813 tm = tcg_const_i32(m);
18814 twd = tcg_const_i32(wd);
18815 tws = tcg_const_i32(ws);
18816
18817 switch (MASK_MSA_BIT(ctx->opcode)) {
18818 case OPC_SLLI_df:
18819 gen_helper_msa_slli_df(cpu_env, tdf, twd, tws, tm);
18820 break;
18821 case OPC_SRAI_df:
18822 gen_helper_msa_srai_df(cpu_env, tdf, twd, tws, tm);
18823 break;
18824 case OPC_SRLI_df:
18825 gen_helper_msa_srli_df(cpu_env, tdf, twd, tws, tm);
18826 break;
18827 case OPC_BCLRI_df:
18828 gen_helper_msa_bclri_df(cpu_env, tdf, twd, tws, tm);
18829 break;
18830 case OPC_BSETI_df:
18831 gen_helper_msa_bseti_df(cpu_env, tdf, twd, tws, tm);
18832 break;
18833 case OPC_BNEGI_df:
18834 gen_helper_msa_bnegi_df(cpu_env, tdf, twd, tws, tm);
18835 break;
18836 case OPC_BINSLI_df:
18837 gen_helper_msa_binsli_df(cpu_env, tdf, twd, tws, tm);
18838 break;
18839 case OPC_BINSRI_df:
18840 gen_helper_msa_binsri_df(cpu_env, tdf, twd, tws, tm);
18841 break;
18842 case OPC_SAT_S_df:
18843 gen_helper_msa_sat_s_df(cpu_env, tdf, twd, tws, tm);
18844 break;
18845 case OPC_SAT_U_df:
18846 gen_helper_msa_sat_u_df(cpu_env, tdf, twd, tws, tm);
18847 break;
18848 case OPC_SRARI_df:
18849 gen_helper_msa_srari_df(cpu_env, tdf, twd, tws, tm);
18850 break;
18851 case OPC_SRLRI_df:
18852 gen_helper_msa_srlri_df(cpu_env, tdf, twd, tws, tm);
18853 break;
18854 default:
18855 MIPS_INVAL("MSA instruction");
9c708c7f 18856 generate_exception_end(ctx, EXCP_RI);
d4cf28de
YK
18857 break;
18858 }
18859
18860 tcg_temp_free_i32(tdf);
18861 tcg_temp_free_i32(tm);
18862 tcg_temp_free_i32(twd);
18863 tcg_temp_free_i32(tws);
18864}
18865
28f99f08
YK
18866static void gen_msa_3r(CPUMIPSState *env, DisasContext *ctx)
18867{
18868#define MASK_MSA_3R(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
18869 uint8_t df = (ctx->opcode >> 21) & 0x3;
18870 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
18871 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18872 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18873
18874 TCGv_i32 tdf = tcg_const_i32(df);
18875 TCGv_i32 twd = tcg_const_i32(wd);
18876 TCGv_i32 tws = tcg_const_i32(ws);
18877 TCGv_i32 twt = tcg_const_i32(wt);
18878
18879 switch (MASK_MSA_3R(ctx->opcode)) {
18880 case OPC_SLL_df:
18881 gen_helper_msa_sll_df(cpu_env, tdf, twd, tws, twt);
18882 break;
18883 case OPC_ADDV_df:
18884 gen_helper_msa_addv_df(cpu_env, tdf, twd, tws, twt);
18885 break;
18886 case OPC_CEQ_df:
18887 gen_helper_msa_ceq_df(cpu_env, tdf, twd, tws, twt);
18888 break;
18889 case OPC_ADD_A_df:
18890 gen_helper_msa_add_a_df(cpu_env, tdf, twd, tws, twt);
18891 break;
18892 case OPC_SUBS_S_df:
18893 gen_helper_msa_subs_s_df(cpu_env, tdf, twd, tws, twt);
18894 break;
18895 case OPC_MULV_df:
18896 gen_helper_msa_mulv_df(cpu_env, tdf, twd, tws, twt);
18897 break;
18898 case OPC_SLD_df:
18899 gen_helper_msa_sld_df(cpu_env, tdf, twd, tws, twt);
18900 break;
18901 case OPC_VSHF_df:
18902 gen_helper_msa_vshf_df(cpu_env, tdf, twd, tws, twt);
18903 break;
18904 case OPC_SRA_df:
18905 gen_helper_msa_sra_df(cpu_env, tdf, twd, tws, twt);
18906 break;
18907 case OPC_SUBV_df:
18908 gen_helper_msa_subv_df(cpu_env, tdf, twd, tws, twt);
18909 break;
18910 case OPC_ADDS_A_df:
18911 gen_helper_msa_adds_a_df(cpu_env, tdf, twd, tws, twt);
18912 break;
18913 case OPC_SUBS_U_df:
18914 gen_helper_msa_subs_u_df(cpu_env, tdf, twd, tws, twt);
18915 break;
18916 case OPC_MADDV_df:
18917 gen_helper_msa_maddv_df(cpu_env, tdf, twd, tws, twt);
18918 break;
18919 case OPC_SPLAT_df:
18920 gen_helper_msa_splat_df(cpu_env, tdf, twd, tws, twt);
18921 break;
18922 case OPC_SRAR_df:
18923 gen_helper_msa_srar_df(cpu_env, tdf, twd, tws, twt);
18924 break;
18925 case OPC_SRL_df:
18926 gen_helper_msa_srl_df(cpu_env, tdf, twd, tws, twt);
18927 break;
18928 case OPC_MAX_S_df:
18929 gen_helper_msa_max_s_df(cpu_env, tdf, twd, tws, twt);
18930 break;
18931 case OPC_CLT_S_df:
18932 gen_helper_msa_clt_s_df(cpu_env, tdf, twd, tws, twt);
18933 break;
18934 case OPC_ADDS_S_df:
18935 gen_helper_msa_adds_s_df(cpu_env, tdf, twd, tws, twt);
18936 break;
18937 case OPC_SUBSUS_U_df:
18938 gen_helper_msa_subsus_u_df(cpu_env, tdf, twd, tws, twt);
18939 break;
18940 case OPC_MSUBV_df:
18941 gen_helper_msa_msubv_df(cpu_env, tdf, twd, tws, twt);
18942 break;
18943 case OPC_PCKEV_df:
18944 gen_helper_msa_pckev_df(cpu_env, tdf, twd, tws, twt);
18945 break;
18946 case OPC_SRLR_df:
18947 gen_helper_msa_srlr_df(cpu_env, tdf, twd, tws, twt);
18948 break;
18949 case OPC_BCLR_df:
18950 gen_helper_msa_bclr_df(cpu_env, tdf, twd, tws, twt);
18951 break;
18952 case OPC_MAX_U_df:
18953 gen_helper_msa_max_u_df(cpu_env, tdf, twd, tws, twt);
18954 break;
18955 case OPC_CLT_U_df:
18956 gen_helper_msa_clt_u_df(cpu_env, tdf, twd, tws, twt);
18957 break;
18958 case OPC_ADDS_U_df:
18959 gen_helper_msa_adds_u_df(cpu_env, tdf, twd, tws, twt);
18960 break;
18961 case OPC_SUBSUU_S_df:
18962 gen_helper_msa_subsuu_s_df(cpu_env, tdf, twd, tws, twt);
18963 break;
18964 case OPC_PCKOD_df:
18965 gen_helper_msa_pckod_df(cpu_env, tdf, twd, tws, twt);
18966 break;
18967 case OPC_BSET_df:
18968 gen_helper_msa_bset_df(cpu_env, tdf, twd, tws, twt);
18969 break;
18970 case OPC_MIN_S_df:
18971 gen_helper_msa_min_s_df(cpu_env, tdf, twd, tws, twt);
18972 break;
18973 case OPC_CLE_S_df:
18974 gen_helper_msa_cle_s_df(cpu_env, tdf, twd, tws, twt);
18975 break;
18976 case OPC_AVE_S_df:
18977 gen_helper_msa_ave_s_df(cpu_env, tdf, twd, tws, twt);
18978 break;
18979 case OPC_ASUB_S_df:
18980 gen_helper_msa_asub_s_df(cpu_env, tdf, twd, tws, twt);
18981 break;
18982 case OPC_DIV_S_df:
18983 gen_helper_msa_div_s_df(cpu_env, tdf, twd, tws, twt);
18984 break;
18985 case OPC_ILVL_df:
18986 gen_helper_msa_ilvl_df(cpu_env, tdf, twd, tws, twt);
18987 break;
18988 case OPC_BNEG_df:
18989 gen_helper_msa_bneg_df(cpu_env, tdf, twd, tws, twt);
18990 break;
18991 case OPC_MIN_U_df:
18992 gen_helper_msa_min_u_df(cpu_env, tdf, twd, tws, twt);
18993 break;
18994 case OPC_CLE_U_df:
18995 gen_helper_msa_cle_u_df(cpu_env, tdf, twd, tws, twt);
18996 break;
18997 case OPC_AVE_U_df:
18998 gen_helper_msa_ave_u_df(cpu_env, tdf, twd, tws, twt);
18999 break;
19000 case OPC_ASUB_U_df:
19001 gen_helper_msa_asub_u_df(cpu_env, tdf, twd, tws, twt);
19002 break;
19003 case OPC_DIV_U_df:
19004 gen_helper_msa_div_u_df(cpu_env, tdf, twd, tws, twt);
19005 break;
19006 case OPC_ILVR_df:
19007 gen_helper_msa_ilvr_df(cpu_env, tdf, twd, tws, twt);
19008 break;
19009 case OPC_BINSL_df:
19010 gen_helper_msa_binsl_df(cpu_env, tdf, twd, tws, twt);
19011 break;
19012 case OPC_MAX_A_df:
19013 gen_helper_msa_max_a_df(cpu_env, tdf, twd, tws, twt);
19014 break;
19015 case OPC_AVER_S_df:
19016 gen_helper_msa_aver_s_df(cpu_env, tdf, twd, tws, twt);
19017 break;
19018 case OPC_MOD_S_df:
19019 gen_helper_msa_mod_s_df(cpu_env, tdf, twd, tws, twt);
19020 break;
19021 case OPC_ILVEV_df:
19022 gen_helper_msa_ilvev_df(cpu_env, tdf, twd, tws, twt);
19023 break;
19024 case OPC_BINSR_df:
19025 gen_helper_msa_binsr_df(cpu_env, tdf, twd, tws, twt);
19026 break;
19027 case OPC_MIN_A_df:
19028 gen_helper_msa_min_a_df(cpu_env, tdf, twd, tws, twt);
19029 break;
19030 case OPC_AVER_U_df:
19031 gen_helper_msa_aver_u_df(cpu_env, tdf, twd, tws, twt);
19032 break;
19033 case OPC_MOD_U_df:
19034 gen_helper_msa_mod_u_df(cpu_env, tdf, twd, tws, twt);
19035 break;
19036 case OPC_ILVOD_df:
19037 gen_helper_msa_ilvod_df(cpu_env, tdf, twd, tws, twt);
19038 break;
19039
19040 case OPC_DOTP_S_df:
19041 case OPC_DOTP_U_df:
19042 case OPC_DPADD_S_df:
19043 case OPC_DPADD_U_df:
19044 case OPC_DPSUB_S_df:
19045 case OPC_HADD_S_df:
19046 case OPC_DPSUB_U_df:
19047 case OPC_HADD_U_df:
19048 case OPC_HSUB_S_df:
19049 case OPC_HSUB_U_df:
19050 if (df == DF_BYTE) {
9c708c7f
PD
19051 generate_exception_end(ctx, EXCP_RI);
19052 break;
28f99f08
YK
19053 }
19054 switch (MASK_MSA_3R(ctx->opcode)) {
19055 case OPC_DOTP_S_df:
19056 gen_helper_msa_dotp_s_df(cpu_env, tdf, twd, tws, twt);
19057 break;
19058 case OPC_DOTP_U_df:
19059 gen_helper_msa_dotp_u_df(cpu_env, tdf, twd, tws, twt);
19060 break;
19061 case OPC_DPADD_S_df:
19062 gen_helper_msa_dpadd_s_df(cpu_env, tdf, twd, tws, twt);
19063 break;
19064 case OPC_DPADD_U_df:
19065 gen_helper_msa_dpadd_u_df(cpu_env, tdf, twd, tws, twt);
19066 break;
19067 case OPC_DPSUB_S_df:
19068 gen_helper_msa_dpsub_s_df(cpu_env, tdf, twd, tws, twt);
19069 break;
19070 case OPC_HADD_S_df:
19071 gen_helper_msa_hadd_s_df(cpu_env, tdf, twd, tws, twt);
19072 break;
19073 case OPC_DPSUB_U_df:
19074 gen_helper_msa_dpsub_u_df(cpu_env, tdf, twd, tws, twt);
19075 break;
19076 case OPC_HADD_U_df:
19077 gen_helper_msa_hadd_u_df(cpu_env, tdf, twd, tws, twt);
19078 break;
19079 case OPC_HSUB_S_df:
19080 gen_helper_msa_hsub_s_df(cpu_env, tdf, twd, tws, twt);
19081 break;
19082 case OPC_HSUB_U_df:
19083 gen_helper_msa_hsub_u_df(cpu_env, tdf, twd, tws, twt);
19084 break;
19085 }
19086 break;
19087 default:
19088 MIPS_INVAL("MSA instruction");
9c708c7f 19089 generate_exception_end(ctx, EXCP_RI);
28f99f08
YK
19090 break;
19091 }
19092 tcg_temp_free_i32(twd);
19093 tcg_temp_free_i32(tws);
19094 tcg_temp_free_i32(twt);
19095 tcg_temp_free_i32(tdf);
19096}
19097
1e608ec1
YK
19098static void gen_msa_elm_3e(CPUMIPSState *env, DisasContext *ctx)
19099{
19100#define MASK_MSA_ELM_DF3E(op) (MASK_MSA_MINOR(op) | (op & (0x3FF << 16)))
19101 uint8_t source = (ctx->opcode >> 11) & 0x1f;
19102 uint8_t dest = (ctx->opcode >> 6) & 0x1f;
19103 TCGv telm = tcg_temp_new();
19104 TCGv_i32 tsr = tcg_const_i32(source);
19105 TCGv_i32 tdt = tcg_const_i32(dest);
19106
19107 switch (MASK_MSA_ELM_DF3E(ctx->opcode)) {
19108 case OPC_CTCMSA:
19109 gen_load_gpr(telm, source);
19110 gen_helper_msa_ctcmsa(cpu_env, telm, tdt);
19111 break;
19112 case OPC_CFCMSA:
19113 gen_helper_msa_cfcmsa(telm, cpu_env, tsr);
19114 gen_store_gpr(telm, dest);
19115 break;
19116 case OPC_MOVE_V:
19117 gen_helper_msa_move_v(cpu_env, tdt, tsr);
19118 break;
19119 default:
19120 MIPS_INVAL("MSA instruction");
9c708c7f 19121 generate_exception_end(ctx, EXCP_RI);
1e608ec1
YK
19122 break;
19123 }
19124
19125 tcg_temp_free(telm);
19126 tcg_temp_free_i32(tdt);
19127 tcg_temp_free_i32(tsr);
19128}
19129
19130static void gen_msa_elm_df(CPUMIPSState *env, DisasContext *ctx, uint32_t df,
19131 uint32_t n)
19132{
19133#define MASK_MSA_ELM(op) (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
19134 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
19135 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
19136
19137 TCGv_i32 tws = tcg_const_i32(ws);
19138 TCGv_i32 twd = tcg_const_i32(wd);
19139 TCGv_i32 tn = tcg_const_i32(n);
19140 TCGv_i32 tdf = tcg_const_i32(df);
19141
19142 switch (MASK_MSA_ELM(ctx->opcode)) {
19143 case OPC_SLDI_df:
19144 gen_helper_msa_sldi_df(cpu_env, tdf, twd, tws, tn);
19145 break;
19146 case OPC_SPLATI_df:
19147 gen_helper_msa_splati_df(cpu_env, tdf, twd, tws, tn);
19148 break;
19149 case OPC_INSVE_df:
19150 gen_helper_msa_insve_df(cpu_env, tdf, twd, tws, tn);
19151 break;
19152 case OPC_COPY_S_df:
19153 case OPC_COPY_U_df:
19154 case OPC_INSERT_df:
19155#if !defined(TARGET_MIPS64)
19156 /* Double format valid only for MIPS64 */
19157 if (df == DF_DOUBLE) {
9c708c7f 19158 generate_exception_end(ctx, EXCP_RI);
1e608ec1
YK
19159 break;
19160 }
19161#endif
19162 switch (MASK_MSA_ELM(ctx->opcode)) {
19163 case OPC_COPY_S_df:
cab48881
MD
19164 if (likely(wd != 0)) {
19165 gen_helper_msa_copy_s_df(cpu_env, tdf, twd, tws, tn);
19166 }
1e608ec1
YK
19167 break;
19168 case OPC_COPY_U_df:
cab48881
MD
19169 if (likely(wd != 0)) {
19170 gen_helper_msa_copy_u_df(cpu_env, tdf, twd, tws, tn);
19171 }
1e608ec1
YK
19172 break;
19173 case OPC_INSERT_df:
19174 gen_helper_msa_insert_df(cpu_env, tdf, twd, tws, tn);
19175 break;
19176 }
19177 break;
19178 default:
19179 MIPS_INVAL("MSA instruction");
9c708c7f 19180 generate_exception_end(ctx, EXCP_RI);
1e608ec1
YK
19181 }
19182 tcg_temp_free_i32(twd);
19183 tcg_temp_free_i32(tws);
19184 tcg_temp_free_i32(tn);
19185 tcg_temp_free_i32(tdf);
19186}
19187
19188static void gen_msa_elm(CPUMIPSState *env, DisasContext *ctx)
19189{
19190 uint8_t dfn = (ctx->opcode >> 16) & 0x3f;
19191 uint32_t df = 0, n = 0;
19192
19193 if ((dfn & 0x30) == 0x00) {
19194 n = dfn & 0x0f;
19195 df = DF_BYTE;
19196 } else if ((dfn & 0x38) == 0x20) {
19197 n = dfn & 0x07;
19198 df = DF_HALF;
19199 } else if ((dfn & 0x3c) == 0x30) {
19200 n = dfn & 0x03;
19201 df = DF_WORD;
19202 } else if ((dfn & 0x3e) == 0x38) {
19203 n = dfn & 0x01;
19204 df = DF_DOUBLE;
19205 } else if (dfn == 0x3E) {
19206 /* CTCMSA, CFCMSA, MOVE.V */
19207 gen_msa_elm_3e(env, ctx);
19208 return;
19209 } else {
9c708c7f 19210 generate_exception_end(ctx, EXCP_RI);
1e608ec1
YK
19211 return;
19212 }
19213
19214 gen_msa_elm_df(env, ctx, df, n);
19215}
19216
7d05b9c8
YK
19217static void gen_msa_3rf(CPUMIPSState *env, DisasContext *ctx)
19218{
19219#define MASK_MSA_3RF(op) (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
19220 uint8_t df = (ctx->opcode >> 21) & 0x1;
19221 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
19222 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
19223 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
19224
19225 TCGv_i32 twd = tcg_const_i32(wd);
19226 TCGv_i32 tws = tcg_const_i32(ws);
19227 TCGv_i32 twt = tcg_const_i32(wt);
19228 TCGv_i32 tdf = tcg_temp_new_i32();
19229
19230 /* adjust df value for floating-point instruction */
19231 tcg_gen_movi_i32(tdf, df + 2);
19232
19233 switch (MASK_MSA_3RF(ctx->opcode)) {
19234 case OPC_FCAF_df:
19235 gen_helper_msa_fcaf_df(cpu_env, tdf, twd, tws, twt);
19236 break;
19237 case OPC_FADD_df:
19238 gen_helper_msa_fadd_df(cpu_env, tdf, twd, tws, twt);
19239 break;
19240 case OPC_FCUN_df:
19241 gen_helper_msa_fcun_df(cpu_env, tdf, twd, tws, twt);
19242 break;
19243 case OPC_FSUB_df:
19244 gen_helper_msa_fsub_df(cpu_env, tdf, twd, tws, twt);
19245 break;
19246 case OPC_FCOR_df:
19247 gen_helper_msa_fcor_df(cpu_env, tdf, twd, tws, twt);
19248 break;
19249 case OPC_FCEQ_df:
19250 gen_helper_msa_fceq_df(cpu_env, tdf, twd, tws, twt);
19251 break;
19252 case OPC_FMUL_df:
19253 gen_helper_msa_fmul_df(cpu_env, tdf, twd, tws, twt);
19254 break;
19255 case OPC_FCUNE_df:
19256 gen_helper_msa_fcune_df(cpu_env, tdf, twd, tws, twt);
19257 break;
19258 case OPC_FCUEQ_df:
19259 gen_helper_msa_fcueq_df(cpu_env, tdf, twd, tws, twt);
19260 break;
19261 case OPC_FDIV_df:
19262 gen_helper_msa_fdiv_df(cpu_env, tdf, twd, tws, twt);
19263 break;
19264 case OPC_FCNE_df:
19265 gen_helper_msa_fcne_df(cpu_env, tdf, twd, tws, twt);
19266 break;
19267 case OPC_FCLT_df:
19268 gen_helper_msa_fclt_df(cpu_env, tdf, twd, tws, twt);
19269 break;
19270 case OPC_FMADD_df:
19271 gen_helper_msa_fmadd_df(cpu_env, tdf, twd, tws, twt);
19272 break;
19273 case OPC_MUL_Q_df:
19274 tcg_gen_movi_i32(tdf, df + 1);
19275 gen_helper_msa_mul_q_df(cpu_env, tdf, twd, tws, twt);
19276 break;
19277 case OPC_FCULT_df:
19278 gen_helper_msa_fcult_df(cpu_env, tdf, twd, tws, twt);
19279 break;
19280 case OPC_FMSUB_df:
19281 gen_helper_msa_fmsub_df(cpu_env, tdf, twd, tws, twt);
19282 break;
19283 case OPC_MADD_Q_df:
19284 tcg_gen_movi_i32(tdf, df + 1);
19285 gen_helper_msa_madd_q_df(cpu_env, tdf, twd, tws, twt);
19286 break;
19287 case OPC_FCLE_df:
19288 gen_helper_msa_fcle_df(cpu_env, tdf, twd, tws, twt);
19289 break;
19290 case OPC_MSUB_Q_df:
19291 tcg_gen_movi_i32(tdf, df + 1);
19292 gen_helper_msa_msub_q_df(cpu_env, tdf, twd, tws, twt);
19293 break;
19294 case OPC_FCULE_df:
19295 gen_helper_msa_fcule_df(cpu_env, tdf, twd, tws, twt);
19296 break;
19297 case OPC_FEXP2_df:
19298 gen_helper_msa_fexp2_df(cpu_env, tdf, twd, tws, twt);
19299 break;
19300 case OPC_FSAF_df:
19301 gen_helper_msa_fsaf_df(cpu_env, tdf, twd, tws, twt);
19302 break;
19303 case OPC_FEXDO_df:
19304 gen_helper_msa_fexdo_df(cpu_env, tdf, twd, tws, twt);
19305 break;
19306 case OPC_FSUN_df:
19307 gen_helper_msa_fsun_df(cpu_env, tdf, twd, tws, twt);
19308 break;
19309 case OPC_FSOR_df:
19310 gen_helper_msa_fsor_df(cpu_env, tdf, twd, tws, twt);
19311 break;
19312 case OPC_FSEQ_df:
19313 gen_helper_msa_fseq_df(cpu_env, tdf, twd, tws, twt);
19314 break;
19315 case OPC_FTQ_df:
19316 gen_helper_msa_ftq_df(cpu_env, tdf, twd, tws, twt);
19317 break;
19318 case OPC_FSUNE_df:
19319 gen_helper_msa_fsune_df(cpu_env, tdf, twd, tws, twt);
19320 break;
19321 case OPC_FSUEQ_df:
19322 gen_helper_msa_fsueq_df(cpu_env, tdf, twd, tws, twt);
19323 break;
19324 case OPC_FSNE_df:
19325 gen_helper_msa_fsne_df(cpu_env, tdf, twd, tws, twt);
19326 break;
19327 case OPC_FSLT_df:
19328 gen_helper_msa_fslt_df(cpu_env, tdf, twd, tws, twt);
19329 break;
19330 case OPC_FMIN_df:
19331 gen_helper_msa_fmin_df(cpu_env, tdf, twd, tws, twt);
19332 break;
19333 case OPC_MULR_Q_df:
19334 tcg_gen_movi_i32(tdf, df + 1);
19335 gen_helper_msa_mulr_q_df(cpu_env, tdf, twd, tws, twt);
19336 break;
19337 case OPC_FSULT_df:
19338 gen_helper_msa_fsult_df(cpu_env, tdf, twd, tws, twt);
19339 break;
19340 case OPC_FMIN_A_df:
19341 gen_helper_msa_fmin_a_df(cpu_env, tdf, twd, tws, twt);
19342 break;
19343 case OPC_MADDR_Q_df:
19344 tcg_gen_movi_i32(tdf, df + 1);
19345 gen_helper_msa_maddr_q_df(cpu_env, tdf, twd, tws, twt);
19346 break;
19347 case OPC_FSLE_df:
19348 gen_helper_msa_fsle_df(cpu_env, tdf, twd, tws, twt);
19349 break;
19350 case OPC_FMAX_df:
19351 gen_helper_msa_fmax_df(cpu_env, tdf, twd, tws, twt);
19352 break;
19353 case OPC_MSUBR_Q_df:
19354 tcg_gen_movi_i32(tdf, df + 1);
19355 gen_helper_msa_msubr_q_df(cpu_env, tdf, twd, tws, twt);
19356 break;
19357 case OPC_FSULE_df:
19358 gen_helper_msa_fsule_df(cpu_env, tdf, twd, tws, twt);
19359 break;
19360 case OPC_FMAX_A_df:
19361 gen_helper_msa_fmax_a_df(cpu_env, tdf, twd, tws, twt);
19362 break;
19363 default:
19364 MIPS_INVAL("MSA instruction");
9c708c7f 19365 generate_exception_end(ctx, EXCP_RI);
7d05b9c8
YK
19366 break;
19367 }
19368
19369 tcg_temp_free_i32(twd);
19370 tcg_temp_free_i32(tws);
19371 tcg_temp_free_i32(twt);
19372 tcg_temp_free_i32(tdf);
19373}
19374
cbe50b9a
YK
19375static void gen_msa_2r(CPUMIPSState *env, DisasContext *ctx)
19376{
19377#define MASK_MSA_2R(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
19378 (op & (0x7 << 18)))
19379 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
19380 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
19381 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
19382 uint8_t df = (ctx->opcode >> 16) & 0x3;
19383 TCGv_i32 twd = tcg_const_i32(wd);
19384 TCGv_i32 tws = tcg_const_i32(ws);
19385 TCGv_i32 twt = tcg_const_i32(wt);
19386 TCGv_i32 tdf = tcg_const_i32(df);
19387
19388 switch (MASK_MSA_2R(ctx->opcode)) {
19389 case OPC_FILL_df:
19390#if !defined(TARGET_MIPS64)
19391 /* Double format valid only for MIPS64 */
19392 if (df == DF_DOUBLE) {
9c708c7f 19393 generate_exception_end(ctx, EXCP_RI);
cbe50b9a
YK
19394 break;
19395 }
19396#endif
19397 gen_helper_msa_fill_df(cpu_env, tdf, twd, tws); /* trs */
19398 break;
19399 case OPC_PCNT_df:
19400 gen_helper_msa_pcnt_df(cpu_env, tdf, twd, tws);
19401 break;
19402 case OPC_NLOC_df:
19403 gen_helper_msa_nloc_df(cpu_env, tdf, twd, tws);
19404 break;
19405 case OPC_NLZC_df:
19406 gen_helper_msa_nlzc_df(cpu_env, tdf, twd, tws);
19407 break;
19408 default:
19409 MIPS_INVAL("MSA instruction");
9c708c7f 19410 generate_exception_end(ctx, EXCP_RI);
cbe50b9a
YK
19411 break;
19412 }
19413
19414 tcg_temp_free_i32(twd);
19415 tcg_temp_free_i32(tws);
19416 tcg_temp_free_i32(twt);
19417 tcg_temp_free_i32(tdf);
19418}
19419
3bdeb688
YK
19420static void gen_msa_2rf(CPUMIPSState *env, DisasContext *ctx)
19421{
19422#define MASK_MSA_2RF(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
19423 (op & (0xf << 17)))
19424 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
19425 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
19426 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
19427 uint8_t df = (ctx->opcode >> 16) & 0x1;
19428 TCGv_i32 twd = tcg_const_i32(wd);
19429 TCGv_i32 tws = tcg_const_i32(ws);
19430 TCGv_i32 twt = tcg_const_i32(wt);
19431 /* adjust df value for floating-point instruction */
19432 TCGv_i32 tdf = tcg_const_i32(df + 2);
19433
19434 switch (MASK_MSA_2RF(ctx->opcode)) {
19435 case OPC_FCLASS_df:
19436 gen_helper_msa_fclass_df(cpu_env, tdf, twd, tws);
19437 break;
19438 case OPC_FTRUNC_S_df:
19439 gen_helper_msa_ftrunc_s_df(cpu_env, tdf, twd, tws);
19440 break;
19441 case OPC_FTRUNC_U_df:
19442 gen_helper_msa_ftrunc_u_df(cpu_env, tdf, twd, tws);
19443 break;
19444 case OPC_FSQRT_df:
19445 gen_helper_msa_fsqrt_df(cpu_env, tdf, twd, tws);
19446 break;
19447 case OPC_FRSQRT_df:
19448 gen_helper_msa_frsqrt_df(cpu_env, tdf, twd, tws);
19449 break;
19450 case OPC_FRCP_df:
19451 gen_helper_msa_frcp_df(cpu_env, tdf, twd, tws);
19452 break;
19453 case OPC_FRINT_df:
19454 gen_helper_msa_frint_df(cpu_env, tdf, twd, tws);
19455 break;
19456 case OPC_FLOG2_df:
19457 gen_helper_msa_flog2_df(cpu_env, tdf, twd, tws);
19458 break;
19459 case OPC_FEXUPL_df:
19460 gen_helper_msa_fexupl_df(cpu_env, tdf, twd, tws);
19461 break;
19462 case OPC_FEXUPR_df:
19463 gen_helper_msa_fexupr_df(cpu_env, tdf, twd, tws);
19464 break;
19465 case OPC_FFQL_df:
19466 gen_helper_msa_ffql_df(cpu_env, tdf, twd, tws);
19467 break;
19468 case OPC_FFQR_df:
19469 gen_helper_msa_ffqr_df(cpu_env, tdf, twd, tws);
19470 break;
19471 case OPC_FTINT_S_df:
19472 gen_helper_msa_ftint_s_df(cpu_env, tdf, twd, tws);
19473 break;
19474 case OPC_FTINT_U_df:
19475 gen_helper_msa_ftint_u_df(cpu_env, tdf, twd, tws);
19476 break;
19477 case OPC_FFINT_S_df:
19478 gen_helper_msa_ffint_s_df(cpu_env, tdf, twd, tws);
19479 break;
19480 case OPC_FFINT_U_df:
19481 gen_helper_msa_ffint_u_df(cpu_env, tdf, twd, tws);
19482 break;
19483 }
19484
19485 tcg_temp_free_i32(twd);
19486 tcg_temp_free_i32(tws);
19487 tcg_temp_free_i32(twt);
19488 tcg_temp_free_i32(tdf);
19489}
19490
cbe50b9a
YK
19491static void gen_msa_vec_v(CPUMIPSState *env, DisasContext *ctx)
19492{
19493#define MASK_MSA_VEC(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)))
19494 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
19495 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
19496 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
19497 TCGv_i32 twd = tcg_const_i32(wd);
19498 TCGv_i32 tws = tcg_const_i32(ws);
19499 TCGv_i32 twt = tcg_const_i32(wt);
19500
19501 switch (MASK_MSA_VEC(ctx->opcode)) {
19502 case OPC_AND_V:
19503 gen_helper_msa_and_v(cpu_env, twd, tws, twt);
19504 break;
19505 case OPC_OR_V:
19506 gen_helper_msa_or_v(cpu_env, twd, tws, twt);
19507 break;
19508 case OPC_NOR_V:
19509 gen_helper_msa_nor_v(cpu_env, twd, tws, twt);
19510 break;
19511 case OPC_XOR_V:
19512 gen_helper_msa_xor_v(cpu_env, twd, tws, twt);
19513 break;
19514 case OPC_BMNZ_V:
19515 gen_helper_msa_bmnz_v(cpu_env, twd, tws, twt);
19516 break;
19517 case OPC_BMZ_V:
19518 gen_helper_msa_bmz_v(cpu_env, twd, tws, twt);
19519 break;
19520 case OPC_BSEL_V:
19521 gen_helper_msa_bsel_v(cpu_env, twd, tws, twt);
19522 break;
19523 default:
19524 MIPS_INVAL("MSA instruction");
9c708c7f 19525 generate_exception_end(ctx, EXCP_RI);
cbe50b9a
YK
19526 break;
19527 }
19528
19529 tcg_temp_free_i32(twd);
19530 tcg_temp_free_i32(tws);
19531 tcg_temp_free_i32(twt);
19532}
19533
19534static void gen_msa_vec(CPUMIPSState *env, DisasContext *ctx)
19535{
19536 switch (MASK_MSA_VEC(ctx->opcode)) {
19537 case OPC_AND_V:
19538 case OPC_OR_V:
19539 case OPC_NOR_V:
19540 case OPC_XOR_V:
19541 case OPC_BMNZ_V:
19542 case OPC_BMZ_V:
19543 case OPC_BSEL_V:
19544 gen_msa_vec_v(env, ctx);
19545 break;
19546 case OPC_MSA_2R:
19547 gen_msa_2r(env, ctx);
19548 break;
3bdeb688
YK
19549 case OPC_MSA_2RF:
19550 gen_msa_2rf(env, ctx);
19551 break;
cbe50b9a
YK
19552 default:
19553 MIPS_INVAL("MSA instruction");
9c708c7f 19554 generate_exception_end(ctx, EXCP_RI);
cbe50b9a
YK
19555 break;
19556 }
19557}
19558
4c789546
YK
19559static void gen_msa(CPUMIPSState *env, DisasContext *ctx)
19560{
19561 uint32_t opcode = ctx->opcode;
19562 check_insn(ctx, ASE_MSA);
19563 check_msa_access(ctx);
19564
19565 switch (MASK_MSA_MINOR(opcode)) {
19566 case OPC_MSA_I8_00:
19567 case OPC_MSA_I8_01:
19568 case OPC_MSA_I8_02:
19569 gen_msa_i8(env, ctx);
19570 break;
80e71591
YK
19571 case OPC_MSA_I5_06:
19572 case OPC_MSA_I5_07:
19573 gen_msa_i5(env, ctx);
19574 break;
d4cf28de
YK
19575 case OPC_MSA_BIT_09:
19576 case OPC_MSA_BIT_0A:
19577 gen_msa_bit(env, ctx);
19578 break;
28f99f08
YK
19579 case OPC_MSA_3R_0D:
19580 case OPC_MSA_3R_0E:
19581 case OPC_MSA_3R_0F:
19582 case OPC_MSA_3R_10:
19583 case OPC_MSA_3R_11:
19584 case OPC_MSA_3R_12:
19585 case OPC_MSA_3R_13:
19586 case OPC_MSA_3R_14:
19587 case OPC_MSA_3R_15:
19588 gen_msa_3r(env, ctx);
19589 break;
1e608ec1
YK
19590 case OPC_MSA_ELM:
19591 gen_msa_elm(env, ctx);
19592 break;
7d05b9c8
YK
19593 case OPC_MSA_3RF_1A:
19594 case OPC_MSA_3RF_1B:
19595 case OPC_MSA_3RF_1C:
19596 gen_msa_3rf(env, ctx);
19597 break;
cbe50b9a
YK
19598 case OPC_MSA_VEC:
19599 gen_msa_vec(env, ctx);
19600 break;
f7685877
YK
19601 case OPC_LD_B:
19602 case OPC_LD_H:
19603 case OPC_LD_W:
19604 case OPC_LD_D:
19605 case OPC_ST_B:
19606 case OPC_ST_H:
19607 case OPC_ST_W:
19608 case OPC_ST_D:
19609 {
19610 int32_t s10 = sextract32(ctx->opcode, 16, 10);
19611 uint8_t rs = (ctx->opcode >> 11) & 0x1f;
19612 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
19613 uint8_t df = (ctx->opcode >> 0) & 0x3;
19614
f7685877 19615 TCGv_i32 twd = tcg_const_i32(wd);
adc370a4
YK
19616 TCGv taddr = tcg_temp_new();
19617 gen_base_offset_addr(ctx, taddr, rs, s10 << df);
f7685877
YK
19618
19619 switch (MASK_MSA_MINOR(opcode)) {
19620 case OPC_LD_B:
adc370a4
YK
19621 gen_helper_msa_ld_b(cpu_env, twd, taddr);
19622 break;
f7685877 19623 case OPC_LD_H:
adc370a4
YK
19624 gen_helper_msa_ld_h(cpu_env, twd, taddr);
19625 break;
f7685877 19626 case OPC_LD_W:
adc370a4
YK
19627 gen_helper_msa_ld_w(cpu_env, twd, taddr);
19628 break;
f7685877 19629 case OPC_LD_D:
adc370a4 19630 gen_helper_msa_ld_d(cpu_env, twd, taddr);
f7685877
YK
19631 break;
19632 case OPC_ST_B:
adc370a4
YK
19633 gen_helper_msa_st_b(cpu_env, twd, taddr);
19634 break;
f7685877 19635 case OPC_ST_H:
adc370a4
YK
19636 gen_helper_msa_st_h(cpu_env, twd, taddr);
19637 break;
f7685877 19638 case OPC_ST_W:
adc370a4
YK
19639 gen_helper_msa_st_w(cpu_env, twd, taddr);
19640 break;
f7685877 19641 case OPC_ST_D:
adc370a4 19642 gen_helper_msa_st_d(cpu_env, twd, taddr);
f7685877
YK
19643 break;
19644 }
19645
19646 tcg_temp_free_i32(twd);
adc370a4 19647 tcg_temp_free(taddr);
f7685877
YK
19648 }
19649 break;
4c789546
YK
19650 default:
19651 MIPS_INVAL("MSA instruction");
9c708c7f 19652 generate_exception_end(ctx, EXCP_RI);
4c789546
YK
19653 break;
19654 }
19655
19656}
19657
d2bfa6e6 19658static void decode_opc(CPUMIPSState *env, DisasContext *ctx)
099e5b4d
LA
19659{
19660 int32_t offset;
19661 int rs, rt, rd, sa;
19662 uint32_t op, op1;
19663 int16_t imm;
19664
19665 /* make sure instructions are on a word boundary */
eeb3bba8
EC
19666 if (ctx->base.pc_next & 0x3) {
19667 env->CP0_BadVAddr = ctx->base.pc_next;
aea14095 19668 generate_exception_err(ctx, EXCP_AdEL, EXCP_INST_NOTAVAIL);
099e5b4d
LA
19669 return;
19670 }
19671
19672 /* Handle blikely not taken case */
19673 if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
42a268c2 19674 TCGLabel *l1 = gen_new_label();
099e5b4d 19675
099e5b4d
LA
19676 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
19677 tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
eeb3bba8 19678 gen_goto_tb(ctx, 1, ctx->base.pc_next + 4);
099e5b4d
LA
19679 gen_set_label(l1);
19680 }
19681
099e5b4d
LA
19682 op = MASK_OP_MAJOR(ctx->opcode);
19683 rs = (ctx->opcode >> 21) & 0x1f;
19684 rt = (ctx->opcode >> 16) & 0x1f;
19685 rd = (ctx->opcode >> 11) & 0x1f;
19686 sa = (ctx->opcode >> 6) & 0x1f;
19687 imm = (int16_t)ctx->opcode;
19688 switch (op) {
19689 case OPC_SPECIAL:
19690 decode_opc_special(env, ctx);
19691 break;
19692 case OPC_SPECIAL2:
4267d3e6 19693 decode_opc_special2_legacy(env, ctx);
099e5b4d
LA
19694 break;
19695 case OPC_SPECIAL3:
19696 decode_opc_special3(env, ctx);
19697 break;
7a387fff
TS
19698 case OPC_REGIMM:
19699 op1 = MASK_REGIMM(ctx->opcode);
19700 switch (op1) {
fecd2646
LA
19701 case OPC_BLTZL: /* REGIMM branches */
19702 case OPC_BGEZL:
19703 case OPC_BLTZALL:
19704 case OPC_BGEZALL:
d9224450 19705 check_insn(ctx, ISA_MIPS2);
fecd2646 19706 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d9224450 19707 /* Fallthrough */
fecd2646
LA
19708 case OPC_BLTZ:
19709 case OPC_BGEZ:
b231c103 19710 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
0aefa333 19711 break;
fecd2646
LA
19712 case OPC_BLTZAL:
19713 case OPC_BGEZAL:
0aefa333
YK
19714 if (ctx->insn_flags & ISA_MIPS32R6) {
19715 if (rs == 0) {
19716 /* OPC_NAL, OPC_BAL */
b231c103 19717 gen_compute_branch(ctx, op1, 4, 0, -1, imm << 2, 4);
0aefa333 19718 } else {
9c708c7f 19719 generate_exception_end(ctx, EXCP_RI);
0aefa333
YK
19720 }
19721 } else {
b231c103 19722 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
0aefa333 19723 }
c9602061 19724 break;
c2e19f3c
AM
19725 case OPC_TGEI: /* REGIMM traps */
19726 case OPC_TGEIU:
19727 case OPC_TLTI:
19728 case OPC_TLTIU:
19729 case OPC_TEQI:
19730
7a387fff 19731 case OPC_TNEI:
d9224450 19732 check_insn(ctx, ISA_MIPS2);
fecd2646 19733 check_insn_opc_removed(ctx, ISA_MIPS32R6);
7a387fff
TS
19734 gen_trap(ctx, op1, rs, -1, imm);
19735 break;
bb238210
YK
19736 case OPC_SIGRIE:
19737 check_insn(ctx, ISA_MIPS32R6);
19738 generate_exception_end(ctx, EXCP_RI);
19739 break;
7a387fff 19740 case OPC_SYNCI:
d75c135e 19741 check_insn(ctx, ISA_MIPS32R2);
a83bddd6
DZ
19742 /* Break the TB to be able to sync copied instructions
19743 immediately */
eeb3bba8 19744 ctx->base.is_jmp = DISAS_STOP;
6af0bf9c 19745 break;
e45a93e2
JL
19746 case OPC_BPOSGE32: /* MIPS DSP branch */
19747#if defined(TARGET_MIPS64)
19748 case OPC_BPOSGE64:
19749#endif
19750 check_dsp(ctx);
b231c103 19751 gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2, 4);
e45a93e2 19752 break;
d4ea6acd
LA
19753#if defined(TARGET_MIPS64)
19754 case OPC_DAHI:
19755 check_insn(ctx, ISA_MIPS32R6);
19756 check_mips_64(ctx);
19757 if (rs != 0) {
19758 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 32);
19759 }
d4ea6acd
LA
19760 break;
19761 case OPC_DATI:
19762 check_insn(ctx, ISA_MIPS32R6);
19763 check_mips_64(ctx);
19764 if (rs != 0) {
19765 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 48);
19766 }
d4ea6acd
LA
19767 break;
19768#endif
6af0bf9c 19769 default: /* Invalid */
923617a3 19770 MIPS_INVAL("regimm");
9c708c7f 19771 generate_exception_end(ctx, EXCP_RI);
6af0bf9c
FB
19772 break;
19773 }
19774 break;
7a387fff 19775 case OPC_CP0:
387a8fe5 19776 check_cp0_enabled(ctx);
7a387fff 19777 op1 = MASK_CP0(ctx->opcode);
6af0bf9c 19778 switch (op1) {
7a387fff
TS
19779 case OPC_MFC0:
19780 case OPC_MTC0:
ead9360e
TS
19781 case OPC_MFTR:
19782 case OPC_MTTR:
5204ea79
LA
19783 case OPC_MFHC0:
19784 case OPC_MTHC0:
d26bc211 19785#if defined(TARGET_MIPS64)
7a387fff
TS
19786 case OPC_DMFC0:
19787 case OPC_DMTC0:
19788#endif
f1aa6320 19789#ifndef CONFIG_USER_ONLY
932e71cd 19790 gen_cp0(env, ctx, op1, rt, rd);
0eaef5aa 19791#endif /* !CONFIG_USER_ONLY */
7a387fff
TS
19792 break;
19793 case OPC_C0_FIRST ... OPC_C0_LAST:
f1aa6320 19794#ifndef CONFIG_USER_ONLY
932e71cd 19795 gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
0eaef5aa 19796#endif /* !CONFIG_USER_ONLY */
7a387fff
TS
19797 break;
19798 case OPC_MFMC0:
8706c382 19799#ifndef CONFIG_USER_ONLY
932e71cd 19800 {
099e5b4d 19801 uint32_t op2;
35fbce2c 19802 TCGv t0 = tcg_temp_new();
6c5c1e20 19803
0eaef5aa 19804 op2 = MASK_MFMC0(ctx->opcode);
6c5c1e20
TS
19805 switch (op2) {
19806 case OPC_DMT:
d75c135e 19807 check_insn(ctx, ASE_MT);
9ed5726c 19808 gen_helper_dmt(t0);
35fbce2c 19809 gen_store_gpr(t0, rt);
6c5c1e20
TS
19810 break;
19811 case OPC_EMT:
d75c135e 19812 check_insn(ctx, ASE_MT);
9ed5726c 19813 gen_helper_emt(t0);
35fbce2c 19814 gen_store_gpr(t0, rt);
da80682b 19815 break;
6c5c1e20 19816 case OPC_DVPE:
d75c135e 19817 check_insn(ctx, ASE_MT);
895c2d04 19818 gen_helper_dvpe(t0, cpu_env);
35fbce2c 19819 gen_store_gpr(t0, rt);
6c5c1e20
TS
19820 break;
19821 case OPC_EVPE:
d75c135e 19822 check_insn(ctx, ASE_MT);
895c2d04 19823 gen_helper_evpe(t0, cpu_env);
35fbce2c 19824 gen_store_gpr(t0, rt);
6c5c1e20 19825 break;
01bc435b
YK
19826 case OPC_DVP:
19827 check_insn(ctx, ISA_MIPS32R6);
19828 if (ctx->vp) {
19829 gen_helper_dvp(t0, cpu_env);
19830 gen_store_gpr(t0, rt);
19831 }
19832 break;
19833 case OPC_EVP:
19834 check_insn(ctx, ISA_MIPS32R6);
19835 if (ctx->vp) {
19836 gen_helper_evp(t0, cpu_env);
19837 gen_store_gpr(t0, rt);
19838 }
19839 break;
6c5c1e20 19840 case OPC_DI:
d75c135e 19841 check_insn(ctx, ISA_MIPS32R2);
867abc7e 19842 save_cpu_state(ctx, 1);
895c2d04 19843 gen_helper_di(t0, cpu_env);
35fbce2c 19844 gen_store_gpr(t0, rt);
d2bfa6e6
MR
19845 /* Stop translation as we may have switched
19846 the execution mode. */
eeb3bba8 19847 ctx->base.is_jmp = DISAS_STOP;
6c5c1e20
TS
19848 break;
19849 case OPC_EI:
d75c135e 19850 check_insn(ctx, ISA_MIPS32R2);
867abc7e 19851 save_cpu_state(ctx, 1);
895c2d04 19852 gen_helper_ei(t0, cpu_env);
35fbce2c 19853 gen_store_gpr(t0, rt);
b28425ba
EC
19854 /* DISAS_STOP isn't sufficient, we need to ensure we break
19855 out of translated code to check for pending interrupts */
eeb3bba8
EC
19856 gen_save_pc(ctx->base.pc_next + 4);
19857 ctx->base.is_jmp = DISAS_EXIT;
6c5c1e20
TS
19858 break;
19859 default: /* Invalid */
19860 MIPS_INVAL("mfmc0");
9c708c7f 19861 generate_exception_end(ctx, EXCP_RI);
6c5c1e20
TS
19862 break;
19863 }
6c5c1e20 19864 tcg_temp_free(t0);
7a387fff 19865 }
0eaef5aa 19866#endif /* !CONFIG_USER_ONLY */
6af0bf9c 19867 break;
7a387fff 19868 case OPC_RDPGPR:
d75c135e 19869 check_insn(ctx, ISA_MIPS32R2);
be24bb4f 19870 gen_load_srsgpr(rt, rd);
ead9360e 19871 break;
7a387fff 19872 case OPC_WRPGPR:
d75c135e 19873 check_insn(ctx, ISA_MIPS32R2);
be24bb4f 19874 gen_store_srsgpr(rt, rd);
38121543 19875 break;
6af0bf9c 19876 default:
923617a3 19877 MIPS_INVAL("cp0");
9c708c7f 19878 generate_exception_end(ctx, EXCP_RI);
6af0bf9c
FB
19879 break;
19880 }
19881 break;
31837be3
YK
19882 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC, OPC_ADDI */
19883 if (ctx->insn_flags & ISA_MIPS32R6) {
19884 /* OPC_BOVC, OPC_BEQZALC, OPC_BEQC */
19885 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19886 } else {
19887 /* OPC_ADDI */
19888 /* Arithmetic with immediate opcode */
19889 gen_arith_imm(ctx, op, rt, rs, imm);
19890 }
19891 break;
324d9e32 19892 case OPC_ADDIU:
d75c135e 19893 gen_arith_imm(ctx, op, rt, rs, imm);
7a387fff 19894 break;
324d9e32
AJ
19895 case OPC_SLTI: /* Set on less than with immediate opcode */
19896 case OPC_SLTIU:
d75c135e 19897 gen_slt_imm(ctx, op, rt, rs, imm);
324d9e32
AJ
19898 break;
19899 case OPC_ANDI: /* Arithmetic with immediate opcode */
d4ea6acd 19900 case OPC_LUI: /* OPC_AUI */
324d9e32
AJ
19901 case OPC_ORI:
19902 case OPC_XORI:
d75c135e 19903 gen_logic_imm(ctx, op, rt, rs, imm);
324d9e32 19904 break;
c2e19f3c
AM
19905 case OPC_J: /* Jump */
19906 case OPC_JAL:
7a387fff 19907 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
b231c103 19908 gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
c9602061 19909 break;
31837be3
YK
19910 /* Branch */
19911 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC, OPC_BLEZL */
19912 if (ctx->insn_flags & ISA_MIPS32R6) {
19913 if (rt == 0) {
9c708c7f 19914 generate_exception_end(ctx, EXCP_RI);
31837be3
YK
19915 break;
19916 }
19917 /* OPC_BLEZC, OPC_BGEZC, OPC_BGEC */
19918 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19919 } else {
19920 /* OPC_BLEZL */
b231c103 19921 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
31837be3
YK
19922 }
19923 break;
19924 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC, OPC_BGTZL */
19925 if (ctx->insn_flags & ISA_MIPS32R6) {
19926 if (rt == 0) {
9c708c7f 19927 generate_exception_end(ctx, EXCP_RI);
31837be3
YK
19928 break;
19929 }
19930 /* OPC_BGTZC, OPC_BLTZC, OPC_BLTC */
19931 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19932 } else {
19933 /* OPC_BGTZL */
b231c103 19934 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
31837be3
YK
19935 }
19936 break;
19937 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC, OPC_BLEZ */
19938 if (rt == 0) {
19939 /* OPC_BLEZ */
b231c103 19940 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
31837be3
YK
19941 } else {
19942 check_insn(ctx, ISA_MIPS32R6);
19943 /* OPC_BLEZALC, OPC_BGEZALC, OPC_BGEUC */
19944 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19945 }
19946 break;
19947 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC, OPC_BGTZ */
19948 if (rt == 0) {
19949 /* OPC_BGTZ */
b231c103 19950 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
31837be3
YK
19951 } else {
19952 check_insn(ctx, ISA_MIPS32R6);
19953 /* OPC_BGTZALC, OPC_BLTZALC, OPC_BLTUC */
19954 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19955 }
19956 break;
19957 case OPC_BEQL:
19958 case OPC_BNEL:
d9224450 19959 check_insn(ctx, ISA_MIPS2);
fecd2646 19960 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d9224450 19961 /* Fallthrough */
31837be3
YK
19962 case OPC_BEQ:
19963 case OPC_BNE:
b231c103 19964 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
c9602061 19965 break;
d9224450
MR
19966 case OPC_LL: /* Load and stores */
19967 check_insn(ctx, ISA_MIPS2);
19968 /* Fallthrough */
19969 case OPC_LWL:
fecd2646
LA
19970 case OPC_LWR:
19971 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d9224450 19972 /* Fallthrough */
c2e19f3c
AM
19973 case OPC_LB:
19974 case OPC_LH:
19975 case OPC_LW:
19976 case OPC_LWPC:
19977 case OPC_LBU:
19978 case OPC_LHU:
d75c135e 19979 gen_ld(ctx, op, rt, rs, imm);
5c13fdfd 19980 break;
fecd2646 19981 case OPC_SWL:
7a387fff 19982 case OPC_SWR:
fecd2646 19983 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b6f3b233 19984 /* fall through */
c2e19f3c
AM
19985 case OPC_SB:
19986 case OPC_SH:
fecd2646 19987 case OPC_SW:
5c13fdfd 19988 gen_st(ctx, op, rt, rs, imm);
7a387fff 19989 break;
d66c7132 19990 case OPC_SC:
d9224450 19991 check_insn(ctx, ISA_MIPS2);
4368b29a 19992 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d66c7132
AJ
19993 gen_st_cond(ctx, op, rt, rs, imm);
19994 break;
7a387fff 19995 case OPC_CACHE:
bf7910c6 19996 check_insn_opc_removed(ctx, ISA_MIPS32R6);
2e15497c 19997 check_cp0_enabled(ctx);
d75c135e 19998 check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
0d74a222
LA
19999 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
20000 gen_cache_operation(ctx, rt, rs, imm);
20001 }
ead9360e 20002 /* Treat as NOP. */
34ae7b51 20003 break;
7a387fff 20004 case OPC_PREF:
bf7910c6 20005 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d75c135e 20006 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
ead9360e 20007 /* Treat as NOP. */
6af0bf9c 20008 break;
4ad40f36 20009
923617a3 20010 /* Floating point (COP1). */
7a387fff
TS
20011 case OPC_LWC1:
20012 case OPC_LDC1:
20013 case OPC_SWC1:
20014 case OPC_SDC1:
5ab5c041 20015 gen_cop1_ldst(ctx, op, rt, rs, imm);
6ea83fed
FB
20016 break;
20017
7a387fff 20018 case OPC_CP1:
5692c6e1
YK
20019 op1 = MASK_CP1(ctx->opcode);
20020
20021 switch (op1) {
20022 case OPC_MFHC1:
20023 case OPC_MTHC1:
5e755519 20024 check_cp1_enabled(ctx);
5692c6e1
YK
20025 check_insn(ctx, ISA_MIPS32R2);
20026 case OPC_MFC1:
20027 case OPC_CFC1:
20028 case OPC_MTC1:
20029 case OPC_CTC1:
20030 check_cp1_enabled(ctx);
20031 gen_cp1(ctx, op1, rt, rd);
20032 break;
d26bc211 20033#if defined(TARGET_MIPS64)
5692c6e1
YK
20034 case OPC_DMFC1:
20035 case OPC_DMTC1:
20036 check_cp1_enabled(ctx);
20037 check_insn(ctx, ISA_MIPS3);
d9224450 20038 check_mips_64(ctx);
5692c6e1
YK
20039 gen_cp1(ctx, op1, rt, rd);
20040 break;
e189e748 20041#endif
5692c6e1
YK
20042 case OPC_BC1EQZ: /* OPC_BC1ANY2 */
20043 check_cp1_enabled(ctx);
20044 if (ctx->insn_flags & ISA_MIPS32R6) {
20045 /* OPC_BC1EQZ */
31837be3 20046 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
65935f07 20047 rt, imm << 2, 4);
5692c6e1
YK
20048 } else {
20049 /* OPC_BC1ANY2 */
b8aa4598 20050 check_cop1x(ctx);
d75c135e 20051 check_insn(ctx, ASE_MIPS3D);
d75c135e 20052 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
5a5012ec 20053 (rt >> 2) & 0x7, imm << 2);
5692c6e1
YK
20054 }
20055 break;
20056 case OPC_BC1NEZ:
20057 check_cp1_enabled(ctx);
20058 check_insn(ctx, ISA_MIPS32R6);
20059 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
65935f07 20060 rt, imm << 2, 4);
5692c6e1
YK
20061 break;
20062 case OPC_BC1ANY4:
20063 check_cp1_enabled(ctx);
20064 check_insn_opc_removed(ctx, ISA_MIPS32R6);
20065 check_cop1x(ctx);
20066 check_insn(ctx, ASE_MIPS3D);
20067 /* fall through */
20068 case OPC_BC1:
20069 check_cp1_enabled(ctx);
20070 check_insn_opc_removed(ctx, ISA_MIPS32R6);
20071 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
20072 (rt >> 2) & 0x7, imm << 2);
20073 break;
20074 case OPC_PS_FMT:
e29c9628 20075 check_ps(ctx);
b6f3b233 20076 /* fall through */
5692c6e1
YK
20077 case OPC_S_FMT:
20078 case OPC_D_FMT:
20079 check_cp1_enabled(ctx);
20080 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
20081 (imm >> 8) & 0x7);
20082 break;
20083 case OPC_W_FMT:
20084 case OPC_L_FMT:
20085 {
20086 int r6_op = ctx->opcode & FOP(0x3f, 0x1f);
20087 check_cp1_enabled(ctx);
20088 if (ctx->insn_flags & ISA_MIPS32R6) {
20089 switch (r6_op) {
20090 case R6_OPC_CMP_AF_S:
20091 case R6_OPC_CMP_UN_S:
20092 case R6_OPC_CMP_EQ_S:
20093 case R6_OPC_CMP_UEQ_S:
20094 case R6_OPC_CMP_LT_S:
20095 case R6_OPC_CMP_ULT_S:
20096 case R6_OPC_CMP_LE_S:
20097 case R6_OPC_CMP_ULE_S:
20098 case R6_OPC_CMP_SAF_S:
20099 case R6_OPC_CMP_SUN_S:
20100 case R6_OPC_CMP_SEQ_S:
20101 case R6_OPC_CMP_SEUQ_S:
20102 case R6_OPC_CMP_SLT_S:
20103 case R6_OPC_CMP_SULT_S:
20104 case R6_OPC_CMP_SLE_S:
20105 case R6_OPC_CMP_SULE_S:
20106 case R6_OPC_CMP_OR_S:
20107 case R6_OPC_CMP_UNE_S:
20108 case R6_OPC_CMP_NE_S:
20109 case R6_OPC_CMP_SOR_S:
20110 case R6_OPC_CMP_SUNE_S:
20111 case R6_OPC_CMP_SNE_S:
20112 gen_r6_cmp_s(ctx, ctx->opcode & 0x1f, rt, rd, sa);
20113 break;
20114 case R6_OPC_CMP_AF_D:
20115 case R6_OPC_CMP_UN_D:
20116 case R6_OPC_CMP_EQ_D:
20117 case R6_OPC_CMP_UEQ_D:
20118 case R6_OPC_CMP_LT_D:
20119 case R6_OPC_CMP_ULT_D:
20120 case R6_OPC_CMP_LE_D:
20121 case R6_OPC_CMP_ULE_D:
20122 case R6_OPC_CMP_SAF_D:
20123 case R6_OPC_CMP_SUN_D:
20124 case R6_OPC_CMP_SEQ_D:
20125 case R6_OPC_CMP_SEUQ_D:
20126 case R6_OPC_CMP_SLT_D:
20127 case R6_OPC_CMP_SULT_D:
20128 case R6_OPC_CMP_SLE_D:
20129 case R6_OPC_CMP_SULE_D:
20130 case R6_OPC_CMP_OR_D:
20131 case R6_OPC_CMP_UNE_D:
20132 case R6_OPC_CMP_NE_D:
20133 case R6_OPC_CMP_SOR_D:
20134 case R6_OPC_CMP_SUNE_D:
20135 case R6_OPC_CMP_SNE_D:
20136 gen_r6_cmp_d(ctx, ctx->opcode & 0x1f, rt, rd, sa);
20137 break;
20138 default:
d2bfa6e6
MR
20139 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f),
20140 rt, rd, sa, (imm >> 8) & 0x7);
20141
5692c6e1 20142 break;
3f493883 20143 }
5692c6e1
YK
20144 } else {
20145 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
20146 (imm >> 8) & 0x7);
36d23958 20147 }
5692c6e1
YK
20148 break;
20149 }
20150 case OPC_BZ_V:
20151 case OPC_BNZ_V:
20152 case OPC_BZ_B:
20153 case OPC_BZ_H:
20154 case OPC_BZ_W:
20155 case OPC_BZ_D:
20156 case OPC_BNZ_B:
20157 case OPC_BNZ_H:
20158 case OPC_BNZ_W:
20159 case OPC_BNZ_D:
20160 check_insn(ctx, ASE_MSA);
20161 gen_msa_branch(env, ctx, op1);
20162 break;
20163 default:
20164 MIPS_INVAL("cp1");
9c708c7f 20165 generate_exception_end(ctx, EXCP_RI);
5692c6e1 20166 break;
6ea83fed 20167 }
4ad40f36
FB
20168 break;
20169
31837be3
YK
20170 /* Compact branches [R6] and COP2 [non-R6] */
20171 case OPC_BC: /* OPC_LWC2 */
20172 case OPC_BALC: /* OPC_SWC2 */
20173 if (ctx->insn_flags & ISA_MIPS32R6) {
20174 /* OPC_BC, OPC_BALC */
20175 gen_compute_compact_branch(ctx, op, 0, 0,
20176 sextract32(ctx->opcode << 2, 0, 28));
20177 } else {
20178 /* OPC_LWC2, OPC_SWC2 */
20179 /* COP2: Not implemented. */
20180 generate_exception_err(ctx, EXCP_CpU, 2);
20181 }
20182 break;
20183 case OPC_BEQZC: /* OPC_JIC, OPC_LDC2 */
20184 case OPC_BNEZC: /* OPC_JIALC, OPC_SDC2 */
20185 if (ctx->insn_flags & ISA_MIPS32R6) {
20186 if (rs != 0) {
20187 /* OPC_BEQZC, OPC_BNEZC */
20188 gen_compute_compact_branch(ctx, op, rs, 0,
20189 sextract32(ctx->opcode << 2, 0, 23));
20190 } else {
20191 /* OPC_JIC, OPC_JIALC */
20192 gen_compute_compact_branch(ctx, op, 0, rt, imm);
20193 }
20194 } else {
20195 /* OPC_LWC2, OPC_SWC2 */
20196 /* COP2: Not implemented. */
20197 generate_exception_err(ctx, EXCP_CpU, 2);
20198 }
4ad40f36 20199 break;
bd277fa1 20200 case OPC_CP2:
d75c135e 20201 check_insn(ctx, INSN_LOONGSON2F);
bd277fa1
RH
20202 /* Note that these instructions use different fields. */
20203 gen_loongson_multimedia(ctx, sa, rd, rt);
20204 break;
4ad40f36 20205
7a387fff 20206 case OPC_CP3:
fecd2646 20207 check_insn_opc_removed(ctx, ISA_MIPS32R6);
5ab5c041 20208 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
5e755519 20209 check_cp1_enabled(ctx);
36d23958
TS
20210 op1 = MASK_CP3(ctx->opcode);
20211 switch (op1) {
d9224450
MR
20212 case OPC_LUXC1:
20213 case OPC_SUXC1:
20214 check_insn(ctx, ISA_MIPS5 | ISA_MIPS32R2);
20215 /* Fallthrough */
5a5012ec
TS
20216 case OPC_LWXC1:
20217 case OPC_LDXC1:
5a5012ec
TS
20218 case OPC_SWXC1:
20219 case OPC_SDXC1:
d9224450 20220 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
93b12ccc 20221 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
5a5012ec 20222 break;
e0c84da7 20223 case OPC_PREFX:
d9224450 20224 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
ead9360e 20225 /* Treat as NOP. */
e0c84da7 20226 break;
5a5012ec 20227 case OPC_ALNV_PS:
d9224450
MR
20228 check_insn(ctx, ISA_MIPS5 | ISA_MIPS32R2);
20229 /* Fallthrough */
5a5012ec
TS
20230 case OPC_MADD_S:
20231 case OPC_MADD_D:
20232 case OPC_MADD_PS:
20233 case OPC_MSUB_S:
20234 case OPC_MSUB_D:
20235 case OPC_MSUB_PS:
20236 case OPC_NMADD_S:
20237 case OPC_NMADD_D:
20238 case OPC_NMADD_PS:
20239 case OPC_NMSUB_S:
20240 case OPC_NMSUB_D:
20241 case OPC_NMSUB_PS:
d9224450 20242 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
5a5012ec
TS
20243 gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
20244 break;
36d23958 20245 default:
923617a3 20246 MIPS_INVAL("cp3");
9c708c7f 20247 generate_exception_end(ctx, EXCP_RI);
36d23958
TS
20248 break;
20249 }
20250 } else {
e397ee33 20251 generate_exception_err(ctx, EXCP_CpU, 1);
7a387fff 20252 }
4ad40f36
FB
20253 break;
20254
d26bc211 20255#if defined(TARGET_MIPS64)
7a387fff 20256 /* MIPS64 opcodes */
c2e19f3c
AM
20257 case OPC_LDL:
20258 case OPC_LDR:
bf7910c6 20259 case OPC_LLD:
fecd2646 20260 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b6f3b233 20261 /* fall through */
fecd2646 20262 case OPC_LWU:
7a387fff 20263 case OPC_LD:
d75c135e 20264 check_insn(ctx, ISA_MIPS3);
5c13fdfd 20265 check_mips_64(ctx);
d75c135e 20266 gen_ld(ctx, op, rt, rs, imm);
5c13fdfd 20267 break;
c2e19f3c
AM
20268 case OPC_SDL:
20269 case OPC_SDR:
fecd2646 20270 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b6f3b233 20271 /* fall through */
7a387fff 20272 case OPC_SD:
d75c135e 20273 check_insn(ctx, ISA_MIPS3);
e189e748 20274 check_mips_64(ctx);
5c13fdfd 20275 gen_st(ctx, op, rt, rs, imm);
7a387fff 20276 break;
d66c7132 20277 case OPC_SCD:
bf7910c6 20278 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d75c135e 20279 check_insn(ctx, ISA_MIPS3);
d66c7132
AJ
20280 check_mips_64(ctx);
20281 gen_st_cond(ctx, op, rt, rs, imm);
20282 break;
31837be3
YK
20283 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC, OPC_DADDI */
20284 if (ctx->insn_flags & ISA_MIPS32R6) {
20285 /* OPC_BNVC, OPC_BNEZALC, OPC_BNEC */
20286 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
20287 } else {
20288 /* OPC_DADDI */
20289 check_insn(ctx, ISA_MIPS3);
20290 check_mips_64(ctx);
20291 gen_arith_imm(ctx, op, rt, rs, imm);
20292 }
20293 break;
324d9e32 20294 case OPC_DADDIU:
d75c135e 20295 check_insn(ctx, ISA_MIPS3);
e189e748 20296 check_mips_64(ctx);
d75c135e 20297 gen_arith_imm(ctx, op, rt, rs, imm);
7a387fff 20298 break;
31837be3
YK
20299#else
20300 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
20301 if (ctx->insn_flags & ISA_MIPS32R6) {
20302 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
20303 } else {
20304 MIPS_INVAL("major opcode");
9c708c7f 20305 generate_exception_end(ctx, EXCP_RI);
31837be3
YK
20306 }
20307 break;
6af0bf9c 20308#endif
d4ea6acd
LA
20309 case OPC_DAUI: /* OPC_JALX */
20310 if (ctx->insn_flags & ISA_MIPS32R6) {
20311#if defined(TARGET_MIPS64)
20312 /* OPC_DAUI */
20313 check_mips_64(ctx);
db77d852
LA
20314 if (rs == 0) {
20315 generate_exception(ctx, EXCP_RI);
20316 } else if (rt != 0) {
d4ea6acd
LA
20317 TCGv t0 = tcg_temp_new();
20318 gen_load_gpr(t0, rs);
20319 tcg_gen_addi_tl(cpu_gpr[rt], t0, imm << 16);
20320 tcg_temp_free(t0);
20321 }
d4ea6acd 20322#else
9c708c7f 20323 generate_exception_end(ctx, EXCP_RI);
d4ea6acd
LA
20324 MIPS_INVAL("major opcode");
20325#endif
20326 } else {
20327 /* OPC_JALX */
20328 check_insn(ctx, ASE_MIPS16 | ASE_MICROMIPS);
20329 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
b231c103 20330 gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
d4ea6acd 20331 }
364d4831 20332 break;
4c789546 20333 case OPC_MSA: /* OPC_MDMX */
7a387fff 20334 /* MDMX: Not implemented. */
4c789546 20335 gen_msa(env, ctx);
d4ea6acd
LA
20336 break;
20337 case OPC_PCREL:
20338 check_insn(ctx, ISA_MIPS32R6);
eeb3bba8 20339 gen_pcrel(ctx, ctx->opcode, ctx->base.pc_next, rs);
d4ea6acd 20340 break;
6af0bf9c 20341 default: /* Invalid */
923617a3 20342 MIPS_INVAL("major opcode");
9c708c7f 20343 generate_exception_end(ctx, EXCP_RI);
6af0bf9c
FB
20344 break;
20345 }
6af0bf9c
FB
20346}
20347
18f440ed 20348static void mips_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
6af0bf9c 20349{
18f440ed 20350 DisasContext *ctx = container_of(dcbase, DisasContext, base);
9c489ea6 20351 CPUMIPSState *env = cs->env_ptr;
12be9258 20352
18f440ed 20353 ctx->page_start = ctx->base.pc_first & TARGET_PAGE_MASK;
12be9258
EC
20354 ctx->saved_pc = -1;
20355 ctx->insn_flags = env->insn_flags;
20356 ctx->CP0_Config1 = env->CP0_Config1;
20357 ctx->btarget = 0;
20358 ctx->kscrexist = (env->CP0_Config4 >> CP0C4_KScrExist) & 0xff;
20359 ctx->rxi = (env->CP0_Config3 >> CP0C3_RXI) & 1;
20360 ctx->ie = (env->CP0_Config4 >> CP0C4_IE) & 3;
20361 ctx->bi = (env->CP0_Config3 >> CP0C3_BI) & 1;
20362 ctx->bp = (env->CP0_Config3 >> CP0C3_BP) & 1;
20363 ctx->PAMask = env->PAMask;
20364 ctx->mvh = (env->CP0_Config5 >> CP0C5_MVH) & 1;
20365 ctx->eva = (env->CP0_Config5 >> CP0C5_EVA) & 1;
20366 ctx->sc = (env->CP0_Config3 >> CP0C3_SC) & 1;
20367 ctx->CP0_LLAddr_shift = env->CP0_LLAddr_shift;
20368 ctx->cmgcr = (env->CP0_Config3 >> CP0C3_CMGCR) & 1;
4ad40f36 20369 /* Restore delay slot state from the tb context. */
12be9258
EC
20370 ctx->hflags = (uint32_t)ctx->base.tb->flags; /* FIXME: maybe use 64 bits? */
20371 ctx->ulri = (env->CP0_Config3 >> CP0C3_ULRI) & 1;
20372 ctx->ps = ((env->active_fpu.fcr0 >> FCR0_PS) & 1) ||
e29c9628 20373 (env->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F));
12be9258
EC
20374 ctx->vp = (env->CP0_Config5 >> CP0C5_VP) & 1;
20375 ctx->mrp = (env->CP0_Config5 >> CP0C5_MRP) & 1;
20376 ctx->nan2008 = (env->active_fpu.fcr31 >> FCR31_NAN2008) & 1;
20377 ctx->abs2008 = (env->active_fpu.fcr31 >> FCR31_ABS2008) & 1;
20378 restore_cpu_state(env, ctx);
932e71cd 20379#ifdef CONFIG_USER_ONLY
12be9258 20380 ctx->mem_idx = MIPS_HFLAG_UM;
932e71cd 20381#else
12be9258 20382 ctx->mem_idx = hflags_mmu_index(ctx->hflags);
932e71cd 20383#endif
12be9258
EC
20384 ctx->default_tcg_memop_mask = (ctx->insn_flags & ISA_MIPS32R6) ?
20385 MO_UNALN : MO_ALIGN;
190ce7fb 20386
18f440ed
EC
20387 LOG_DISAS("\ntb %p idx %d hflags %04x\n", ctx->base.tb, ctx->mem_idx,
20388 ctx->hflags);
20389}
12be9258 20390
18f440ed
EC
20391static void mips_tr_tb_start(DisasContextBase *dcbase, CPUState *cs)
20392{
20393}
b933066a 20394
18f440ed
EC
20395static void mips_tr_insn_start(DisasContextBase *dcbase, CPUState *cs)
20396{
20397 DisasContext *ctx = container_of(dcbase, DisasContext, base);
c9602061 20398
18f440ed
EC
20399 tcg_gen_insn_start(ctx->base.pc_next, ctx->hflags & MIPS_HFLAG_BMASK,
20400 ctx->btarget);
20401}
31837be3 20402
18f440ed
EC
20403static bool mips_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cs,
20404 const CPUBreakpoint *bp)
20405{
20406 DisasContext *ctx = container_of(dcbase, DisasContext, base);
c9602061 20407
18f440ed
EC
20408 save_cpu_state(ctx, 1);
20409 ctx->base.is_jmp = DISAS_NORETURN;
20410 gen_helper_raise_exception_debug(cpu_env);
20411 /* The address covered by the breakpoint must be included in
20412 [tb->pc, tb->pc + tb->size) in order to for it to be
20413 properly cleared -- thus we increment the PC here so that
20414 the logic setting tb->size below does the right thing. */
20415 ctx->base.pc_next += 4;
20416 return true;
20417}
4ad40f36 20418
18f440ed
EC
20419static void mips_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
20420{
20421 CPUMIPSState *env = cs->env_ptr;
20422 DisasContext *ctx = container_of(dcbase, DisasContext, base);
20423 int insn_bytes;
20424 int is_slot;
4ad40f36 20425
18f440ed
EC
20426 is_slot = ctx->hflags & MIPS_HFLAG_BMASK;
20427 if (!(ctx->hflags & MIPS_HFLAG_M16)) {
20428 ctx->opcode = cpu_ldl_code(env, ctx->base.pc_next);
20429 insn_bytes = 4;
20430 decode_opc(env, ctx);
20431 } else if (ctx->insn_flags & ASE_MICROMIPS) {
20432 ctx->opcode = cpu_lduw_code(env, ctx->base.pc_next);
20433 insn_bytes = decode_micromips_opc(env, ctx);
20434 } else if (ctx->insn_flags & ASE_MIPS16) {
20435 ctx->opcode = cpu_lduw_code(env, ctx->base.pc_next);
20436 insn_bytes = decode_mips16_opc(env, ctx);
20437 } else {
20438 generate_exception_end(ctx, EXCP_RI);
20439 g_assert(ctx->base.is_jmp == DISAS_NORETURN);
20440 return;
20441 }
faf7aaa9 20442
18f440ed
EC
20443 if (ctx->hflags & MIPS_HFLAG_BMASK) {
20444 if (!(ctx->hflags & (MIPS_HFLAG_BDS16 | MIPS_HFLAG_BDS32 |
20445 MIPS_HFLAG_FBNSLOT))) {
20446 /* force to generate branch as there is neither delay nor
20447 forbidden slot */
20448 is_slot = 1;
20449 }
20450 if ((ctx->hflags & MIPS_HFLAG_M16) &&
20451 (ctx->hflags & MIPS_HFLAG_FBNSLOT)) {
20452 /* Force to generate branch as microMIPS R6 doesn't restrict
20453 branches in the forbidden slot. */
20454 is_slot = 1;
eeb3bba8 20455 }
18f440ed
EC
20456 }
20457 if (is_slot) {
20458 gen_branch(ctx, insn_bytes);
20459 }
20460 ctx->base.pc_next += insn_bytes;
1b530a6d 20461
18f440ed
EC
20462 if (ctx->base.is_jmp != DISAS_NEXT) {
20463 return;
6af0bf9c 20464 }
18f440ed
EC
20465 /* Execute a branch and its delay slot as a single instruction.
20466 This is what GDB expects and is consistent with what the
20467 hardware does (e.g. if a delay slot instruction faults, the
20468 reported PC is the PC of the branch). */
20469 if (ctx->base.singlestep_enabled &&
20470 (ctx->hflags & MIPS_HFLAG_BMASK) == 0) {
20471 ctx->base.is_jmp = DISAS_TOO_MANY;
20472 }
20473 if (ctx->base.pc_next - ctx->page_start >= TARGET_PAGE_SIZE) {
20474 ctx->base.is_jmp = DISAS_TOO_MANY;
ed2803da 20475 }
18f440ed
EC
20476}
20477
20478static void mips_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
20479{
20480 DisasContext *ctx = container_of(dcbase, DisasContext, base);
20481
12be9258
EC
20482 if (ctx->base.singlestep_enabled && ctx->base.is_jmp != DISAS_NORETURN) {
20483 save_cpu_state(ctx, ctx->base.is_jmp != DISAS_EXIT);
9c708c7f 20484 gen_helper_raise_exception_debug(cpu_env);
16c00cb2 20485 } else {
12be9258 20486 switch (ctx->base.is_jmp) {
b28425ba 20487 case DISAS_STOP:
12be9258 20488 gen_save_pc(ctx->base.pc_next);
cd314a7d 20489 tcg_gen_lookup_and_goto_ptr();
df1561e2 20490 break;
b28425ba 20491 case DISAS_NEXT:
18f440ed 20492 case DISAS_TOO_MANY:
12be9258
EC
20493 save_cpu_state(ctx, 0);
20494 gen_goto_tb(ctx, 0, ctx->base.pc_next);
16c00cb2 20495 break;
b28425ba 20496 case DISAS_EXIT:
07ea28b4 20497 tcg_gen_exit_tb(NULL, 0);
16c00cb2 20498 break;
b28425ba 20499 case DISAS_NORETURN:
5a5012ec 20500 break;
18f440ed
EC
20501 default:
20502 g_assert_not_reached();
6958549d 20503 }
6af0bf9c 20504 }
18f440ed
EC
20505}
20506
20507static void mips_tr_disas_log(const DisasContextBase *dcbase, CPUState *cs)
20508{
20509 qemu_log("IN: %s\n", lookup_symbol(dcbase->pc_first));
20510 log_target_disas(cs, dcbase->pc_first, dcbase->tb->size);
20511}
20512
20513static const TranslatorOps mips_tr_ops = {
20514 .init_disas_context = mips_tr_init_disas_context,
20515 .tb_start = mips_tr_tb_start,
20516 .insn_start = mips_tr_insn_start,
20517 .breakpoint_check = mips_tr_breakpoint_check,
20518 .translate_insn = mips_tr_translate_insn,
20519 .tb_stop = mips_tr_tb_stop,
20520 .disas_log = mips_tr_disas_log,
20521};
20522
20523void gen_intermediate_code(CPUState *cs, struct TranslationBlock *tb)
20524{
20525 DisasContext ctx;
20526
20527 translator_loop(&mips_tr_ops, &ctx.base, cs, tb);
6af0bf9c
FB
20528}
20529
7db13fae 20530static void fpu_dump_state(CPUMIPSState *env, FILE *f, fprintf_function fpu_fprintf,
8706c382 20531 int flags)
6ea83fed
FB
20532{
20533 int i;
5e755519 20534 int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
5a5012ec 20535
2a5612e6
SW
20536#define printfpr(fp) \
20537 do { \
20538 if (is_fpu64) \
20539 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
20540 " fd:%13g fs:%13g psu: %13g\n", \
20541 (fp)->w[FP_ENDIAN_IDX], (fp)->d, \
20542 (double)(fp)->fd, \
20543 (double)(fp)->fs[FP_ENDIAN_IDX], \
20544 (double)(fp)->fs[!FP_ENDIAN_IDX]); \
20545 else { \
20546 fpr_t tmp; \
20547 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
20548 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
20549 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
20550 " fd:%13g fs:%13g psu:%13g\n", \
20551 tmp.w[FP_ENDIAN_IDX], tmp.d, \
20552 (double)tmp.fd, \
20553 (double)tmp.fs[FP_ENDIAN_IDX], \
20554 (double)tmp.fs[!FP_ENDIAN_IDX]); \
20555 } \
6ea83fed
FB
20556 } while(0)
20557
5a5012ec 20558
9a78eead
SW
20559 fpu_fprintf(f, "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%02x\n",
20560 env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64,
f01be154 20561 get_float_exception_flags(&env->active_fpu.fp_status));
5a5012ec
TS
20562 for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
20563 fpu_fprintf(f, "%3s: ", fregnames[i]);
f01be154 20564 printfpr(&env->active_fpu.fpr[i]);
6ea83fed
FB
20565 }
20566
20567#undef printfpr
20568}
20569
878096ee
AF
20570void mips_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
20571 int flags)
6af0bf9c 20572{
878096ee
AF
20573 MIPSCPU *cpu = MIPS_CPU(cs);
20574 CPUMIPSState *env = &cpu->env;
6af0bf9c 20575 int i;
3b46e624 20576
a7200c9f
SW
20577 cpu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
20578 " LO=0x" TARGET_FMT_lx " ds %04x "
20579 TARGET_FMT_lx " " TARGET_FMT_ld "\n",
3d5be870
TS
20580 env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
20581 env->hflags, env->btarget, env->bcond);
6af0bf9c
FB
20582 for (i = 0; i < 32; i++) {
20583 if ((i & 3) == 0)
20584 cpu_fprintf(f, "GPR%02d:", i);
b5dc7732 20585 cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
6af0bf9c
FB
20586 if ((i & 3) == 3)
20587 cpu_fprintf(f, "\n");
20588 }
568b600d 20589
3594c774 20590 cpu_fprintf(f, "CP0 Status 0x%08x Cause 0x%08x EPC 0x" TARGET_FMT_lx "\n",
5e755519 20591 env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
284b731a
LA
20592 cpu_fprintf(f, " Config0 0x%08x Config1 0x%08x LLAddr 0x%016"
20593 PRIx64 "\n",
5499b6ff 20594 env->CP0_Config0, env->CP0_Config1, env->lladdr);
27e1fb13
MR
20595 cpu_fprintf(f, " Config2 0x%08x Config3 0x%08x\n",
20596 env->CP0_Config2, env->CP0_Config3);
20597 cpu_fprintf(f, " Config4 0x%08x Config5 0x%08x\n",
20598 env->CP0_Config4, env->CP0_Config5);
1cc5af69 20599 if ((flags & CPU_DUMP_FPU) && (env->hflags & MIPS_HFLAG_FPU)) {
7a387fff 20600 fpu_dump_state(env, f, cpu_fprintf, flags);
1cc5af69 20601 }
6af0bf9c
FB
20602}
20603
78ce64f4 20604void mips_tcg_init(void)
39454628 20605{
f01be154 20606 int i;
39454628 20607
f764718d 20608 cpu_gpr[0] = NULL;
bb928dbe 20609 for (i = 1; i < 32; i++)
e1ccc054 20610 cpu_gpr[i] = tcg_global_mem_new(cpu_env,
7db13fae 20611 offsetof(CPUMIPSState, active_tc.gpr[i]),
4b2eb8d2 20612 regnames[i]);
d73ee8a2 20613
863f264d
YK
20614 for (i = 0; i < 32; i++) {
20615 int off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[0]);
20616 msa_wr_d[i * 2] =
e1ccc054 20617 tcg_global_mem_new_i64(cpu_env, off, msaregnames[i * 2]);
cb269f27
YK
20618 /* The scalar floating-point unit (FPU) registers are mapped on
20619 * the MSA vector registers. */
20620 fpu_f64[i] = msa_wr_d[i * 2];
863f264d
YK
20621 off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[1]);
20622 msa_wr_d[i * 2 + 1] =
e1ccc054 20623 tcg_global_mem_new_i64(cpu_env, off, msaregnames[i * 2 + 1]);
863f264d
YK
20624 }
20625
e1ccc054 20626 cpu_PC = tcg_global_mem_new(cpu_env,
7db13fae 20627 offsetof(CPUMIPSState, active_tc.PC), "PC");
4b2eb8d2 20628 for (i = 0; i < MIPS_DSP_ACC; i++) {
e1ccc054 20629 cpu_HI[i] = tcg_global_mem_new(cpu_env,
7db13fae 20630 offsetof(CPUMIPSState, active_tc.HI[i]),
4b2eb8d2 20631 regnames_HI[i]);
e1ccc054 20632 cpu_LO[i] = tcg_global_mem_new(cpu_env,
7db13fae 20633 offsetof(CPUMIPSState, active_tc.LO[i]),
4b2eb8d2 20634 regnames_LO[i]);
4b2eb8d2 20635 }
e1ccc054 20636 cpu_dspctrl = tcg_global_mem_new(cpu_env,
7db13fae 20637 offsetof(CPUMIPSState, active_tc.DSPControl),
4b2eb8d2 20638 "DSPControl");
e1ccc054 20639 bcond = tcg_global_mem_new(cpu_env,
7db13fae 20640 offsetof(CPUMIPSState, bcond), "bcond");
e1ccc054 20641 btarget = tcg_global_mem_new(cpu_env,
7db13fae 20642 offsetof(CPUMIPSState, btarget), "btarget");
e1ccc054 20643 hflags = tcg_global_mem_new_i32(cpu_env,
7db13fae 20644 offsetof(CPUMIPSState, hflags), "hflags");
41db4607 20645
e1ccc054 20646 fpu_fcr0 = tcg_global_mem_new_i32(cpu_env,
7db13fae 20647 offsetof(CPUMIPSState, active_fpu.fcr0),
a7812ae4 20648 "fcr0");
e1ccc054 20649 fpu_fcr31 = tcg_global_mem_new_i32(cpu_env,
7db13fae 20650 offsetof(CPUMIPSState, active_fpu.fcr31),
a7812ae4 20651 "fcr31");
39454628
TS
20652}
20653
5b27a92d 20654#include "translate_init.inc.c"
aaed909a 20655
27e38392
PMD
20656void cpu_mips_realize_env(CPUMIPSState *env)
20657{
20658 env->exception_base = (int32_t)0xBFC00000;
20659
20660#ifndef CONFIG_USER_ONLY
20661 mmu_init(env, env->cpu_model);
20662#endif
20663 fpu_init(env, env->cpu_model);
20664 mvp_init(env, env->cpu_model);
20665}
20666
a7519f2b 20667bool cpu_supports_cps_smp(const char *cpu_type)
bff384a4 20668{
a7519f2b
IM
20669 const MIPSCPUClass *mcc = MIPS_CPU_CLASS(object_class_by_name(cpu_type));
20670 return (mcc->cpu_def->CP0_Config3 & (1 << CP0C3_CMGCR)) != 0;
bff384a4
LA
20671}
20672
a7519f2b 20673bool cpu_supports_isa(const char *cpu_type, unsigned int isa)
bed9e5ce 20674{
a7519f2b
IM
20675 const MIPSCPUClass *mcc = MIPS_CPU_CLASS(object_class_by_name(cpu_type));
20676 return (mcc->cpu_def->insn_flags & isa) != 0;
bed9e5ce
PB
20677}
20678
89777fd1
LA
20679void cpu_set_exception_base(int vp_index, target_ulong address)
20680{
20681 MIPSCPU *vp = MIPS_CPU(qemu_get_cpu(vp_index));
20682 vp->env.exception_base = address;
20683}
20684
1bba0dc9 20685void cpu_state_reset(CPUMIPSState *env)
6ae81775 20686{
55e5c285
AF
20687 MIPSCPU *cpu = mips_env_get_cpu(env);
20688 CPUState *cs = CPU(cpu);
6ae81775 20689
51cc2e78
BS
20690 /* Reset registers to their default values */
20691 env->CP0_PRid = env->cpu_model->CP0_PRid;
20692 env->CP0_Config0 = env->cpu_model->CP0_Config0;
20693#ifdef TARGET_WORDS_BIGENDIAN
20694 env->CP0_Config0 |= (1 << CP0C0_BE);
20695#endif
20696 env->CP0_Config1 = env->cpu_model->CP0_Config1;
20697 env->CP0_Config2 = env->cpu_model->CP0_Config2;
20698 env->CP0_Config3 = env->cpu_model->CP0_Config3;
b4160af1
PJ
20699 env->CP0_Config4 = env->cpu_model->CP0_Config4;
20700 env->CP0_Config4_rw_bitmask = env->cpu_model->CP0_Config4_rw_bitmask;
b4dd99a3
PJ
20701 env->CP0_Config5 = env->cpu_model->CP0_Config5;
20702 env->CP0_Config5_rw_bitmask = env->cpu_model->CP0_Config5_rw_bitmask;
51cc2e78
BS
20703 env->CP0_Config6 = env->cpu_model->CP0_Config6;
20704 env->CP0_Config7 = env->cpu_model->CP0_Config7;
2a6e32dd
AJ
20705 env->CP0_LLAddr_rw_bitmask = env->cpu_model->CP0_LLAddr_rw_bitmask
20706 << env->cpu_model->CP0_LLAddr_shift;
20707 env->CP0_LLAddr_shift = env->cpu_model->CP0_LLAddr_shift;
51cc2e78
BS
20708 env->SYNCI_Step = env->cpu_model->SYNCI_Step;
20709 env->CCRes = env->cpu_model->CCRes;
20710 env->CP0_Status_rw_bitmask = env->cpu_model->CP0_Status_rw_bitmask;
20711 env->CP0_TCStatus_rw_bitmask = env->cpu_model->CP0_TCStatus_rw_bitmask;
20712 env->CP0_SRSCtl = env->cpu_model->CP0_SRSCtl;
20713 env->current_tc = 0;
20714 env->SEGBITS = env->cpu_model->SEGBITS;
20715 env->SEGMask = (target_ulong)((1ULL << env->cpu_model->SEGBITS) - 1);
20716#if defined(TARGET_MIPS64)
20717 if (env->cpu_model->insn_flags & ISA_MIPS3) {
20718 env->SEGMask |= 3ULL << 62;
20719 }
20720#endif
20721 env->PABITS = env->cpu_model->PABITS;
51cc2e78
BS
20722 env->CP0_SRSConf0_rw_bitmask = env->cpu_model->CP0_SRSConf0_rw_bitmask;
20723 env->CP0_SRSConf0 = env->cpu_model->CP0_SRSConf0;
20724 env->CP0_SRSConf1_rw_bitmask = env->cpu_model->CP0_SRSConf1_rw_bitmask;
20725 env->CP0_SRSConf1 = env->cpu_model->CP0_SRSConf1;
20726 env->CP0_SRSConf2_rw_bitmask = env->cpu_model->CP0_SRSConf2_rw_bitmask;
20727 env->CP0_SRSConf2 = env->cpu_model->CP0_SRSConf2;
20728 env->CP0_SRSConf3_rw_bitmask = env->cpu_model->CP0_SRSConf3_rw_bitmask;
20729 env->CP0_SRSConf3 = env->cpu_model->CP0_SRSConf3;
20730 env->CP0_SRSConf4_rw_bitmask = env->cpu_model->CP0_SRSConf4_rw_bitmask;
20731 env->CP0_SRSConf4 = env->cpu_model->CP0_SRSConf4;
7207c7f9
LA
20732 env->CP0_PageGrain_rw_bitmask = env->cpu_model->CP0_PageGrain_rw_bitmask;
20733 env->CP0_PageGrain = env->cpu_model->CP0_PageGrain;
74dbf824 20734 env->CP0_EBaseWG_rw_bitmask = env->cpu_model->CP0_EBaseWG_rw_bitmask;
f1cb0951 20735 env->active_fpu.fcr0 = env->cpu_model->CP1_fcr0;
599bc5e8 20736 env->active_fpu.fcr31_rw_bitmask = env->cpu_model->CP1_fcr31_rw_bitmask;
ba5c79f2 20737 env->active_fpu.fcr31 = env->cpu_model->CP1_fcr31;
863f264d 20738 env->msair = env->cpu_model->MSAIR;
51cc2e78
BS
20739 env->insn_flags = env->cpu_model->insn_flags;
20740
0eaef5aa 20741#if defined(CONFIG_USER_ONLY)
03e6e501 20742 env->CP0_Status = (MIPS_HFLAG_UM << CP0St_KSU);
68473f15
RH
20743# ifdef TARGET_MIPS64
20744 /* Enable 64-bit register mode. */
20745 env->CP0_Status |= (1 << CP0St_PX);
20746# endif
20747# ifdef TARGET_ABI_MIPSN64
20748 /* Enable 64-bit address mode. */
20749 env->CP0_Status |= (1 << CP0St_UX);
20750# endif
94159135
MI
20751 /* Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
20752 hardware registers. */
20753 env->CP0_HWREna |= 0x0000000F;
91a75935 20754 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
03e6e501 20755 env->CP0_Status |= (1 << CP0St_CU1);
91a75935 20756 }
6f0af304
PJ
20757 if (env->CP0_Config3 & (1 << CP0C3_DSPP)) {
20758 env->CP0_Status |= (1 << CP0St_MX);
853c3240 20759 }
4d66261f
PJ
20760# if defined(TARGET_MIPS64)
20761 /* For MIPS64, init FR bit to 1 if FPU unit is there and bit is writable. */
20762 if ((env->CP0_Config1 & (1 << CP0C1_FP)) &&
20763 (env->CP0_Status_rw_bitmask & (1 << CP0St_FR))) {
68473f15
RH
20764 env->CP0_Status |= (1 << CP0St_FR);
20765 }
4d66261f 20766# endif
932e71cd
AJ
20767#else
20768 if (env->hflags & MIPS_HFLAG_BMASK) {
20769 /* If the exception was raised from a delay slot,
20770 come back to the jump. */
c3577479
MR
20771 env->CP0_ErrorEPC = (env->active_tc.PC
20772 - (env->hflags & MIPS_HFLAG_B16 ? 2 : 4));
aa328add 20773 } else {
932e71cd
AJ
20774 env->CP0_ErrorEPC = env->active_tc.PC;
20775 }
89777fd1 20776 env->active_tc.PC = env->exception_base;
51cc2e78
BS
20777 env->CP0_Random = env->tlb->nb_tlb - 1;
20778 env->tlb->tlb_in_use = env->tlb->nb_tlb;
932e71cd 20779 env->CP0_Wired = 0;
01bc435b 20780 env->CP0_GlobalNumber = (cs->cpu_index & 0xFF) << CP0GN_VPId;
0a2672b7 20781 env->CP0_EBase = (cs->cpu_index & 0x3FF);
d3d93c6c 20782 if (mips_um_ksegs_enabled()) {
0a2672b7
JH
20783 env->CP0_EBase |= 0x40000000;
20784 } else {
74dbf824 20785 env->CP0_EBase |= (int32_t)0x80000000;
0a2672b7 20786 }
c870e3f5
YK
20787 if (env->CP0_Config3 & (1 << CP0C3_CMGCR)) {
20788 env->CP0_CMGCRBase = 0x1fbf8000 >> 4;
20789 }
a0c80608
PB
20790 env->CP0_EntryHi_ASID_mask = (env->CP0_Config4 & (1 << CP0C4_AE)) ?
20791 0x3ff : 0xff;
932e71cd
AJ
20792 env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
20793 /* vectored interrupts not implemented, timer on int 7,
20794 no performance counters. */
20795 env->CP0_IntCtl = 0xe0000000;
20796 {
20797 int i;
20798
20799 for (i = 0; i < 7; i++) {
20800 env->CP0_WatchLo[i] = 0;
20801 env->CP0_WatchHi[i] = 0x80000000;
fd88b6ab 20802 }
932e71cd
AJ
20803 env->CP0_WatchLo[7] = 0;
20804 env->CP0_WatchHi[7] = 0;
fd88b6ab 20805 }
932e71cd
AJ
20806 /* Count register increments in debug mode, EJTAG version 1 */
20807 env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
9e56e756 20808
4b69c7e2
JH
20809 cpu_mips_store_count(env, 1);
20810
9e56e756
EI
20811 if (env->CP0_Config3 & (1 << CP0C3_MT)) {
20812 int i;
20813
20814 /* Only TC0 on VPE 0 starts as active. */
20815 for (i = 0; i < ARRAY_SIZE(env->tcs); i++) {
55e5c285 20816 env->tcs[i].CP0_TCBind = cs->cpu_index << CP0TCBd_CurVPE;
9e56e756
EI
20817 env->tcs[i].CP0_TCHalt = 1;
20818 }
20819 env->active_tc.CP0_TCHalt = 1;
259186a7 20820 cs->halted = 1;
9e56e756 20821
55e5c285 20822 if (cs->cpu_index == 0) {
9e56e756
EI
20823 /* VPE0 starts up enabled. */
20824 env->mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
20825 env->CP0_VPEConf0 |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
20826
20827 /* TC0 starts up unhalted. */
259186a7 20828 cs->halted = 0;
9e56e756
EI
20829 env->active_tc.CP0_TCHalt = 0;
20830 env->tcs[0].CP0_TCHalt = 0;
20831 /* With thread 0 active. */
20832 env->active_tc.CP0_TCStatus = (1 << CP0TCSt_A);
20833 env->tcs[0].CP0_TCStatus = (1 << CP0TCSt_A);
20834 }
20835 }
cec56a73
JH
20836
20837 /*
20838 * Configure default legacy segmentation control. We use this regardless of
20839 * whether segmentation control is presented to the guest.
20840 */
20841 /* KSeg3 (seg0 0xE0000000..0xFFFFFFFF) */
20842 env->CP0_SegCtl0 = (CP0SC_AM_MK << CP0SC_AM);
20843 /* KSeg2 (seg1 0xC0000000..0xDFFFFFFF) */
20844 env->CP0_SegCtl0 |= ((CP0SC_AM_MSK << CP0SC_AM)) << 16;
20845 /* KSeg1 (seg2 0xA0000000..0x9FFFFFFF) */
20846 env->CP0_SegCtl1 = (0 << CP0SC_PA) | (CP0SC_AM_UK << CP0SC_AM) |
20847 (2 << CP0SC_C);
20848 /* KSeg0 (seg3 0x80000000..0x9FFFFFFF) */
20849 env->CP0_SegCtl1 |= ((0 << CP0SC_PA) | (CP0SC_AM_UK << CP0SC_AM) |
20850 (3 << CP0SC_C)) << 16;
20851 /* USeg (seg4 0x40000000..0x7FFFFFFF) */
20852 env->CP0_SegCtl2 = (2 << CP0SC_PA) | (CP0SC_AM_MUSK << CP0SC_AM) |
20853 (1 << CP0SC_EU) | (2 << CP0SC_C);
20854 /* USeg (seg5 0x00000000..0x3FFFFFFF) */
20855 env->CP0_SegCtl2 |= ((0 << CP0SC_PA) | (CP0SC_AM_MUSK << CP0SC_AM) |
20856 (1 << CP0SC_EU) | (2 << CP0SC_C)) << 16;
20857 /* XKPhys (note, SegCtl2.XR = 0, so XAM won't be used) */
20858 env->CP0_SegCtl1 |= (CP0SC_AM_UK << CP0SC1_XAM);
51cc2e78 20859#endif
ddc584bd
LA
20860 if ((env->insn_flags & ISA_MIPS32R6) &&
20861 (env->active_fpu.fcr0 & (1 << FCR0_F64))) {
20862 /* Status.FR = 0 mode in 64-bit FPU not allowed in R6 */
20863 env->CP0_Status |= (1 << CP0St_FR);
20864 }
20865
0305d194
YK
20866 if (env->CP0_Config3 & (1 << CP0C3_ISA)) {
20867 /* microMIPS on reset when Config3.ISA == {1, 3} */
20868 env->hflags |= MIPS_HFLAG_M16;
20869 }
20870
863f264d
YK
20871 /* MSA */
20872 if (env->CP0_Config3 & (1 << CP0C3_MSAP)) {
20873 msa_reset(env);
20874 }
20875
03e6e501 20876 compute_hflags(env);
599bc5e8 20877 restore_fp_status(env);
e117f526 20878 restore_pamask(env);
27103424 20879 cs->exception_index = EXCP_NONE;
3b3c1694
LA
20880
20881 if (semihosting_get_argc()) {
20882 /* UHI interface can be used to obtain argc and argv */
20883 env->active_tc.gpr[4] = -1;
20884 }
6af0bf9c 20885}
d2856f1a 20886
bad729e2
RH
20887void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb,
20888 target_ulong *data)
d2856f1a 20889{
bad729e2 20890 env->active_tc.PC = data[0];
d2856f1a 20891 env->hflags &= ~MIPS_HFLAG_BMASK;
bad729e2 20892 env->hflags |= data[1];
4636401d
AJ
20893 switch (env->hflags & MIPS_HFLAG_BMASK_BASE) {
20894 case MIPS_HFLAG_BR:
20895 break;
20896 case MIPS_HFLAG_BC:
20897 case MIPS_HFLAG_BL:
20898 case MIPS_HFLAG_B:
bad729e2 20899 env->btarget = data[2];
4636401d
AJ
20900 break;
20901 }
d2856f1a 20902}