]> git.proxmox.com Git - mirror_qemu.git/blame - target/mips/translate.c
target/mips: convert to DisasContextBase
[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;
8e9ade68 1435 uint32_t opcode;
d75c135e 1436 int insn_flags;
5ab5c041 1437 int32_t CP0_Config1;
8e9ade68
TS
1438 /* Routine used to access memory */
1439 int mem_idx;
be3a8c53 1440 TCGMemOp default_tcg_memop_mask;
8e9ade68 1441 uint32_t hflags, saved_hflags;
8e9ade68 1442 target_ulong btarget;
d279279e 1443 bool ulri;
e98c0d17 1444 int kscrexist;
7207c7f9 1445 bool rxi;
9456c2fb 1446 int ie;
aea14095
LA
1447 bool bi;
1448 bool bp;
5204ea79
LA
1449 uint64_t PAMask;
1450 bool mvh;
76964147 1451 bool eva;
cec56a73 1452 bool sc;
5204ea79 1453 int CP0_LLAddr_shift;
e29c9628 1454 bool ps;
01bc435b 1455 bool vp;
c870e3f5 1456 bool cmgcr;
f6d4dd81 1457 bool mrp;
87552089 1458 bool nan2008;
6be77480 1459 bool abs2008;
8e9ade68
TS
1460} DisasContext;
1461
b28425ba
EC
1462#define DISAS_STOP DISAS_TARGET_0
1463#define DISAS_EXIT DISAS_TARGET_1
8e9ade68 1464
d73ee8a2
RH
1465static const char * const regnames[] = {
1466 "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
1467 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
1468 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
1469 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
1470};
6af0bf9c 1471
d73ee8a2
RH
1472static const char * const regnames_HI[] = {
1473 "HI0", "HI1", "HI2", "HI3",
1474};
4b2eb8d2 1475
d73ee8a2
RH
1476static const char * const regnames_LO[] = {
1477 "LO0", "LO1", "LO2", "LO3",
1478};
4b2eb8d2 1479
d73ee8a2
RH
1480static const char * const fregnames[] = {
1481 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
1482 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
1483 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
1484 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
1485};
958fb4a9 1486
863f264d
YK
1487static const char * const msaregnames[] = {
1488 "w0.d0", "w0.d1", "w1.d0", "w1.d1",
1489 "w2.d0", "w2.d1", "w3.d0", "w3.d1",
1490 "w4.d0", "w4.d1", "w5.d0", "w5.d1",
1491 "w6.d0", "w6.d1", "w7.d0", "w7.d1",
1492 "w8.d0", "w8.d1", "w9.d0", "w9.d1",
1493 "w10.d0", "w10.d1", "w11.d0", "w11.d1",
1494 "w12.d0", "w12.d1", "w13.d0", "w13.d1",
1495 "w14.d0", "w14.d1", "w15.d0", "w15.d1",
1496 "w16.d0", "w16.d1", "w17.d0", "w17.d1",
1497 "w18.d0", "w18.d1", "w19.d0", "w19.d1",
1498 "w20.d0", "w20.d1", "w21.d0", "w21.d1",
1499 "w22.d0", "w22.d1", "w23.d0", "w23.d1",
1500 "w24.d0", "w24.d1", "w25.d0", "w25.d1",
1501 "w26.d0", "w26.d1", "w27.d0", "w27.d1",
1502 "w28.d0", "w28.d1", "w29.d0", "w29.d1",
1503 "w30.d0", "w30.d1", "w31.d0", "w31.d1",
1504};
1505
9d68ac14 1506#define LOG_DISAS(...) \
fb7729e2
RH
1507 do { \
1508 if (MIPS_DEBUG_DISAS) { \
9d68ac14 1509 qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__); \
fb7729e2
RH
1510 } \
1511 } while (0)
1512
9d68ac14 1513#define MIPS_INVAL(op) \
fb7729e2
RH
1514 do { \
1515 if (MIPS_DEBUG_DISAS) { \
9d68ac14
AJ
1516 qemu_log_mask(CPU_LOG_TB_IN_ASM, \
1517 TARGET_FMT_lx ": %08x Invalid %s %03x %03x %03x\n", \
eeb3bba8
EC
1518 ctx->base.pc_next, ctx->opcode, op, \
1519 ctx->opcode >> 26, ctx->opcode & 0x3F, \
1520 ((ctx->opcode >> 16) & 0x1F)); \
fb7729e2
RH
1521 } \
1522 } while (0)
958fb4a9 1523
8e9ade68
TS
1524/* General purpose registers moves. */
1525static inline void gen_load_gpr (TCGv t, int reg)
aaa9128a 1526{
8e9ade68
TS
1527 if (reg == 0)
1528 tcg_gen_movi_tl(t, 0);
1529 else
4b2eb8d2 1530 tcg_gen_mov_tl(t, cpu_gpr[reg]);
aaa9128a
TS
1531}
1532
8e9ade68 1533static inline void gen_store_gpr (TCGv t, int reg)
aaa9128a 1534{
8e9ade68 1535 if (reg != 0)
4b2eb8d2 1536 tcg_gen_mov_tl(cpu_gpr[reg], t);
aaa9128a
TS
1537}
1538
8e9ade68 1539/* Moves to/from shadow registers. */
be24bb4f 1540static inline void gen_load_srsgpr (int from, int to)
aaa9128a 1541{
d9bea114 1542 TCGv t0 = tcg_temp_new();
be24bb4f
TS
1543
1544 if (from == 0)
d9bea114 1545 tcg_gen_movi_tl(t0, 0);
8e9ade68 1546 else {
d9bea114 1547 TCGv_i32 t2 = tcg_temp_new_i32();
a7812ae4 1548 TCGv_ptr addr = tcg_temp_new_ptr();
aaa9128a 1549
7db13fae 1550 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
d9bea114
AJ
1551 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1552 tcg_gen_andi_i32(t2, t2, 0xf);
1553 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1554 tcg_gen_ext_i32_ptr(addr, t2);
a7812ae4 1555 tcg_gen_add_ptr(addr, cpu_env, addr);
aaa9128a 1556
d9bea114 1557 tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from);
a7812ae4 1558 tcg_temp_free_ptr(addr);
d9bea114 1559 tcg_temp_free_i32(t2);
8e9ade68 1560 }
d9bea114
AJ
1561 gen_store_gpr(t0, to);
1562 tcg_temp_free(t0);
aaa9128a
TS
1563}
1564
be24bb4f 1565static inline void gen_store_srsgpr (int from, int to)
aaa9128a 1566{
be24bb4f 1567 if (to != 0) {
d9bea114
AJ
1568 TCGv t0 = tcg_temp_new();
1569 TCGv_i32 t2 = tcg_temp_new_i32();
a7812ae4 1570 TCGv_ptr addr = tcg_temp_new_ptr();
be24bb4f 1571
d9bea114 1572 gen_load_gpr(t0, from);
7db13fae 1573 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
d9bea114
AJ
1574 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1575 tcg_gen_andi_i32(t2, t2, 0xf);
1576 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1577 tcg_gen_ext_i32_ptr(addr, t2);
a7812ae4 1578 tcg_gen_add_ptr(addr, cpu_env, addr);
be24bb4f 1579
d9bea114 1580 tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to);
a7812ae4 1581 tcg_temp_free_ptr(addr);
d9bea114
AJ
1582 tcg_temp_free_i32(t2);
1583 tcg_temp_free(t0);
8e9ade68 1584 }
aaa9128a
TS
1585}
1586
eab9944c
LA
1587/* Tests */
1588static inline void gen_save_pc(target_ulong pc)
1589{
1590 tcg_gen_movi_tl(cpu_PC, pc);
1591}
1592
1593static inline void save_cpu_state(DisasContext *ctx, int do_save_pc)
1594{
1595 LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
eeb3bba8
EC
1596 if (do_save_pc && ctx->base.pc_next != ctx->saved_pc) {
1597 gen_save_pc(ctx->base.pc_next);
1598 ctx->saved_pc = ctx->base.pc_next;
eab9944c
LA
1599 }
1600 if (ctx->hflags != ctx->saved_hflags) {
1601 tcg_gen_movi_i32(hflags, ctx->hflags);
1602 ctx->saved_hflags = ctx->hflags;
1603 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
1604 case MIPS_HFLAG_BR:
1605 break;
1606 case MIPS_HFLAG_BC:
1607 case MIPS_HFLAG_BL:
1608 case MIPS_HFLAG_B:
1609 tcg_gen_movi_tl(btarget, ctx->btarget);
1610 break;
1611 }
1612 }
1613}
1614
1615static inline void restore_cpu_state(CPUMIPSState *env, DisasContext *ctx)
1616{
1617 ctx->saved_hflags = ctx->hflags;
1618 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
1619 case MIPS_HFLAG_BR:
1620 break;
1621 case MIPS_HFLAG_BC:
1622 case MIPS_HFLAG_BL:
1623 case MIPS_HFLAG_B:
1624 ctx->btarget = env->btarget;
1625 break;
1626 }
1627}
1628
1629static inline void generate_exception_err(DisasContext *ctx, int excp, int err)
1630{
1631 TCGv_i32 texcp = tcg_const_i32(excp);
1632 TCGv_i32 terr = tcg_const_i32(err);
1633 save_cpu_state(ctx, 1);
1634 gen_helper_raise_exception_err(cpu_env, texcp, terr);
1635 tcg_temp_free_i32(terr);
1636 tcg_temp_free_i32(texcp);
eeb3bba8 1637 ctx->base.is_jmp = DISAS_NORETURN;
eab9944c
LA
1638}
1639
1640static inline void generate_exception(DisasContext *ctx, int excp)
1641{
eab9944c
LA
1642 gen_helper_0e0i(raise_exception, excp);
1643}
1644
9c708c7f
PD
1645static inline void generate_exception_end(DisasContext *ctx, int excp)
1646{
1647 generate_exception_err(ctx, excp, 0);
1648}
1649
aaa9128a 1650/* Floating point register moves. */
7c979afd 1651static void gen_load_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
aa0bf00b 1652{
7c979afd
LA
1653 if (ctx->hflags & MIPS_HFLAG_FRE) {
1654 generate_exception(ctx, EXCP_RI);
1655 }
ecc7b3aa 1656 tcg_gen_extrl_i64_i32(t, fpu_f64[reg]);
6ea83fed
FB
1657}
1658
7c979afd 1659static void gen_store_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
aa0bf00b 1660{
7c979afd
LA
1661 TCGv_i64 t64;
1662 if (ctx->hflags & MIPS_HFLAG_FRE) {
1663 generate_exception(ctx, EXCP_RI);
1664 }
1665 t64 = tcg_temp_new_i64();
d73ee8a2
RH
1666 tcg_gen_extu_i32_i64(t64, t);
1667 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 0, 32);
1668 tcg_temp_free_i64(t64);
6d066274
AJ
1669}
1670
7f6613ce 1671static void gen_load_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
6d066274 1672{
7f6613ce 1673 if (ctx->hflags & MIPS_HFLAG_F64) {
71f303cd 1674 tcg_gen_extrh_i64_i32(t, fpu_f64[reg]);
7f6613ce 1675 } else {
7c979afd 1676 gen_load_fpr32(ctx, t, reg | 1);
7f6613ce 1677 }
6d066274
AJ
1678}
1679
7f6613ce 1680static void gen_store_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
6d066274 1681{
7f6613ce
PJ
1682 if (ctx->hflags & MIPS_HFLAG_F64) {
1683 TCGv_i64 t64 = tcg_temp_new_i64();
1684 tcg_gen_extu_i32_i64(t64, t);
1685 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 32, 32);
1686 tcg_temp_free_i64(t64);
1687 } else {
7c979afd 1688 gen_store_fpr32(ctx, t, reg | 1);
7f6613ce 1689 }
aa0bf00b 1690}
6ea83fed 1691
d73ee8a2 1692static void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
aa0bf00b 1693{
f364515c 1694 if (ctx->hflags & MIPS_HFLAG_F64) {
d73ee8a2 1695 tcg_gen_mov_i64(t, fpu_f64[reg]);
f364515c 1696 } else {
d73ee8a2 1697 tcg_gen_concat32_i64(t, fpu_f64[reg & ~1], fpu_f64[reg | 1]);
aa0bf00b
TS
1698 }
1699}
6ea83fed 1700
d73ee8a2 1701static void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
aa0bf00b 1702{
f364515c 1703 if (ctx->hflags & MIPS_HFLAG_F64) {
d73ee8a2 1704 tcg_gen_mov_i64(fpu_f64[reg], t);
f364515c 1705 } else {
d73ee8a2
RH
1706 TCGv_i64 t0;
1707 tcg_gen_deposit_i64(fpu_f64[reg & ~1], fpu_f64[reg & ~1], t, 0, 32);
1708 t0 = tcg_temp_new_i64();
6d066274 1709 tcg_gen_shri_i64(t0, t, 32);
d73ee8a2 1710 tcg_gen_deposit_i64(fpu_f64[reg | 1], fpu_f64[reg | 1], t0, 0, 32);
6d066274 1711 tcg_temp_free_i64(t0);
aa0bf00b
TS
1712 }
1713}
6ea83fed 1714
d94536f4 1715static inline int get_fp_bit (int cc)
a16336e4 1716{
d94536f4
AJ
1717 if (cc)
1718 return 24 + cc;
1719 else
1720 return 23;
a16336e4
TS
1721}
1722
48d38ca5 1723/* Addresses computation */
941694d0 1724static inline void gen_op_addr_add (DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1)
4ad40f36 1725{
941694d0 1726 tcg_gen_add_tl(ret, arg0, arg1);
48d38ca5
TS
1727
1728#if defined(TARGET_MIPS64)
01f72885 1729 if (ctx->hflags & MIPS_HFLAG_AWRAP) {
941694d0 1730 tcg_gen_ext32s_i64(ret, ret);
48d38ca5
TS
1731 }
1732#endif
4ad40f36
FB
1733}
1734
31837be3
YK
1735/* Addresses computation (translation time) */
1736static target_long addr_add(DisasContext *ctx, target_long base,
1737 target_long offset)
1738{
1739 target_long sum = base + offset;
1740
1741#if defined(TARGET_MIPS64)
1742 if (ctx->hflags & MIPS_HFLAG_AWRAP) {
1743 sum = (int32_t)sum;
1744 }
1745#endif
1746 return sum;
1747}
1748
71f303cd 1749/* Sign-extract the low 32-bits to a target_long. */
1f1b4c00
YK
1750static inline void gen_move_low32(TCGv ret, TCGv_i64 arg)
1751{
1752#if defined(TARGET_MIPS64)
71f303cd
RH
1753 tcg_gen_ext32s_i64(ret, arg);
1754#else
1755 tcg_gen_extrl_i64_i32(ret, arg);
1756#endif
1757}
1758
1759/* Sign-extract the high 32-bits to a target_long. */
1760static inline void gen_move_high32(TCGv ret, TCGv_i64 arg)
1761{
1762#if defined(TARGET_MIPS64)
1763 tcg_gen_sari_i64(ret, arg, 32);
1f1b4c00 1764#else
71f303cd 1765 tcg_gen_extrh_i64_i32(ret, arg);
1f1b4c00
YK
1766#endif
1767}
1768
356265ae 1769static inline void check_cp0_enabled(DisasContext *ctx)
387a8fe5 1770{
fe253235 1771 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
c2c65dab 1772 generate_exception_err(ctx, EXCP_CpU, 0);
387a8fe5
TS
1773}
1774
356265ae 1775static inline void check_cp1_enabled(DisasContext *ctx)
5e755519 1776{
fe253235 1777 if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
5e755519
TS
1778 generate_exception_err(ctx, EXCP_CpU, 1);
1779}
1780
b8aa4598
TS
1781/* Verify that the processor is running with COP1X instructions enabled.
1782 This is associated with the nabla symbol in the MIPS32 and MIPS64
1783 opcode tables. */
1784
356265ae 1785static inline void check_cop1x(DisasContext *ctx)
b8aa4598
TS
1786{
1787 if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
9c708c7f 1788 generate_exception_end(ctx, EXCP_RI);
b8aa4598
TS
1789}
1790
1791/* Verify that the processor is running with 64-bit floating-point
1792 operations enabled. */
1793
356265ae 1794static inline void check_cp1_64bitmode(DisasContext *ctx)
5e755519 1795{
b8aa4598 1796 if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
9c708c7f 1797 generate_exception_end(ctx, EXCP_RI);
5e755519
TS
1798}
1799
1800/*
1801 * Verify if floating point register is valid; an operation is not defined
1802 * if bit 0 of any register specification is set and the FR bit in the
1803 * Status register equals zero, since the register numbers specify an
1804 * even-odd pair of adjacent coprocessor general registers. When the FR bit
1805 * in the Status register equals one, both even and odd register numbers
1806 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
1807 *
1808 * Multiple 64 bit wide registers can be checked by calling
1809 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
1810 */
356265ae 1811static inline void check_cp1_registers(DisasContext *ctx, int regs)
5e755519 1812{
fe253235 1813 if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)))
9c708c7f 1814 generate_exception_end(ctx, EXCP_RI);
5e755519
TS
1815}
1816
853c3240
JL
1817/* Verify that the processor is running with DSP instructions enabled.
1818 This is enabled by CP0 Status register MX(24) bit.
1819 */
1820
1821static inline void check_dsp(DisasContext *ctx)
1822{
1823 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP))) {
ad153f15 1824 if (ctx->insn_flags & ASE_DSP) {
9c708c7f 1825 generate_exception_end(ctx, EXCP_DSPDIS);
ad153f15 1826 } else {
9c708c7f 1827 generate_exception_end(ctx, EXCP_RI);
ad153f15 1828 }
853c3240
JL
1829 }
1830}
1831
1832static inline void check_dspr2(DisasContext *ctx)
1833{
1834 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSPR2))) {
ad153f15 1835 if (ctx->insn_flags & ASE_DSP) {
9c708c7f 1836 generate_exception_end(ctx, EXCP_DSPDIS);
ad153f15 1837 } else {
9c708c7f 1838 generate_exception_end(ctx, EXCP_RI);
ad153f15 1839 }
853c3240
JL
1840 }
1841}
1842
3a95e3a7 1843/* This code generates a "reserved instruction" exception if the
e189e748 1844 CPU does not support the instruction set corresponding to flags. */
d75c135e 1845static inline void check_insn(DisasContext *ctx, int flags)
3a95e3a7 1846{
d75c135e 1847 if (unlikely(!(ctx->insn_flags & flags))) {
9c708c7f 1848 generate_exception_end(ctx, EXCP_RI);
d75c135e 1849 }
3a95e3a7
TS
1850}
1851
fecd2646
LA
1852/* This code generates a "reserved instruction" exception if the
1853 CPU has corresponding flag set which indicates that the instruction
1854 has been removed. */
1855static inline void check_insn_opc_removed(DisasContext *ctx, int flags)
1856{
1857 if (unlikely(ctx->insn_flags & flags)) {
9c708c7f 1858 generate_exception_end(ctx, EXCP_RI);
fecd2646
LA
1859 }
1860}
1861
e29c9628
YK
1862/* This code generates a "reserved instruction" exception if the
1863 CPU does not support 64-bit paired-single (PS) floating point data type */
1864static inline void check_ps(DisasContext *ctx)
1865{
1866 if (unlikely(!ctx->ps)) {
1867 generate_exception(ctx, EXCP_RI);
1868 }
1869 check_cp1_64bitmode(ctx);
1870}
1871
c7986fd6 1872#ifdef TARGET_MIPS64
e189e748
TS
1873/* This code generates a "reserved instruction" exception if 64-bit
1874 instructions are not enabled. */
356265ae 1875static inline void check_mips_64(DisasContext *ctx)
e189e748 1876{
fe253235 1877 if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
9c708c7f 1878 generate_exception_end(ctx, EXCP_RI);
e189e748 1879}
c7986fd6 1880#endif
e189e748 1881
5204ea79
LA
1882#ifndef CONFIG_USER_ONLY
1883static inline void check_mvh(DisasContext *ctx)
1884{
1885 if (unlikely(!ctx->mvh)) {
1886 generate_exception(ctx, EXCP_RI);
1887 }
1888}
1889#endif
1890
8153667c
NF
1891/* Define small wrappers for gen_load_fpr* so that we have a uniform
1892 calling interface for 32 and 64-bit FPRs. No sense in changing
1893 all callers for gen_load_fpr32 when we need the CTX parameter for
1894 this one use. */
7c979afd 1895#define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(ctx, x, y)
8153667c
NF
1896#define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
1897#define FOP_CONDS(type, abs, fmt, ifmt, bits) \
1898static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \
1899 int ft, int fs, int cc) \
1900{ \
1901 TCGv_i##bits fp0 = tcg_temp_new_i##bits (); \
1902 TCGv_i##bits fp1 = tcg_temp_new_i##bits (); \
1903 switch (ifmt) { \
1904 case FMT_PS: \
e29c9628 1905 check_ps(ctx); \
8153667c
NF
1906 break; \
1907 case FMT_D: \
1908 if (abs) { \
1909 check_cop1x(ctx); \
1910 } \
1911 check_cp1_registers(ctx, fs | ft); \
1912 break; \
1913 case FMT_S: \
1914 if (abs) { \
1915 check_cop1x(ctx); \
1916 } \
1917 break; \
1918 } \
1919 gen_ldcmp_fpr##bits (ctx, fp0, fs); \
1920 gen_ldcmp_fpr##bits (ctx, fp1, ft); \
1921 switch (n) { \
895c2d04
BS
1922 case 0: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc); break;\
1923 case 1: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc); break;\
1924 case 2: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc); break;\
1925 case 3: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc); break;\
1926 case 4: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc); break;\
1927 case 5: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc); break;\
1928 case 6: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc); break;\
1929 case 7: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc); break;\
1930 case 8: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc); break;\
1931 case 9: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); break;\
1932 case 10: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc); break;\
1933 case 11: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc); break;\
1934 case 12: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc); break;\
1935 case 13: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc); break;\
1936 case 14: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc); break;\
1937 case 15: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc); break;\
8153667c
NF
1938 default: abort(); \
1939 } \
1940 tcg_temp_free_i##bits (fp0); \
1941 tcg_temp_free_i##bits (fp1); \
1942}
1943
1944FOP_CONDS(, 0, d, FMT_D, 64)
1945FOP_CONDS(abs, 1, d, FMT_D, 64)
1946FOP_CONDS(, 0, s, FMT_S, 32)
1947FOP_CONDS(abs, 1, s, FMT_S, 32)
1948FOP_CONDS(, 0, ps, FMT_PS, 64)
1949FOP_CONDS(abs, 1, ps, FMT_PS, 64)
1950#undef FOP_CONDS
3f493883
YK
1951
1952#define FOP_CONDNS(fmt, ifmt, bits, STORE) \
1953static inline void gen_r6_cmp_ ## fmt(DisasContext * ctx, int n, \
1954 int ft, int fs, int fd) \
1955{ \
1956 TCGv_i ## bits fp0 = tcg_temp_new_i ## bits(); \
1957 TCGv_i ## bits fp1 = tcg_temp_new_i ## bits(); \
00fb4a11 1958 if (ifmt == FMT_D) { \
3f493883 1959 check_cp1_registers(ctx, fs | ft | fd); \
3f493883
YK
1960 } \
1961 gen_ldcmp_fpr ## bits(ctx, fp0, fs); \
1962 gen_ldcmp_fpr ## bits(ctx, fp1, ft); \
1963 switch (n) { \
1964 case 0: \
1965 gen_helper_r6_cmp_ ## fmt ## _af(fp0, cpu_env, fp0, fp1); \
1966 break; \
1967 case 1: \
1968 gen_helper_r6_cmp_ ## fmt ## _un(fp0, cpu_env, fp0, fp1); \
1969 break; \
1970 case 2: \
1971 gen_helper_r6_cmp_ ## fmt ## _eq(fp0, cpu_env, fp0, fp1); \
1972 break; \
1973 case 3: \
1974 gen_helper_r6_cmp_ ## fmt ## _ueq(fp0, cpu_env, fp0, fp1); \
1975 break; \
1976 case 4: \
1977 gen_helper_r6_cmp_ ## fmt ## _lt(fp0, cpu_env, fp0, fp1); \
1978 break; \
1979 case 5: \
1980 gen_helper_r6_cmp_ ## fmt ## _ult(fp0, cpu_env, fp0, fp1); \
1981 break; \
1982 case 6: \
1983 gen_helper_r6_cmp_ ## fmt ## _le(fp0, cpu_env, fp0, fp1); \
1984 break; \
1985 case 7: \
1986 gen_helper_r6_cmp_ ## fmt ## _ule(fp0, cpu_env, fp0, fp1); \
1987 break; \
1988 case 8: \
1989 gen_helper_r6_cmp_ ## fmt ## _saf(fp0, cpu_env, fp0, fp1); \
1990 break; \
1991 case 9: \
1992 gen_helper_r6_cmp_ ## fmt ## _sun(fp0, cpu_env, fp0, fp1); \
1993 break; \
1994 case 10: \
1995 gen_helper_r6_cmp_ ## fmt ## _seq(fp0, cpu_env, fp0, fp1); \
1996 break; \
1997 case 11: \
1998 gen_helper_r6_cmp_ ## fmt ## _sueq(fp0, cpu_env, fp0, fp1); \
1999 break; \
2000 case 12: \
2001 gen_helper_r6_cmp_ ## fmt ## _slt(fp0, cpu_env, fp0, fp1); \
2002 break; \
2003 case 13: \
2004 gen_helper_r6_cmp_ ## fmt ## _sult(fp0, cpu_env, fp0, fp1); \
2005 break; \
2006 case 14: \
2007 gen_helper_r6_cmp_ ## fmt ## _sle(fp0, cpu_env, fp0, fp1); \
2008 break; \
2009 case 15: \
2010 gen_helper_r6_cmp_ ## fmt ## _sule(fp0, cpu_env, fp0, fp1); \
2011 break; \
2012 case 17: \
2013 gen_helper_r6_cmp_ ## fmt ## _or(fp0, cpu_env, fp0, fp1); \
2014 break; \
2015 case 18: \
2016 gen_helper_r6_cmp_ ## fmt ## _une(fp0, cpu_env, fp0, fp1); \
2017 break; \
2018 case 19: \
2019 gen_helper_r6_cmp_ ## fmt ## _ne(fp0, cpu_env, fp0, fp1); \
2020 break; \
2021 case 25: \
2022 gen_helper_r6_cmp_ ## fmt ## _sor(fp0, cpu_env, fp0, fp1); \
2023 break; \
2024 case 26: \
2025 gen_helper_r6_cmp_ ## fmt ## _sune(fp0, cpu_env, fp0, fp1); \
2026 break; \
2027 case 27: \
2028 gen_helper_r6_cmp_ ## fmt ## _sne(fp0, cpu_env, fp0, fp1); \
2029 break; \
2030 default: \
2031 abort(); \
2032 } \
2033 STORE; \
2034 tcg_temp_free_i ## bits (fp0); \
2035 tcg_temp_free_i ## bits (fp1); \
2036}
2037
2038FOP_CONDNS(d, FMT_D, 64, gen_store_fpr64(ctx, fp0, fd))
7c979afd 2039FOP_CONDNS(s, FMT_S, 32, gen_store_fpr32(ctx, fp0, fd))
3f493883 2040#undef FOP_CONDNS
8153667c
NF
2041#undef gen_ldcmp_fpr32
2042#undef gen_ldcmp_fpr64
2043
958fb4a9 2044/* load/store instructions. */
e7139c44 2045#ifdef CONFIG_USER_ONLY
d9bea114 2046#define OP_LD_ATOMIC(insn,fname) \
dd4096cd
JH
2047static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx, \
2048 DisasContext *ctx) \
d9bea114
AJ
2049{ \
2050 TCGv t0 = tcg_temp_new(); \
2051 tcg_gen_mov_tl(t0, arg1); \
2052 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
7db13fae
AF
2053 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
2054 tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval)); \
d9bea114 2055 tcg_temp_free(t0); \
aaa9128a 2056}
e7139c44
AJ
2057#else
2058#define OP_LD_ATOMIC(insn,fname) \
dd4096cd
JH
2059static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx, \
2060 DisasContext *ctx) \
e7139c44 2061{ \
dd4096cd 2062 gen_helper_1e1i(insn, ret, arg1, mem_idx); \
e7139c44
AJ
2063}
2064#endif
aaa9128a
TS
2065OP_LD_ATOMIC(ll,ld32s);
2066#if defined(TARGET_MIPS64)
2067OP_LD_ATOMIC(lld,ld64);
2068#endif
2069#undef OP_LD_ATOMIC
2070
590bc601
PB
2071#ifdef CONFIG_USER_ONLY
2072#define OP_ST_ATOMIC(insn,fname,ldname,almask) \
dd4096cd
JH
2073static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, int mem_idx, \
2074 DisasContext *ctx) \
590bc601
PB
2075{ \
2076 TCGv t0 = tcg_temp_new(); \
42a268c2
RH
2077 TCGLabel *l1 = gen_new_label(); \
2078 TCGLabel *l2 = gen_new_label(); \
590bc601
PB
2079 \
2080 tcg_gen_andi_tl(t0, arg2, almask); \
2081 tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1); \
7db13fae 2082 tcg_gen_st_tl(arg2, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr)); \
590bc601
PB
2083 generate_exception(ctx, EXCP_AdES); \
2084 gen_set_label(l1); \
7db13fae 2085 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
590bc601
PB
2086 tcg_gen_brcond_tl(TCG_COND_NE, arg2, t0, l2); \
2087 tcg_gen_movi_tl(t0, rt | ((almask << 3) & 0x20)); \
7db13fae
AF
2088 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, llreg)); \
2089 tcg_gen_st_tl(arg1, cpu_env, offsetof(CPUMIPSState, llnewval)); \
9c708c7f 2090 generate_exception_end(ctx, EXCP_SC); \
590bc601
PB
2091 gen_set_label(l2); \
2092 tcg_gen_movi_tl(t0, 0); \
2093 gen_store_gpr(t0, rt); \
2094 tcg_temp_free(t0); \
2095}
2096#else
2097#define OP_ST_ATOMIC(insn,fname,ldname,almask) \
dd4096cd
JH
2098static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, int mem_idx, \
2099 DisasContext *ctx) \
590bc601
PB
2100{ \
2101 TCGv t0 = tcg_temp_new(); \
dd4096cd 2102 gen_helper_1e2i(insn, t0, arg1, arg2, mem_idx); \
590bc601 2103 gen_store_gpr(t0, rt); \
590bc601
PB
2104 tcg_temp_free(t0); \
2105}
2106#endif
590bc601 2107OP_ST_ATOMIC(sc,st32,ld32s,0x3);
aaa9128a 2108#if defined(TARGET_MIPS64)
590bc601 2109OP_ST_ATOMIC(scd,st64,ld64,0x7);
aaa9128a
TS
2110#endif
2111#undef OP_ST_ATOMIC
2112
662d7485
NF
2113static void gen_base_offset_addr (DisasContext *ctx, TCGv addr,
2114 int base, int16_t offset)
2115{
2116 if (base == 0) {
2117 tcg_gen_movi_tl(addr, offset);
2118 } else if (offset == 0) {
2119 gen_load_gpr(addr, base);
2120 } else {
2121 tcg_gen_movi_tl(addr, offset);
2122 gen_op_addr_add(ctx, addr, cpu_gpr[base], addr);
2123 }
2124}
2125
364d4831
NF
2126static target_ulong pc_relative_pc (DisasContext *ctx)
2127{
eeb3bba8 2128 target_ulong pc = ctx->base.pc_next;
364d4831
NF
2129
2130 if (ctx->hflags & MIPS_HFLAG_BMASK) {
2131 int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
2132
2133 pc -= branch_bytes;
2134 }
2135
2136 pc &= ~(target_ulong)3;
2137 return pc;
2138}
2139
5c13fdfd 2140/* Load */
d75c135e
AJ
2141static void gen_ld(DisasContext *ctx, uint32_t opc,
2142 int rt, int base, int16_t offset)
6af0bf9c 2143{
fc40787a 2144 TCGv t0, t1, t2;
dd4096cd 2145 int mem_idx = ctx->mem_idx;
afa88c3a 2146
d75c135e 2147 if (rt == 0 && ctx->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)) {
afa88c3a
AJ
2148 /* Loongson CPU uses a load to zero register for prefetch.
2149 We emulate it as a NOP. On other CPU we must perform the
2150 actual memory access. */
afa88c3a
AJ
2151 return;
2152 }
6af0bf9c 2153
afa88c3a 2154 t0 = tcg_temp_new();
662d7485 2155 gen_base_offset_addr(ctx, t0, base, offset);
afa88c3a 2156
6af0bf9c 2157 switch (opc) {
d26bc211 2158#if defined(TARGET_MIPS64)
6e473128 2159 case OPC_LWU:
dd4096cd 2160 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL |
be3a8c53 2161 ctx->default_tcg_memop_mask);
78723684 2162 gen_store_gpr(t0, rt);
6e473128 2163 break;
6af0bf9c 2164 case OPC_LD:
dd4096cd 2165 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ |
be3a8c53 2166 ctx->default_tcg_memop_mask);
78723684 2167 gen_store_gpr(t0, rt);
6af0bf9c 2168 break;
7a387fff 2169 case OPC_LLD:
bf7910c6 2170 case R6_OPC_LLD:
dd4096cd 2171 op_ld_lld(t0, t0, mem_idx, ctx);
78723684 2172 gen_store_gpr(t0, rt);
7a387fff 2173 break;
6af0bf9c 2174 case OPC_LDL:
3cee3050 2175 t1 = tcg_temp_new();
908680c6
AJ
2176 /* Do a byte access to possibly trigger a page
2177 fault with the unaligned address. */
dd4096cd 2178 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
fc40787a
AJ
2179 tcg_gen_andi_tl(t1, t0, 7);
2180#ifndef TARGET_WORDS_BIGENDIAN
2181 tcg_gen_xori_tl(t1, t1, 7);
2182#endif
2183 tcg_gen_shli_tl(t1, t1, 3);
2184 tcg_gen_andi_tl(t0, t0, ~7);
dd4096cd 2185 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
fc40787a 2186 tcg_gen_shl_tl(t0, t0, t1);
eb02cc3f
AJ
2187 t2 = tcg_const_tl(-1);
2188 tcg_gen_shl_tl(t2, t2, t1);
78723684 2189 gen_load_gpr(t1, rt);
eb02cc3f 2190 tcg_gen_andc_tl(t1, t1, t2);
fc40787a
AJ
2191 tcg_temp_free(t2);
2192 tcg_gen_or_tl(t0, t0, t1);
3cee3050 2193 tcg_temp_free(t1);
fc40787a 2194 gen_store_gpr(t0, rt);
6af0bf9c 2195 break;
6af0bf9c 2196 case OPC_LDR:
3cee3050 2197 t1 = tcg_temp_new();
908680c6
AJ
2198 /* Do a byte access to possibly trigger a page
2199 fault with the unaligned address. */
dd4096cd 2200 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
fc40787a
AJ
2201 tcg_gen_andi_tl(t1, t0, 7);
2202#ifdef TARGET_WORDS_BIGENDIAN
2203 tcg_gen_xori_tl(t1, t1, 7);
2204#endif
2205 tcg_gen_shli_tl(t1, t1, 3);
2206 tcg_gen_andi_tl(t0, t0, ~7);
dd4096cd 2207 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
fc40787a
AJ
2208 tcg_gen_shr_tl(t0, t0, t1);
2209 tcg_gen_xori_tl(t1, t1, 63);
2210 t2 = tcg_const_tl(0xfffffffffffffffeull);
2211 tcg_gen_shl_tl(t2, t2, t1);
78723684 2212 gen_load_gpr(t1, rt);
fc40787a
AJ
2213 tcg_gen_and_tl(t1, t1, t2);
2214 tcg_temp_free(t2);
2215 tcg_gen_or_tl(t0, t0, t1);
3cee3050 2216 tcg_temp_free(t1);
fc40787a 2217 gen_store_gpr(t0, rt);
6af0bf9c 2218 break;
364d4831 2219 case OPC_LDPC:
3cee3050 2220 t1 = tcg_const_tl(pc_relative_pc(ctx));
364d4831 2221 gen_op_addr_add(ctx, t0, t0, t1);
3cee3050 2222 tcg_temp_free(t1);
dd4096cd 2223 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
364d4831
NF
2224 gen_store_gpr(t0, rt);
2225 break;
6af0bf9c 2226#endif
364d4831 2227 case OPC_LWPC:
3cee3050 2228 t1 = tcg_const_tl(pc_relative_pc(ctx));
364d4831 2229 gen_op_addr_add(ctx, t0, t0, t1);
3cee3050 2230 tcg_temp_free(t1);
dd4096cd 2231 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESL);
364d4831
NF
2232 gen_store_gpr(t0, rt);
2233 break;
76964147
JH
2234 case OPC_LWE:
2235 mem_idx = MIPS_HFLAG_UM;
2236 /* fall through */
6af0bf9c 2237 case OPC_LW:
dd4096cd 2238 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESL |
be3a8c53 2239 ctx->default_tcg_memop_mask);
78723684 2240 gen_store_gpr(t0, rt);
6af0bf9c 2241 break;
76964147
JH
2242 case OPC_LHE:
2243 mem_idx = MIPS_HFLAG_UM;
2244 /* fall through */
6af0bf9c 2245 case OPC_LH:
dd4096cd 2246 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESW |
be3a8c53 2247 ctx->default_tcg_memop_mask);
78723684 2248 gen_store_gpr(t0, rt);
6af0bf9c 2249 break;
76964147
JH
2250 case OPC_LHUE:
2251 mem_idx = MIPS_HFLAG_UM;
2252 /* fall through */
6af0bf9c 2253 case OPC_LHU:
dd4096cd 2254 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUW |
be3a8c53 2255 ctx->default_tcg_memop_mask);
78723684 2256 gen_store_gpr(t0, rt);
6af0bf9c 2257 break;
76964147
JH
2258 case OPC_LBE:
2259 mem_idx = MIPS_HFLAG_UM;
2260 /* fall through */
6af0bf9c 2261 case OPC_LB:
dd4096cd 2262 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_SB);
78723684 2263 gen_store_gpr(t0, rt);
6af0bf9c 2264 break;
76964147
JH
2265 case OPC_LBUE:
2266 mem_idx = MIPS_HFLAG_UM;
2267 /* fall through */
6af0bf9c 2268 case OPC_LBU:
dd4096cd 2269 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_UB);
78723684 2270 gen_store_gpr(t0, rt);
6af0bf9c 2271 break;
76964147
JH
2272 case OPC_LWLE:
2273 mem_idx = MIPS_HFLAG_UM;
2274 /* fall through */
6af0bf9c 2275 case OPC_LWL:
3cee3050 2276 t1 = tcg_temp_new();
908680c6
AJ
2277 /* Do a byte access to possibly trigger a page
2278 fault with the unaligned address. */
dd4096cd 2279 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
fc40787a
AJ
2280 tcg_gen_andi_tl(t1, t0, 3);
2281#ifndef TARGET_WORDS_BIGENDIAN
2282 tcg_gen_xori_tl(t1, t1, 3);
2283#endif
2284 tcg_gen_shli_tl(t1, t1, 3);
2285 tcg_gen_andi_tl(t0, t0, ~3);
dd4096cd 2286 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL);
fc40787a 2287 tcg_gen_shl_tl(t0, t0, t1);
eb02cc3f
AJ
2288 t2 = tcg_const_tl(-1);
2289 tcg_gen_shl_tl(t2, t2, t1);
6958549d 2290 gen_load_gpr(t1, rt);
eb02cc3f 2291 tcg_gen_andc_tl(t1, t1, t2);
fc40787a
AJ
2292 tcg_temp_free(t2);
2293 tcg_gen_or_tl(t0, t0, t1);
3cee3050 2294 tcg_temp_free(t1);
fc40787a
AJ
2295 tcg_gen_ext32s_tl(t0, t0);
2296 gen_store_gpr(t0, rt);
6af0bf9c 2297 break;
76964147
JH
2298 case OPC_LWRE:
2299 mem_idx = MIPS_HFLAG_UM;
2300 /* fall through */
6af0bf9c 2301 case OPC_LWR:
3cee3050 2302 t1 = tcg_temp_new();
908680c6
AJ
2303 /* Do a byte access to possibly trigger a page
2304 fault with the unaligned address. */
dd4096cd 2305 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
fc40787a
AJ
2306 tcg_gen_andi_tl(t1, t0, 3);
2307#ifdef TARGET_WORDS_BIGENDIAN
2308 tcg_gen_xori_tl(t1, t1, 3);
2309#endif
2310 tcg_gen_shli_tl(t1, t1, 3);
2311 tcg_gen_andi_tl(t0, t0, ~3);
dd4096cd 2312 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL);
fc40787a
AJ
2313 tcg_gen_shr_tl(t0, t0, t1);
2314 tcg_gen_xori_tl(t1, t1, 31);
2315 t2 = tcg_const_tl(0xfffffffeull);
2316 tcg_gen_shl_tl(t2, t2, t1);
6958549d 2317 gen_load_gpr(t1, rt);
fc40787a
AJ
2318 tcg_gen_and_tl(t1, t1, t2);
2319 tcg_temp_free(t2);
2320 tcg_gen_or_tl(t0, t0, t1);
3cee3050 2321 tcg_temp_free(t1);
c728154b 2322 tcg_gen_ext32s_tl(t0, t0);
fc40787a 2323 gen_store_gpr(t0, rt);
6af0bf9c 2324 break;
76964147
JH
2325 case OPC_LLE:
2326 mem_idx = MIPS_HFLAG_UM;
2327 /* fall through */
6af0bf9c 2328 case OPC_LL:
4368b29a 2329 case R6_OPC_LL:
dd4096cd 2330 op_ld_ll(t0, t0, mem_idx, ctx);
78723684 2331 gen_store_gpr(t0, rt);
6af0bf9c 2332 break;
d66c7132 2333 }
d66c7132 2334 tcg_temp_free(t0);
d66c7132
AJ
2335}
2336
5c13fdfd
AJ
2337/* Store */
2338static void gen_st (DisasContext *ctx, uint32_t opc, int rt,
2339 int base, int16_t offset)
2340{
5c13fdfd
AJ
2341 TCGv t0 = tcg_temp_new();
2342 TCGv t1 = tcg_temp_new();
dd4096cd 2343 int mem_idx = ctx->mem_idx;
5c13fdfd
AJ
2344
2345 gen_base_offset_addr(ctx, t0, base, offset);
2346 gen_load_gpr(t1, rt);
2347 switch (opc) {
2348#if defined(TARGET_MIPS64)
2349 case OPC_SD:
dd4096cd 2350 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEQ |
be3a8c53 2351 ctx->default_tcg_memop_mask);
5c13fdfd
AJ
2352 break;
2353 case OPC_SDL:
dd4096cd 2354 gen_helper_0e2i(sdl, t1, t0, mem_idx);
5c13fdfd
AJ
2355 break;
2356 case OPC_SDR:
dd4096cd 2357 gen_helper_0e2i(sdr, t1, t0, mem_idx);
5c13fdfd
AJ
2358 break;
2359#endif
76964147
JH
2360 case OPC_SWE:
2361 mem_idx = MIPS_HFLAG_UM;
2362 /* fall through */
5c13fdfd 2363 case OPC_SW:
dd4096cd 2364 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUL |
be3a8c53 2365 ctx->default_tcg_memop_mask);
5c13fdfd 2366 break;
76964147
JH
2367 case OPC_SHE:
2368 mem_idx = MIPS_HFLAG_UM;
2369 /* fall through */
5c13fdfd 2370 case OPC_SH:
dd4096cd 2371 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUW |
be3a8c53 2372 ctx->default_tcg_memop_mask);
5c13fdfd 2373 break;
76964147
JH
2374 case OPC_SBE:
2375 mem_idx = MIPS_HFLAG_UM;
2376 /* fall through */
5c13fdfd 2377 case OPC_SB:
dd4096cd 2378 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_8);
5c13fdfd 2379 break;
76964147
JH
2380 case OPC_SWLE:
2381 mem_idx = MIPS_HFLAG_UM;
2382 /* fall through */
5c13fdfd 2383 case OPC_SWL:
dd4096cd 2384 gen_helper_0e2i(swl, t1, t0, mem_idx);
5c13fdfd 2385 break;
76964147
JH
2386 case OPC_SWRE:
2387 mem_idx = MIPS_HFLAG_UM;
2388 /* fall through */
5c13fdfd 2389 case OPC_SWR:
dd4096cd 2390 gen_helper_0e2i(swr, t1, t0, mem_idx);
5c13fdfd
AJ
2391 break;
2392 }
5c13fdfd
AJ
2393 tcg_temp_free(t0);
2394 tcg_temp_free(t1);
2395}
2396
2397
d66c7132
AJ
2398/* Store conditional */
2399static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt,
2400 int base, int16_t offset)
2401{
d66c7132 2402 TCGv t0, t1;
dd4096cd 2403 int mem_idx = ctx->mem_idx;
d66c7132 2404
2d2826b9 2405#ifdef CONFIG_USER_ONLY
d66c7132 2406 t0 = tcg_temp_local_new();
d66c7132 2407 t1 = tcg_temp_local_new();
2d2826b9
AJ
2408#else
2409 t0 = tcg_temp_new();
2410 t1 = tcg_temp_new();
2411#endif
2412 gen_base_offset_addr(ctx, t0, base, offset);
d66c7132
AJ
2413 gen_load_gpr(t1, rt);
2414 switch (opc) {
2415#if defined(TARGET_MIPS64)
2416 case OPC_SCD:
bf7910c6 2417 case R6_OPC_SCD:
dd4096cd 2418 op_st_scd(t1, t0, rt, mem_idx, ctx);
d66c7132
AJ
2419 break;
2420#endif
76964147
JH
2421 case OPC_SCE:
2422 mem_idx = MIPS_HFLAG_UM;
2423 /* fall through */
6af0bf9c 2424 case OPC_SC:
4368b29a 2425 case R6_OPC_SC:
dd4096cd 2426 op_st_sc(t1, t0, rt, mem_idx, ctx);
6af0bf9c 2427 break;
6af0bf9c 2428 }
78723684 2429 tcg_temp_free(t1);
d66c7132 2430 tcg_temp_free(t0);
6af0bf9c
FB
2431}
2432
6ea83fed 2433/* Load and store */
7a387fff 2434static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
356265ae 2435 int base, int16_t offset)
6ea83fed 2436{
4e2474d6 2437 TCGv t0 = tcg_temp_new();
6ea83fed 2438
662d7485 2439 gen_base_offset_addr(ctx, t0, base, offset);
6ea83fed 2440 /* Don't do NOP if destination is zero: we must perform the actual
ead9360e 2441 memory access. */
6ea83fed
FB
2442 switch (opc) {
2443 case OPC_LWC1:
b6d96bed 2444 {
a7812ae4 2445 TCGv_i32 fp0 = tcg_temp_new_i32();
be3a8c53
YK
2446 tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, MO_TESL |
2447 ctx->default_tcg_memop_mask);
7c979afd 2448 gen_store_fpr32(ctx, fp0, ft);
a7812ae4 2449 tcg_temp_free_i32(fp0);
b6d96bed 2450 }
6ea83fed
FB
2451 break;
2452 case OPC_SWC1:
b6d96bed 2453 {
a7812ae4 2454 TCGv_i32 fp0 = tcg_temp_new_i32();
7c979afd 2455 gen_load_fpr32(ctx, fp0, ft);
be3a8c53
YK
2456 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL |
2457 ctx->default_tcg_memop_mask);
a7812ae4 2458 tcg_temp_free_i32(fp0);
b6d96bed 2459 }
6ea83fed
FB
2460 break;
2461 case OPC_LDC1:
b6d96bed 2462 {
a7812ae4 2463 TCGv_i64 fp0 = tcg_temp_new_i64();
be3a8c53
YK
2464 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ |
2465 ctx->default_tcg_memop_mask);
b6d96bed 2466 gen_store_fpr64(ctx, fp0, ft);
a7812ae4 2467 tcg_temp_free_i64(fp0);
b6d96bed 2468 }
6ea83fed
FB
2469 break;
2470 case OPC_SDC1:
b6d96bed 2471 {
a7812ae4 2472 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 2473 gen_load_fpr64(ctx, fp0, ft);
be3a8c53
YK
2474 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ |
2475 ctx->default_tcg_memop_mask);
a7812ae4 2476 tcg_temp_free_i64(fp0);
b6d96bed 2477 }
6ea83fed
FB
2478 break;
2479 default:
9d68ac14 2480 MIPS_INVAL("flt_ldst");
9c708c7f 2481 generate_exception_end(ctx, EXCP_RI);
78723684 2482 goto out;
6ea83fed 2483 }
78723684
TS
2484 out:
2485 tcg_temp_free(t0);
6ea83fed 2486}
6ea83fed 2487
5ab5c041
AJ
2488static void gen_cop1_ldst(DisasContext *ctx, uint32_t op, int rt,
2489 int rs, int16_t imm)
26ebe468 2490{
5ab5c041 2491 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
26ebe468 2492 check_cp1_enabled(ctx);
d9224450
MR
2493 switch (op) {
2494 case OPC_LDC1:
2495 case OPC_SDC1:
2496 check_insn(ctx, ISA_MIPS2);
2497 /* Fallthrough */
2498 default:
2499 gen_flt_ldst(ctx, op, rt, rs, imm);
2500 }
26ebe468
NF
2501 } else {
2502 generate_exception_err(ctx, EXCP_CpU, 1);
2503 }
2504}
2505
6af0bf9c 2506/* Arithmetic with immediate operand */
d75c135e
AJ
2507static void gen_arith_imm(DisasContext *ctx, uint32_t opc,
2508 int rt, int rs, int16_t 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);
eeb3bba8 4293 tcg_gen_exit_tb((uintptr_t)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) {
fd88b6ab 5497 case 0 ... 7:
895c2d04 5498 gen_helper_1e0i(mfc0_watchlo, arg, sel);
2423f660
TS
5499 rn = "WatchLo";
5500 break;
7a387fff 5501 default:
f31b035a 5502 goto cp0_unimplemented;
7a387fff 5503 }
873eb012
TS
5504 break;
5505 case 19:
7a387fff 5506 switch (sel) {
fd88b6ab 5507 case 0 ...7:
895c2d04 5508 gen_helper_1e0i(mfc0_watchhi, arg, sel);
2423f660
TS
5509 rn = "WatchHi";
5510 break;
7a387fff 5511 default:
f31b035a 5512 goto cp0_unimplemented;
7a387fff 5513 }
873eb012 5514 break;
8c0fdd85 5515 case 20:
7a387fff
TS
5516 switch (sel) {
5517 case 0:
d26bc211 5518#if defined(TARGET_MIPS64)
d75c135e 5519 check_insn(ctx, ISA_MIPS3);
7db13fae 5520 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
d9bea114 5521 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
5522 rn = "XContext";
5523 break;
703eaf37 5524#endif
7a387fff 5525 default:
f31b035a 5526 goto cp0_unimplemented;
7a387fff 5527 }
8c0fdd85
TS
5528 break;
5529 case 21:
7a387fff 5530 /* Officially reserved, but sel 0 is used for R1x000 framemask */
f31b035a 5531 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
7a387fff
TS
5532 switch (sel) {
5533 case 0:
7db13fae 5534 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
2423f660
TS
5535 rn = "Framemask";
5536 break;
7a387fff 5537 default:
f31b035a 5538 goto cp0_unimplemented;
7a387fff 5539 }
8c0fdd85
TS
5540 break;
5541 case 22:
d9bea114 5542 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
5543 rn = "'Diagnostic"; /* implementation dependent */
5544 break;
873eb012 5545 case 23:
7a387fff
TS
5546 switch (sel) {
5547 case 0:
895c2d04 5548 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
2423f660
TS
5549 rn = "Debug";
5550 break;
7a387fff 5551 case 1:
d9bea114 5552// gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
2423f660 5553 rn = "TraceControl";
3570d7f6 5554 goto cp0_unimplemented;
7a387fff 5555 case 2:
d9bea114 5556// gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
2423f660 5557 rn = "TraceControl2";
3570d7f6 5558 goto cp0_unimplemented;
7a387fff 5559 case 3:
d9bea114 5560// gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
2423f660 5561 rn = "UserTraceData";
3570d7f6 5562 goto cp0_unimplemented;
7a387fff 5563 case 4:
d9bea114 5564// gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
2423f660 5565 rn = "TraceBPC";
3570d7f6 5566 goto cp0_unimplemented;
7a387fff 5567 default:
f31b035a 5568 goto cp0_unimplemented;
7a387fff 5569 }
873eb012
TS
5570 break;
5571 case 24:
7a387fff
TS
5572 switch (sel) {
5573 case 0:
f0b3f3ae 5574 /* EJTAG support */
7db13fae 5575 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
d9bea114 5576 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
5577 rn = "DEPC";
5578 break;
7a387fff 5579 default:
f31b035a 5580 goto cp0_unimplemented;
7a387fff 5581 }
873eb012 5582 break;
8c0fdd85 5583 case 25:
7a387fff
TS
5584 switch (sel) {
5585 case 0:
7db13fae 5586 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
2423f660 5587 rn = "Performance0";
7a387fff
TS
5588 break;
5589 case 1:
d9bea114 5590// gen_helper_mfc0_performance1(arg);
2423f660 5591 rn = "Performance1";
3570d7f6 5592 goto cp0_unimplemented;
7a387fff 5593 case 2:
d9bea114 5594// gen_helper_mfc0_performance2(arg);
2423f660 5595 rn = "Performance2";
3570d7f6 5596 goto cp0_unimplemented;
7a387fff 5597 case 3:
d9bea114 5598// gen_helper_mfc0_performance3(arg);
2423f660 5599 rn = "Performance3";
3570d7f6 5600 goto cp0_unimplemented;
7a387fff 5601 case 4:
d9bea114 5602// gen_helper_mfc0_performance4(arg);
2423f660 5603 rn = "Performance4";
3570d7f6 5604 goto cp0_unimplemented;
7a387fff 5605 case 5:
d9bea114 5606// gen_helper_mfc0_performance5(arg);
2423f660 5607 rn = "Performance5";
3570d7f6 5608 goto cp0_unimplemented;
7a387fff 5609 case 6:
d9bea114 5610// gen_helper_mfc0_performance6(arg);
2423f660 5611 rn = "Performance6";
3570d7f6 5612 goto cp0_unimplemented;
7a387fff 5613 case 7:
d9bea114 5614// gen_helper_mfc0_performance7(arg);
2423f660 5615 rn = "Performance7";
3570d7f6 5616 goto cp0_unimplemented;
7a387fff 5617 default:
f31b035a 5618 goto cp0_unimplemented;
7a387fff 5619 }
8c0fdd85
TS
5620 break;
5621 case 26:
0d74a222
LA
5622 switch (sel) {
5623 case 0:
5624 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl));
5625 rn = "ErrCtl";
5626 break;
5627 default:
5628 goto cp0_unimplemented;
5629 }
da80682b 5630 break;
8c0fdd85 5631 case 27:
7a387fff 5632 switch (sel) {
7a387fff 5633 case 0 ... 3:
d9bea114 5634 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
5635 rn = "CacheErr";
5636 break;
7a387fff 5637 default:
f31b035a 5638 goto cp0_unimplemented;
7a387fff 5639 }
8c0fdd85 5640 break;
873eb012
TS
5641 case 28:
5642 switch (sel) {
5643 case 0:
7a387fff
TS
5644 case 2:
5645 case 4:
5646 case 6:
284b731a
LA
5647 {
5648 TCGv_i64 tmp = tcg_temp_new_i64();
5649 tcg_gen_ld_i64(tmp, cpu_env, offsetof(CPUMIPSState, CP0_TagLo));
5650 gen_move_low32(arg, tmp);
5651 tcg_temp_free_i64(tmp);
5652 }
873eb012
TS
5653 rn = "TagLo";
5654 break;
5655 case 1:
7a387fff
TS
5656 case 3:
5657 case 5:
5658 case 7:
7db13fae 5659 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
873eb012
TS
5660 rn = "DataLo";
5661 break;
5662 default:
f31b035a 5663 goto cp0_unimplemented;
873eb012
TS
5664 }
5665 break;
8c0fdd85 5666 case 29:
7a387fff
TS
5667 switch (sel) {
5668 case 0:
5669 case 2:
5670 case 4:
5671 case 6:
7db13fae 5672 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
7a387fff
TS
5673 rn = "TagHi";
5674 break;
5675 case 1:
5676 case 3:
5677 case 5:
5678 case 7:
7db13fae 5679 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
7a387fff
TS
5680 rn = "DataHi";
5681 break;
5682 default:
f31b035a 5683 goto cp0_unimplemented;
7a387fff 5684 }
8c0fdd85 5685 break;
873eb012 5686 case 30:
7a387fff
TS
5687 switch (sel) {
5688 case 0:
7db13fae 5689 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
d9bea114 5690 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
5691 rn = "ErrorEPC";
5692 break;
7a387fff 5693 default:
f31b035a 5694 goto cp0_unimplemented;
7a387fff 5695 }
873eb012
TS
5696 break;
5697 case 31:
7a387fff
TS
5698 switch (sel) {
5699 case 0:
f0b3f3ae 5700 /* EJTAG support */
7db13fae 5701 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
5702 rn = "DESAVE";
5703 break;
e98c0d17 5704 case 2 ... 7:
f31b035a
LA
5705 CP0_CHECK(ctx->kscrexist & (1 << sel));
5706 tcg_gen_ld_tl(arg, cpu_env,
5707 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
5708 tcg_gen_ext32s_tl(arg, arg);
5709 rn = "KScratch";
e98c0d17 5710 break;
7a387fff 5711 default:
f31b035a 5712 goto cp0_unimplemented;
7a387fff 5713 }
873eb012
TS
5714 break;
5715 default:
f31b035a 5716 goto cp0_unimplemented;
873eb012 5717 }
b44a7fb1 5718 trace_mips_translate_c0("mfc0", rn, reg, sel);
873eb012
TS
5719 return;
5720
f31b035a 5721cp0_unimplemented:
965447ee 5722 qemu_log_mask(LOG_UNIMP, "mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
f31b035a 5723 gen_mfc0_unimplemented(ctx, arg);
873eb012
TS
5724}
5725
d75c135e 5726static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
8c0fdd85 5727{
7a387fff
TS
5728 const char *rn = "invalid";
5729
e189e748 5730 if (sel != 0)
d75c135e 5731 check_insn(ctx, ISA_MIPS32);
e189e748 5732
eeb3bba8 5733 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
2e70f6ef 5734 gen_io_start();
bd79255d 5735 }
2e70f6ef 5736
8c0fdd85
TS
5737 switch (reg) {
5738 case 0:
7a387fff
TS
5739 switch (sel) {
5740 case 0:
895c2d04 5741 gen_helper_mtc0_index(cpu_env, arg);
7a387fff
TS
5742 rn = "Index";
5743 break;
5744 case 1:
f31b035a 5745 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5746 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
7a387fff 5747 rn = "MVPControl";
ead9360e 5748 break;
7a387fff 5749 case 2:
f31b035a 5750 CP0_CHECK(ctx->insn_flags & ASE_MT);
ead9360e 5751 /* ignored */
7a387fff 5752 rn = "MVPConf0";
ead9360e 5753 break;
7a387fff 5754 case 3:
f31b035a 5755 CP0_CHECK(ctx->insn_flags & ASE_MT);
ead9360e 5756 /* ignored */
7a387fff 5757 rn = "MVPConf1";
ead9360e 5758 break;
01bc435b
YK
5759 case 4:
5760 CP0_CHECK(ctx->vp);
5761 /* ignored */
5762 rn = "VPControl";
5763 break;
7a387fff 5764 default:
f31b035a 5765 goto cp0_unimplemented;
7a387fff 5766 }
8c0fdd85
TS
5767 break;
5768 case 1:
7a387fff
TS
5769 switch (sel) {
5770 case 0:
2423f660 5771 /* ignored */
7a387fff 5772 rn = "Random";
2423f660 5773 break;
7a387fff 5774 case 1:
f31b035a 5775 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5776 gen_helper_mtc0_vpecontrol(cpu_env, arg);
7a387fff 5777 rn = "VPEControl";
ead9360e 5778 break;
7a387fff 5779 case 2:
f31b035a 5780 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5781 gen_helper_mtc0_vpeconf0(cpu_env, arg);
7a387fff 5782 rn = "VPEConf0";
ead9360e 5783 break;
7a387fff 5784 case 3:
f31b035a 5785 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5786 gen_helper_mtc0_vpeconf1(cpu_env, arg);
7a387fff 5787 rn = "VPEConf1";
ead9360e 5788 break;
7a387fff 5789 case 4:
f31b035a 5790 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5791 gen_helper_mtc0_yqmask(cpu_env, arg);
7a387fff 5792 rn = "YQMask";
ead9360e 5793 break;
7a387fff 5794 case 5:
f31b035a 5795 CP0_CHECK(ctx->insn_flags & ASE_MT);
d54a299b
LA
5796 tcg_gen_st_tl(arg, cpu_env,
5797 offsetof(CPUMIPSState, CP0_VPESchedule));
7a387fff 5798 rn = "VPESchedule";
ead9360e 5799 break;
7a387fff 5800 case 6:
f31b035a 5801 CP0_CHECK(ctx->insn_flags & ASE_MT);
d54a299b
LA
5802 tcg_gen_st_tl(arg, cpu_env,
5803 offsetof(CPUMIPSState, CP0_VPEScheFBack));
7a387fff 5804 rn = "VPEScheFBack";
ead9360e 5805 break;
7a387fff 5806 case 7:
f31b035a 5807 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5808 gen_helper_mtc0_vpeopt(cpu_env, arg);
7a387fff 5809 rn = "VPEOpt";
ead9360e 5810 break;
7a387fff 5811 default:
f31b035a 5812 goto cp0_unimplemented;
7a387fff 5813 }
8c0fdd85
TS
5814 break;
5815 case 2:
7a387fff
TS
5816 switch (sel) {
5817 case 0:
895c2d04 5818 gen_helper_mtc0_entrylo0(cpu_env, arg);
2423f660
TS
5819 rn = "EntryLo0";
5820 break;
7a387fff 5821 case 1:
f31b035a 5822 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5823 gen_helper_mtc0_tcstatus(cpu_env, arg);
2423f660 5824 rn = "TCStatus";
ead9360e 5825 break;
7a387fff 5826 case 2:
f31b035a 5827 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5828 gen_helper_mtc0_tcbind(cpu_env, arg);
2423f660 5829 rn = "TCBind";
ead9360e 5830 break;
7a387fff 5831 case 3:
f31b035a 5832 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5833 gen_helper_mtc0_tcrestart(cpu_env, arg);
2423f660 5834 rn = "TCRestart";
ead9360e 5835 break;
7a387fff 5836 case 4:
f31b035a 5837 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5838 gen_helper_mtc0_tchalt(cpu_env, arg);
2423f660 5839 rn = "TCHalt";
ead9360e 5840 break;
7a387fff 5841 case 5:
f31b035a 5842 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5843 gen_helper_mtc0_tccontext(cpu_env, arg);
2423f660 5844 rn = "TCContext";
ead9360e 5845 break;
7a387fff 5846 case 6:
f31b035a 5847 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5848 gen_helper_mtc0_tcschedule(cpu_env, arg);
2423f660 5849 rn = "TCSchedule";
ead9360e 5850 break;
7a387fff 5851 case 7:
f31b035a 5852 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5853 gen_helper_mtc0_tcschefback(cpu_env, arg);
2423f660 5854 rn = "TCScheFBack";
ead9360e 5855 break;
7a387fff 5856 default:
f31b035a 5857 goto cp0_unimplemented;
7a387fff 5858 }
8c0fdd85
TS
5859 break;
5860 case 3:
7a387fff
TS
5861 switch (sel) {
5862 case 0:
895c2d04 5863 gen_helper_mtc0_entrylo1(cpu_env, arg);
2423f660
TS
5864 rn = "EntryLo1";
5865 break;
01bc435b
YK
5866 case 1:
5867 CP0_CHECK(ctx->vp);
5868 /* ignored */
5869 rn = "GlobalNumber";
5870 break;
7a387fff 5871 default:
f31b035a 5872 goto cp0_unimplemented;
876d4b07 5873 }
8c0fdd85
TS
5874 break;
5875 case 4:
7a387fff
TS
5876 switch (sel) {
5877 case 0:
895c2d04 5878 gen_helper_mtc0_context(cpu_env, arg);
2423f660
TS
5879 rn = "Context";
5880 break;
7a387fff 5881 case 1:
895c2d04 5882// gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
2423f660 5883 rn = "ContextConfig";
f31b035a 5884 goto cp0_unimplemented;
d279279e 5885 case 2:
f31b035a
LA
5886 CP0_CHECK(ctx->ulri);
5887 tcg_gen_st_tl(arg, cpu_env,
5888 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
5889 rn = "UserLocal";
d279279e 5890 break;
7a387fff 5891 default:
f31b035a 5892 goto cp0_unimplemented;
876d4b07 5893 }
8c0fdd85
TS
5894 break;
5895 case 5:
7a387fff
TS
5896 switch (sel) {
5897 case 0:
895c2d04 5898 gen_helper_mtc0_pagemask(cpu_env, arg);
2423f660
TS
5899 rn = "PageMask";
5900 break;
7a387fff 5901 case 1:
d75c135e 5902 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5903 gen_helper_mtc0_pagegrain(cpu_env, arg);
2423f660 5904 rn = "PageGrain";
eeb3bba8 5905 ctx->base.is_jmp = DISAS_STOP;
2423f660 5906 break;
cec56a73
JH
5907 case 2:
5908 CP0_CHECK(ctx->sc);
5909 gen_helper_mtc0_segctl0(cpu_env, arg);
5910 rn = "SegCtl0";
5911 break;
5912 case 3:
5913 CP0_CHECK(ctx->sc);
5914 gen_helper_mtc0_segctl1(cpu_env, arg);
5915 rn = "SegCtl1";
5916 break;
5917 case 4:
5918 CP0_CHECK(ctx->sc);
5919 gen_helper_mtc0_segctl2(cpu_env, arg);
5920 rn = "SegCtl2";
5921 break;
7a387fff 5922 default:
f31b035a 5923 goto cp0_unimplemented;
876d4b07 5924 }
8c0fdd85
TS
5925 break;
5926 case 6:
7a387fff
TS
5927 switch (sel) {
5928 case 0:
895c2d04 5929 gen_helper_mtc0_wired(cpu_env, arg);
2423f660
TS
5930 rn = "Wired";
5931 break;
7a387fff 5932 case 1:
d75c135e 5933 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5934 gen_helper_mtc0_srsconf0(cpu_env, arg);
2423f660 5935 rn = "SRSConf0";
ead9360e 5936 break;
7a387fff 5937 case 2:
d75c135e 5938 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5939 gen_helper_mtc0_srsconf1(cpu_env, arg);
2423f660 5940 rn = "SRSConf1";
ead9360e 5941 break;
7a387fff 5942 case 3:
d75c135e 5943 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5944 gen_helper_mtc0_srsconf2(cpu_env, arg);
2423f660 5945 rn = "SRSConf2";
ead9360e 5946 break;
7a387fff 5947 case 4:
d75c135e 5948 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5949 gen_helper_mtc0_srsconf3(cpu_env, arg);
2423f660 5950 rn = "SRSConf3";
ead9360e 5951 break;
7a387fff 5952 case 5:
d75c135e 5953 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5954 gen_helper_mtc0_srsconf4(cpu_env, arg);
2423f660 5955 rn = "SRSConf4";
ead9360e 5956 break;
7a387fff 5957 default:
f31b035a 5958 goto cp0_unimplemented;
876d4b07 5959 }
8c0fdd85
TS
5960 break;
5961 case 7:
7a387fff
TS
5962 switch (sel) {
5963 case 0:
d75c135e 5964 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5965 gen_helper_mtc0_hwrena(cpu_env, arg);
eeb3bba8 5966 ctx->base.is_jmp = DISAS_STOP;
2423f660
TS
5967 rn = "HWREna";
5968 break;
7a387fff 5969 default:
f31b035a 5970 goto cp0_unimplemented;
876d4b07 5971 }
8c0fdd85
TS
5972 break;
5973 case 8:
aea14095
LA
5974 switch (sel) {
5975 case 0:
5976 /* ignored */
5977 rn = "BadVAddr";
5978 break;
5979 case 1:
5980 /* ignored */
5981 rn = "BadInstr";
5982 break;
5983 case 2:
5984 /* ignored */
5985 rn = "BadInstrP";
5986 break;
5987 default:
f31b035a 5988 goto cp0_unimplemented;
aea14095 5989 }
8c0fdd85
TS
5990 break;
5991 case 9:
7a387fff
TS
5992 switch (sel) {
5993 case 0:
895c2d04 5994 gen_helper_mtc0_count(cpu_env, arg);
2423f660
TS
5995 rn = "Count";
5996 break;
876d4b07 5997 /* 6,7 are implementation dependent */
7a387fff 5998 default:
f31b035a 5999 goto cp0_unimplemented;
876d4b07 6000 }
8c0fdd85
TS
6001 break;
6002 case 10:
7a387fff
TS
6003 switch (sel) {
6004 case 0:
895c2d04 6005 gen_helper_mtc0_entryhi(cpu_env, arg);
2423f660
TS
6006 rn = "EntryHi";
6007 break;
7a387fff 6008 default:
f31b035a 6009 goto cp0_unimplemented;
876d4b07 6010 }
8c0fdd85
TS
6011 break;
6012 case 11:
7a387fff
TS
6013 switch (sel) {
6014 case 0:
895c2d04 6015 gen_helper_mtc0_compare(cpu_env, arg);
2423f660
TS
6016 rn = "Compare";
6017 break;
6018 /* 6,7 are implementation dependent */
7a387fff 6019 default:
f31b035a 6020 goto cp0_unimplemented;
876d4b07 6021 }
8c0fdd85
TS
6022 break;
6023 case 12:
7a387fff
TS
6024 switch (sel) {
6025 case 0:
867abc7e 6026 save_cpu_state(ctx, 1);
895c2d04 6027 gen_helper_mtc0_status(cpu_env, arg);
b28425ba 6028 /* DISAS_STOP isn't good enough here, hflags may have changed. */
eeb3bba8
EC
6029 gen_save_pc(ctx->base.pc_next + 4);
6030 ctx->base.is_jmp = DISAS_EXIT;
2423f660
TS
6031 rn = "Status";
6032 break;
7a387fff 6033 case 1:
d75c135e 6034 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6035 gen_helper_mtc0_intctl(cpu_env, arg);
8487327a 6036 /* Stop translation as we may have switched the execution mode */
eeb3bba8 6037 ctx->base.is_jmp = DISAS_STOP;
2423f660
TS
6038 rn = "IntCtl";
6039 break;
7a387fff 6040 case 2:
d75c135e 6041 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6042 gen_helper_mtc0_srsctl(cpu_env, arg);
8487327a 6043 /* Stop translation as we may have switched the execution mode */
eeb3bba8 6044 ctx->base.is_jmp = DISAS_STOP;
2423f660
TS
6045 rn = "SRSCtl";
6046 break;
7a387fff 6047 case 3:
d75c135e 6048 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6049 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
8487327a 6050 /* Stop translation as we may have switched the execution mode */
eeb3bba8 6051 ctx->base.is_jmp = DISAS_STOP;
2423f660 6052 rn = "SRSMap";
fd88b6ab 6053 break;
7a387fff 6054 default:
f31b035a 6055 goto cp0_unimplemented;
876d4b07 6056 }
8c0fdd85
TS
6057 break;
6058 case 13:
7a387fff
TS
6059 switch (sel) {
6060 case 0:
867abc7e 6061 save_cpu_state(ctx, 1);
895c2d04 6062 gen_helper_mtc0_cause(cpu_env, arg);
b28425ba
EC
6063 /* Stop translation as we may have triggered an interrupt.
6064 * DISAS_STOP isn't sufficient, we need to ensure we break out of
6065 * translated code to check for pending interrupts. */
eeb3bba8
EC
6066 gen_save_pc(ctx->base.pc_next + 4);
6067 ctx->base.is_jmp = DISAS_EXIT;
2423f660
TS
6068 rn = "Cause";
6069 break;
7a387fff 6070 default:
f31b035a 6071 goto cp0_unimplemented;
876d4b07 6072 }
8c0fdd85
TS
6073 break;
6074 case 14:
7a387fff
TS
6075 switch (sel) {
6076 case 0:
d54a299b 6077 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
2423f660
TS
6078 rn = "EPC";
6079 break;
7a387fff 6080 default:
f31b035a 6081 goto cp0_unimplemented;
876d4b07 6082 }
8c0fdd85
TS
6083 break;
6084 case 15:
7a387fff
TS
6085 switch (sel) {
6086 case 0:
2423f660
TS
6087 /* ignored */
6088 rn = "PRid";
6089 break;
7a387fff 6090 case 1:
d75c135e 6091 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6092 gen_helper_mtc0_ebase(cpu_env, arg);
2423f660
TS
6093 rn = "EBase";
6094 break;
7a387fff 6095 default:
f31b035a 6096 goto cp0_unimplemented;
1579a72e 6097 }
8c0fdd85
TS
6098 break;
6099 case 16:
6100 switch (sel) {
6101 case 0:
895c2d04 6102 gen_helper_mtc0_config0(cpu_env, arg);
7a387fff 6103 rn = "Config";
2423f660 6104 /* Stop translation as we may have switched the execution mode */
eeb3bba8 6105 ctx->base.is_jmp = DISAS_STOP;
7a387fff
TS
6106 break;
6107 case 1:
e397ee33 6108 /* ignored, read only */
7a387fff
TS
6109 rn = "Config1";
6110 break;
6111 case 2:
895c2d04 6112 gen_helper_mtc0_config2(cpu_env, arg);
7a387fff 6113 rn = "Config2";
2423f660 6114 /* Stop translation as we may have switched the execution mode */
eeb3bba8 6115 ctx->base.is_jmp = DISAS_STOP;
8c0fdd85 6116 break;
7a387fff 6117 case 3:
90f12d73 6118 gen_helper_mtc0_config3(cpu_env, arg);
7a387fff 6119 rn = "Config3";
90f12d73 6120 /* Stop translation as we may have switched the execution mode */
eeb3bba8 6121 ctx->base.is_jmp = DISAS_STOP;
7a387fff 6122 break;
b4160af1
PJ
6123 case 4:
6124 gen_helper_mtc0_config4(cpu_env, arg);
6125 rn = "Config4";
eeb3bba8 6126 ctx->base.is_jmp = DISAS_STOP;
b4160af1 6127 break;
b4dd99a3
PJ
6128 case 5:
6129 gen_helper_mtc0_config5(cpu_env, arg);
6130 rn = "Config5";
6131 /* Stop translation as we may have switched the execution mode */
eeb3bba8 6132 ctx->base.is_jmp = DISAS_STOP;
b4dd99a3 6133 break;
e397ee33
TS
6134 /* 6,7 are implementation dependent */
6135 case 6:
6136 /* ignored */
6137 rn = "Config6";
6138 break;
6139 case 7:
6140 /* ignored */
6141 rn = "Config7";
6142 break;
8c0fdd85
TS
6143 default:
6144 rn = "Invalid config selector";
f31b035a 6145 goto cp0_unimplemented;
8c0fdd85
TS
6146 }
6147 break;
6148 case 17:
7a387fff
TS
6149 switch (sel) {
6150 case 0:
895c2d04 6151 gen_helper_mtc0_lladdr(cpu_env, arg);
2423f660
TS
6152 rn = "LLAddr";
6153 break;
f6d4dd81
YK
6154 case 1:
6155 CP0_CHECK(ctx->mrp);
6156 gen_helper_mtc0_maar(cpu_env, arg);
6157 rn = "MAAR";
6158 break;
6159 case 2:
6160 CP0_CHECK(ctx->mrp);
6161 gen_helper_mtc0_maari(cpu_env, arg);
6162 rn = "MAARI";
6163 break;
7a387fff 6164 default:
f31b035a 6165 goto cp0_unimplemented;
7a387fff 6166 }
8c0fdd85
TS
6167 break;
6168 case 18:
7a387fff 6169 switch (sel) {
fd88b6ab 6170 case 0 ... 7:
895c2d04 6171 gen_helper_0e1i(mtc0_watchlo, arg, sel);
2423f660
TS
6172 rn = "WatchLo";
6173 break;
7a387fff 6174 default:
f31b035a 6175 goto cp0_unimplemented;
7a387fff 6176 }
8c0fdd85
TS
6177 break;
6178 case 19:
7a387fff 6179 switch (sel) {
fd88b6ab 6180 case 0 ... 7:
895c2d04 6181 gen_helper_0e1i(mtc0_watchhi, arg, sel);
2423f660
TS
6182 rn = "WatchHi";
6183 break;
7a387fff 6184 default:
f31b035a 6185 goto cp0_unimplemented;
7a387fff 6186 }
8c0fdd85
TS
6187 break;
6188 case 20:
7a387fff
TS
6189 switch (sel) {
6190 case 0:
d26bc211 6191#if defined(TARGET_MIPS64)
d75c135e 6192 check_insn(ctx, ISA_MIPS3);
895c2d04 6193 gen_helper_mtc0_xcontext(cpu_env, arg);
2423f660
TS
6194 rn = "XContext";
6195 break;
703eaf37 6196#endif
7a387fff 6197 default:
f31b035a 6198 goto cp0_unimplemented;
7a387fff 6199 }
8c0fdd85
TS
6200 break;
6201 case 21:
7a387fff 6202 /* Officially reserved, but sel 0 is used for R1x000 framemask */
f31b035a 6203 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
7a387fff
TS
6204 switch (sel) {
6205 case 0:
895c2d04 6206 gen_helper_mtc0_framemask(cpu_env, arg);
2423f660
TS
6207 rn = "Framemask";
6208 break;
7a387fff 6209 default:
f31b035a 6210 goto cp0_unimplemented;
7a387fff
TS
6211 }
6212 break;
8c0fdd85 6213 case 22:
7a387fff
TS
6214 /* ignored */
6215 rn = "Diagnostic"; /* implementation dependent */
2423f660 6216 break;
8c0fdd85 6217 case 23:
7a387fff
TS
6218 switch (sel) {
6219 case 0:
895c2d04 6220 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
b28425ba 6221 /* DISAS_STOP isn't good enough here, hflags may have changed. */
eeb3bba8
EC
6222 gen_save_pc(ctx->base.pc_next + 4);
6223 ctx->base.is_jmp = DISAS_EXIT;
2423f660
TS
6224 rn = "Debug";
6225 break;
7a387fff 6226 case 1:
895c2d04 6227// gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
2423f660 6228 rn = "TraceControl";
8487327a 6229 /* Stop translation as we may have switched the execution mode */
eeb3bba8 6230 ctx->base.is_jmp = DISAS_STOP;
3570d7f6 6231 goto cp0_unimplemented;
7a387fff 6232 case 2:
895c2d04 6233// gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
2423f660 6234 rn = "TraceControl2";
8487327a 6235 /* Stop translation as we may have switched the execution mode */
eeb3bba8 6236 ctx->base.is_jmp = DISAS_STOP;
3570d7f6 6237 goto cp0_unimplemented;
7a387fff 6238 case 3:
8487327a 6239 /* Stop translation as we may have switched the execution mode */
eeb3bba8 6240 ctx->base.is_jmp = DISAS_STOP;
895c2d04 6241// gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
2423f660 6242 rn = "UserTraceData";
8487327a 6243 /* Stop translation as we may have switched the execution mode */
eeb3bba8 6244 ctx->base.is_jmp = DISAS_STOP;
3570d7f6 6245 goto cp0_unimplemented;
7a387fff 6246 case 4:
895c2d04 6247// gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
8487327a 6248 /* Stop translation as we may have switched the execution mode */
eeb3bba8 6249 ctx->base.is_jmp = DISAS_STOP;
2423f660 6250 rn = "TraceBPC";
3570d7f6 6251 goto cp0_unimplemented;
7a387fff 6252 default:
f31b035a 6253 goto cp0_unimplemented;
7a387fff 6254 }
8c0fdd85
TS
6255 break;
6256 case 24:
7a387fff
TS
6257 switch (sel) {
6258 case 0:
f1aa6320 6259 /* EJTAG support */
d54a299b 6260 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
2423f660
TS
6261 rn = "DEPC";
6262 break;
7a387fff 6263 default:
f31b035a 6264 goto cp0_unimplemented;
7a387fff 6265 }
8c0fdd85
TS
6266 break;
6267 case 25:
7a387fff
TS
6268 switch (sel) {
6269 case 0:
895c2d04 6270 gen_helper_mtc0_performance0(cpu_env, arg);
2423f660
TS
6271 rn = "Performance0";
6272 break;
7a387fff 6273 case 1:
d9bea114 6274// gen_helper_mtc0_performance1(arg);
2423f660 6275 rn = "Performance1";
3570d7f6 6276 goto cp0_unimplemented;
7a387fff 6277 case 2:
d9bea114 6278// gen_helper_mtc0_performance2(arg);
2423f660 6279 rn = "Performance2";
3570d7f6 6280 goto cp0_unimplemented;
7a387fff 6281 case 3:
d9bea114 6282// gen_helper_mtc0_performance3(arg);
2423f660 6283 rn = "Performance3";
3570d7f6 6284 goto cp0_unimplemented;
7a387fff 6285 case 4:
d9bea114 6286// gen_helper_mtc0_performance4(arg);
2423f660 6287 rn = "Performance4";
3570d7f6 6288 goto cp0_unimplemented;
7a387fff 6289 case 5:
d9bea114 6290// gen_helper_mtc0_performance5(arg);
2423f660 6291 rn = "Performance5";
3570d7f6 6292 goto cp0_unimplemented;
7a387fff 6293 case 6:
d9bea114 6294// gen_helper_mtc0_performance6(arg);
2423f660 6295 rn = "Performance6";
3570d7f6 6296 goto cp0_unimplemented;
7a387fff 6297 case 7:
d9bea114 6298// gen_helper_mtc0_performance7(arg);
2423f660 6299 rn = "Performance7";
3570d7f6 6300 goto cp0_unimplemented;
7a387fff 6301 default:
f31b035a 6302 goto cp0_unimplemented;
7a387fff 6303 }
8c0fdd85
TS
6304 break;
6305 case 26:
0d74a222
LA
6306 switch (sel) {
6307 case 0:
6308 gen_helper_mtc0_errctl(cpu_env, arg);
eeb3bba8 6309 ctx->base.is_jmp = DISAS_STOP;
0d74a222
LA
6310 rn = "ErrCtl";
6311 break;
6312 default:
6313 goto cp0_unimplemented;
6314 }
2423f660 6315 break;
8c0fdd85 6316 case 27:
7a387fff
TS
6317 switch (sel) {
6318 case 0 ... 3:
2423f660
TS
6319 /* ignored */
6320 rn = "CacheErr";
6321 break;
7a387fff 6322 default:
f31b035a 6323 goto cp0_unimplemented;
7a387fff 6324 }
8c0fdd85
TS
6325 break;
6326 case 28:
6327 switch (sel) {
6328 case 0:
7a387fff
TS
6329 case 2:
6330 case 4:
6331 case 6:
895c2d04 6332 gen_helper_mtc0_taglo(cpu_env, arg);
8c0fdd85
TS
6333 rn = "TagLo";
6334 break;
7a387fff
TS
6335 case 1:
6336 case 3:
6337 case 5:
6338 case 7:
895c2d04 6339 gen_helper_mtc0_datalo(cpu_env, arg);
7a387fff
TS
6340 rn = "DataLo";
6341 break;
8c0fdd85 6342 default:
f31b035a 6343 goto cp0_unimplemented;
8c0fdd85
TS
6344 }
6345 break;
6346 case 29:
7a387fff
TS
6347 switch (sel) {
6348 case 0:
6349 case 2:
6350 case 4:
6351 case 6:
895c2d04 6352 gen_helper_mtc0_taghi(cpu_env, arg);
7a387fff
TS
6353 rn = "TagHi";
6354 break;
6355 case 1:
6356 case 3:
6357 case 5:
6358 case 7:
895c2d04 6359 gen_helper_mtc0_datahi(cpu_env, arg);
7a387fff
TS
6360 rn = "DataHi";
6361 break;
6362 default:
6363 rn = "invalid sel";
f31b035a 6364 goto cp0_unimplemented;
7a387fff 6365 }
8c0fdd85
TS
6366 break;
6367 case 30:
7a387fff
TS
6368 switch (sel) {
6369 case 0:
d54a299b 6370 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
2423f660
TS
6371 rn = "ErrorEPC";
6372 break;
7a387fff 6373 default:
f31b035a 6374 goto cp0_unimplemented;
7a387fff 6375 }
8c0fdd85
TS
6376 break;
6377 case 31:
7a387fff
TS
6378 switch (sel) {
6379 case 0:
f1aa6320 6380 /* EJTAG support */
7db13fae 6381 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
6382 rn = "DESAVE";
6383 break;
e98c0d17 6384 case 2 ... 7:
f31b035a
LA
6385 CP0_CHECK(ctx->kscrexist & (1 << sel));
6386 tcg_gen_st_tl(arg, cpu_env,
6387 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
6388 rn = "KScratch";
e98c0d17 6389 break;
7a387fff 6390 default:
f31b035a 6391 goto cp0_unimplemented;
7a387fff 6392 }
8c0fdd85
TS
6393 break;
6394 default:
f31b035a 6395 goto cp0_unimplemented;
8c0fdd85 6396 }
b44a7fb1
PMD
6397 trace_mips_translate_c0("mtc0", rn, reg, sel);
6398
bf20dc07 6399 /* For simplicity assume that all writes can cause interrupts. */
eeb3bba8 6400 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
2e70f6ef 6401 gen_io_end();
b28425ba 6402 /* DISAS_STOP isn't sufficient, we need to ensure we break out of
b74cddcb 6403 * translated code to check for pending interrupts. */
eeb3bba8
EC
6404 gen_save_pc(ctx->base.pc_next + 4);
6405 ctx->base.is_jmp = DISAS_EXIT;
2e70f6ef 6406 }
8c0fdd85
TS
6407 return;
6408
f31b035a 6409cp0_unimplemented:
965447ee 6410 qemu_log_mask(LOG_UNIMP, "mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
8c0fdd85
TS
6411}
6412
d26bc211 6413#if defined(TARGET_MIPS64)
d75c135e 6414static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
9c2149c8
TS
6415{
6416 const char *rn = "invalid";
6417
e189e748 6418 if (sel != 0)
d75c135e 6419 check_insn(ctx, ISA_MIPS64);
e189e748 6420
9c2149c8
TS
6421 switch (reg) {
6422 case 0:
6423 switch (sel) {
6424 case 0:
7db13fae 6425 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
9c2149c8
TS
6426 rn = "Index";
6427 break;
6428 case 1:
f31b035a 6429 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6430 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
9c2149c8 6431 rn = "MVPControl";
ead9360e 6432 break;
9c2149c8 6433 case 2:
f31b035a 6434 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6435 gen_helper_mfc0_mvpconf0(arg, cpu_env);
9c2149c8 6436 rn = "MVPConf0";
ead9360e 6437 break;
9c2149c8 6438 case 3:
f31b035a 6439 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6440 gen_helper_mfc0_mvpconf1(arg, cpu_env);
9c2149c8 6441 rn = "MVPConf1";
ead9360e 6442 break;
01bc435b
YK
6443 case 4:
6444 CP0_CHECK(ctx->vp);
6445 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl));
6446 rn = "VPControl";
6447 break;
9c2149c8 6448 default:
f31b035a 6449 goto cp0_unimplemented;
9c2149c8
TS
6450 }
6451 break;
6452 case 1:
6453 switch (sel) {
6454 case 0:
f31b035a 6455 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
895c2d04 6456 gen_helper_mfc0_random(arg, cpu_env);
9c2149c8 6457 rn = "Random";
2423f660 6458 break;
9c2149c8 6459 case 1:
f31b035a 6460 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6461 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
9c2149c8 6462 rn = "VPEControl";
ead9360e 6463 break;
9c2149c8 6464 case 2:
f31b035a 6465 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6466 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
9c2149c8 6467 rn = "VPEConf0";
ead9360e 6468 break;
9c2149c8 6469 case 3:
f31b035a 6470 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6471 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
9c2149c8 6472 rn = "VPEConf1";
ead9360e 6473 break;
9c2149c8 6474 case 4:
f31b035a 6475 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6476 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_YQMask));
9c2149c8 6477 rn = "YQMask";
ead9360e 6478 break;
9c2149c8 6479 case 5:
f31b035a 6480 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6481 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
9c2149c8 6482 rn = "VPESchedule";
ead9360e 6483 break;
9c2149c8 6484 case 6:
f31b035a 6485 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6486 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
9c2149c8 6487 rn = "VPEScheFBack";
ead9360e 6488 break;
9c2149c8 6489 case 7:
f31b035a 6490 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6491 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
9c2149c8 6492 rn = "VPEOpt";
ead9360e 6493 break;
9c2149c8 6494 default:
f31b035a 6495 goto cp0_unimplemented;
9c2149c8
TS
6496 }
6497 break;
6498 case 2:
6499 switch (sel) {
6500 case 0:
7db13fae 6501 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
2423f660
TS
6502 rn = "EntryLo0";
6503 break;
9c2149c8 6504 case 1:
f31b035a 6505 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6506 gen_helper_mfc0_tcstatus(arg, cpu_env);
2423f660 6507 rn = "TCStatus";
ead9360e 6508 break;
9c2149c8 6509 case 2:
f31b035a 6510 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6511 gen_helper_mfc0_tcbind(arg, cpu_env);
2423f660 6512 rn = "TCBind";
ead9360e 6513 break;
9c2149c8 6514 case 3:
f31b035a 6515 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6516 gen_helper_dmfc0_tcrestart(arg, cpu_env);
2423f660 6517 rn = "TCRestart";
ead9360e 6518 break;
9c2149c8 6519 case 4:
f31b035a 6520 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6521 gen_helper_dmfc0_tchalt(arg, cpu_env);
2423f660 6522 rn = "TCHalt";
ead9360e 6523 break;
9c2149c8 6524 case 5:
f31b035a 6525 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6526 gen_helper_dmfc0_tccontext(arg, cpu_env);
2423f660 6527 rn = "TCContext";
ead9360e 6528 break;
9c2149c8 6529 case 6:
f31b035a 6530 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6531 gen_helper_dmfc0_tcschedule(arg, cpu_env);
2423f660 6532 rn = "TCSchedule";
ead9360e 6533 break;
9c2149c8 6534 case 7:
f31b035a 6535 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6536 gen_helper_dmfc0_tcschefback(arg, cpu_env);
2423f660 6537 rn = "TCScheFBack";
ead9360e 6538 break;
9c2149c8 6539 default:
f31b035a 6540 goto cp0_unimplemented;
9c2149c8
TS
6541 }
6542 break;
6543 case 3:
6544 switch (sel) {
6545 case 0:
7db13fae 6546 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
2423f660
TS
6547 rn = "EntryLo1";
6548 break;
01bc435b
YK
6549 case 1:
6550 CP0_CHECK(ctx->vp);
6551 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber));
6552 rn = "GlobalNumber";
6553 break;
9c2149c8 6554 default:
f31b035a 6555 goto cp0_unimplemented;
1579a72e 6556 }
9c2149c8
TS
6557 break;
6558 case 4:
6559 switch (sel) {
6560 case 0:
7db13fae 6561 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
2423f660
TS
6562 rn = "Context";
6563 break;
9c2149c8 6564 case 1:
d9bea114 6565// gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
2423f660 6566 rn = "ContextConfig";
f31b035a 6567 goto cp0_unimplemented;
d279279e 6568 case 2:
f31b035a
LA
6569 CP0_CHECK(ctx->ulri);
6570 tcg_gen_ld_tl(arg, cpu_env,
6571 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
6572 rn = "UserLocal";
d279279e 6573 break;
9c2149c8 6574 default:
f31b035a 6575 goto cp0_unimplemented;
876d4b07 6576 }
9c2149c8
TS
6577 break;
6578 case 5:
6579 switch (sel) {
6580 case 0:
7db13fae 6581 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
2423f660
TS
6582 rn = "PageMask";
6583 break;
9c2149c8 6584 case 1:
d75c135e 6585 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6586 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
2423f660
TS
6587 rn = "PageGrain";
6588 break;
cec56a73
JH
6589 case 2:
6590 CP0_CHECK(ctx->sc);
6591 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl0));
6592 rn = "SegCtl0";
6593 break;
6594 case 3:
6595 CP0_CHECK(ctx->sc);
6596 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl1));
6597 rn = "SegCtl1";
6598 break;
6599 case 4:
6600 CP0_CHECK(ctx->sc);
6601 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl2));
6602 rn = "SegCtl2";
6603 break;
9c2149c8 6604 default:
f31b035a 6605 goto cp0_unimplemented;
876d4b07 6606 }
9c2149c8
TS
6607 break;
6608 case 6:
6609 switch (sel) {
6610 case 0:
7db13fae 6611 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
2423f660
TS
6612 rn = "Wired";
6613 break;
9c2149c8 6614 case 1:
d75c135e 6615 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6616 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
2423f660 6617 rn = "SRSConf0";
ead9360e 6618 break;
9c2149c8 6619 case 2:
d75c135e 6620 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6621 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
2423f660 6622 rn = "SRSConf1";
ead9360e 6623 break;
9c2149c8 6624 case 3:
d75c135e 6625 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6626 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
2423f660 6627 rn = "SRSConf2";
ead9360e 6628 break;
9c2149c8 6629 case 4:
d75c135e 6630 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6631 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
2423f660 6632 rn = "SRSConf3";
ead9360e 6633 break;
9c2149c8 6634 case 5:
d75c135e 6635 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6636 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
2423f660 6637 rn = "SRSConf4";
ead9360e 6638 break;
9c2149c8 6639 default:
f31b035a 6640 goto cp0_unimplemented;
876d4b07 6641 }
9c2149c8
TS
6642 break;
6643 case 7:
6644 switch (sel) {
6645 case 0:
d75c135e 6646 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6647 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
2423f660
TS
6648 rn = "HWREna";
6649 break;
9c2149c8 6650 default:
f31b035a 6651 goto cp0_unimplemented;
876d4b07 6652 }
9c2149c8
TS
6653 break;
6654 case 8:
6655 switch (sel) {
6656 case 0:
7db13fae 6657 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
f0b3f3ae 6658 rn = "BadVAddr";
2423f660 6659 break;
aea14095 6660 case 1:
f31b035a
LA
6661 CP0_CHECK(ctx->bi);
6662 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
6663 rn = "BadInstr";
aea14095
LA
6664 break;
6665 case 2:
f31b035a
LA
6666 CP0_CHECK(ctx->bp);
6667 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
6668 rn = "BadInstrP";
aea14095 6669 break;
9c2149c8 6670 default:
f31b035a 6671 goto cp0_unimplemented;
876d4b07 6672 }
9c2149c8
TS
6673 break;
6674 case 9:
6675 switch (sel) {
6676 case 0:
2e70f6ef 6677 /* Mark as an IO operation because we read the time. */
eeb3bba8 6678 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
2e70f6ef 6679 gen_io_start();
bd79255d 6680 }
895c2d04 6681 gen_helper_mfc0_count(arg, cpu_env);
eeb3bba8 6682 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
2e70f6ef 6683 gen_io_end();
2e70f6ef 6684 }
55807224 6685 /* Break the TB to be able to take timer interrupts immediately
b28425ba
EC
6686 after reading count. DISAS_STOP isn't sufficient, we need to
6687 ensure we break completely out of translated code. */
eeb3bba8
EC
6688 gen_save_pc(ctx->base.pc_next + 4);
6689 ctx->base.is_jmp = DISAS_EXIT;
2423f660
TS
6690 rn = "Count";
6691 break;
6692 /* 6,7 are implementation dependent */
9c2149c8 6693 default:
f31b035a 6694 goto cp0_unimplemented;
876d4b07 6695 }
9c2149c8
TS
6696 break;
6697 case 10:
6698 switch (sel) {
6699 case 0:
7db13fae 6700 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
2423f660
TS
6701 rn = "EntryHi";
6702 break;
9c2149c8 6703 default:
f31b035a 6704 goto cp0_unimplemented;
876d4b07 6705 }
9c2149c8
TS
6706 break;
6707 case 11:
6708 switch (sel) {
6709 case 0:
7db13fae 6710 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
2423f660
TS
6711 rn = "Compare";
6712 break;
876d4b07 6713 /* 6,7 are implementation dependent */
9c2149c8 6714 default:
f31b035a 6715 goto cp0_unimplemented;
876d4b07 6716 }
9c2149c8
TS
6717 break;
6718 case 12:
6719 switch (sel) {
6720 case 0:
7db13fae 6721 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
2423f660
TS
6722 rn = "Status";
6723 break;
9c2149c8 6724 case 1:
d75c135e 6725 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6726 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
2423f660
TS
6727 rn = "IntCtl";
6728 break;
9c2149c8 6729 case 2:
d75c135e 6730 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6731 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
2423f660
TS
6732 rn = "SRSCtl";
6733 break;
9c2149c8 6734 case 3:
d75c135e 6735 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6736 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
2423f660
TS
6737 rn = "SRSMap";
6738 break;
9c2149c8 6739 default:
f31b035a 6740 goto cp0_unimplemented;
876d4b07 6741 }
9c2149c8
TS
6742 break;
6743 case 13:
6744 switch (sel) {
6745 case 0:
7db13fae 6746 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
2423f660
TS
6747 rn = "Cause";
6748 break;
9c2149c8 6749 default:
f31b035a 6750 goto cp0_unimplemented;
876d4b07 6751 }
9c2149c8
TS
6752 break;
6753 case 14:
6754 switch (sel) {
6755 case 0:
7db13fae 6756 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
2423f660
TS
6757 rn = "EPC";
6758 break;
9c2149c8 6759 default:
f31b035a 6760 goto cp0_unimplemented;
876d4b07 6761 }
9c2149c8
TS
6762 break;
6763 case 15:
6764 switch (sel) {
6765 case 0:
7db13fae 6766 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
2423f660
TS
6767 rn = "PRid";
6768 break;
9c2149c8 6769 case 1:
d75c135e 6770 check_insn(ctx, ISA_MIPS32R2);
74dbf824 6771 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EBase));
2423f660
TS
6772 rn = "EBase";
6773 break;
c870e3f5
YK
6774 case 3:
6775 check_insn(ctx, ISA_MIPS32R2);
6776 CP0_CHECK(ctx->cmgcr);
6777 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase));
6778 rn = "CMGCRBase";
6779 break;
9c2149c8 6780 default:
f31b035a 6781 goto cp0_unimplemented;
876d4b07 6782 }
9c2149c8
TS
6783 break;
6784 case 16:
6785 switch (sel) {
6786 case 0:
7db13fae 6787 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
9c2149c8
TS
6788 rn = "Config";
6789 break;
6790 case 1:
7db13fae 6791 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
9c2149c8
TS
6792 rn = "Config1";
6793 break;
6794 case 2:
7db13fae 6795 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
9c2149c8
TS
6796 rn = "Config2";
6797 break;
6798 case 3:
7db13fae 6799 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
9c2149c8
TS
6800 rn = "Config3";
6801 break;
faf1f68b
LA
6802 case 4:
6803 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
6804 rn = "Config4";
6805 break;
6806 case 5:
6807 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
6808 rn = "Config5";
6809 break;
9c2149c8 6810 /* 6,7 are implementation dependent */
f0b3f3ae 6811 case 6:
7db13fae 6812 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
f0b3f3ae
TS
6813 rn = "Config6";
6814 break;
6815 case 7:
7db13fae 6816 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
f0b3f3ae
TS
6817 rn = "Config7";
6818 break;
9c2149c8 6819 default:
f31b035a 6820 goto cp0_unimplemented;
9c2149c8
TS
6821 }
6822 break;
6823 case 17:
6824 switch (sel) {
6825 case 0:
895c2d04 6826 gen_helper_dmfc0_lladdr(arg, cpu_env);
2423f660
TS
6827 rn = "LLAddr";
6828 break;
f6d4dd81
YK
6829 case 1:
6830 CP0_CHECK(ctx->mrp);
6831 gen_helper_dmfc0_maar(arg, cpu_env);
6832 rn = "MAAR";
6833 break;
6834 case 2:
6835 CP0_CHECK(ctx->mrp);
6836 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI));
6837 rn = "MAARI";
6838 break;
9c2149c8 6839 default:
f31b035a 6840 goto cp0_unimplemented;
9c2149c8
TS
6841 }
6842 break;
6843 case 18:
6844 switch (sel) {
fd88b6ab 6845 case 0 ... 7:
895c2d04 6846 gen_helper_1e0i(dmfc0_watchlo, arg, sel);
2423f660
TS
6847 rn = "WatchLo";
6848 break;
9c2149c8 6849 default:
f31b035a 6850 goto cp0_unimplemented;
9c2149c8
TS
6851 }
6852 break;
6853 case 19:
6854 switch (sel) {
fd88b6ab 6855 case 0 ... 7:
895c2d04 6856 gen_helper_1e0i(mfc0_watchhi, arg, sel);
2423f660
TS
6857 rn = "WatchHi";
6858 break;
9c2149c8 6859 default:
f31b035a 6860 goto cp0_unimplemented;
9c2149c8
TS
6861 }
6862 break;
6863 case 20:
6864 switch (sel) {
6865 case 0:
d75c135e 6866 check_insn(ctx, ISA_MIPS3);
7db13fae 6867 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
2423f660
TS
6868 rn = "XContext";
6869 break;
9c2149c8 6870 default:
f31b035a 6871 goto cp0_unimplemented;
9c2149c8
TS
6872 }
6873 break;
6874 case 21:
6875 /* Officially reserved, but sel 0 is used for R1x000 framemask */
f31b035a 6876 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
9c2149c8
TS
6877 switch (sel) {
6878 case 0:
7db13fae 6879 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
2423f660
TS
6880 rn = "Framemask";
6881 break;
9c2149c8 6882 default:
f31b035a 6883 goto cp0_unimplemented;
9c2149c8
TS
6884 }
6885 break;
6886 case 22:
d9bea114 6887 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
6888 rn = "'Diagnostic"; /* implementation dependent */
6889 break;
9c2149c8
TS
6890 case 23:
6891 switch (sel) {
6892 case 0:
895c2d04 6893 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
2423f660
TS
6894 rn = "Debug";
6895 break;
9c2149c8 6896 case 1:
895c2d04 6897// gen_helper_dmfc0_tracecontrol(arg, cpu_env); /* PDtrace support */
2423f660 6898 rn = "TraceControl";
3570d7f6 6899 goto cp0_unimplemented;
9c2149c8 6900 case 2:
895c2d04 6901// gen_helper_dmfc0_tracecontrol2(arg, cpu_env); /* PDtrace support */
2423f660 6902 rn = "TraceControl2";
3570d7f6 6903 goto cp0_unimplemented;
9c2149c8 6904 case 3:
895c2d04 6905// gen_helper_dmfc0_usertracedata(arg, cpu_env); /* PDtrace support */
2423f660 6906 rn = "UserTraceData";
3570d7f6 6907 goto cp0_unimplemented;
9c2149c8 6908 case 4:
895c2d04 6909// gen_helper_dmfc0_tracebpc(arg, cpu_env); /* PDtrace support */
2423f660 6910 rn = "TraceBPC";
3570d7f6 6911 goto cp0_unimplemented;
9c2149c8 6912 default:
f31b035a 6913 goto cp0_unimplemented;
9c2149c8
TS
6914 }
6915 break;
6916 case 24:
6917 switch (sel) {
6918 case 0:
f0b3f3ae 6919 /* EJTAG support */
7db13fae 6920 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
2423f660
TS
6921 rn = "DEPC";
6922 break;
9c2149c8 6923 default:
f31b035a 6924 goto cp0_unimplemented;
9c2149c8
TS
6925 }
6926 break;
6927 case 25:
6928 switch (sel) {
6929 case 0:
7db13fae 6930 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
2423f660 6931 rn = "Performance0";
9c2149c8
TS
6932 break;
6933 case 1:
d9bea114 6934// gen_helper_dmfc0_performance1(arg);
2423f660 6935 rn = "Performance1";
3570d7f6 6936 goto cp0_unimplemented;
9c2149c8 6937 case 2:
d9bea114 6938// gen_helper_dmfc0_performance2(arg);
2423f660 6939 rn = "Performance2";
3570d7f6 6940 goto cp0_unimplemented;
9c2149c8 6941 case 3:
d9bea114 6942// gen_helper_dmfc0_performance3(arg);
2423f660 6943 rn = "Performance3";
3570d7f6 6944 goto cp0_unimplemented;
9c2149c8 6945 case 4:
d9bea114 6946// gen_helper_dmfc0_performance4(arg);
2423f660 6947 rn = "Performance4";
3570d7f6 6948 goto cp0_unimplemented;
9c2149c8 6949 case 5:
d9bea114 6950// gen_helper_dmfc0_performance5(arg);
2423f660 6951 rn = "Performance5";
3570d7f6 6952 goto cp0_unimplemented;
9c2149c8 6953 case 6:
d9bea114 6954// gen_helper_dmfc0_performance6(arg);
2423f660 6955 rn = "Performance6";
3570d7f6 6956 goto cp0_unimplemented;
9c2149c8 6957 case 7:
d9bea114 6958// gen_helper_dmfc0_performance7(arg);
2423f660 6959 rn = "Performance7";
3570d7f6 6960 goto cp0_unimplemented;
9c2149c8 6961 default:
f31b035a 6962 goto cp0_unimplemented;
9c2149c8
TS
6963 }
6964 break;
6965 case 26:
0d74a222
LA
6966 switch (sel) {
6967 case 0:
6968 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl));
6969 rn = "ErrCtl";
6970 break;
6971 default:
6972 goto cp0_unimplemented;
6973 }
da80682b 6974 break;
9c2149c8
TS
6975 case 27:
6976 switch (sel) {
6977 /* ignored */
6978 case 0 ... 3:
d9bea114 6979 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
6980 rn = "CacheErr";
6981 break;
9c2149c8 6982 default:
f31b035a 6983 goto cp0_unimplemented;
9c2149c8
TS
6984 }
6985 break;
6986 case 28:
6987 switch (sel) {
6988 case 0:
6989 case 2:
6990 case 4:
6991 case 6:
7db13fae 6992 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
9c2149c8
TS
6993 rn = "TagLo";
6994 break;
6995 case 1:
6996 case 3:
6997 case 5:
6998 case 7:
7db13fae 6999 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
9c2149c8
TS
7000 rn = "DataLo";
7001 break;
7002 default:
f31b035a 7003 goto cp0_unimplemented;
9c2149c8
TS
7004 }
7005 break;
7006 case 29:
7007 switch (sel) {
7008 case 0:
7009 case 2:
7010 case 4:
7011 case 6:
7db13fae 7012 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
9c2149c8
TS
7013 rn = "TagHi";
7014 break;
7015 case 1:
7016 case 3:
7017 case 5:
7018 case 7:
7db13fae 7019 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
9c2149c8
TS
7020 rn = "DataHi";
7021 break;
7022 default:
f31b035a 7023 goto cp0_unimplemented;
9c2149c8
TS
7024 }
7025 break;
7026 case 30:
7027 switch (sel) {
7028 case 0:
7db13fae 7029 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
2423f660
TS
7030 rn = "ErrorEPC";
7031 break;
9c2149c8 7032 default:
f31b035a 7033 goto cp0_unimplemented;
9c2149c8
TS
7034 }
7035 break;
7036 case 31:
7037 switch (sel) {
7038 case 0:
f0b3f3ae 7039 /* EJTAG support */
7db13fae 7040 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
7041 rn = "DESAVE";
7042 break;
e98c0d17 7043 case 2 ... 7:
f31b035a
LA
7044 CP0_CHECK(ctx->kscrexist & (1 << sel));
7045 tcg_gen_ld_tl(arg, cpu_env,
7046 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
7047 rn = "KScratch";
e98c0d17 7048 break;
9c2149c8 7049 default:
f31b035a 7050 goto cp0_unimplemented;
9c2149c8
TS
7051 }
7052 break;
7053 default:
f31b035a 7054 goto cp0_unimplemented;
9c2149c8 7055 }
b44a7fb1 7056 trace_mips_translate_c0("dmfc0", rn, reg, sel);
9c2149c8
TS
7057 return;
7058
f31b035a 7059cp0_unimplemented:
965447ee 7060 qemu_log_mask(LOG_UNIMP, "dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
f31b035a 7061 gen_mfc0_unimplemented(ctx, arg);
9c2149c8
TS
7062}
7063
d75c135e 7064static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
9c2149c8
TS
7065{
7066 const char *rn = "invalid";
7067
e189e748 7068 if (sel != 0)
d75c135e 7069 check_insn(ctx, ISA_MIPS64);
e189e748 7070
eeb3bba8 7071 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
2e70f6ef 7072 gen_io_start();
bd79255d 7073 }
2e70f6ef 7074
9c2149c8
TS
7075 switch (reg) {
7076 case 0:
7077 switch (sel) {
7078 case 0:
895c2d04 7079 gen_helper_mtc0_index(cpu_env, arg);
9c2149c8
TS
7080 rn = "Index";
7081 break;
7082 case 1:
f31b035a 7083 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7084 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
9c2149c8 7085 rn = "MVPControl";
ead9360e 7086 break;
9c2149c8 7087 case 2:
f31b035a 7088 CP0_CHECK(ctx->insn_flags & ASE_MT);
ead9360e 7089 /* ignored */
9c2149c8 7090 rn = "MVPConf0";
ead9360e 7091 break;
9c2149c8 7092 case 3:
f31b035a 7093 CP0_CHECK(ctx->insn_flags & ASE_MT);
ead9360e 7094 /* ignored */
9c2149c8 7095 rn = "MVPConf1";
ead9360e 7096 break;
01bc435b
YK
7097 case 4:
7098 CP0_CHECK(ctx->vp);
7099 /* ignored */
7100 rn = "VPControl";
7101 break;
9c2149c8 7102 default:
f31b035a 7103 goto cp0_unimplemented;
9c2149c8
TS
7104 }
7105 break;
7106 case 1:
7107 switch (sel) {
7108 case 0:
2423f660 7109 /* ignored */
9c2149c8 7110 rn = "Random";
2423f660 7111 break;
9c2149c8 7112 case 1:
f31b035a 7113 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7114 gen_helper_mtc0_vpecontrol(cpu_env, arg);
9c2149c8 7115 rn = "VPEControl";
ead9360e 7116 break;
9c2149c8 7117 case 2:
f31b035a 7118 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7119 gen_helper_mtc0_vpeconf0(cpu_env, arg);
9c2149c8 7120 rn = "VPEConf0";
ead9360e 7121 break;
9c2149c8 7122 case 3:
f31b035a 7123 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7124 gen_helper_mtc0_vpeconf1(cpu_env, arg);
9c2149c8 7125 rn = "VPEConf1";
ead9360e 7126 break;
9c2149c8 7127 case 4:
f31b035a 7128 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7129 gen_helper_mtc0_yqmask(cpu_env, arg);
9c2149c8 7130 rn = "YQMask";
ead9360e 7131 break;
9c2149c8 7132 case 5:
f31b035a 7133 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 7134 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
9c2149c8 7135 rn = "VPESchedule";
ead9360e 7136 break;
9c2149c8 7137 case 6:
f31b035a 7138 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 7139 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
9c2149c8 7140 rn = "VPEScheFBack";
ead9360e 7141 break;
9c2149c8 7142 case 7:
f31b035a 7143 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7144 gen_helper_mtc0_vpeopt(cpu_env, arg);
9c2149c8 7145 rn = "VPEOpt";
ead9360e 7146 break;
9c2149c8 7147 default:
f31b035a 7148 goto cp0_unimplemented;
9c2149c8
TS
7149 }
7150 break;
7151 case 2:
7152 switch (sel) {
7153 case 0:
7207c7f9 7154 gen_helper_dmtc0_entrylo0(cpu_env, arg);
2423f660
TS
7155 rn = "EntryLo0";
7156 break;
9c2149c8 7157 case 1:
f31b035a 7158 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7159 gen_helper_mtc0_tcstatus(cpu_env, arg);
2423f660 7160 rn = "TCStatus";
ead9360e 7161 break;
9c2149c8 7162 case 2:
f31b035a 7163 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7164 gen_helper_mtc0_tcbind(cpu_env, arg);
2423f660 7165 rn = "TCBind";
ead9360e 7166 break;
9c2149c8 7167 case 3:
f31b035a 7168 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7169 gen_helper_mtc0_tcrestart(cpu_env, arg);
2423f660 7170 rn = "TCRestart";
ead9360e 7171 break;
9c2149c8 7172 case 4:
f31b035a 7173 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7174 gen_helper_mtc0_tchalt(cpu_env, arg);
2423f660 7175 rn = "TCHalt";
ead9360e 7176 break;
9c2149c8 7177 case 5:
f31b035a 7178 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7179 gen_helper_mtc0_tccontext(cpu_env, arg);
2423f660 7180 rn = "TCContext";
ead9360e 7181 break;
9c2149c8 7182 case 6:
f31b035a 7183 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7184 gen_helper_mtc0_tcschedule(cpu_env, arg);
2423f660 7185 rn = "TCSchedule";
ead9360e 7186 break;
9c2149c8 7187 case 7:
f31b035a 7188 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7189 gen_helper_mtc0_tcschefback(cpu_env, arg);
2423f660 7190 rn = "TCScheFBack";
ead9360e 7191 break;
9c2149c8 7192 default:
f31b035a 7193 goto cp0_unimplemented;
9c2149c8
TS
7194 }
7195 break;
7196 case 3:
7197 switch (sel) {
7198 case 0:
7207c7f9 7199 gen_helper_dmtc0_entrylo1(cpu_env, arg);
2423f660
TS
7200 rn = "EntryLo1";
7201 break;
01bc435b
YK
7202 case 1:
7203 CP0_CHECK(ctx->vp);
7204 /* ignored */
7205 rn = "GlobalNumber";
7206 break;
9c2149c8 7207 default:
f31b035a 7208 goto cp0_unimplemented;
876d4b07 7209 }
9c2149c8
TS
7210 break;
7211 case 4:
7212 switch (sel) {
7213 case 0:
895c2d04 7214 gen_helper_mtc0_context(cpu_env, arg);
2423f660
TS
7215 rn = "Context";
7216 break;
9c2149c8 7217 case 1:
895c2d04 7218// gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
2423f660 7219 rn = "ContextConfig";
f31b035a 7220 goto cp0_unimplemented;
d279279e 7221 case 2:
f31b035a
LA
7222 CP0_CHECK(ctx->ulri);
7223 tcg_gen_st_tl(arg, cpu_env,
7224 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
7225 rn = "UserLocal";
d279279e 7226 break;
9c2149c8 7227 default:
f31b035a 7228 goto cp0_unimplemented;
876d4b07 7229 }
9c2149c8
TS
7230 break;
7231 case 5:
7232 switch (sel) {
7233 case 0:
895c2d04 7234 gen_helper_mtc0_pagemask(cpu_env, arg);
2423f660
TS
7235 rn = "PageMask";
7236 break;
9c2149c8 7237 case 1:
d75c135e 7238 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7239 gen_helper_mtc0_pagegrain(cpu_env, arg);
2423f660
TS
7240 rn = "PageGrain";
7241 break;
cec56a73
JH
7242 case 2:
7243 CP0_CHECK(ctx->sc);
7244 gen_helper_mtc0_segctl0(cpu_env, arg);
7245 rn = "SegCtl0";
7246 break;
7247 case 3:
7248 CP0_CHECK(ctx->sc);
7249 gen_helper_mtc0_segctl1(cpu_env, arg);
7250 rn = "SegCtl1";
7251 break;
7252 case 4:
7253 CP0_CHECK(ctx->sc);
7254 gen_helper_mtc0_segctl2(cpu_env, arg);
7255 rn = "SegCtl2";
7256 break;
9c2149c8 7257 default:
f31b035a 7258 goto cp0_unimplemented;
876d4b07 7259 }
9c2149c8
TS
7260 break;
7261 case 6:
7262 switch (sel) {
7263 case 0:
895c2d04 7264 gen_helper_mtc0_wired(cpu_env, arg);
2423f660
TS
7265 rn = "Wired";
7266 break;
9c2149c8 7267 case 1:
d75c135e 7268 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7269 gen_helper_mtc0_srsconf0(cpu_env, arg);
2423f660 7270 rn = "SRSConf0";
ead9360e 7271 break;
9c2149c8 7272 case 2:
d75c135e 7273 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7274 gen_helper_mtc0_srsconf1(cpu_env, arg);
2423f660 7275 rn = "SRSConf1";
ead9360e 7276 break;
9c2149c8 7277 case 3:
d75c135e 7278 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7279 gen_helper_mtc0_srsconf2(cpu_env, arg);
2423f660 7280 rn = "SRSConf2";
ead9360e 7281 break;
9c2149c8 7282 case 4:
d75c135e 7283 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7284 gen_helper_mtc0_srsconf3(cpu_env, arg);
2423f660 7285 rn = "SRSConf3";
ead9360e 7286 break;
9c2149c8 7287 case 5:
d75c135e 7288 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7289 gen_helper_mtc0_srsconf4(cpu_env, arg);
2423f660 7290 rn = "SRSConf4";
ead9360e 7291 break;
9c2149c8 7292 default:
f31b035a 7293 goto cp0_unimplemented;
876d4b07 7294 }
9c2149c8
TS
7295 break;
7296 case 7:
7297 switch (sel) {
7298 case 0:
d75c135e 7299 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7300 gen_helper_mtc0_hwrena(cpu_env, arg);
eeb3bba8 7301 ctx->base.is_jmp = DISAS_STOP;
2423f660
TS
7302 rn = "HWREna";
7303 break;
9c2149c8 7304 default:
f31b035a 7305 goto cp0_unimplemented;
876d4b07 7306 }
9c2149c8
TS
7307 break;
7308 case 8:
aea14095
LA
7309 switch (sel) {
7310 case 0:
7311 /* ignored */
7312 rn = "BadVAddr";
7313 break;
7314 case 1:
7315 /* ignored */
7316 rn = "BadInstr";
7317 break;
7318 case 2:
7319 /* ignored */
7320 rn = "BadInstrP";
7321 break;
7322 default:
f31b035a 7323 goto cp0_unimplemented;
aea14095 7324 }
9c2149c8
TS
7325 break;
7326 case 9:
7327 switch (sel) {
7328 case 0:
895c2d04 7329 gen_helper_mtc0_count(cpu_env, arg);
2423f660
TS
7330 rn = "Count";
7331 break;
876d4b07 7332 /* 6,7 are implementation dependent */
9c2149c8 7333 default:
f31b035a 7334 goto cp0_unimplemented;
876d4b07
TS
7335 }
7336 /* Stop translation as we may have switched the execution mode */
eeb3bba8 7337 ctx->base.is_jmp = DISAS_STOP;
9c2149c8
TS
7338 break;
7339 case 10:
7340 switch (sel) {
7341 case 0:
895c2d04 7342 gen_helper_mtc0_entryhi(cpu_env, arg);
2423f660
TS
7343 rn = "EntryHi";
7344 break;
9c2149c8 7345 default:
f31b035a 7346 goto cp0_unimplemented;
876d4b07 7347 }
9c2149c8
TS
7348 break;
7349 case 11:
7350 switch (sel) {
7351 case 0:
895c2d04 7352 gen_helper_mtc0_compare(cpu_env, arg);
2423f660
TS
7353 rn = "Compare";
7354 break;
876d4b07 7355 /* 6,7 are implementation dependent */
9c2149c8 7356 default:
f31b035a 7357 goto cp0_unimplemented;
876d4b07 7358 }
de9a95f0 7359 /* Stop translation as we may have switched the execution mode */
eeb3bba8 7360 ctx->base.is_jmp = DISAS_STOP;
9c2149c8
TS
7361 break;
7362 case 12:
7363 switch (sel) {
7364 case 0:
867abc7e 7365 save_cpu_state(ctx, 1);
895c2d04 7366 gen_helper_mtc0_status(cpu_env, arg);
b28425ba 7367 /* DISAS_STOP isn't good enough here, hflags may have changed. */
eeb3bba8
EC
7368 gen_save_pc(ctx->base.pc_next + 4);
7369 ctx->base.is_jmp = DISAS_EXIT;
2423f660
TS
7370 rn = "Status";
7371 break;
9c2149c8 7372 case 1:
d75c135e 7373 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7374 gen_helper_mtc0_intctl(cpu_env, arg);
8487327a 7375 /* Stop translation as we may have switched the execution mode */
eeb3bba8 7376 ctx->base.is_jmp = DISAS_STOP;
2423f660
TS
7377 rn = "IntCtl";
7378 break;
9c2149c8 7379 case 2:
d75c135e 7380 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7381 gen_helper_mtc0_srsctl(cpu_env, arg);
8487327a 7382 /* Stop translation as we may have switched the execution mode */
eeb3bba8 7383 ctx->base.is_jmp = DISAS_STOP;
2423f660
TS
7384 rn = "SRSCtl";
7385 break;
9c2149c8 7386 case 3:
d75c135e 7387 check_insn(ctx, ISA_MIPS32R2);
7db13fae 7388 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
8487327a 7389 /* Stop translation as we may have switched the execution mode */
eeb3bba8 7390 ctx->base.is_jmp = DISAS_STOP;
2423f660
TS
7391 rn = "SRSMap";
7392 break;
7393 default:
f31b035a 7394 goto cp0_unimplemented;
876d4b07 7395 }
9c2149c8
TS
7396 break;
7397 case 13:
7398 switch (sel) {
7399 case 0:
867abc7e 7400 save_cpu_state(ctx, 1);
895c2d04 7401 gen_helper_mtc0_cause(cpu_env, arg);
b28425ba
EC
7402 /* Stop translation as we may have triggered an interrupt.
7403 * DISAS_STOP isn't sufficient, we need to ensure we break out of
7404 * translated code to check for pending interrupts. */
eeb3bba8
EC
7405 gen_save_pc(ctx->base.pc_next + 4);
7406 ctx->base.is_jmp = DISAS_EXIT;
2423f660
TS
7407 rn = "Cause";
7408 break;
9c2149c8 7409 default:
f31b035a 7410 goto cp0_unimplemented;
876d4b07 7411 }
9c2149c8
TS
7412 break;
7413 case 14:
7414 switch (sel) {
7415 case 0:
7db13fae 7416 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
2423f660
TS
7417 rn = "EPC";
7418 break;
9c2149c8 7419 default:
f31b035a 7420 goto cp0_unimplemented;
876d4b07 7421 }
9c2149c8
TS
7422 break;
7423 case 15:
7424 switch (sel) {
7425 case 0:
2423f660
TS
7426 /* ignored */
7427 rn = "PRid";
7428 break;
9c2149c8 7429 case 1:
d75c135e 7430 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7431 gen_helper_mtc0_ebase(cpu_env, arg);
2423f660
TS
7432 rn = "EBase";
7433 break;
9c2149c8 7434 default:
f31b035a 7435 goto cp0_unimplemented;
876d4b07 7436 }
9c2149c8
TS
7437 break;
7438 case 16:
7439 switch (sel) {
7440 case 0:
895c2d04 7441 gen_helper_mtc0_config0(cpu_env, arg);
9c2149c8 7442 rn = "Config";
2423f660 7443 /* Stop translation as we may have switched the execution mode */
eeb3bba8 7444 ctx->base.is_jmp = DISAS_STOP;
9c2149c8
TS
7445 break;
7446 case 1:
1fc7bf6e 7447 /* ignored, read only */
9c2149c8
TS
7448 rn = "Config1";
7449 break;
7450 case 2:
895c2d04 7451 gen_helper_mtc0_config2(cpu_env, arg);
9c2149c8 7452 rn = "Config2";
2423f660 7453 /* Stop translation as we may have switched the execution mode */
eeb3bba8 7454 ctx->base.is_jmp = DISAS_STOP;
9c2149c8
TS
7455 break;
7456 case 3:
90f12d73 7457 gen_helper_mtc0_config3(cpu_env, arg);
9c2149c8 7458 rn = "Config3";
90f12d73 7459 /* Stop translation as we may have switched the execution mode */
eeb3bba8 7460 ctx->base.is_jmp = DISAS_STOP;
9c2149c8 7461 break;
faf1f68b
LA
7462 case 4:
7463 /* currently ignored */
7464 rn = "Config4";
7465 break;
7466 case 5:
7467 gen_helper_mtc0_config5(cpu_env, arg);
7468 rn = "Config5";
7469 /* Stop translation as we may have switched the execution mode */
eeb3bba8 7470 ctx->base.is_jmp = DISAS_STOP;
faf1f68b 7471 break;
9c2149c8
TS
7472 /* 6,7 are implementation dependent */
7473 default:
7474 rn = "Invalid config selector";
f31b035a 7475 goto cp0_unimplemented;
9c2149c8 7476 }
9c2149c8
TS
7477 break;
7478 case 17:
7479 switch (sel) {
7480 case 0:
895c2d04 7481 gen_helper_mtc0_lladdr(cpu_env, arg);
2423f660
TS
7482 rn = "LLAddr";
7483 break;
f6d4dd81
YK
7484 case 1:
7485 CP0_CHECK(ctx->mrp);
7486 gen_helper_mtc0_maar(cpu_env, arg);
7487 rn = "MAAR";
7488 break;
7489 case 2:
7490 CP0_CHECK(ctx->mrp);
7491 gen_helper_mtc0_maari(cpu_env, arg);
7492 rn = "MAARI";
7493 break;
9c2149c8 7494 default:
f31b035a 7495 goto cp0_unimplemented;
9c2149c8
TS
7496 }
7497 break;
7498 case 18:
7499 switch (sel) {
fd88b6ab 7500 case 0 ... 7:
895c2d04 7501 gen_helper_0e1i(mtc0_watchlo, arg, sel);
2423f660
TS
7502 rn = "WatchLo";
7503 break;
9c2149c8 7504 default:
f31b035a 7505 goto cp0_unimplemented;
9c2149c8
TS
7506 }
7507 break;
7508 case 19:
7509 switch (sel) {
fd88b6ab 7510 case 0 ... 7:
895c2d04 7511 gen_helper_0e1i(mtc0_watchhi, arg, sel);
2423f660
TS
7512 rn = "WatchHi";
7513 break;
9c2149c8 7514 default:
f31b035a 7515 goto cp0_unimplemented;
9c2149c8
TS
7516 }
7517 break;
7518 case 20:
7519 switch (sel) {
7520 case 0:
d75c135e 7521 check_insn(ctx, ISA_MIPS3);
895c2d04 7522 gen_helper_mtc0_xcontext(cpu_env, arg);
2423f660
TS
7523 rn = "XContext";
7524 break;
9c2149c8 7525 default:
f31b035a 7526 goto cp0_unimplemented;
9c2149c8
TS
7527 }
7528 break;
7529 case 21:
7530 /* Officially reserved, but sel 0 is used for R1x000 framemask */
f31b035a 7531 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
9c2149c8
TS
7532 switch (sel) {
7533 case 0:
895c2d04 7534 gen_helper_mtc0_framemask(cpu_env, arg);
2423f660
TS
7535 rn = "Framemask";
7536 break;
9c2149c8 7537 default:
f31b035a 7538 goto cp0_unimplemented;
9c2149c8
TS
7539 }
7540 break;
7541 case 22:
7542 /* ignored */
7543 rn = "Diagnostic"; /* implementation dependent */
876d4b07 7544 break;
9c2149c8
TS
7545 case 23:
7546 switch (sel) {
7547 case 0:
895c2d04 7548 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
b28425ba 7549 /* DISAS_STOP isn't good enough here, hflags may have changed. */
eeb3bba8
EC
7550 gen_save_pc(ctx->base.pc_next + 4);
7551 ctx->base.is_jmp = DISAS_EXIT;
2423f660
TS
7552 rn = "Debug";
7553 break;
9c2149c8 7554 case 1:
895c2d04 7555// gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
8487327a 7556 /* Stop translation as we may have switched the execution mode */
eeb3bba8 7557 ctx->base.is_jmp = DISAS_STOP;
2423f660 7558 rn = "TraceControl";
3570d7f6 7559 goto cp0_unimplemented;
9c2149c8 7560 case 2:
895c2d04 7561// gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
8487327a 7562 /* Stop translation as we may have switched the execution mode */
eeb3bba8 7563 ctx->base.is_jmp = DISAS_STOP;
2423f660 7564 rn = "TraceControl2";
3570d7f6 7565 goto cp0_unimplemented;
9c2149c8 7566 case 3:
895c2d04 7567// gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
8487327a 7568 /* Stop translation as we may have switched the execution mode */
eeb3bba8 7569 ctx->base.is_jmp = DISAS_STOP;
2423f660 7570 rn = "UserTraceData";
3570d7f6 7571 goto cp0_unimplemented;
9c2149c8 7572 case 4:
895c2d04 7573// gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
8487327a 7574 /* Stop translation as we may have switched the execution mode */
eeb3bba8 7575 ctx->base.is_jmp = DISAS_STOP;
2423f660 7576 rn = "TraceBPC";
3570d7f6 7577 goto cp0_unimplemented;
9c2149c8 7578 default:
f31b035a 7579 goto cp0_unimplemented;
9c2149c8 7580 }
9c2149c8
TS
7581 break;
7582 case 24:
7583 switch (sel) {
7584 case 0:
f1aa6320 7585 /* EJTAG support */
7db13fae 7586 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
2423f660
TS
7587 rn = "DEPC";
7588 break;
9c2149c8 7589 default:
f31b035a 7590 goto cp0_unimplemented;
9c2149c8
TS
7591 }
7592 break;
7593 case 25:
7594 switch (sel) {
7595 case 0:
895c2d04 7596 gen_helper_mtc0_performance0(cpu_env, arg);
2423f660
TS
7597 rn = "Performance0";
7598 break;
9c2149c8 7599 case 1:
895c2d04 7600// gen_helper_mtc0_performance1(cpu_env, arg);
2423f660 7601 rn = "Performance1";
3570d7f6 7602 goto cp0_unimplemented;
9c2149c8 7603 case 2:
895c2d04 7604// gen_helper_mtc0_performance2(cpu_env, arg);
2423f660 7605 rn = "Performance2";
3570d7f6 7606 goto cp0_unimplemented;
9c2149c8 7607 case 3:
895c2d04 7608// gen_helper_mtc0_performance3(cpu_env, arg);
2423f660 7609 rn = "Performance3";
3570d7f6 7610 goto cp0_unimplemented;
9c2149c8 7611 case 4:
895c2d04 7612// gen_helper_mtc0_performance4(cpu_env, arg);
2423f660 7613 rn = "Performance4";
3570d7f6 7614 goto cp0_unimplemented;
9c2149c8 7615 case 5:
895c2d04 7616// gen_helper_mtc0_performance5(cpu_env, arg);
2423f660 7617 rn = "Performance5";
3570d7f6 7618 goto cp0_unimplemented;
9c2149c8 7619 case 6:
895c2d04 7620// gen_helper_mtc0_performance6(cpu_env, arg);
2423f660 7621 rn = "Performance6";
3570d7f6 7622 goto cp0_unimplemented;
9c2149c8 7623 case 7:
895c2d04 7624// gen_helper_mtc0_performance7(cpu_env, arg);
2423f660 7625 rn = "Performance7";
3570d7f6 7626 goto cp0_unimplemented;
9c2149c8 7627 default:
f31b035a 7628 goto cp0_unimplemented;
9c2149c8 7629 }
876d4b07 7630 break;
9c2149c8 7631 case 26:
0d74a222
LA
7632 switch (sel) {
7633 case 0:
7634 gen_helper_mtc0_errctl(cpu_env, arg);
eeb3bba8 7635 ctx->base.is_jmp = DISAS_STOP;
0d74a222
LA
7636 rn = "ErrCtl";
7637 break;
7638 default:
7639 goto cp0_unimplemented;
7640 }
876d4b07 7641 break;
9c2149c8
TS
7642 case 27:
7643 switch (sel) {
7644 case 0 ... 3:
2423f660
TS
7645 /* ignored */
7646 rn = "CacheErr";
7647 break;
9c2149c8 7648 default:
f31b035a 7649 goto cp0_unimplemented;
9c2149c8 7650 }
876d4b07 7651 break;
9c2149c8
TS
7652 case 28:
7653 switch (sel) {
7654 case 0:
7655 case 2:
7656 case 4:
7657 case 6:
895c2d04 7658 gen_helper_mtc0_taglo(cpu_env, arg);
9c2149c8
TS
7659 rn = "TagLo";
7660 break;
7661 case 1:
7662 case 3:
7663 case 5:
7664 case 7:
895c2d04 7665 gen_helper_mtc0_datalo(cpu_env, arg);
9c2149c8
TS
7666 rn = "DataLo";
7667 break;
7668 default:
f31b035a 7669 goto cp0_unimplemented;
9c2149c8
TS
7670 }
7671 break;
7672 case 29:
7673 switch (sel) {
7674 case 0:
7675 case 2:
7676 case 4:
7677 case 6:
895c2d04 7678 gen_helper_mtc0_taghi(cpu_env, arg);
9c2149c8
TS
7679 rn = "TagHi";
7680 break;
7681 case 1:
7682 case 3:
7683 case 5:
7684 case 7:
895c2d04 7685 gen_helper_mtc0_datahi(cpu_env, arg);
9c2149c8
TS
7686 rn = "DataHi";
7687 break;
7688 default:
7689 rn = "invalid sel";
f31b035a 7690 goto cp0_unimplemented;
9c2149c8 7691 }
876d4b07 7692 break;
9c2149c8
TS
7693 case 30:
7694 switch (sel) {
7695 case 0:
7db13fae 7696 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
2423f660
TS
7697 rn = "ErrorEPC";
7698 break;
9c2149c8 7699 default:
f31b035a 7700 goto cp0_unimplemented;
9c2149c8
TS
7701 }
7702 break;
7703 case 31:
7704 switch (sel) {
7705 case 0:
f1aa6320 7706 /* EJTAG support */
7db13fae 7707 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
7708 rn = "DESAVE";
7709 break;
e98c0d17 7710 case 2 ... 7:
f31b035a
LA
7711 CP0_CHECK(ctx->kscrexist & (1 << sel));
7712 tcg_gen_st_tl(arg, cpu_env,
7713 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
7714 rn = "KScratch";
e98c0d17 7715 break;
9c2149c8 7716 default:
f31b035a 7717 goto cp0_unimplemented;
9c2149c8 7718 }
9c2149c8
TS
7719 break;
7720 default:
f31b035a 7721 goto cp0_unimplemented;
9c2149c8 7722 }
b44a7fb1
PMD
7723 trace_mips_translate_c0("dmtc0", rn, reg, sel);
7724
bf20dc07 7725 /* For simplicity assume that all writes can cause interrupts. */
eeb3bba8 7726 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
2e70f6ef 7727 gen_io_end();
b28425ba 7728 /* DISAS_STOP isn't sufficient, we need to ensure we break out of
b74cddcb 7729 * translated code to check for pending interrupts. */
eeb3bba8
EC
7730 gen_save_pc(ctx->base.pc_next + 4);
7731 ctx->base.is_jmp = DISAS_EXIT;
2e70f6ef 7732 }
9c2149c8
TS
7733 return;
7734
f31b035a 7735cp0_unimplemented:
965447ee 7736 qemu_log_mask(LOG_UNIMP, "dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
9c2149c8 7737}
d26bc211 7738#endif /* TARGET_MIPS64 */
9c2149c8 7739
7db13fae 7740static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
ead9360e
TS
7741 int u, int sel, int h)
7742{
7743 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
a7812ae4 7744 TCGv t0 = tcg_temp_local_new();
ead9360e
TS
7745
7746 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
b5dc7732
TS
7747 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
7748 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
1a3fd9c3 7749 tcg_gen_movi_tl(t0, -1);
ead9360e
TS
7750 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
7751 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
1a3fd9c3 7752 tcg_gen_movi_tl(t0, -1);
ead9360e
TS
7753 else if (u == 0) {
7754 switch (rt) {
5a25ce94
EI
7755 case 1:
7756 switch (sel) {
7757 case 1:
895c2d04 7758 gen_helper_mftc0_vpecontrol(t0, cpu_env);
5a25ce94
EI
7759 break;
7760 case 2:
895c2d04 7761 gen_helper_mftc0_vpeconf0(t0, cpu_env);
5a25ce94
EI
7762 break;
7763 default:
7764 goto die;
7765 break;
7766 }
7767 break;
ead9360e
TS
7768 case 2:
7769 switch (sel) {
7770 case 1:
895c2d04 7771 gen_helper_mftc0_tcstatus(t0, cpu_env);
ead9360e
TS
7772 break;
7773 case 2:
895c2d04 7774 gen_helper_mftc0_tcbind(t0, cpu_env);
ead9360e
TS
7775 break;
7776 case 3:
895c2d04 7777 gen_helper_mftc0_tcrestart(t0, cpu_env);
ead9360e
TS
7778 break;
7779 case 4:
895c2d04 7780 gen_helper_mftc0_tchalt(t0, cpu_env);
ead9360e
TS
7781 break;
7782 case 5:
895c2d04 7783 gen_helper_mftc0_tccontext(t0, cpu_env);
ead9360e
TS
7784 break;
7785 case 6:
895c2d04 7786 gen_helper_mftc0_tcschedule(t0, cpu_env);
ead9360e
TS
7787 break;
7788 case 7:
895c2d04 7789 gen_helper_mftc0_tcschefback(t0, cpu_env);
ead9360e
TS
7790 break;
7791 default:
d75c135e 7792 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
7793 break;
7794 }
7795 break;
7796 case 10:
7797 switch (sel) {
7798 case 0:
895c2d04 7799 gen_helper_mftc0_entryhi(t0, cpu_env);
ead9360e
TS
7800 break;
7801 default:
d75c135e 7802 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
7803 break;
7804 }
7805 case 12:
7806 switch (sel) {
7807 case 0:
895c2d04 7808 gen_helper_mftc0_status(t0, cpu_env);
ead9360e
TS
7809 break;
7810 default:
d75c135e 7811 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
7812 break;
7813 }
5a25ce94
EI
7814 case 13:
7815 switch (sel) {
7816 case 0:
895c2d04 7817 gen_helper_mftc0_cause(t0, cpu_env);
5a25ce94
EI
7818 break;
7819 default:
7820 goto die;
7821 break;
7822 }
7823 break;
7824 case 14:
7825 switch (sel) {
7826 case 0:
895c2d04 7827 gen_helper_mftc0_epc(t0, cpu_env);
5a25ce94
EI
7828 break;
7829 default:
7830 goto die;
7831 break;
7832 }
7833 break;
7834 case 15:
7835 switch (sel) {
7836 case 1:
895c2d04 7837 gen_helper_mftc0_ebase(t0, cpu_env);
5a25ce94
EI
7838 break;
7839 default:
7840 goto die;
7841 break;
7842 }
7843 break;
7844 case 16:
7845 switch (sel) {
7846 case 0 ... 7:
895c2d04 7847 gen_helper_mftc0_configx(t0, cpu_env, tcg_const_tl(sel));
5a25ce94
EI
7848 break;
7849 default:
7850 goto die;
7851 break;
7852 }
7853 break;
ead9360e
TS
7854 case 23:
7855 switch (sel) {
7856 case 0:
895c2d04 7857 gen_helper_mftc0_debug(t0, cpu_env);
ead9360e
TS
7858 break;
7859 default:
d75c135e 7860 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
7861 break;
7862 }
7863 break;
7864 default:
d75c135e 7865 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
7866 }
7867 } else switch (sel) {
7868 /* GPR registers. */
7869 case 0:
895c2d04 7870 gen_helper_1e0i(mftgpr, t0, rt);
ead9360e
TS
7871 break;
7872 /* Auxiliary CPU registers */
7873 case 1:
7874 switch (rt) {
7875 case 0:
895c2d04 7876 gen_helper_1e0i(mftlo, t0, 0);
ead9360e
TS
7877 break;
7878 case 1:
895c2d04 7879 gen_helper_1e0i(mfthi, t0, 0);
ead9360e
TS
7880 break;
7881 case 2:
895c2d04 7882 gen_helper_1e0i(mftacx, t0, 0);
ead9360e
TS
7883 break;
7884 case 4:
895c2d04 7885 gen_helper_1e0i(mftlo, t0, 1);
ead9360e
TS
7886 break;
7887 case 5:
895c2d04 7888 gen_helper_1e0i(mfthi, t0, 1);
ead9360e
TS
7889 break;
7890 case 6:
895c2d04 7891 gen_helper_1e0i(mftacx, t0, 1);
ead9360e
TS
7892 break;
7893 case 8:
895c2d04 7894 gen_helper_1e0i(mftlo, t0, 2);
ead9360e
TS
7895 break;
7896 case 9:
895c2d04 7897 gen_helper_1e0i(mfthi, t0, 2);
ead9360e
TS
7898 break;
7899 case 10:
895c2d04 7900 gen_helper_1e0i(mftacx, t0, 2);
ead9360e
TS
7901 break;
7902 case 12:
895c2d04 7903 gen_helper_1e0i(mftlo, t0, 3);
ead9360e
TS
7904 break;
7905 case 13:
895c2d04 7906 gen_helper_1e0i(mfthi, t0, 3);
ead9360e
TS
7907 break;
7908 case 14:
895c2d04 7909 gen_helper_1e0i(mftacx, t0, 3);
ead9360e
TS
7910 break;
7911 case 16:
895c2d04 7912 gen_helper_mftdsp(t0, cpu_env);
ead9360e
TS
7913 break;
7914 default:
7915 goto die;
7916 }
7917 break;
7918 /* Floating point (COP1). */
7919 case 2:
7920 /* XXX: For now we support only a single FPU context. */
7921 if (h == 0) {
a7812ae4 7922 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 7923
7c979afd 7924 gen_load_fpr32(ctx, fp0, rt);
b6d96bed 7925 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 7926 tcg_temp_free_i32(fp0);
ead9360e 7927 } else {
a7812ae4 7928 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 7929
7f6613ce 7930 gen_load_fpr32h(ctx, fp0, rt);
b6d96bed 7931 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 7932 tcg_temp_free_i32(fp0);
ead9360e
TS
7933 }
7934 break;
7935 case 3:
7936 /* XXX: For now we support only a single FPU context. */
895c2d04 7937 gen_helper_1e0i(cfc1, t0, rt);
ead9360e
TS
7938 break;
7939 /* COP2: Not implemented. */
7940 case 4:
7941 case 5:
7942 /* fall through */
7943 default:
7944 goto die;
7945 }
b44a7fb1 7946 trace_mips_translate_tr("mftr", rt, u, sel, h);
1a3fd9c3
TS
7947 gen_store_gpr(t0, rd);
7948 tcg_temp_free(t0);
ead9360e
TS
7949 return;
7950
7951die:
1a3fd9c3 7952 tcg_temp_free(t0);
d12d51d5 7953 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
9c708c7f 7954 generate_exception_end(ctx, EXCP_RI);
ead9360e
TS
7955}
7956
7db13fae 7957static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
ead9360e
TS
7958 int u, int sel, int h)
7959{
7960 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
a7812ae4 7961 TCGv t0 = tcg_temp_local_new();
ead9360e 7962
1a3fd9c3 7963 gen_load_gpr(t0, rt);
ead9360e 7964 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
b5dc7732
TS
7965 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
7966 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
ead9360e
TS
7967 /* NOP */ ;
7968 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
7969 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
7970 /* NOP */ ;
7971 else if (u == 0) {
7972 switch (rd) {
5a25ce94
EI
7973 case 1:
7974 switch (sel) {
7975 case 1:
895c2d04 7976 gen_helper_mttc0_vpecontrol(cpu_env, t0);
5a25ce94
EI
7977 break;
7978 case 2:
895c2d04 7979 gen_helper_mttc0_vpeconf0(cpu_env, t0);
5a25ce94
EI
7980 break;
7981 default:
7982 goto die;
7983 break;
7984 }
7985 break;
ead9360e
TS
7986 case 2:
7987 switch (sel) {
7988 case 1:
895c2d04 7989 gen_helper_mttc0_tcstatus(cpu_env, t0);
ead9360e
TS
7990 break;
7991 case 2:
895c2d04 7992 gen_helper_mttc0_tcbind(cpu_env, t0);
ead9360e
TS
7993 break;
7994 case 3:
895c2d04 7995 gen_helper_mttc0_tcrestart(cpu_env, t0);
ead9360e
TS
7996 break;
7997 case 4:
895c2d04 7998 gen_helper_mttc0_tchalt(cpu_env, t0);
ead9360e
TS
7999 break;
8000 case 5:
895c2d04 8001 gen_helper_mttc0_tccontext(cpu_env, t0);
ead9360e
TS
8002 break;
8003 case 6:
895c2d04 8004 gen_helper_mttc0_tcschedule(cpu_env, t0);
ead9360e
TS
8005 break;
8006 case 7:
895c2d04 8007 gen_helper_mttc0_tcschefback(cpu_env, t0);
ead9360e
TS
8008 break;
8009 default:
d75c135e 8010 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
8011 break;
8012 }
8013 break;
8014 case 10:
8015 switch (sel) {
8016 case 0:
895c2d04 8017 gen_helper_mttc0_entryhi(cpu_env, t0);
ead9360e
TS
8018 break;
8019 default:
d75c135e 8020 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
8021 break;
8022 }
8023 case 12:
8024 switch (sel) {
8025 case 0:
895c2d04 8026 gen_helper_mttc0_status(cpu_env, t0);
ead9360e
TS
8027 break;
8028 default:
d75c135e 8029 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
8030 break;
8031 }
5a25ce94
EI
8032 case 13:
8033 switch (sel) {
8034 case 0:
895c2d04 8035 gen_helper_mttc0_cause(cpu_env, t0);
5a25ce94
EI
8036 break;
8037 default:
8038 goto die;
8039 break;
8040 }
8041 break;
8042 case 15:
8043 switch (sel) {
8044 case 1:
895c2d04 8045 gen_helper_mttc0_ebase(cpu_env, t0);
5a25ce94
EI
8046 break;
8047 default:
8048 goto die;
8049 break;
8050 }
8051 break;
ead9360e
TS
8052 case 23:
8053 switch (sel) {
8054 case 0:
895c2d04 8055 gen_helper_mttc0_debug(cpu_env, t0);
ead9360e
TS
8056 break;
8057 default:
d75c135e 8058 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
8059 break;
8060 }
8061 break;
8062 default:
d75c135e 8063 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
8064 }
8065 } else switch (sel) {
8066 /* GPR registers. */
8067 case 0:
895c2d04 8068 gen_helper_0e1i(mttgpr, t0, rd);
ead9360e
TS
8069 break;
8070 /* Auxiliary CPU registers */
8071 case 1:
8072 switch (rd) {
8073 case 0:
895c2d04 8074 gen_helper_0e1i(mttlo, t0, 0);
ead9360e
TS
8075 break;
8076 case 1:
895c2d04 8077 gen_helper_0e1i(mtthi, t0, 0);
ead9360e
TS
8078 break;
8079 case 2:
895c2d04 8080 gen_helper_0e1i(mttacx, t0, 0);
ead9360e
TS
8081 break;
8082 case 4:
895c2d04 8083 gen_helper_0e1i(mttlo, t0, 1);
ead9360e
TS
8084 break;
8085 case 5:
895c2d04 8086 gen_helper_0e1i(mtthi, t0, 1);
ead9360e
TS
8087 break;
8088 case 6:
895c2d04 8089 gen_helper_0e1i(mttacx, t0, 1);
ead9360e
TS
8090 break;
8091 case 8:
895c2d04 8092 gen_helper_0e1i(mttlo, t0, 2);
ead9360e
TS
8093 break;
8094 case 9:
895c2d04 8095 gen_helper_0e1i(mtthi, t0, 2);
ead9360e
TS
8096 break;
8097 case 10:
895c2d04 8098 gen_helper_0e1i(mttacx, t0, 2);
ead9360e
TS
8099 break;
8100 case 12:
895c2d04 8101 gen_helper_0e1i(mttlo, t0, 3);
ead9360e
TS
8102 break;
8103 case 13:
895c2d04 8104 gen_helper_0e1i(mtthi, t0, 3);
ead9360e
TS
8105 break;
8106 case 14:
895c2d04 8107 gen_helper_0e1i(mttacx, t0, 3);
ead9360e
TS
8108 break;
8109 case 16:
895c2d04 8110 gen_helper_mttdsp(cpu_env, t0);
ead9360e
TS
8111 break;
8112 default:
8113 goto die;
8114 }
8115 break;
8116 /* Floating point (COP1). */
8117 case 2:
8118 /* XXX: For now we support only a single FPU context. */
8119 if (h == 0) {
a7812ae4 8120 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8121
8122 tcg_gen_trunc_tl_i32(fp0, t0);
7c979afd 8123 gen_store_fpr32(ctx, fp0, rd);
a7812ae4 8124 tcg_temp_free_i32(fp0);
ead9360e 8125 } else {
a7812ae4 8126 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8127
8128 tcg_gen_trunc_tl_i32(fp0, t0);
7f6613ce 8129 gen_store_fpr32h(ctx, fp0, rd);
a7812ae4 8130 tcg_temp_free_i32(fp0);
ead9360e
TS
8131 }
8132 break;
8133 case 3:
8134 /* XXX: For now we support only a single FPU context. */
736d120a
PJ
8135 {
8136 TCGv_i32 fs_tmp = tcg_const_i32(rd);
8137
8138 gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
8139 tcg_temp_free_i32(fs_tmp);
8140 }
4cf8a45f 8141 /* Stop translation as we may have changed hflags */
eeb3bba8 8142 ctx->base.is_jmp = DISAS_STOP;
ead9360e
TS
8143 break;
8144 /* COP2: Not implemented. */
8145 case 4:
8146 case 5:
8147 /* fall through */
8148 default:
8149 goto die;
8150 }
b44a7fb1 8151 trace_mips_translate_tr("mttr", rd, u, sel, h);
1a3fd9c3 8152 tcg_temp_free(t0);
ead9360e
TS
8153 return;
8154
8155die:
1a3fd9c3 8156 tcg_temp_free(t0);
d12d51d5 8157 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
9c708c7f 8158 generate_exception_end(ctx, EXCP_RI);
ead9360e
TS
8159}
8160
7db13fae 8161static void gen_cp0 (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
6af0bf9c 8162{
287c4b84 8163 const char *opn = "ldst";
6af0bf9c 8164
2e15497c 8165 check_cp0_enabled(ctx);
6af0bf9c
FB
8166 switch (opc) {
8167 case OPC_MFC0:
8168 if (rt == 0) {
ead9360e 8169 /* Treat as NOP. */
6af0bf9c
FB
8170 return;
8171 }
d75c135e 8172 gen_mfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
6af0bf9c
FB
8173 opn = "mfc0";
8174 break;
8175 case OPC_MTC0:
1a3fd9c3 8176 {
1fc7bf6e 8177 TCGv t0 = tcg_temp_new();
1a3fd9c3
TS
8178
8179 gen_load_gpr(t0, rt);
d75c135e 8180 gen_mtc0(ctx, t0, rd, ctx->opcode & 0x7);
1a3fd9c3
TS
8181 tcg_temp_free(t0);
8182 }
6af0bf9c
FB
8183 opn = "mtc0";
8184 break;
d26bc211 8185#if defined(TARGET_MIPS64)
9c2149c8 8186 case OPC_DMFC0:
d75c135e 8187 check_insn(ctx, ISA_MIPS3);
9c2149c8 8188 if (rt == 0) {
ead9360e 8189 /* Treat as NOP. */
9c2149c8
TS
8190 return;
8191 }
d75c135e 8192 gen_dmfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
9c2149c8
TS
8193 opn = "dmfc0";
8194 break;
8195 case OPC_DMTC0:
d75c135e 8196 check_insn(ctx, ISA_MIPS3);
1a3fd9c3 8197 {
1fc7bf6e 8198 TCGv t0 = tcg_temp_new();
1a3fd9c3
TS
8199
8200 gen_load_gpr(t0, rt);
d75c135e 8201 gen_dmtc0(ctx, t0, rd, ctx->opcode & 0x7);
1a3fd9c3
TS
8202 tcg_temp_free(t0);
8203 }
9c2149c8
TS
8204 opn = "dmtc0";
8205 break;
534ce69f 8206#endif
5204ea79
LA
8207 case OPC_MFHC0:
8208 check_mvh(ctx);
8209 if (rt == 0) {
8210 /* Treat as NOP. */
8211 return;
8212 }
8213 gen_mfhc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
8214 opn = "mfhc0";
8215 break;
8216 case OPC_MTHC0:
8217 check_mvh(ctx);
8218 {
8219 TCGv t0 = tcg_temp_new();
8220 gen_load_gpr(t0, rt);
8221 gen_mthc0(ctx, t0, rd, ctx->opcode & 0x7);
8222 tcg_temp_free(t0);
8223 }
8224 opn = "mthc0";
8225 break;
ead9360e 8226 case OPC_MFTR:
d75c135e 8227 check_insn(ctx, ASE_MT);
ead9360e
TS
8228 if (rd == 0) {
8229 /* Treat as NOP. */
8230 return;
8231 }
6c5c1e20 8232 gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
ead9360e 8233 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
ead9360e
TS
8234 opn = "mftr";
8235 break;
8236 case OPC_MTTR:
d75c135e 8237 check_insn(ctx, ASE_MT);
6c5c1e20 8238 gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
ead9360e
TS
8239 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
8240 opn = "mttr";
8241 break;
6af0bf9c 8242 case OPC_TLBWI:
6af0bf9c 8243 opn = "tlbwi";
c01fccd2 8244 if (!env->tlb->helper_tlbwi)
29929e34 8245 goto die;
895c2d04 8246 gen_helper_tlbwi(cpu_env);
6af0bf9c 8247 break;
9456c2fb
LA
8248 case OPC_TLBINV:
8249 opn = "tlbinv";
8250 if (ctx->ie >= 2) {
8251 if (!env->tlb->helper_tlbinv) {
8252 goto die;
8253 }
8254 gen_helper_tlbinv(cpu_env);
8255 } /* treat as nop if TLBINV not supported */
8256 break;
8257 case OPC_TLBINVF:
8258 opn = "tlbinvf";
8259 if (ctx->ie >= 2) {
8260 if (!env->tlb->helper_tlbinvf) {
8261 goto die;
8262 }
8263 gen_helper_tlbinvf(cpu_env);
8264 } /* treat as nop if TLBINV not supported */
8265 break;
6af0bf9c 8266 case OPC_TLBWR:
6af0bf9c 8267 opn = "tlbwr";
c01fccd2 8268 if (!env->tlb->helper_tlbwr)
29929e34 8269 goto die;
895c2d04 8270 gen_helper_tlbwr(cpu_env);
6af0bf9c
FB
8271 break;
8272 case OPC_TLBP:
6af0bf9c 8273 opn = "tlbp";
c01fccd2 8274 if (!env->tlb->helper_tlbp)
29929e34 8275 goto die;
895c2d04 8276 gen_helper_tlbp(cpu_env);
6af0bf9c
FB
8277 break;
8278 case OPC_TLBR:
6af0bf9c 8279 opn = "tlbr";
c01fccd2 8280 if (!env->tlb->helper_tlbr)
29929e34 8281 goto die;
895c2d04 8282 gen_helper_tlbr(cpu_env);
6af0bf9c 8283 break;
ce9782f4 8284 case OPC_ERET: /* OPC_ERETNC */
339cd2a8
LA
8285 if ((ctx->insn_flags & ISA_MIPS32R6) &&
8286 (ctx->hflags & MIPS_HFLAG_BMASK)) {
339cd2a8 8287 goto die;
ce9782f4
LA
8288 } else {
8289 int bit_shift = (ctx->hflags & MIPS_HFLAG_M16) ? 16 : 6;
8290 if (ctx->opcode & (1 << bit_shift)) {
8291 /* OPC_ERETNC */
8292 opn = "eretnc";
8293 check_insn(ctx, ISA_MIPS32R5);
8294 gen_helper_eretnc(cpu_env);
8295 } else {
8296 /* OPC_ERET */
8297 opn = "eret";
8298 check_insn(ctx, ISA_MIPS2);
8299 gen_helper_eret(cpu_env);
8300 }
eeb3bba8 8301 ctx->base.is_jmp = DISAS_EXIT;
339cd2a8 8302 }
6af0bf9c
FB
8303 break;
8304 case OPC_DERET:
8305 opn = "deret";
d75c135e 8306 check_insn(ctx, ISA_MIPS32);
339cd2a8
LA
8307 if ((ctx->insn_flags & ISA_MIPS32R6) &&
8308 (ctx->hflags & MIPS_HFLAG_BMASK)) {
339cd2a8
LA
8309 goto die;
8310 }
6af0bf9c 8311 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
923617a3 8312 MIPS_INVAL(opn);
9c708c7f 8313 generate_exception_end(ctx, EXCP_RI);
6af0bf9c 8314 } else {
895c2d04 8315 gen_helper_deret(cpu_env);
eeb3bba8 8316 ctx->base.is_jmp = DISAS_EXIT;
6af0bf9c
FB
8317 }
8318 break;
4ad40f36
FB
8319 case OPC_WAIT:
8320 opn = "wait";
d75c135e 8321 check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
339cd2a8
LA
8322 if ((ctx->insn_flags & ISA_MIPS32R6) &&
8323 (ctx->hflags & MIPS_HFLAG_BMASK)) {
339cd2a8
LA
8324 goto die;
8325 }
4ad40f36 8326 /* If we get an exception, we want to restart at next instruction */
eeb3bba8 8327 ctx->base.pc_next += 4;
4ad40f36 8328 save_cpu_state(ctx, 1);
eeb3bba8 8329 ctx->base.pc_next -= 4;
895c2d04 8330 gen_helper_wait(cpu_env);
eeb3bba8 8331 ctx->base.is_jmp = DISAS_NORETURN;
4ad40f36 8332 break;
6af0bf9c 8333 default:
29929e34 8334 die:
923617a3 8335 MIPS_INVAL(opn);
9c708c7f 8336 generate_exception_end(ctx, EXCP_RI);
6af0bf9c
FB
8337 return;
8338 }
2abf314d 8339 (void)opn; /* avoid a compiler warning */
6af0bf9c 8340}
f1aa6320 8341#endif /* !CONFIG_USER_ONLY */
6af0bf9c 8342
6ea83fed 8343/* CP1 Branches (before delay slot) */
d75c135e
AJ
8344static void gen_compute_branch1(DisasContext *ctx, uint32_t op,
8345 int32_t cc, int32_t offset)
6ea83fed
FB
8346{
8347 target_ulong btarget;
a7812ae4 8348 TCGv_i32 t0 = tcg_temp_new_i32();
6ea83fed 8349
339cd2a8 8350 if ((ctx->insn_flags & ISA_MIPS32R6) && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9c708c7f 8351 generate_exception_end(ctx, EXCP_RI);
339cd2a8
LA
8352 goto out;
8353 }
8354
e189e748 8355 if (cc != 0)
d75c135e 8356 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
e189e748 8357
eeb3bba8 8358 btarget = ctx->base.pc_next + 4 + offset;
6ea83fed 8359
7a387fff
TS
8360 switch (op) {
8361 case OPC_BC1F:
d94536f4
AJ
8362 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8363 tcg_gen_not_i32(t0, t0);
8364 tcg_gen_andi_i32(t0, t0, 1);
8365 tcg_gen_extu_i32_tl(bcond, t0);
6ea83fed 8366 goto not_likely;
7a387fff 8367 case OPC_BC1FL:
d94536f4
AJ
8368 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8369 tcg_gen_not_i32(t0, t0);
8370 tcg_gen_andi_i32(t0, t0, 1);
8371 tcg_gen_extu_i32_tl(bcond, t0);
6ea83fed 8372 goto likely;
7a387fff 8373 case OPC_BC1T:
d94536f4
AJ
8374 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8375 tcg_gen_andi_i32(t0, t0, 1);
8376 tcg_gen_extu_i32_tl(bcond, t0);
5a5012ec 8377 goto not_likely;
7a387fff 8378 case OPC_BC1TL:
d94536f4
AJ
8379 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8380 tcg_gen_andi_i32(t0, t0, 1);
8381 tcg_gen_extu_i32_tl(bcond, t0);
6ea83fed
FB
8382 likely:
8383 ctx->hflags |= MIPS_HFLAG_BL;
8384 break;
5a5012ec 8385 case OPC_BC1FANY2:
a16336e4 8386 {
d94536f4
AJ
8387 TCGv_i32 t1 = tcg_temp_new_i32();
8388 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8389 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
d7f66b52 8390 tcg_gen_nand_i32(t0, t0, t1);
d94536f4 8391 tcg_temp_free_i32(t1);
d94536f4
AJ
8392 tcg_gen_andi_i32(t0, t0, 1);
8393 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 8394 }
5a5012ec
TS
8395 goto not_likely;
8396 case OPC_BC1TANY2:
a16336e4 8397 {
d94536f4
AJ
8398 TCGv_i32 t1 = tcg_temp_new_i32();
8399 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8400 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
8401 tcg_gen_or_i32(t0, t0, t1);
8402 tcg_temp_free_i32(t1);
8403 tcg_gen_andi_i32(t0, t0, 1);
8404 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 8405 }
5a5012ec
TS
8406 goto not_likely;
8407 case OPC_BC1FANY4:
a16336e4 8408 {
d94536f4
AJ
8409 TCGv_i32 t1 = tcg_temp_new_i32();
8410 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8411 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
d7f66b52 8412 tcg_gen_and_i32(t0, t0, t1);
d94536f4 8413 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
d7f66b52 8414 tcg_gen_and_i32(t0, t0, t1);
d94536f4 8415 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
d7f66b52 8416 tcg_gen_nand_i32(t0, t0, t1);
d94536f4 8417 tcg_temp_free_i32(t1);
d94536f4
AJ
8418 tcg_gen_andi_i32(t0, t0, 1);
8419 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 8420 }
5a5012ec
TS
8421 goto not_likely;
8422 case OPC_BC1TANY4:
a16336e4 8423 {
d94536f4
AJ
8424 TCGv_i32 t1 = tcg_temp_new_i32();
8425 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8426 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
8427 tcg_gen_or_i32(t0, t0, t1);
8428 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
8429 tcg_gen_or_i32(t0, t0, t1);
8430 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
8431 tcg_gen_or_i32(t0, t0, t1);
8432 tcg_temp_free_i32(t1);
8433 tcg_gen_andi_i32(t0, t0, 1);
8434 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 8435 }
5a5012ec
TS
8436 not_likely:
8437 ctx->hflags |= MIPS_HFLAG_BC;
5a5012ec
TS
8438 break;
8439 default:
9d68ac14 8440 MIPS_INVAL("cp1 cond branch");
9c708c7f 8441 generate_exception_end(ctx, EXCP_RI);
6c5c1e20 8442 goto out;
6ea83fed 8443 }
6ea83fed 8444 ctx->btarget = btarget;
b231c103 8445 ctx->hflags |= MIPS_HFLAG_BDS32;
6c5c1e20 8446 out:
a7812ae4 8447 tcg_temp_free_i32(t0);
6ea83fed
FB
8448}
8449
31837be3
YK
8450/* R6 CP1 Branches */
8451static void gen_compute_branch1_r6(DisasContext *ctx, uint32_t op,
65935f07
YK
8452 int32_t ft, int32_t offset,
8453 int delayslot_size)
31837be3
YK
8454{
8455 target_ulong btarget;
31837be3
YK
8456 TCGv_i64 t0 = tcg_temp_new_i64();
8457
8458 if (ctx->hflags & MIPS_HFLAG_BMASK) {
8459#ifdef MIPS_DEBUG_DISAS
339cd2a8 8460 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
eeb3bba8 8461 "\n", ctx->base.pc_next);
31837be3 8462#endif
9c708c7f 8463 generate_exception_end(ctx, EXCP_RI);
31837be3
YK
8464 goto out;
8465 }
8466
8467 gen_load_fpr64(ctx, t0, ft);
8468 tcg_gen_andi_i64(t0, t0, 1);
8469
eeb3bba8 8470 btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
31837be3
YK
8471
8472 switch (op) {
8473 case OPC_BC1EQZ:
8474 tcg_gen_xori_i64(t0, t0, 1);
31837be3
YK
8475 ctx->hflags |= MIPS_HFLAG_BC;
8476 break;
8477 case OPC_BC1NEZ:
8478 /* t0 already set */
31837be3
YK
8479 ctx->hflags |= MIPS_HFLAG_BC;
8480 break;
8481 default:
9d68ac14 8482 MIPS_INVAL("cp1 cond branch");
9c708c7f 8483 generate_exception_end(ctx, EXCP_RI);
31837be3
YK
8484 goto out;
8485 }
8486
8487 tcg_gen_trunc_i64_tl(bcond, t0);
8488
31837be3 8489 ctx->btarget = btarget;
65935f07
YK
8490
8491 switch (delayslot_size) {
8492 case 2:
8493 ctx->hflags |= MIPS_HFLAG_BDS16;
8494 break;
8495 case 4:
8496 ctx->hflags |= MIPS_HFLAG_BDS32;
8497 break;
8498 }
31837be3
YK
8499
8500out:
8501 tcg_temp_free_i64(t0);
8502}
8503
6af0bf9c 8504/* Coprocessor 1 (FPU) */
5a5012ec 8505
5a5012ec
TS
8506#define FOP(func, fmt) (((fmt) << 21) | (func))
8507
bf4120ad
NF
8508enum fopcode {
8509 OPC_ADD_S = FOP(0, FMT_S),
8510 OPC_SUB_S = FOP(1, FMT_S),
8511 OPC_MUL_S = FOP(2, FMT_S),
8512 OPC_DIV_S = FOP(3, FMT_S),
8513 OPC_SQRT_S = FOP(4, FMT_S),
8514 OPC_ABS_S = FOP(5, FMT_S),
8515 OPC_MOV_S = FOP(6, FMT_S),
8516 OPC_NEG_S = FOP(7, FMT_S),
8517 OPC_ROUND_L_S = FOP(8, FMT_S),
8518 OPC_TRUNC_L_S = FOP(9, FMT_S),
8519 OPC_CEIL_L_S = FOP(10, FMT_S),
8520 OPC_FLOOR_L_S = FOP(11, FMT_S),
8521 OPC_ROUND_W_S = FOP(12, FMT_S),
8522 OPC_TRUNC_W_S = FOP(13, FMT_S),
8523 OPC_CEIL_W_S = FOP(14, FMT_S),
8524 OPC_FLOOR_W_S = FOP(15, FMT_S),
e7f16abb 8525 OPC_SEL_S = FOP(16, FMT_S),
bf4120ad
NF
8526 OPC_MOVCF_S = FOP(17, FMT_S),
8527 OPC_MOVZ_S = FOP(18, FMT_S),
8528 OPC_MOVN_S = FOP(19, FMT_S),
e7f16abb 8529 OPC_SELEQZ_S = FOP(20, FMT_S),
bf4120ad
NF
8530 OPC_RECIP_S = FOP(21, FMT_S),
8531 OPC_RSQRT_S = FOP(22, FMT_S),
e7f16abb
LA
8532 OPC_SELNEZ_S = FOP(23, FMT_S),
8533 OPC_MADDF_S = FOP(24, FMT_S),
8534 OPC_MSUBF_S = FOP(25, FMT_S),
8535 OPC_RINT_S = FOP(26, FMT_S),
8536 OPC_CLASS_S = FOP(27, FMT_S),
8537 OPC_MIN_S = FOP(28, FMT_S),
bf4120ad 8538 OPC_RECIP2_S = FOP(28, FMT_S),
e7f16abb 8539 OPC_MINA_S = FOP(29, FMT_S),
bf4120ad 8540 OPC_RECIP1_S = FOP(29, FMT_S),
e7f16abb 8541 OPC_MAX_S = FOP(30, FMT_S),
bf4120ad 8542 OPC_RSQRT1_S = FOP(30, FMT_S),
e7f16abb 8543 OPC_MAXA_S = FOP(31, FMT_S),
bf4120ad
NF
8544 OPC_RSQRT2_S = FOP(31, FMT_S),
8545 OPC_CVT_D_S = FOP(33, FMT_S),
8546 OPC_CVT_W_S = FOP(36, FMT_S),
8547 OPC_CVT_L_S = FOP(37, FMT_S),
8548 OPC_CVT_PS_S = FOP(38, FMT_S),
8549 OPC_CMP_F_S = FOP (48, FMT_S),
8550 OPC_CMP_UN_S = FOP (49, FMT_S),
8551 OPC_CMP_EQ_S = FOP (50, FMT_S),
8552 OPC_CMP_UEQ_S = FOP (51, FMT_S),
8553 OPC_CMP_OLT_S = FOP (52, FMT_S),
8554 OPC_CMP_ULT_S = FOP (53, FMT_S),
8555 OPC_CMP_OLE_S = FOP (54, FMT_S),
8556 OPC_CMP_ULE_S = FOP (55, FMT_S),
8557 OPC_CMP_SF_S = FOP (56, FMT_S),
8558 OPC_CMP_NGLE_S = FOP (57, FMT_S),
8559 OPC_CMP_SEQ_S = FOP (58, FMT_S),
8560 OPC_CMP_NGL_S = FOP (59, FMT_S),
8561 OPC_CMP_LT_S = FOP (60, FMT_S),
8562 OPC_CMP_NGE_S = FOP (61, FMT_S),
8563 OPC_CMP_LE_S = FOP (62, FMT_S),
8564 OPC_CMP_NGT_S = FOP (63, FMT_S),
8565
8566 OPC_ADD_D = FOP(0, FMT_D),
8567 OPC_SUB_D = FOP(1, FMT_D),
8568 OPC_MUL_D = FOP(2, FMT_D),
8569 OPC_DIV_D = FOP(3, FMT_D),
8570 OPC_SQRT_D = FOP(4, FMT_D),
8571 OPC_ABS_D = FOP(5, FMT_D),
8572 OPC_MOV_D = FOP(6, FMT_D),
8573 OPC_NEG_D = FOP(7, FMT_D),
8574 OPC_ROUND_L_D = FOP(8, FMT_D),
8575 OPC_TRUNC_L_D = FOP(9, FMT_D),
8576 OPC_CEIL_L_D = FOP(10, FMT_D),
8577 OPC_FLOOR_L_D = FOP(11, FMT_D),
8578 OPC_ROUND_W_D = FOP(12, FMT_D),
8579 OPC_TRUNC_W_D = FOP(13, FMT_D),
8580 OPC_CEIL_W_D = FOP(14, FMT_D),
8581 OPC_FLOOR_W_D = FOP(15, FMT_D),
e7f16abb 8582 OPC_SEL_D = FOP(16, FMT_D),
bf4120ad
NF
8583 OPC_MOVCF_D = FOP(17, FMT_D),
8584 OPC_MOVZ_D = FOP(18, FMT_D),
8585 OPC_MOVN_D = FOP(19, FMT_D),
e7f16abb 8586 OPC_SELEQZ_D = FOP(20, FMT_D),
bf4120ad
NF
8587 OPC_RECIP_D = FOP(21, FMT_D),
8588 OPC_RSQRT_D = FOP(22, FMT_D),
e7f16abb
LA
8589 OPC_SELNEZ_D = FOP(23, FMT_D),
8590 OPC_MADDF_D = FOP(24, FMT_D),
8591 OPC_MSUBF_D = FOP(25, FMT_D),
8592 OPC_RINT_D = FOP(26, FMT_D),
8593 OPC_CLASS_D = FOP(27, FMT_D),
8594 OPC_MIN_D = FOP(28, FMT_D),
bf4120ad 8595 OPC_RECIP2_D = FOP(28, FMT_D),
e7f16abb 8596 OPC_MINA_D = FOP(29, FMT_D),
bf4120ad 8597 OPC_RECIP1_D = FOP(29, FMT_D),
e7f16abb 8598 OPC_MAX_D = FOP(30, FMT_D),
bf4120ad 8599 OPC_RSQRT1_D = FOP(30, FMT_D),
e7f16abb 8600 OPC_MAXA_D = FOP(31, FMT_D),
bf4120ad
NF
8601 OPC_RSQRT2_D = FOP(31, FMT_D),
8602 OPC_CVT_S_D = FOP(32, FMT_D),
8603 OPC_CVT_W_D = FOP(36, FMT_D),
8604 OPC_CVT_L_D = FOP(37, FMT_D),
8605 OPC_CMP_F_D = FOP (48, FMT_D),
8606 OPC_CMP_UN_D = FOP (49, FMT_D),
8607 OPC_CMP_EQ_D = FOP (50, FMT_D),
8608 OPC_CMP_UEQ_D = FOP (51, FMT_D),
8609 OPC_CMP_OLT_D = FOP (52, FMT_D),
8610 OPC_CMP_ULT_D = FOP (53, FMT_D),
8611 OPC_CMP_OLE_D = FOP (54, FMT_D),
8612 OPC_CMP_ULE_D = FOP (55, FMT_D),
8613 OPC_CMP_SF_D = FOP (56, FMT_D),
8614 OPC_CMP_NGLE_D = FOP (57, FMT_D),
8615 OPC_CMP_SEQ_D = FOP (58, FMT_D),
8616 OPC_CMP_NGL_D = FOP (59, FMT_D),
8617 OPC_CMP_LT_D = FOP (60, FMT_D),
8618 OPC_CMP_NGE_D = FOP (61, FMT_D),
8619 OPC_CMP_LE_D = FOP (62, FMT_D),
8620 OPC_CMP_NGT_D = FOP (63, FMT_D),
8621
8622 OPC_CVT_S_W = FOP(32, FMT_W),
8623 OPC_CVT_D_W = FOP(33, FMT_W),
8624 OPC_CVT_S_L = FOP(32, FMT_L),
8625 OPC_CVT_D_L = FOP(33, FMT_L),
8626 OPC_CVT_PS_PW = FOP(38, FMT_W),
8627
8628 OPC_ADD_PS = FOP(0, FMT_PS),
8629 OPC_SUB_PS = FOP(1, FMT_PS),
8630 OPC_MUL_PS = FOP(2, FMT_PS),
8631 OPC_DIV_PS = FOP(3, FMT_PS),
8632 OPC_ABS_PS = FOP(5, FMT_PS),
8633 OPC_MOV_PS = FOP(6, FMT_PS),
8634 OPC_NEG_PS = FOP(7, FMT_PS),
8635 OPC_MOVCF_PS = FOP(17, FMT_PS),
8636 OPC_MOVZ_PS = FOP(18, FMT_PS),
8637 OPC_MOVN_PS = FOP(19, FMT_PS),
8638 OPC_ADDR_PS = FOP(24, FMT_PS),
8639 OPC_MULR_PS = FOP(26, FMT_PS),
8640 OPC_RECIP2_PS = FOP(28, FMT_PS),
8641 OPC_RECIP1_PS = FOP(29, FMT_PS),
8642 OPC_RSQRT1_PS = FOP(30, FMT_PS),
8643 OPC_RSQRT2_PS = FOP(31, FMT_PS),
8644
8645 OPC_CVT_S_PU = FOP(32, FMT_PS),
8646 OPC_CVT_PW_PS = FOP(36, FMT_PS),
8647 OPC_CVT_S_PL = FOP(40, FMT_PS),
8648 OPC_PLL_PS = FOP(44, FMT_PS),
8649 OPC_PLU_PS = FOP(45, FMT_PS),
8650 OPC_PUL_PS = FOP(46, FMT_PS),
8651 OPC_PUU_PS = FOP(47, FMT_PS),
8652 OPC_CMP_F_PS = FOP (48, FMT_PS),
8653 OPC_CMP_UN_PS = FOP (49, FMT_PS),
8654 OPC_CMP_EQ_PS = FOP (50, FMT_PS),
8655 OPC_CMP_UEQ_PS = FOP (51, FMT_PS),
8656 OPC_CMP_OLT_PS = FOP (52, FMT_PS),
8657 OPC_CMP_ULT_PS = FOP (53, FMT_PS),
8658 OPC_CMP_OLE_PS = FOP (54, FMT_PS),
8659 OPC_CMP_ULE_PS = FOP (55, FMT_PS),
8660 OPC_CMP_SF_PS = FOP (56, FMT_PS),
8661 OPC_CMP_NGLE_PS = FOP (57, FMT_PS),
8662 OPC_CMP_SEQ_PS = FOP (58, FMT_PS),
8663 OPC_CMP_NGL_PS = FOP (59, FMT_PS),
8664 OPC_CMP_LT_PS = FOP (60, FMT_PS),
8665 OPC_CMP_NGE_PS = FOP (61, FMT_PS),
8666 OPC_CMP_LE_PS = FOP (62, FMT_PS),
8667 OPC_CMP_NGT_PS = FOP (63, FMT_PS),
8668};
8669
3f493883
YK
8670enum r6_f_cmp_op {
8671 R6_OPC_CMP_AF_S = FOP(0, FMT_W),
8672 R6_OPC_CMP_UN_S = FOP(1, FMT_W),
8673 R6_OPC_CMP_EQ_S = FOP(2, FMT_W),
8674 R6_OPC_CMP_UEQ_S = FOP(3, FMT_W),
8675 R6_OPC_CMP_LT_S = FOP(4, FMT_W),
8676 R6_OPC_CMP_ULT_S = FOP(5, FMT_W),
8677 R6_OPC_CMP_LE_S = FOP(6, FMT_W),
8678 R6_OPC_CMP_ULE_S = FOP(7, FMT_W),
8679 R6_OPC_CMP_SAF_S = FOP(8, FMT_W),
8680 R6_OPC_CMP_SUN_S = FOP(9, FMT_W),
8681 R6_OPC_CMP_SEQ_S = FOP(10, FMT_W),
8682 R6_OPC_CMP_SEUQ_S = FOP(11, FMT_W),
8683 R6_OPC_CMP_SLT_S = FOP(12, FMT_W),
8684 R6_OPC_CMP_SULT_S = FOP(13, FMT_W),
8685 R6_OPC_CMP_SLE_S = FOP(14, FMT_W),
8686 R6_OPC_CMP_SULE_S = FOP(15, FMT_W),
8687 R6_OPC_CMP_OR_S = FOP(17, FMT_W),
8688 R6_OPC_CMP_UNE_S = FOP(18, FMT_W),
8689 R6_OPC_CMP_NE_S = FOP(19, FMT_W),
8690 R6_OPC_CMP_SOR_S = FOP(25, FMT_W),
8691 R6_OPC_CMP_SUNE_S = FOP(26, FMT_W),
8692 R6_OPC_CMP_SNE_S = FOP(27, FMT_W),
8693
8694 R6_OPC_CMP_AF_D = FOP(0, FMT_L),
8695 R6_OPC_CMP_UN_D = FOP(1, FMT_L),
8696 R6_OPC_CMP_EQ_D = FOP(2, FMT_L),
8697 R6_OPC_CMP_UEQ_D = FOP(3, FMT_L),
8698 R6_OPC_CMP_LT_D = FOP(4, FMT_L),
8699 R6_OPC_CMP_ULT_D = FOP(5, FMT_L),
8700 R6_OPC_CMP_LE_D = FOP(6, FMT_L),
8701 R6_OPC_CMP_ULE_D = FOP(7, FMT_L),
8702 R6_OPC_CMP_SAF_D = FOP(8, FMT_L),
8703 R6_OPC_CMP_SUN_D = FOP(9, FMT_L),
8704 R6_OPC_CMP_SEQ_D = FOP(10, FMT_L),
8705 R6_OPC_CMP_SEUQ_D = FOP(11, FMT_L),
8706 R6_OPC_CMP_SLT_D = FOP(12, FMT_L),
8707 R6_OPC_CMP_SULT_D = FOP(13, FMT_L),
8708 R6_OPC_CMP_SLE_D = FOP(14, FMT_L),
8709 R6_OPC_CMP_SULE_D = FOP(15, FMT_L),
8710 R6_OPC_CMP_OR_D = FOP(17, FMT_L),
8711 R6_OPC_CMP_UNE_D = FOP(18, FMT_L),
8712 R6_OPC_CMP_NE_D = FOP(19, FMT_L),
8713 R6_OPC_CMP_SOR_D = FOP(25, FMT_L),
8714 R6_OPC_CMP_SUNE_D = FOP(26, FMT_L),
8715 R6_OPC_CMP_SNE_D = FOP(27, FMT_L),
8716};
7a387fff 8717static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
6ea83fed 8718{
72c3a3ee 8719 TCGv t0 = tcg_temp_new();
6ea83fed
FB
8720
8721 switch (opc) {
8722 case OPC_MFC1:
b6d96bed 8723 {
a7812ae4 8724 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8725
7c979afd 8726 gen_load_fpr32(ctx, fp0, fs);
b6d96bed 8727 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 8728 tcg_temp_free_i32(fp0);
6958549d 8729 }
6c5c1e20 8730 gen_store_gpr(t0, rt);
6ea83fed
FB
8731 break;
8732 case OPC_MTC1:
6c5c1e20 8733 gen_load_gpr(t0, rt);
b6d96bed 8734 {
a7812ae4 8735 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8736
8737 tcg_gen_trunc_tl_i32(fp0, t0);
7c979afd 8738 gen_store_fpr32(ctx, fp0, fs);
a7812ae4 8739 tcg_temp_free_i32(fp0);
6958549d 8740 }
6ea83fed
FB
8741 break;
8742 case OPC_CFC1:
895c2d04 8743 gen_helper_1e0i(cfc1, t0, fs);
6c5c1e20 8744 gen_store_gpr(t0, rt);
6ea83fed
FB
8745 break;
8746 case OPC_CTC1:
6c5c1e20 8747 gen_load_gpr(t0, rt);
9c708c7f 8748 save_cpu_state(ctx, 0);
736d120a
PJ
8749 {
8750 TCGv_i32 fs_tmp = tcg_const_i32(fs);
8751
8752 gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
8753 tcg_temp_free_i32(fs_tmp);
8754 }
4cf8a45f 8755 /* Stop translation as we may have changed hflags */
eeb3bba8 8756 ctx->base.is_jmp = DISAS_STOP;
6ea83fed 8757 break;
72c3a3ee 8758#if defined(TARGET_MIPS64)
9c2149c8 8759 case OPC_DMFC1:
72c3a3ee 8760 gen_load_fpr64(ctx, t0, fs);
6c5c1e20 8761 gen_store_gpr(t0, rt);
5a5012ec 8762 break;
9c2149c8 8763 case OPC_DMTC1:
6c5c1e20 8764 gen_load_gpr(t0, rt);
72c3a3ee 8765 gen_store_fpr64(ctx, t0, fs);
5a5012ec 8766 break;
72c3a3ee 8767#endif
5a5012ec 8768 case OPC_MFHC1:
b6d96bed 8769 {
a7812ae4 8770 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8771
7f6613ce 8772 gen_load_fpr32h(ctx, fp0, fs);
b6d96bed 8773 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 8774 tcg_temp_free_i32(fp0);
6958549d 8775 }
6c5c1e20 8776 gen_store_gpr(t0, rt);
5a5012ec
TS
8777 break;
8778 case OPC_MTHC1:
6c5c1e20 8779 gen_load_gpr(t0, rt);
b6d96bed 8780 {
a7812ae4 8781 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8782
8783 tcg_gen_trunc_tl_i32(fp0, t0);
7f6613ce 8784 gen_store_fpr32h(ctx, fp0, fs);
a7812ae4 8785 tcg_temp_free_i32(fp0);
6958549d 8786 }
5a5012ec 8787 break;
6ea83fed 8788 default:
9d68ac14 8789 MIPS_INVAL("cp1 move");
9c708c7f 8790 generate_exception_end(ctx, EXCP_RI);
6c5c1e20 8791 goto out;
6ea83fed 8792 }
6c5c1e20
TS
8793
8794 out:
8795 tcg_temp_free(t0);
6ea83fed
FB
8796}
8797
5a5012ec
TS
8798static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
8799{
42a268c2 8800 TCGLabel *l1;
e214b9bb 8801 TCGCond cond;
af58f9ca
AJ
8802 TCGv_i32 t0;
8803
8804 if (rd == 0) {
8805 /* Treat as NOP. */
8806 return;
8807 }
6ea83fed 8808
e214b9bb 8809 if (tf)
e214b9bb 8810 cond = TCG_COND_EQ;
27848470
TS
8811 else
8812 cond = TCG_COND_NE;
8813
af58f9ca
AJ
8814 l1 = gen_new_label();
8815 t0 = tcg_temp_new_i32();
fa31af0e 8816 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
af58f9ca 8817 tcg_gen_brcondi_i32(cond, t0, 0, l1);
a4e8338d 8818 tcg_temp_free_i32(t0);
af58f9ca
AJ
8819 if (rs == 0) {
8820 tcg_gen_movi_tl(cpu_gpr[rd], 0);
8821 } else {
8822 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
8823 }
e214b9bb 8824 gen_set_label(l1);
5a5012ec
TS
8825}
8826
7c979afd
LA
8827static inline void gen_movcf_s(DisasContext *ctx, int fs, int fd, int cc,
8828 int tf)
a16336e4 8829{
a16336e4 8830 int cond;
cbc37b28 8831 TCGv_i32 t0 = tcg_temp_new_i32();
42a268c2 8832 TCGLabel *l1 = gen_new_label();
a16336e4 8833
a16336e4
TS
8834 if (tf)
8835 cond = TCG_COND_EQ;
8836 else
8837 cond = TCG_COND_NE;
8838
fa31af0e 8839 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
cbc37b28 8840 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7c979afd
LA
8841 gen_load_fpr32(ctx, t0, fs);
8842 gen_store_fpr32(ctx, t0, fd);
a16336e4 8843 gen_set_label(l1);
cbc37b28 8844 tcg_temp_free_i32(t0);
5a5012ec 8845}
a16336e4 8846
b6d96bed 8847static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
a16336e4 8848{
a16336e4 8849 int cond;
cbc37b28
AJ
8850 TCGv_i32 t0 = tcg_temp_new_i32();
8851 TCGv_i64 fp0;
42a268c2 8852 TCGLabel *l1 = gen_new_label();
a16336e4 8853
a16336e4
TS
8854 if (tf)
8855 cond = TCG_COND_EQ;
8856 else
8857 cond = TCG_COND_NE;
8858
fa31af0e 8859 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
cbc37b28 8860 tcg_gen_brcondi_i32(cond, t0, 0, l1);
a4e8338d 8861 tcg_temp_free_i32(t0);
11f94258 8862 fp0 = tcg_temp_new_i64();
9bf3eb2c 8863 gen_load_fpr64(ctx, fp0, fs);
9bf3eb2c 8864 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8865 tcg_temp_free_i64(fp0);
cbc37b28 8866 gen_set_label(l1);
a16336e4
TS
8867}
8868
7f6613ce
PJ
8869static inline void gen_movcf_ps(DisasContext *ctx, int fs, int fd,
8870 int cc, int tf)
a16336e4
TS
8871{
8872 int cond;
cbc37b28 8873 TCGv_i32 t0 = tcg_temp_new_i32();
42a268c2
RH
8874 TCGLabel *l1 = gen_new_label();
8875 TCGLabel *l2 = gen_new_label();
a16336e4
TS
8876
8877 if (tf)
8878 cond = TCG_COND_EQ;
8879 else
8880 cond = TCG_COND_NE;
8881
fa31af0e 8882 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
cbc37b28 8883 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7c979afd
LA
8884 gen_load_fpr32(ctx, t0, fs);
8885 gen_store_fpr32(ctx, t0, fd);
a16336e4 8886 gen_set_label(l1);
9bf3eb2c 8887
fa31af0e 8888 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc+1));
cbc37b28 8889 tcg_gen_brcondi_i32(cond, t0, 0, l2);
7f6613ce
PJ
8890 gen_load_fpr32h(ctx, t0, fs);
8891 gen_store_fpr32h(ctx, t0, fd);
52a0e9eb 8892 tcg_temp_free_i32(t0);
a16336e4 8893 gen_set_label(l2);
a16336e4
TS
8894}
8895
e7f16abb
LA
8896static void gen_sel_s(DisasContext *ctx, enum fopcode op1, int fd, int ft,
8897 int fs)
8898{
8899 TCGv_i32 t1 = tcg_const_i32(0);
8900 TCGv_i32 fp0 = tcg_temp_new_i32();
8901 TCGv_i32 fp1 = tcg_temp_new_i32();
8902 TCGv_i32 fp2 = tcg_temp_new_i32();
7c979afd
LA
8903 gen_load_fpr32(ctx, fp0, fd);
8904 gen_load_fpr32(ctx, fp1, ft);
8905 gen_load_fpr32(ctx, fp2, fs);
e7f16abb
LA
8906
8907 switch (op1) {
8908 case OPC_SEL_S:
8909 tcg_gen_andi_i32(fp0, fp0, 1);
8910 tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
8911 break;
8912 case OPC_SELEQZ_S:
8913 tcg_gen_andi_i32(fp1, fp1, 1);
8914 tcg_gen_movcond_i32(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
8915 break;
8916 case OPC_SELNEZ_S:
8917 tcg_gen_andi_i32(fp1, fp1, 1);
8918 tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
8919 break;
8920 default:
8921 MIPS_INVAL("gen_sel_s");
9c708c7f 8922 generate_exception_end(ctx, EXCP_RI);
e7f16abb
LA
8923 break;
8924 }
8925
7c979afd 8926 gen_store_fpr32(ctx, fp0, fd);
e7f16abb
LA
8927 tcg_temp_free_i32(fp2);
8928 tcg_temp_free_i32(fp1);
8929 tcg_temp_free_i32(fp0);
8930 tcg_temp_free_i32(t1);
8931}
8932
8933static void gen_sel_d(DisasContext *ctx, enum fopcode op1, int fd, int ft,
8934 int fs)
8935{
8936 TCGv_i64 t1 = tcg_const_i64(0);
8937 TCGv_i64 fp0 = tcg_temp_new_i64();
8938 TCGv_i64 fp1 = tcg_temp_new_i64();
8939 TCGv_i64 fp2 = tcg_temp_new_i64();
8940 gen_load_fpr64(ctx, fp0, fd);
8941 gen_load_fpr64(ctx, fp1, ft);
8942 gen_load_fpr64(ctx, fp2, fs);
8943
8944 switch (op1) {
8945 case OPC_SEL_D:
8946 tcg_gen_andi_i64(fp0, fp0, 1);
8947 tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
8948 break;
8949 case OPC_SELEQZ_D:
8950 tcg_gen_andi_i64(fp1, fp1, 1);
8951 tcg_gen_movcond_i64(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
8952 break;
8953 case OPC_SELNEZ_D:
8954 tcg_gen_andi_i64(fp1, fp1, 1);
8955 tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
8956 break;
8957 default:
8958 MIPS_INVAL("gen_sel_d");
9c708c7f 8959 generate_exception_end(ctx, EXCP_RI);
e7f16abb
LA
8960 break;
8961 }
8962
8963 gen_store_fpr64(ctx, fp0, fd);
8964 tcg_temp_free_i64(fp2);
8965 tcg_temp_free_i64(fp1);
8966 tcg_temp_free_i64(fp0);
8967 tcg_temp_free_i64(t1);
8968}
6ea83fed 8969
bf4120ad 8970static void gen_farith (DisasContext *ctx, enum fopcode op1,
5e755519 8971 int ft, int fs, int fd, int cc)
6ea83fed 8972{
7a387fff 8973 uint32_t func = ctx->opcode & 0x3f;
bf4120ad
NF
8974 switch (op1) {
8975 case OPC_ADD_S:
b6d96bed 8976 {
a7812ae4
PB
8977 TCGv_i32 fp0 = tcg_temp_new_i32();
8978 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 8979
7c979afd
LA
8980 gen_load_fpr32(ctx, fp0, fs);
8981 gen_load_fpr32(ctx, fp1, ft);
895c2d04 8982 gen_helper_float_add_s(fp0, cpu_env, fp0, fp1);
a7812ae4 8983 tcg_temp_free_i32(fp1);
7c979afd 8984 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 8985 tcg_temp_free_i32(fp0);
b6d96bed 8986 }
5a5012ec 8987 break;
bf4120ad 8988 case OPC_SUB_S:
b6d96bed 8989 {
a7812ae4
PB
8990 TCGv_i32 fp0 = tcg_temp_new_i32();
8991 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 8992
7c979afd
LA
8993 gen_load_fpr32(ctx, fp0, fs);
8994 gen_load_fpr32(ctx, fp1, ft);
895c2d04 8995 gen_helper_float_sub_s(fp0, cpu_env, fp0, fp1);
a7812ae4 8996 tcg_temp_free_i32(fp1);
7c979afd 8997 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 8998 tcg_temp_free_i32(fp0);
b6d96bed 8999 }
5a5012ec 9000 break;
bf4120ad 9001 case OPC_MUL_S:
b6d96bed 9002 {
a7812ae4
PB
9003 TCGv_i32 fp0 = tcg_temp_new_i32();
9004 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 9005
7c979afd
LA
9006 gen_load_fpr32(ctx, fp0, fs);
9007 gen_load_fpr32(ctx, fp1, ft);
895c2d04 9008 gen_helper_float_mul_s(fp0, cpu_env, fp0, fp1);
a7812ae4 9009 tcg_temp_free_i32(fp1);
7c979afd 9010 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9011 tcg_temp_free_i32(fp0);
b6d96bed 9012 }
5a5012ec 9013 break;
bf4120ad 9014 case OPC_DIV_S:
b6d96bed 9015 {
a7812ae4
PB
9016 TCGv_i32 fp0 = tcg_temp_new_i32();
9017 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 9018
7c979afd
LA
9019 gen_load_fpr32(ctx, fp0, fs);
9020 gen_load_fpr32(ctx, fp1, ft);
895c2d04 9021 gen_helper_float_div_s(fp0, cpu_env, fp0, fp1);
a7812ae4 9022 tcg_temp_free_i32(fp1);
7c979afd 9023 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9024 tcg_temp_free_i32(fp0);
b6d96bed 9025 }
5a5012ec 9026 break;
bf4120ad 9027 case OPC_SQRT_S:
b6d96bed 9028 {
a7812ae4 9029 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9030
7c979afd 9031 gen_load_fpr32(ctx, fp0, fs);
895c2d04 9032 gen_helper_float_sqrt_s(fp0, cpu_env, fp0);
7c979afd 9033 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9034 tcg_temp_free_i32(fp0);
b6d96bed 9035 }
5a5012ec 9036 break;
bf4120ad 9037 case OPC_ABS_S:
b6d96bed 9038 {
a7812ae4 9039 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9040
7c979afd 9041 gen_load_fpr32(ctx, fp0, fs);
6be77480
AM
9042 if (ctx->abs2008) {
9043 tcg_gen_andi_i32(fp0, fp0, 0x7fffffffUL);
9044 } else {
9045 gen_helper_float_abs_s(fp0, fp0);
9046 }
7c979afd 9047 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9048 tcg_temp_free_i32(fp0);
b6d96bed 9049 }
5a5012ec 9050 break;
bf4120ad 9051 case OPC_MOV_S:
b6d96bed 9052 {
a7812ae4 9053 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9054
7c979afd
LA
9055 gen_load_fpr32(ctx, fp0, fs);
9056 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9057 tcg_temp_free_i32(fp0);
b6d96bed 9058 }
5a5012ec 9059 break;
bf4120ad 9060 case OPC_NEG_S:
b6d96bed 9061 {
a7812ae4 9062 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9063
7c979afd 9064 gen_load_fpr32(ctx, fp0, fs);
6be77480
AM
9065 if (ctx->abs2008) {
9066 tcg_gen_xori_i32(fp0, fp0, 1UL << 31);
9067 } else {
9068 gen_helper_float_chs_s(fp0, fp0);
9069 }
7c979afd 9070 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9071 tcg_temp_free_i32(fp0);
b6d96bed 9072 }
5a5012ec 9073 break;
bf4120ad 9074 case OPC_ROUND_L_S:
5e755519 9075 check_cp1_64bitmode(ctx);
b6d96bed 9076 {
a7812ae4
PB
9077 TCGv_i32 fp32 = tcg_temp_new_i32();
9078 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 9079
7c979afd 9080 gen_load_fpr32(ctx, fp32, fs);
87552089
AM
9081 if (ctx->nan2008) {
9082 gen_helper_float_round_2008_l_s(fp64, cpu_env, fp32);
9083 } else {
9084 gen_helper_float_round_l_s(fp64, cpu_env, fp32);
9085 }
a7812ae4 9086 tcg_temp_free_i32(fp32);
b6d96bed 9087 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 9088 tcg_temp_free_i64(fp64);
b6d96bed 9089 }
5a5012ec 9090 break;
bf4120ad 9091 case OPC_TRUNC_L_S:
5e755519 9092 check_cp1_64bitmode(ctx);
b6d96bed 9093 {
a7812ae4
PB
9094 TCGv_i32 fp32 = tcg_temp_new_i32();
9095 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 9096
7c979afd 9097 gen_load_fpr32(ctx, fp32, fs);
87552089
AM
9098 if (ctx->nan2008) {
9099 gen_helper_float_trunc_2008_l_s(fp64, cpu_env, fp32);
9100 } else {
9101 gen_helper_float_trunc_l_s(fp64, cpu_env, fp32);
9102 }
a7812ae4 9103 tcg_temp_free_i32(fp32);
b6d96bed 9104 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 9105 tcg_temp_free_i64(fp64);
b6d96bed 9106 }
5a5012ec 9107 break;
bf4120ad 9108 case OPC_CEIL_L_S:
5e755519 9109 check_cp1_64bitmode(ctx);
b6d96bed 9110 {
a7812ae4
PB
9111 TCGv_i32 fp32 = tcg_temp_new_i32();
9112 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 9113
7c979afd 9114 gen_load_fpr32(ctx, fp32, fs);
87552089
AM
9115 if (ctx->nan2008) {
9116 gen_helper_float_ceil_2008_l_s(fp64, cpu_env, fp32);
9117 } else {
9118 gen_helper_float_ceil_l_s(fp64, cpu_env, fp32);
9119 }
a7812ae4 9120 tcg_temp_free_i32(fp32);
b6d96bed 9121 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 9122 tcg_temp_free_i64(fp64);
b6d96bed 9123 }
5a5012ec 9124 break;
bf4120ad 9125 case OPC_FLOOR_L_S:
5e755519 9126 check_cp1_64bitmode(ctx);
b6d96bed 9127 {
a7812ae4
PB
9128 TCGv_i32 fp32 = tcg_temp_new_i32();
9129 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 9130
7c979afd 9131 gen_load_fpr32(ctx, fp32, fs);
87552089
AM
9132 if (ctx->nan2008) {
9133 gen_helper_float_floor_2008_l_s(fp64, cpu_env, fp32);
9134 } else {
9135 gen_helper_float_floor_l_s(fp64, cpu_env, fp32);
9136 }
a7812ae4 9137 tcg_temp_free_i32(fp32);
b6d96bed 9138 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 9139 tcg_temp_free_i64(fp64);
b6d96bed 9140 }
5a5012ec 9141 break;
bf4120ad 9142 case OPC_ROUND_W_S:
b6d96bed 9143 {
a7812ae4 9144 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9145
7c979afd 9146 gen_load_fpr32(ctx, fp0, fs);
87552089
AM
9147 if (ctx->nan2008) {
9148 gen_helper_float_round_2008_w_s(fp0, cpu_env, fp0);
9149 } else {
9150 gen_helper_float_round_w_s(fp0, cpu_env, fp0);
9151 }
7c979afd 9152 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9153 tcg_temp_free_i32(fp0);
b6d96bed 9154 }
5a5012ec 9155 break;
bf4120ad 9156 case OPC_TRUNC_W_S:
b6d96bed 9157 {
a7812ae4 9158 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9159
7c979afd 9160 gen_load_fpr32(ctx, fp0, fs);
87552089
AM
9161 if (ctx->nan2008) {
9162 gen_helper_float_trunc_2008_w_s(fp0, cpu_env, fp0);
9163 } else {
9164 gen_helper_float_trunc_w_s(fp0, cpu_env, fp0);
9165 }
7c979afd 9166 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9167 tcg_temp_free_i32(fp0);
b6d96bed 9168 }
5a5012ec 9169 break;
bf4120ad 9170 case OPC_CEIL_W_S:
b6d96bed 9171 {
a7812ae4 9172 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9173
7c979afd 9174 gen_load_fpr32(ctx, fp0, fs);
87552089
AM
9175 if (ctx->nan2008) {
9176 gen_helper_float_ceil_2008_w_s(fp0, cpu_env, fp0);
9177 } else {
9178 gen_helper_float_ceil_w_s(fp0, cpu_env, fp0);
9179 }
7c979afd 9180 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9181 tcg_temp_free_i32(fp0);
b6d96bed 9182 }
5a5012ec 9183 break;
bf4120ad 9184 case OPC_FLOOR_W_S:
b6d96bed 9185 {
a7812ae4 9186 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9187
7c979afd 9188 gen_load_fpr32(ctx, fp0, fs);
87552089
AM
9189 if (ctx->nan2008) {
9190 gen_helper_float_floor_2008_w_s(fp0, cpu_env, fp0);
9191 } else {
9192 gen_helper_float_floor_w_s(fp0, cpu_env, fp0);
9193 }
7c979afd 9194 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9195 tcg_temp_free_i32(fp0);
b6d96bed 9196 }
5a5012ec 9197 break;
e7f16abb
LA
9198 case OPC_SEL_S:
9199 check_insn(ctx, ISA_MIPS32R6);
9200 gen_sel_s(ctx, op1, fd, ft, fs);
e7f16abb
LA
9201 break;
9202 case OPC_SELEQZ_S:
9203 check_insn(ctx, ISA_MIPS32R6);
9204 gen_sel_s(ctx, op1, fd, ft, fs);
e7f16abb
LA
9205 break;
9206 case OPC_SELNEZ_S:
9207 check_insn(ctx, ISA_MIPS32R6);
9208 gen_sel_s(ctx, op1, fd, ft, fs);
e7f16abb 9209 break;
bf4120ad 9210 case OPC_MOVCF_S:
fecd2646 9211 check_insn_opc_removed(ctx, ISA_MIPS32R6);
7c979afd 9212 gen_movcf_s(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
5a5012ec 9213 break;
bf4120ad 9214 case OPC_MOVZ_S:
fecd2646 9215 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a16336e4 9216 {
42a268c2 9217 TCGLabel *l1 = gen_new_label();
c9297f4d 9218 TCGv_i32 fp0;
a16336e4 9219
c9297f4d
AJ
9220 if (ft != 0) {
9221 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
9222 }
9223 fp0 = tcg_temp_new_i32();
7c979afd
LA
9224 gen_load_fpr32(ctx, fp0, fs);
9225 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9226 tcg_temp_free_i32(fp0);
a16336e4
TS
9227 gen_set_label(l1);
9228 }
5a5012ec 9229 break;
bf4120ad 9230 case OPC_MOVN_S:
fecd2646 9231 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a16336e4 9232 {
42a268c2 9233 TCGLabel *l1 = gen_new_label();
c9297f4d
AJ
9234 TCGv_i32 fp0;
9235
9236 if (ft != 0) {
9237 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
9238 fp0 = tcg_temp_new_i32();
7c979afd
LA
9239 gen_load_fpr32(ctx, fp0, fs);
9240 gen_store_fpr32(ctx, fp0, fd);
c9297f4d
AJ
9241 tcg_temp_free_i32(fp0);
9242 gen_set_label(l1);
9243 }
a16336e4 9244 }
5a5012ec 9245 break;
bf4120ad 9246 case OPC_RECIP_S:
b6d96bed 9247 {
a7812ae4 9248 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9249
7c979afd 9250 gen_load_fpr32(ctx, fp0, fs);
895c2d04 9251 gen_helper_float_recip_s(fp0, cpu_env, fp0);
7c979afd 9252 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9253 tcg_temp_free_i32(fp0);
b6d96bed 9254 }
57fa1fb3 9255 break;
bf4120ad 9256 case OPC_RSQRT_S:
b6d96bed 9257 {
a7812ae4 9258 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9259
7c979afd 9260 gen_load_fpr32(ctx, fp0, fs);
895c2d04 9261 gen_helper_float_rsqrt_s(fp0, cpu_env, fp0);
7c979afd 9262 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9263 tcg_temp_free_i32(fp0);
b6d96bed 9264 }
57fa1fb3 9265 break;
e7f16abb
LA
9266 case OPC_MADDF_S:
9267 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 9268 {
a7812ae4
PB
9269 TCGv_i32 fp0 = tcg_temp_new_i32();
9270 TCGv_i32 fp1 = tcg_temp_new_i32();
e7f16abb 9271 TCGv_i32 fp2 = tcg_temp_new_i32();
7c979afd
LA
9272 gen_load_fpr32(ctx, fp0, fs);
9273 gen_load_fpr32(ctx, fp1, ft);
9274 gen_load_fpr32(ctx, fp2, fd);
e7f16abb 9275 gen_helper_float_maddf_s(fp2, cpu_env, fp0, fp1, fp2);
7c979afd 9276 gen_store_fpr32(ctx, fp2, fd);
e7f16abb 9277 tcg_temp_free_i32(fp2);
a7812ae4 9278 tcg_temp_free_i32(fp1);
a7812ae4 9279 tcg_temp_free_i32(fp0);
b6d96bed 9280 }
57fa1fb3 9281 break;
e7f16abb
LA
9282 case OPC_MSUBF_S:
9283 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 9284 {
a7812ae4 9285 TCGv_i32 fp0 = tcg_temp_new_i32();
e7f16abb
LA
9286 TCGv_i32 fp1 = tcg_temp_new_i32();
9287 TCGv_i32 fp2 = tcg_temp_new_i32();
7c979afd
LA
9288 gen_load_fpr32(ctx, fp0, fs);
9289 gen_load_fpr32(ctx, fp1, ft);
9290 gen_load_fpr32(ctx, fp2, fd);
e7f16abb 9291 gen_helper_float_msubf_s(fp2, cpu_env, fp0, fp1, fp2);
7c979afd 9292 gen_store_fpr32(ctx, fp2, fd);
e7f16abb
LA
9293 tcg_temp_free_i32(fp2);
9294 tcg_temp_free_i32(fp1);
a7812ae4 9295 tcg_temp_free_i32(fp0);
b6d96bed 9296 }
57fa1fb3 9297 break;
e7f16abb
LA
9298 case OPC_RINT_S:
9299 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 9300 {
a7812ae4 9301 TCGv_i32 fp0 = tcg_temp_new_i32();
7c979afd 9302 gen_load_fpr32(ctx, fp0, fs);
e7f16abb 9303 gen_helper_float_rint_s(fp0, cpu_env, fp0);
7c979afd 9304 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9305 tcg_temp_free_i32(fp0);
b6d96bed 9306 }
57fa1fb3 9307 break;
e7f16abb
LA
9308 case OPC_CLASS_S:
9309 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 9310 {
e7f16abb 9311 TCGv_i32 fp0 = tcg_temp_new_i32();
7c979afd 9312 gen_load_fpr32(ctx, fp0, fs);
af39bc8c 9313 gen_helper_float_class_s(fp0, cpu_env, fp0);
7c979afd 9314 gen_store_fpr32(ctx, fp0, fd);
e7f16abb 9315 tcg_temp_free_i32(fp0);
e7f16abb
LA
9316 }
9317 break;
9318 case OPC_MIN_S: /* OPC_RECIP2_S */
9319 if (ctx->insn_flags & ISA_MIPS32R6) {
9320 /* OPC_MIN_S */
a7812ae4
PB
9321 TCGv_i32 fp0 = tcg_temp_new_i32();
9322 TCGv_i32 fp1 = tcg_temp_new_i32();
e7f16abb 9323 TCGv_i32 fp2 = tcg_temp_new_i32();
7c979afd
LA
9324 gen_load_fpr32(ctx, fp0, fs);
9325 gen_load_fpr32(ctx, fp1, ft);
e7f16abb 9326 gen_helper_float_min_s(fp2, cpu_env, fp0, fp1);
7c979afd 9327 gen_store_fpr32(ctx, fp2, fd);
e7f16abb
LA
9328 tcg_temp_free_i32(fp2);
9329 tcg_temp_free_i32(fp1);
9330 tcg_temp_free_i32(fp0);
e7f16abb
LA
9331 } else {
9332 /* OPC_RECIP2_S */
9333 check_cp1_64bitmode(ctx);
9334 {
9335 TCGv_i32 fp0 = tcg_temp_new_i32();
9336 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 9337
7c979afd
LA
9338 gen_load_fpr32(ctx, fp0, fs);
9339 gen_load_fpr32(ctx, fp1, ft);
e7f16abb
LA
9340 gen_helper_float_recip2_s(fp0, cpu_env, fp0, fp1);
9341 tcg_temp_free_i32(fp1);
7c979afd 9342 gen_store_fpr32(ctx, fp0, fd);
e7f16abb
LA
9343 tcg_temp_free_i32(fp0);
9344 }
e7f16abb
LA
9345 }
9346 break;
9347 case OPC_MINA_S: /* OPC_RECIP1_S */
9348 if (ctx->insn_flags & ISA_MIPS32R6) {
9349 /* OPC_MINA_S */
9350 TCGv_i32 fp0 = tcg_temp_new_i32();
9351 TCGv_i32 fp1 = tcg_temp_new_i32();
9352 TCGv_i32 fp2 = tcg_temp_new_i32();
7c979afd
LA
9353 gen_load_fpr32(ctx, fp0, fs);
9354 gen_load_fpr32(ctx, fp1, ft);
e7f16abb 9355 gen_helper_float_mina_s(fp2, cpu_env, fp0, fp1);
7c979afd 9356 gen_store_fpr32(ctx, fp2, fd);
e7f16abb
LA
9357 tcg_temp_free_i32(fp2);
9358 tcg_temp_free_i32(fp1);
9359 tcg_temp_free_i32(fp0);
e7f16abb
LA
9360 } else {
9361 /* OPC_RECIP1_S */
9362 check_cp1_64bitmode(ctx);
9363 {
9364 TCGv_i32 fp0 = tcg_temp_new_i32();
9365
7c979afd 9366 gen_load_fpr32(ctx, fp0, fs);
e7f16abb 9367 gen_helper_float_recip1_s(fp0, cpu_env, fp0);
7c979afd 9368 gen_store_fpr32(ctx, fp0, fd);
e7f16abb
LA
9369 tcg_temp_free_i32(fp0);
9370 }
e7f16abb
LA
9371 }
9372 break;
9373 case OPC_MAX_S: /* OPC_RSQRT1_S */
9374 if (ctx->insn_flags & ISA_MIPS32R6) {
9375 /* OPC_MAX_S */
9376 TCGv_i32 fp0 = tcg_temp_new_i32();
9377 TCGv_i32 fp1 = tcg_temp_new_i32();
7c979afd
LA
9378 gen_load_fpr32(ctx, fp0, fs);
9379 gen_load_fpr32(ctx, fp1, ft);
e7f16abb 9380 gen_helper_float_max_s(fp1, cpu_env, fp0, fp1);
7c979afd 9381 gen_store_fpr32(ctx, fp1, fd);
e7f16abb
LA
9382 tcg_temp_free_i32(fp1);
9383 tcg_temp_free_i32(fp0);
e7f16abb
LA
9384 } else {
9385 /* OPC_RSQRT1_S */
9386 check_cp1_64bitmode(ctx);
9387 {
9388 TCGv_i32 fp0 = tcg_temp_new_i32();
9389
7c979afd 9390 gen_load_fpr32(ctx, fp0, fs);
e7f16abb 9391 gen_helper_float_rsqrt1_s(fp0, cpu_env, fp0);
7c979afd 9392 gen_store_fpr32(ctx, fp0, fd);
e7f16abb
LA
9393 tcg_temp_free_i32(fp0);
9394 }
e7f16abb
LA
9395 }
9396 break;
9397 case OPC_MAXA_S: /* OPC_RSQRT2_S */
9398 if (ctx->insn_flags & ISA_MIPS32R6) {
9399 /* OPC_MAXA_S */
9400 TCGv_i32 fp0 = tcg_temp_new_i32();
9401 TCGv_i32 fp1 = tcg_temp_new_i32();
7c979afd
LA
9402 gen_load_fpr32(ctx, fp0, fs);
9403 gen_load_fpr32(ctx, fp1, ft);
e7f16abb 9404 gen_helper_float_maxa_s(fp1, cpu_env, fp0, fp1);
7c979afd 9405 gen_store_fpr32(ctx, fp1, fd);
a7812ae4 9406 tcg_temp_free_i32(fp1);
a7812ae4 9407 tcg_temp_free_i32(fp0);
e7f16abb
LA
9408 } else {
9409 /* OPC_RSQRT2_S */
9410 check_cp1_64bitmode(ctx);
9411 {
9412 TCGv_i32 fp0 = tcg_temp_new_i32();
9413 TCGv_i32 fp1 = tcg_temp_new_i32();
9414
7c979afd
LA
9415 gen_load_fpr32(ctx, fp0, fs);
9416 gen_load_fpr32(ctx, fp1, ft);
e7f16abb
LA
9417 gen_helper_float_rsqrt2_s(fp0, cpu_env, fp0, fp1);
9418 tcg_temp_free_i32(fp1);
7c979afd 9419 gen_store_fpr32(ctx, fp0, fd);
e7f16abb
LA
9420 tcg_temp_free_i32(fp0);
9421 }
b6d96bed 9422 }
57fa1fb3 9423 break;
bf4120ad 9424 case OPC_CVT_D_S:
5e755519 9425 check_cp1_registers(ctx, fd);
b6d96bed 9426 {
a7812ae4
PB
9427 TCGv_i32 fp32 = tcg_temp_new_i32();
9428 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 9429
7c979afd 9430 gen_load_fpr32(ctx, fp32, fs);
895c2d04 9431 gen_helper_float_cvtd_s(fp64, cpu_env, fp32);
a7812ae4 9432 tcg_temp_free_i32(fp32);
b6d96bed 9433 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 9434 tcg_temp_free_i64(fp64);
b6d96bed 9435 }
5a5012ec 9436 break;
bf4120ad 9437 case OPC_CVT_W_S:
b6d96bed 9438 {
a7812ae4 9439 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9440
7c979afd 9441 gen_load_fpr32(ctx, fp0, fs);
87552089
AM
9442 if (ctx->nan2008) {
9443 gen_helper_float_cvt_2008_w_s(fp0, cpu_env, fp0);
9444 } else {
9445 gen_helper_float_cvt_w_s(fp0, cpu_env, fp0);
9446 }
7c979afd 9447 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9448 tcg_temp_free_i32(fp0);
b6d96bed 9449 }
5a5012ec 9450 break;
bf4120ad 9451 case OPC_CVT_L_S:
5e755519 9452 check_cp1_64bitmode(ctx);
b6d96bed 9453 {
a7812ae4
PB
9454 TCGv_i32 fp32 = tcg_temp_new_i32();
9455 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 9456
7c979afd 9457 gen_load_fpr32(ctx, fp32, fs);
87552089
AM
9458 if (ctx->nan2008) {
9459 gen_helper_float_cvt_2008_l_s(fp64, cpu_env, fp32);
9460 } else {
9461 gen_helper_float_cvt_l_s(fp64, cpu_env, fp32);
9462 }
a7812ae4 9463 tcg_temp_free_i32(fp32);
b6d96bed 9464 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 9465 tcg_temp_free_i64(fp64);
b6d96bed 9466 }
5a5012ec 9467 break;
bf4120ad 9468 case OPC_CVT_PS_S:
e29c9628 9469 check_ps(ctx);
b6d96bed 9470 {
a7812ae4
PB
9471 TCGv_i64 fp64 = tcg_temp_new_i64();
9472 TCGv_i32 fp32_0 = tcg_temp_new_i32();
9473 TCGv_i32 fp32_1 = tcg_temp_new_i32();
b6d96bed 9474
7c979afd
LA
9475 gen_load_fpr32(ctx, fp32_0, fs);
9476 gen_load_fpr32(ctx, fp32_1, ft);
13d24f49 9477 tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0);
a7812ae4
PB
9478 tcg_temp_free_i32(fp32_1);
9479 tcg_temp_free_i32(fp32_0);
36aa55dc 9480 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 9481 tcg_temp_free_i64(fp64);
b6d96bed 9482 }
5a5012ec 9483 break;
bf4120ad
NF
9484 case OPC_CMP_F_S:
9485 case OPC_CMP_UN_S:
9486 case OPC_CMP_EQ_S:
9487 case OPC_CMP_UEQ_S:
9488 case OPC_CMP_OLT_S:
9489 case OPC_CMP_ULT_S:
9490 case OPC_CMP_OLE_S:
9491 case OPC_CMP_ULE_S:
9492 case OPC_CMP_SF_S:
9493 case OPC_CMP_NGLE_S:
9494 case OPC_CMP_SEQ_S:
9495 case OPC_CMP_NGL_S:
9496 case OPC_CMP_LT_S:
9497 case OPC_CMP_NGE_S:
9498 case OPC_CMP_LE_S:
9499 case OPC_CMP_NGT_S:
fecd2646 9500 check_insn_opc_removed(ctx, ISA_MIPS32R6);
8153667c
NF
9501 if (ctx->opcode & (1 << 6)) {
9502 gen_cmpabs_s(ctx, func-48, ft, fs, cc);
8153667c
NF
9503 } else {
9504 gen_cmp_s(ctx, func-48, ft, fs, cc);
5a1e8ffb 9505 }
5a5012ec 9506 break;
bf4120ad 9507 case OPC_ADD_D:
5e755519 9508 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 9509 {
a7812ae4
PB
9510 TCGv_i64 fp0 = tcg_temp_new_i64();
9511 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9512
9513 gen_load_fpr64(ctx, fp0, fs);
9514 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9515 gen_helper_float_add_d(fp0, cpu_env, fp0, fp1);
a7812ae4 9516 tcg_temp_free_i64(fp1);
b6d96bed 9517 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9518 tcg_temp_free_i64(fp0);
b6d96bed 9519 }
6ea83fed 9520 break;
bf4120ad 9521 case OPC_SUB_D:
5e755519 9522 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 9523 {
a7812ae4
PB
9524 TCGv_i64 fp0 = tcg_temp_new_i64();
9525 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9526
9527 gen_load_fpr64(ctx, fp0, fs);
9528 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9529 gen_helper_float_sub_d(fp0, cpu_env, fp0, fp1);
a7812ae4 9530 tcg_temp_free_i64(fp1);
b6d96bed 9531 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9532 tcg_temp_free_i64(fp0);
b6d96bed 9533 }
6ea83fed 9534 break;
bf4120ad 9535 case OPC_MUL_D:
5e755519 9536 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 9537 {
a7812ae4
PB
9538 TCGv_i64 fp0 = tcg_temp_new_i64();
9539 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9540
9541 gen_load_fpr64(ctx, fp0, fs);
9542 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9543 gen_helper_float_mul_d(fp0, cpu_env, fp0, fp1);
a7812ae4 9544 tcg_temp_free_i64(fp1);
b6d96bed 9545 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9546 tcg_temp_free_i64(fp0);
b6d96bed 9547 }
6ea83fed 9548 break;
bf4120ad 9549 case OPC_DIV_D:
5e755519 9550 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 9551 {
a7812ae4
PB
9552 TCGv_i64 fp0 = tcg_temp_new_i64();
9553 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9554
9555 gen_load_fpr64(ctx, fp0, fs);
9556 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9557 gen_helper_float_div_d(fp0, cpu_env, fp0, fp1);
a7812ae4 9558 tcg_temp_free_i64(fp1);
b6d96bed 9559 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9560 tcg_temp_free_i64(fp0);
b6d96bed 9561 }
6ea83fed 9562 break;
bf4120ad 9563 case OPC_SQRT_D:
5e755519 9564 check_cp1_registers(ctx, fs | fd);
b6d96bed 9565 {
a7812ae4 9566 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9567
9568 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9569 gen_helper_float_sqrt_d(fp0, cpu_env, fp0);
b6d96bed 9570 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9571 tcg_temp_free_i64(fp0);
b6d96bed 9572 }
6ea83fed 9573 break;
bf4120ad 9574 case OPC_ABS_D:
5e755519 9575 check_cp1_registers(ctx, fs | fd);
b6d96bed 9576 {
a7812ae4 9577 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9578
9579 gen_load_fpr64(ctx, fp0, fs);
6be77480
AM
9580 if (ctx->abs2008) {
9581 tcg_gen_andi_i64(fp0, fp0, 0x7fffffffffffffffULL);
9582 } else {
9583 gen_helper_float_abs_d(fp0, fp0);
9584 }
b6d96bed 9585 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9586 tcg_temp_free_i64(fp0);
b6d96bed 9587 }
6ea83fed 9588 break;
bf4120ad 9589 case OPC_MOV_D:
5e755519 9590 check_cp1_registers(ctx, fs | fd);
b6d96bed 9591 {
a7812ae4 9592 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9593
9594 gen_load_fpr64(ctx, fp0, fs);
9595 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9596 tcg_temp_free_i64(fp0);
b6d96bed 9597 }
6ea83fed 9598 break;
bf4120ad 9599 case OPC_NEG_D:
5e755519 9600 check_cp1_registers(ctx, fs | fd);
b6d96bed 9601 {
a7812ae4 9602 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9603
9604 gen_load_fpr64(ctx, fp0, fs);
6be77480
AM
9605 if (ctx->abs2008) {
9606 tcg_gen_xori_i64(fp0, fp0, 1ULL << 63);
9607 } else {
9608 gen_helper_float_chs_d(fp0, fp0);
9609 }
b6d96bed 9610 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9611 tcg_temp_free_i64(fp0);
b6d96bed 9612 }
6ea83fed 9613 break;
bf4120ad 9614 case OPC_ROUND_L_D:
5e755519 9615 check_cp1_64bitmode(ctx);
b6d96bed 9616 {
a7812ae4 9617 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9618
9619 gen_load_fpr64(ctx, fp0, fs);
87552089
AM
9620 if (ctx->nan2008) {
9621 gen_helper_float_round_2008_l_d(fp0, cpu_env, fp0);
9622 } else {
9623 gen_helper_float_round_l_d(fp0, cpu_env, fp0);
9624 }
b6d96bed 9625 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9626 tcg_temp_free_i64(fp0);
b6d96bed 9627 }
5a5012ec 9628 break;
bf4120ad 9629 case OPC_TRUNC_L_D:
5e755519 9630 check_cp1_64bitmode(ctx);
b6d96bed 9631 {
a7812ae4 9632 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9633
9634 gen_load_fpr64(ctx, fp0, fs);
87552089
AM
9635 if (ctx->nan2008) {
9636 gen_helper_float_trunc_2008_l_d(fp0, cpu_env, fp0);
9637 } else {
9638 gen_helper_float_trunc_l_d(fp0, cpu_env, fp0);
9639 }
b6d96bed 9640 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9641 tcg_temp_free_i64(fp0);
b6d96bed 9642 }
5a5012ec 9643 break;
bf4120ad 9644 case OPC_CEIL_L_D:
5e755519 9645 check_cp1_64bitmode(ctx);
b6d96bed 9646 {
a7812ae4 9647 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9648
9649 gen_load_fpr64(ctx, fp0, fs);
87552089
AM
9650 if (ctx->nan2008) {
9651 gen_helper_float_ceil_2008_l_d(fp0, cpu_env, fp0);
9652 } else {
9653 gen_helper_float_ceil_l_d(fp0, cpu_env, fp0);
9654 }
b6d96bed 9655 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9656 tcg_temp_free_i64(fp0);
b6d96bed 9657 }
5a5012ec 9658 break;
bf4120ad 9659 case OPC_FLOOR_L_D:
5e755519 9660 check_cp1_64bitmode(ctx);
b6d96bed 9661 {
a7812ae4 9662 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9663
9664 gen_load_fpr64(ctx, fp0, fs);
87552089
AM
9665 if (ctx->nan2008) {
9666 gen_helper_float_floor_2008_l_d(fp0, cpu_env, fp0);
9667 } else {
9668 gen_helper_float_floor_l_d(fp0, cpu_env, fp0);
9669 }
b6d96bed 9670 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9671 tcg_temp_free_i64(fp0);
b6d96bed 9672 }
5a5012ec 9673 break;
bf4120ad 9674 case OPC_ROUND_W_D:
5e755519 9675 check_cp1_registers(ctx, fs);
b6d96bed 9676 {
a7812ae4
PB
9677 TCGv_i32 fp32 = tcg_temp_new_i32();
9678 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
9679
9680 gen_load_fpr64(ctx, fp64, fs);
87552089
AM
9681 if (ctx->nan2008) {
9682 gen_helper_float_round_2008_w_d(fp32, cpu_env, fp64);
9683 } else {
9684 gen_helper_float_round_w_d(fp32, cpu_env, fp64);
9685 }
a7812ae4 9686 tcg_temp_free_i64(fp64);
7c979afd 9687 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 9688 tcg_temp_free_i32(fp32);
b6d96bed 9689 }
6ea83fed 9690 break;
bf4120ad 9691 case OPC_TRUNC_W_D:
5e755519 9692 check_cp1_registers(ctx, fs);
b6d96bed 9693 {
a7812ae4
PB
9694 TCGv_i32 fp32 = tcg_temp_new_i32();
9695 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
9696
9697 gen_load_fpr64(ctx, fp64, fs);
87552089
AM
9698 if (ctx->nan2008) {
9699 gen_helper_float_trunc_2008_w_d(fp32, cpu_env, fp64);
9700 } else {
9701 gen_helper_float_trunc_w_d(fp32, cpu_env, fp64);
9702 }
a7812ae4 9703 tcg_temp_free_i64(fp64);
7c979afd 9704 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 9705 tcg_temp_free_i32(fp32);
b6d96bed 9706 }
6ea83fed 9707 break;
bf4120ad 9708 case OPC_CEIL_W_D:
5e755519 9709 check_cp1_registers(ctx, fs);
b6d96bed 9710 {
a7812ae4
PB
9711 TCGv_i32 fp32 = tcg_temp_new_i32();
9712 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
9713
9714 gen_load_fpr64(ctx, fp64, fs);
87552089
AM
9715 if (ctx->nan2008) {
9716 gen_helper_float_ceil_2008_w_d(fp32, cpu_env, fp64);
9717 } else {
9718 gen_helper_float_ceil_w_d(fp32, cpu_env, fp64);
9719 }
a7812ae4 9720 tcg_temp_free_i64(fp64);
7c979afd 9721 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 9722 tcg_temp_free_i32(fp32);
b6d96bed 9723 }
6ea83fed 9724 break;
bf4120ad 9725 case OPC_FLOOR_W_D:
5e755519 9726 check_cp1_registers(ctx, fs);
b6d96bed 9727 {
a7812ae4
PB
9728 TCGv_i32 fp32 = tcg_temp_new_i32();
9729 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
9730
9731 gen_load_fpr64(ctx, fp64, fs);
87552089
AM
9732 if (ctx->nan2008) {
9733 gen_helper_float_floor_2008_w_d(fp32, cpu_env, fp64);
9734 } else {
9735 gen_helper_float_floor_w_d(fp32, cpu_env, fp64);
9736 }
a7812ae4 9737 tcg_temp_free_i64(fp64);
7c979afd 9738 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 9739 tcg_temp_free_i32(fp32);
b6d96bed 9740 }
6ea83fed 9741 break;
e7f16abb
LA
9742 case OPC_SEL_D:
9743 check_insn(ctx, ISA_MIPS32R6);
9744 gen_sel_d(ctx, op1, fd, ft, fs);
e7f16abb
LA
9745 break;
9746 case OPC_SELEQZ_D:
9747 check_insn(ctx, ISA_MIPS32R6);
9748 gen_sel_d(ctx, op1, fd, ft, fs);
e7f16abb
LA
9749 break;
9750 case OPC_SELNEZ_D:
9751 check_insn(ctx, ISA_MIPS32R6);
9752 gen_sel_d(ctx, op1, fd, ft, fs);
e7f16abb 9753 break;
bf4120ad 9754 case OPC_MOVCF_D:
fecd2646 9755 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b6d96bed 9756 gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
dd016883 9757 break;
bf4120ad 9758 case OPC_MOVZ_D:
fecd2646 9759 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a16336e4 9760 {
42a268c2 9761 TCGLabel *l1 = gen_new_label();
c9297f4d 9762 TCGv_i64 fp0;
a16336e4 9763
c9297f4d
AJ
9764 if (ft != 0) {
9765 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
9766 }
9767 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9768 gen_load_fpr64(ctx, fp0, fs);
9769 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9770 tcg_temp_free_i64(fp0);
a16336e4
TS
9771 gen_set_label(l1);
9772 }
5a5012ec 9773 break;
bf4120ad 9774 case OPC_MOVN_D:
fecd2646 9775 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a16336e4 9776 {
42a268c2 9777 TCGLabel *l1 = gen_new_label();
c9297f4d
AJ
9778 TCGv_i64 fp0;
9779
9780 if (ft != 0) {
9781 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
9782 fp0 = tcg_temp_new_i64();
9783 gen_load_fpr64(ctx, fp0, fs);
9784 gen_store_fpr64(ctx, fp0, fd);
9785 tcg_temp_free_i64(fp0);
9786 gen_set_label(l1);
9787 }
a16336e4 9788 }
6ea83fed 9789 break;
bf4120ad 9790 case OPC_RECIP_D:
ca6c7803 9791 check_cp1_registers(ctx, fs | fd);
b6d96bed 9792 {
a7812ae4 9793 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9794
9795 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9796 gen_helper_float_recip_d(fp0, cpu_env, fp0);
b6d96bed 9797 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9798 tcg_temp_free_i64(fp0);
b6d96bed 9799 }
57fa1fb3 9800 break;
bf4120ad 9801 case OPC_RSQRT_D:
ca6c7803 9802 check_cp1_registers(ctx, fs | fd);
b6d96bed 9803 {
a7812ae4 9804 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9805
9806 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9807 gen_helper_float_rsqrt_d(fp0, cpu_env, fp0);
b6d96bed 9808 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9809 tcg_temp_free_i64(fp0);
b6d96bed 9810 }
57fa1fb3 9811 break;
e7f16abb
LA
9812 case OPC_MADDF_D:
9813 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 9814 {
a7812ae4
PB
9815 TCGv_i64 fp0 = tcg_temp_new_i64();
9816 TCGv_i64 fp1 = tcg_temp_new_i64();
e7f16abb 9817 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
9818 gen_load_fpr64(ctx, fp0, fs);
9819 gen_load_fpr64(ctx, fp1, ft);
e7f16abb
LA
9820 gen_load_fpr64(ctx, fp2, fd);
9821 gen_helper_float_maddf_d(fp2, cpu_env, fp0, fp1, fp2);
9822 gen_store_fpr64(ctx, fp2, fd);
9823 tcg_temp_free_i64(fp2);
a7812ae4 9824 tcg_temp_free_i64(fp1);
a7812ae4 9825 tcg_temp_free_i64(fp0);
b6d96bed 9826 }
57fa1fb3 9827 break;
e7f16abb
LA
9828 case OPC_MSUBF_D:
9829 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 9830 {
a7812ae4 9831 TCGv_i64 fp0 = tcg_temp_new_i64();
e7f16abb
LA
9832 TCGv_i64 fp1 = tcg_temp_new_i64();
9833 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed 9834 gen_load_fpr64(ctx, fp0, fs);
e7f16abb
LA
9835 gen_load_fpr64(ctx, fp1, ft);
9836 gen_load_fpr64(ctx, fp2, fd);
9837 gen_helper_float_msubf_d(fp2, cpu_env, fp0, fp1, fp2);
9838 gen_store_fpr64(ctx, fp2, fd);
9839 tcg_temp_free_i64(fp2);
9840 tcg_temp_free_i64(fp1);
a7812ae4 9841 tcg_temp_free_i64(fp0);
b6d96bed 9842 }
57fa1fb3 9843 break;
e7f16abb
LA
9844 case OPC_RINT_D:
9845 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 9846 {
a7812ae4 9847 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 9848 gen_load_fpr64(ctx, fp0, fs);
e7f16abb 9849 gen_helper_float_rint_d(fp0, cpu_env, fp0);
b6d96bed 9850 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9851 tcg_temp_free_i64(fp0);
b6d96bed 9852 }
57fa1fb3 9853 break;
e7f16abb
LA
9854 case OPC_CLASS_D:
9855 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 9856 {
e7f16abb
LA
9857 TCGv_i64 fp0 = tcg_temp_new_i64();
9858 gen_load_fpr64(ctx, fp0, fs);
af39bc8c 9859 gen_helper_float_class_d(fp0, cpu_env, fp0);
e7f16abb
LA
9860 gen_store_fpr64(ctx, fp0, fd);
9861 tcg_temp_free_i64(fp0);
e7f16abb
LA
9862 }
9863 break;
9864 case OPC_MIN_D: /* OPC_RECIP2_D */
9865 if (ctx->insn_flags & ISA_MIPS32R6) {
9866 /* OPC_MIN_D */
a7812ae4
PB
9867 TCGv_i64 fp0 = tcg_temp_new_i64();
9868 TCGv_i64 fp1 = tcg_temp_new_i64();
e7f16abb
LA
9869 gen_load_fpr64(ctx, fp0, fs);
9870 gen_load_fpr64(ctx, fp1, ft);
9871 gen_helper_float_min_d(fp1, cpu_env, fp0, fp1);
9872 gen_store_fpr64(ctx, fp1, fd);
9873 tcg_temp_free_i64(fp1);
9874 tcg_temp_free_i64(fp0);
e7f16abb
LA
9875 } else {
9876 /* OPC_RECIP2_D */
9877 check_cp1_64bitmode(ctx);
9878 {
9879 TCGv_i64 fp0 = tcg_temp_new_i64();
9880 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed 9881
e7f16abb
LA
9882 gen_load_fpr64(ctx, fp0, fs);
9883 gen_load_fpr64(ctx, fp1, ft);
9884 gen_helper_float_recip2_d(fp0, cpu_env, fp0, fp1);
9885 tcg_temp_free_i64(fp1);
9886 gen_store_fpr64(ctx, fp0, fd);
9887 tcg_temp_free_i64(fp0);
9888 }
e7f16abb
LA
9889 }
9890 break;
9891 case OPC_MINA_D: /* OPC_RECIP1_D */
9892 if (ctx->insn_flags & ISA_MIPS32R6) {
9893 /* OPC_MINA_D */
9894 TCGv_i64 fp0 = tcg_temp_new_i64();
9895 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9896 gen_load_fpr64(ctx, fp0, fs);
9897 gen_load_fpr64(ctx, fp1, ft);
e7f16abb
LA
9898 gen_helper_float_mina_d(fp1, cpu_env, fp0, fp1);
9899 gen_store_fpr64(ctx, fp1, fd);
9900 tcg_temp_free_i64(fp1);
9901 tcg_temp_free_i64(fp0);
e7f16abb
LA
9902 } else {
9903 /* OPC_RECIP1_D */
9904 check_cp1_64bitmode(ctx);
9905 {
9906 TCGv_i64 fp0 = tcg_temp_new_i64();
9907
9908 gen_load_fpr64(ctx, fp0, fs);
9909 gen_helper_float_recip1_d(fp0, cpu_env, fp0);
9910 gen_store_fpr64(ctx, fp0, fd);
9911 tcg_temp_free_i64(fp0);
9912 }
e7f16abb
LA
9913 }
9914 break;
9915 case OPC_MAX_D: /* OPC_RSQRT1_D */
9916 if (ctx->insn_flags & ISA_MIPS32R6) {
9917 /* OPC_MAX_D */
9918 TCGv_i64 fp0 = tcg_temp_new_i64();
9919 TCGv_i64 fp1 = tcg_temp_new_i64();
9920 gen_load_fpr64(ctx, fp0, fs);
9921 gen_load_fpr64(ctx, fp1, ft);
9922 gen_helper_float_max_d(fp1, cpu_env, fp0, fp1);
9923 gen_store_fpr64(ctx, fp1, fd);
a7812ae4 9924 tcg_temp_free_i64(fp1);
a7812ae4 9925 tcg_temp_free_i64(fp0);
e7f16abb
LA
9926 } else {
9927 /* OPC_RSQRT1_D */
9928 check_cp1_64bitmode(ctx);
9929 {
9930 TCGv_i64 fp0 = tcg_temp_new_i64();
9931
9932 gen_load_fpr64(ctx, fp0, fs);
9933 gen_helper_float_rsqrt1_d(fp0, cpu_env, fp0);
9934 gen_store_fpr64(ctx, fp0, fd);
9935 tcg_temp_free_i64(fp0);
9936 }
e7f16abb
LA
9937 }
9938 break;
9939 case OPC_MAXA_D: /* OPC_RSQRT2_D */
9940 if (ctx->insn_flags & ISA_MIPS32R6) {
9941 /* OPC_MAXA_D */
9942 TCGv_i64 fp0 = tcg_temp_new_i64();
9943 TCGv_i64 fp1 = tcg_temp_new_i64();
9944 gen_load_fpr64(ctx, fp0, fs);
9945 gen_load_fpr64(ctx, fp1, ft);
9946 gen_helper_float_maxa_d(fp1, cpu_env, fp0, fp1);
9947 gen_store_fpr64(ctx, fp1, fd);
9948 tcg_temp_free_i64(fp1);
9949 tcg_temp_free_i64(fp0);
e7f16abb
LA
9950 } else {
9951 /* OPC_RSQRT2_D */
9952 check_cp1_64bitmode(ctx);
9953 {
9954 TCGv_i64 fp0 = tcg_temp_new_i64();
9955 TCGv_i64 fp1 = tcg_temp_new_i64();
9956
9957 gen_load_fpr64(ctx, fp0, fs);
9958 gen_load_fpr64(ctx, fp1, ft);
9959 gen_helper_float_rsqrt2_d(fp0, cpu_env, fp0, fp1);
9960 tcg_temp_free_i64(fp1);
9961 gen_store_fpr64(ctx, fp0, fd);
9962 tcg_temp_free_i64(fp0);
9963 }
b6d96bed 9964 }
57fa1fb3 9965 break;
bf4120ad
NF
9966 case OPC_CMP_F_D:
9967 case OPC_CMP_UN_D:
9968 case OPC_CMP_EQ_D:
9969 case OPC_CMP_UEQ_D:
9970 case OPC_CMP_OLT_D:
9971 case OPC_CMP_ULT_D:
9972 case OPC_CMP_OLE_D:
9973 case OPC_CMP_ULE_D:
9974 case OPC_CMP_SF_D:
9975 case OPC_CMP_NGLE_D:
9976 case OPC_CMP_SEQ_D:
9977 case OPC_CMP_NGL_D:
9978 case OPC_CMP_LT_D:
9979 case OPC_CMP_NGE_D:
9980 case OPC_CMP_LE_D:
9981 case OPC_CMP_NGT_D:
fecd2646 9982 check_insn_opc_removed(ctx, ISA_MIPS32R6);
8153667c
NF
9983 if (ctx->opcode & (1 << 6)) {
9984 gen_cmpabs_d(ctx, func-48, ft, fs, cc);
8153667c
NF
9985 } else {
9986 gen_cmp_d(ctx, func-48, ft, fs, cc);
5a1e8ffb 9987 }
6ea83fed 9988 break;
bf4120ad 9989 case OPC_CVT_S_D:
5e755519 9990 check_cp1_registers(ctx, fs);
b6d96bed 9991 {
a7812ae4
PB
9992 TCGv_i32 fp32 = tcg_temp_new_i32();
9993 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
9994
9995 gen_load_fpr64(ctx, fp64, fs);
895c2d04 9996 gen_helper_float_cvts_d(fp32, cpu_env, fp64);
a7812ae4 9997 tcg_temp_free_i64(fp64);
7c979afd 9998 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 9999 tcg_temp_free_i32(fp32);
b6d96bed 10000 }
5a5012ec 10001 break;
bf4120ad 10002 case OPC_CVT_W_D:
5e755519 10003 check_cp1_registers(ctx, fs);
b6d96bed 10004 {
a7812ae4
PB
10005 TCGv_i32 fp32 = tcg_temp_new_i32();
10006 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
10007
10008 gen_load_fpr64(ctx, fp64, fs);
87552089
AM
10009 if (ctx->nan2008) {
10010 gen_helper_float_cvt_2008_w_d(fp32, cpu_env, fp64);
10011 } else {
10012 gen_helper_float_cvt_w_d(fp32, cpu_env, fp64);
10013 }
a7812ae4 10014 tcg_temp_free_i64(fp64);
7c979afd 10015 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 10016 tcg_temp_free_i32(fp32);
b6d96bed 10017 }
5a5012ec 10018 break;
bf4120ad 10019 case OPC_CVT_L_D:
5e755519 10020 check_cp1_64bitmode(ctx);
b6d96bed 10021 {
a7812ae4 10022 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
10023
10024 gen_load_fpr64(ctx, fp0, fs);
87552089
AM
10025 if (ctx->nan2008) {
10026 gen_helper_float_cvt_2008_l_d(fp0, cpu_env, fp0);
10027 } else {
10028 gen_helper_float_cvt_l_d(fp0, cpu_env, fp0);
10029 }
b6d96bed 10030 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10031 tcg_temp_free_i64(fp0);
b6d96bed 10032 }
5a5012ec 10033 break;
bf4120ad 10034 case OPC_CVT_S_W:
b6d96bed 10035 {
a7812ae4 10036 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 10037
7c979afd 10038 gen_load_fpr32(ctx, fp0, fs);
895c2d04 10039 gen_helper_float_cvts_w(fp0, cpu_env, fp0);
7c979afd 10040 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 10041 tcg_temp_free_i32(fp0);
b6d96bed 10042 }
6ea83fed 10043 break;
bf4120ad 10044 case OPC_CVT_D_W:
5e755519 10045 check_cp1_registers(ctx, fd);
b6d96bed 10046 {
a7812ae4
PB
10047 TCGv_i32 fp32 = tcg_temp_new_i32();
10048 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 10049
7c979afd 10050 gen_load_fpr32(ctx, fp32, fs);
895c2d04 10051 gen_helper_float_cvtd_w(fp64, cpu_env, fp32);
a7812ae4 10052 tcg_temp_free_i32(fp32);
b6d96bed 10053 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 10054 tcg_temp_free_i64(fp64);
b6d96bed 10055 }
5a5012ec 10056 break;
bf4120ad 10057 case OPC_CVT_S_L:
5e755519 10058 check_cp1_64bitmode(ctx);
b6d96bed 10059 {
a7812ae4
PB
10060 TCGv_i32 fp32 = tcg_temp_new_i32();
10061 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
10062
10063 gen_load_fpr64(ctx, fp64, fs);
895c2d04 10064 gen_helper_float_cvts_l(fp32, cpu_env, fp64);
a7812ae4 10065 tcg_temp_free_i64(fp64);
7c979afd 10066 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 10067 tcg_temp_free_i32(fp32);
b6d96bed 10068 }
5a5012ec 10069 break;
bf4120ad 10070 case OPC_CVT_D_L:
5e755519 10071 check_cp1_64bitmode(ctx);
b6d96bed 10072 {
a7812ae4 10073 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
10074
10075 gen_load_fpr64(ctx, fp0, fs);
895c2d04 10076 gen_helper_float_cvtd_l(fp0, cpu_env, fp0);
b6d96bed 10077 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10078 tcg_temp_free_i64(fp0);
b6d96bed 10079 }
5a5012ec 10080 break;
bf4120ad 10081 case OPC_CVT_PS_PW:
e29c9628 10082 check_ps(ctx);
b6d96bed 10083 {
a7812ae4 10084 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
10085
10086 gen_load_fpr64(ctx, fp0, fs);
895c2d04 10087 gen_helper_float_cvtps_pw(fp0, cpu_env, fp0);
b6d96bed 10088 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10089 tcg_temp_free_i64(fp0);
b6d96bed 10090 }
5a5012ec 10091 break;
bf4120ad 10092 case OPC_ADD_PS:
e29c9628 10093 check_ps(ctx);
b6d96bed 10094 {
a7812ae4
PB
10095 TCGv_i64 fp0 = tcg_temp_new_i64();
10096 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
10097
10098 gen_load_fpr64(ctx, fp0, fs);
10099 gen_load_fpr64(ctx, fp1, ft);
895c2d04 10100 gen_helper_float_add_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 10101 tcg_temp_free_i64(fp1);
b6d96bed 10102 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10103 tcg_temp_free_i64(fp0);
b6d96bed 10104 }
6ea83fed 10105 break;
bf4120ad 10106 case OPC_SUB_PS:
e29c9628 10107 check_ps(ctx);
b6d96bed 10108 {
a7812ae4
PB
10109 TCGv_i64 fp0 = tcg_temp_new_i64();
10110 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
10111
10112 gen_load_fpr64(ctx, fp0, fs);
10113 gen_load_fpr64(ctx, fp1, ft);
895c2d04 10114 gen_helper_float_sub_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 10115 tcg_temp_free_i64(fp1);
b6d96bed 10116 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10117 tcg_temp_free_i64(fp0);
b6d96bed 10118 }
6ea83fed 10119 break;
bf4120ad 10120 case OPC_MUL_PS:
e29c9628 10121 check_ps(ctx);
b6d96bed 10122 {
a7812ae4
PB
10123 TCGv_i64 fp0 = tcg_temp_new_i64();
10124 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
10125
10126 gen_load_fpr64(ctx, fp0, fs);
10127 gen_load_fpr64(ctx, fp1, ft);
895c2d04 10128 gen_helper_float_mul_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 10129 tcg_temp_free_i64(fp1);
b6d96bed 10130 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10131 tcg_temp_free_i64(fp0);
b6d96bed 10132 }
6ea83fed 10133 break;
bf4120ad 10134 case OPC_ABS_PS:
e29c9628 10135 check_ps(ctx);
b6d96bed 10136 {
a7812ae4 10137 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
10138
10139 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 10140 gen_helper_float_abs_ps(fp0, fp0);
b6d96bed 10141 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10142 tcg_temp_free_i64(fp0);
b6d96bed 10143 }
6ea83fed 10144 break;
bf4120ad 10145 case OPC_MOV_PS:
e29c9628 10146 check_ps(ctx);
b6d96bed 10147 {
a7812ae4 10148 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
10149
10150 gen_load_fpr64(ctx, fp0, fs);
10151 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10152 tcg_temp_free_i64(fp0);
b6d96bed 10153 }
6ea83fed 10154 break;
bf4120ad 10155 case OPC_NEG_PS:
e29c9628 10156 check_ps(ctx);
b6d96bed 10157 {
a7812ae4 10158 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
10159
10160 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 10161 gen_helper_float_chs_ps(fp0, fp0);
b6d96bed 10162 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10163 tcg_temp_free_i64(fp0);
b6d96bed 10164 }
6ea83fed 10165 break;
bf4120ad 10166 case OPC_MOVCF_PS:
e29c9628 10167 check_ps(ctx);
7f6613ce 10168 gen_movcf_ps(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
6ea83fed 10169 break;
bf4120ad 10170 case OPC_MOVZ_PS:
e29c9628 10171 check_ps(ctx);
a16336e4 10172 {
42a268c2 10173 TCGLabel *l1 = gen_new_label();
30a3848b 10174 TCGv_i64 fp0;
a16336e4 10175
c9297f4d
AJ
10176 if (ft != 0)
10177 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
10178 fp0 = tcg_temp_new_i64();
10179 gen_load_fpr64(ctx, fp0, fs);
10180 gen_store_fpr64(ctx, fp0, fd);
10181 tcg_temp_free_i64(fp0);
a16336e4
TS
10182 gen_set_label(l1);
10183 }
6ea83fed 10184 break;
bf4120ad 10185 case OPC_MOVN_PS:
e29c9628 10186 check_ps(ctx);
a16336e4 10187 {
42a268c2 10188 TCGLabel *l1 = gen_new_label();
30a3848b 10189 TCGv_i64 fp0;
c9297f4d
AJ
10190
10191 if (ft != 0) {
10192 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
10193 fp0 = tcg_temp_new_i64();
10194 gen_load_fpr64(ctx, fp0, fs);
10195 gen_store_fpr64(ctx, fp0, fd);
10196 tcg_temp_free_i64(fp0);
10197 gen_set_label(l1);
10198 }
a16336e4 10199 }
6ea83fed 10200 break;
bf4120ad 10201 case OPC_ADDR_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, ft);
10208 gen_load_fpr64(ctx, fp1, fs);
895c2d04 10209 gen_helper_float_addr_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 }
fbcc6828 10214 break;
bf4120ad 10215 case OPC_MULR_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, ft);
10222 gen_load_fpr64(ctx, fp1, fs);
895c2d04 10223 gen_helper_float_mulr_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 }
57fa1fb3 10228 break;
bf4120ad 10229 case OPC_RECIP2_PS:
e29c9628 10230 check_ps(ctx);
b6d96bed 10231 {
a7812ae4
PB
10232 TCGv_i64 fp0 = tcg_temp_new_i64();
10233 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
10234
10235 gen_load_fpr64(ctx, fp0, fs);
d22d7289 10236 gen_load_fpr64(ctx, fp1, ft);
895c2d04 10237 gen_helper_float_recip2_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 10238 tcg_temp_free_i64(fp1);
b6d96bed 10239 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10240 tcg_temp_free_i64(fp0);
b6d96bed 10241 }
57fa1fb3 10242 break;
bf4120ad 10243 case OPC_RECIP1_PS:
e29c9628 10244 check_ps(ctx);
b6d96bed 10245 {
a7812ae4 10246 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
10247
10248 gen_load_fpr64(ctx, fp0, fs);
895c2d04 10249 gen_helper_float_recip1_ps(fp0, cpu_env, fp0);
b6d96bed 10250 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10251 tcg_temp_free_i64(fp0);
b6d96bed 10252 }
57fa1fb3 10253 break;
bf4120ad 10254 case OPC_RSQRT1_PS:
e29c9628 10255 check_ps(ctx);
b6d96bed 10256 {
a7812ae4 10257 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
10258
10259 gen_load_fpr64(ctx, fp0, fs);
895c2d04 10260 gen_helper_float_rsqrt1_ps(fp0, cpu_env, fp0);
b6d96bed 10261 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10262 tcg_temp_free_i64(fp0);
b6d96bed 10263 }
57fa1fb3 10264 break;
bf4120ad 10265 case OPC_RSQRT2_PS:
e29c9628 10266 check_ps(ctx);
b6d96bed 10267 {
a7812ae4
PB
10268 TCGv_i64 fp0 = tcg_temp_new_i64();
10269 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
10270
10271 gen_load_fpr64(ctx, fp0, fs);
10272 gen_load_fpr64(ctx, fp1, ft);
895c2d04 10273 gen_helper_float_rsqrt2_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 10274 tcg_temp_free_i64(fp1);
b6d96bed 10275 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10276 tcg_temp_free_i64(fp0);
b6d96bed 10277 }
57fa1fb3 10278 break;
bf4120ad 10279 case OPC_CVT_S_PU:
5e755519 10280 check_cp1_64bitmode(ctx);
b6d96bed 10281 {
a7812ae4 10282 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 10283
7f6613ce 10284 gen_load_fpr32h(ctx, fp0, fs);
895c2d04 10285 gen_helper_float_cvts_pu(fp0, cpu_env, fp0);
7c979afd 10286 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 10287 tcg_temp_free_i32(fp0);
b6d96bed 10288 }
dd016883 10289 break;
bf4120ad 10290 case OPC_CVT_PW_PS:
e29c9628 10291 check_ps(ctx);
b6d96bed 10292 {
a7812ae4 10293 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
10294
10295 gen_load_fpr64(ctx, fp0, fs);
895c2d04 10296 gen_helper_float_cvtpw_ps(fp0, cpu_env, fp0);
b6d96bed 10297 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10298 tcg_temp_free_i64(fp0);
b6d96bed 10299 }
6ea83fed 10300 break;
bf4120ad 10301 case OPC_CVT_S_PL:
5e755519 10302 check_cp1_64bitmode(ctx);
b6d96bed 10303 {
a7812ae4 10304 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 10305
7c979afd 10306 gen_load_fpr32(ctx, fp0, fs);
895c2d04 10307 gen_helper_float_cvts_pl(fp0, cpu_env, fp0);
7c979afd 10308 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 10309 tcg_temp_free_i32(fp0);
b6d96bed 10310 }
6ea83fed 10311 break;
bf4120ad 10312 case OPC_PLL_PS:
e29c9628 10313 check_ps(ctx);
b6d96bed 10314 {
a7812ae4
PB
10315 TCGv_i32 fp0 = tcg_temp_new_i32();
10316 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 10317
7c979afd
LA
10318 gen_load_fpr32(ctx, fp0, fs);
10319 gen_load_fpr32(ctx, fp1, ft);
7f6613ce 10320 gen_store_fpr32h(ctx, fp0, fd);
7c979afd 10321 gen_store_fpr32(ctx, fp1, fd);
a7812ae4
PB
10322 tcg_temp_free_i32(fp0);
10323 tcg_temp_free_i32(fp1);
b6d96bed 10324 }
6ea83fed 10325 break;
bf4120ad 10326 case OPC_PLU_PS:
e29c9628 10327 check_ps(ctx);
b6d96bed 10328 {
a7812ae4
PB
10329 TCGv_i32 fp0 = tcg_temp_new_i32();
10330 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 10331
7c979afd 10332 gen_load_fpr32(ctx, fp0, fs);
7f6613ce 10333 gen_load_fpr32h(ctx, fp1, ft);
7c979afd 10334 gen_store_fpr32(ctx, fp1, fd);
7f6613ce 10335 gen_store_fpr32h(ctx, fp0, fd);
a7812ae4
PB
10336 tcg_temp_free_i32(fp0);
10337 tcg_temp_free_i32(fp1);
b6d96bed 10338 }
5a5012ec 10339 break;
bf4120ad 10340 case OPC_PUL_PS:
e29c9628 10341 check_ps(ctx);
b6d96bed 10342 {
a7812ae4
PB
10343 TCGv_i32 fp0 = tcg_temp_new_i32();
10344 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 10345
7f6613ce 10346 gen_load_fpr32h(ctx, fp0, fs);
7c979afd
LA
10347 gen_load_fpr32(ctx, fp1, ft);
10348 gen_store_fpr32(ctx, fp1, fd);
7f6613ce 10349 gen_store_fpr32h(ctx, fp0, fd);
a7812ae4
PB
10350 tcg_temp_free_i32(fp0);
10351 tcg_temp_free_i32(fp1);
b6d96bed 10352 }
5a5012ec 10353 break;
bf4120ad 10354 case OPC_PUU_PS:
e29c9628 10355 check_ps(ctx);
b6d96bed 10356 {
a7812ae4
PB
10357 TCGv_i32 fp0 = tcg_temp_new_i32();
10358 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 10359
7f6613ce
PJ
10360 gen_load_fpr32h(ctx, fp0, fs);
10361 gen_load_fpr32h(ctx, fp1, ft);
7c979afd 10362 gen_store_fpr32(ctx, fp1, fd);
7f6613ce 10363 gen_store_fpr32h(ctx, fp0, fd);
a7812ae4
PB
10364 tcg_temp_free_i32(fp0);
10365 tcg_temp_free_i32(fp1);
b6d96bed 10366 }
5a5012ec 10367 break;
bf4120ad
NF
10368 case OPC_CMP_F_PS:
10369 case OPC_CMP_UN_PS:
10370 case OPC_CMP_EQ_PS:
10371 case OPC_CMP_UEQ_PS:
10372 case OPC_CMP_OLT_PS:
10373 case OPC_CMP_ULT_PS:
10374 case OPC_CMP_OLE_PS:
10375 case OPC_CMP_ULE_PS:
10376 case OPC_CMP_SF_PS:
10377 case OPC_CMP_NGLE_PS:
10378 case OPC_CMP_SEQ_PS:
10379 case OPC_CMP_NGL_PS:
10380 case OPC_CMP_LT_PS:
10381 case OPC_CMP_NGE_PS:
10382 case OPC_CMP_LE_PS:
10383 case OPC_CMP_NGT_PS:
8153667c
NF
10384 if (ctx->opcode & (1 << 6)) {
10385 gen_cmpabs_ps(ctx, func-48, ft, fs, cc);
8153667c
NF
10386 } else {
10387 gen_cmp_ps(ctx, func-48, ft, fs, cc);
5a1e8ffb 10388 }
6ea83fed 10389 break;
5a5012ec 10390 default:
9d68ac14 10391 MIPS_INVAL("farith");
9c708c7f 10392 generate_exception_end(ctx, EXCP_RI);
6ea83fed
FB
10393 return;
10394 }
6ea83fed 10395}
6af0bf9c 10396
5a5012ec 10397/* Coprocessor 3 (FPU) */
5e755519
TS
10398static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
10399 int fd, int fs, int base, int index)
7a387fff 10400{
4e2474d6 10401 TCGv t0 = tcg_temp_new();
7a387fff 10402
93b12ccc 10403 if (base == 0) {
6c5c1e20 10404 gen_load_gpr(t0, index);
93b12ccc 10405 } else if (index == 0) {
6c5c1e20 10406 gen_load_gpr(t0, base);
93b12ccc 10407 } else {
05168674 10408 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]);
93b12ccc 10409 }
5a5012ec 10410 /* Don't do NOP if destination is zero: we must perform the actual
ead9360e 10411 memory access. */
5a5012ec
TS
10412 switch (opc) {
10413 case OPC_LWXC1:
8c0ab41f 10414 check_cop1x(ctx);
b6d96bed 10415 {
a7812ae4 10416 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 10417
5f68f5ae 10418 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
585c88d5 10419 tcg_gen_trunc_tl_i32(fp0, t0);
7c979afd 10420 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 10421 tcg_temp_free_i32(fp0);
b6d96bed 10422 }
5a5012ec
TS
10423 break;
10424 case OPC_LDXC1:
8c0ab41f
AJ
10425 check_cop1x(ctx);
10426 check_cp1_registers(ctx, fd);
b6d96bed 10427 {
a7812ae4 10428 TCGv_i64 fp0 = tcg_temp_new_i64();
5f68f5ae 10429 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
b6d96bed 10430 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10431 tcg_temp_free_i64(fp0);
b6d96bed 10432 }
5a5012ec
TS
10433 break;
10434 case OPC_LUXC1:
8c0ab41f 10435 check_cp1_64bitmode(ctx);
6c5c1e20 10436 tcg_gen_andi_tl(t0, t0, ~0x7);
b6d96bed 10437 {
a7812ae4 10438 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 10439
5f68f5ae 10440 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
b6d96bed 10441 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10442 tcg_temp_free_i64(fp0);
b6d96bed 10443 }
5a5012ec
TS
10444 break;
10445 case OPC_SWXC1:
8c0ab41f 10446 check_cop1x(ctx);
b6d96bed 10447 {
a7812ae4 10448 TCGv_i32 fp0 = tcg_temp_new_i32();
7c979afd 10449 gen_load_fpr32(ctx, fp0, fs);
5f68f5ae 10450 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL);
a7812ae4 10451 tcg_temp_free_i32(fp0);
b6d96bed 10452 }
5a5012ec
TS
10453 break;
10454 case OPC_SDXC1:
8c0ab41f
AJ
10455 check_cop1x(ctx);
10456 check_cp1_registers(ctx, fs);
b6d96bed 10457 {
a7812ae4 10458 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 10459 gen_load_fpr64(ctx, fp0, fs);
5f68f5ae 10460 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
a7812ae4 10461 tcg_temp_free_i64(fp0);
b6d96bed 10462 }
5a5012ec
TS
10463 break;
10464 case OPC_SUXC1:
8c0ab41f 10465 check_cp1_64bitmode(ctx);
6c5c1e20 10466 tcg_gen_andi_tl(t0, t0, ~0x7);
b6d96bed 10467 {
a7812ae4 10468 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 10469 gen_load_fpr64(ctx, fp0, fs);
5f68f5ae 10470 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
a7812ae4 10471 tcg_temp_free_i64(fp0);
b6d96bed 10472 }
5a5012ec 10473 break;
5a5012ec 10474 }
6c5c1e20 10475 tcg_temp_free(t0);
5a5012ec
TS
10476}
10477
5e755519
TS
10478static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
10479 int fd, int fr, int fs, int ft)
5a5012ec 10480{
5a5012ec
TS
10481 switch (opc) {
10482 case OPC_ALNV_PS:
e29c9628 10483 check_ps(ctx);
a16336e4 10484 {
a7812ae4 10485 TCGv t0 = tcg_temp_local_new();
c905fdac
AJ
10486 TCGv_i32 fp = tcg_temp_new_i32();
10487 TCGv_i32 fph = tcg_temp_new_i32();
42a268c2
RH
10488 TCGLabel *l1 = gen_new_label();
10489 TCGLabel *l2 = gen_new_label();
a16336e4 10490
6c5c1e20
TS
10491 gen_load_gpr(t0, fr);
10492 tcg_gen_andi_tl(t0, t0, 0x7);
6c5c1e20
TS
10493
10494 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
7c979afd 10495 gen_load_fpr32(ctx, fp, fs);
7f6613ce 10496 gen_load_fpr32h(ctx, fph, fs);
7c979afd 10497 gen_store_fpr32(ctx, fp, fd);
7f6613ce 10498 gen_store_fpr32h(ctx, fph, fd);
a16336e4
TS
10499 tcg_gen_br(l2);
10500 gen_set_label(l1);
6c5c1e20
TS
10501 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
10502 tcg_temp_free(t0);
a16336e4 10503#ifdef TARGET_WORDS_BIGENDIAN
7c979afd 10504 gen_load_fpr32(ctx, fp, fs);
7f6613ce
PJ
10505 gen_load_fpr32h(ctx, fph, ft);
10506 gen_store_fpr32h(ctx, fp, fd);
7c979afd 10507 gen_store_fpr32(ctx, fph, fd);
a16336e4 10508#else
7f6613ce 10509 gen_load_fpr32h(ctx, fph, fs);
7c979afd
LA
10510 gen_load_fpr32(ctx, fp, ft);
10511 gen_store_fpr32(ctx, fph, fd);
7f6613ce 10512 gen_store_fpr32h(ctx, fp, fd);
a16336e4
TS
10513#endif
10514 gen_set_label(l2);
c905fdac
AJ
10515 tcg_temp_free_i32(fp);
10516 tcg_temp_free_i32(fph);
a16336e4 10517 }
5a5012ec
TS
10518 break;
10519 case OPC_MADD_S:
b8aa4598 10520 check_cop1x(ctx);
b6d96bed 10521 {
a7812ae4
PB
10522 TCGv_i32 fp0 = tcg_temp_new_i32();
10523 TCGv_i32 fp1 = tcg_temp_new_i32();
10524 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed 10525
7c979afd
LA
10526 gen_load_fpr32(ctx, fp0, fs);
10527 gen_load_fpr32(ctx, fp1, ft);
10528 gen_load_fpr32(ctx, fp2, fr);
b3d6cd44 10529 gen_helper_float_madd_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10530 tcg_temp_free_i32(fp0);
10531 tcg_temp_free_i32(fp1);
7c979afd 10532 gen_store_fpr32(ctx, fp2, fd);
a7812ae4 10533 tcg_temp_free_i32(fp2);
b6d96bed 10534 }
5a5012ec
TS
10535 break;
10536 case OPC_MADD_D:
b8aa4598
TS
10537 check_cop1x(ctx);
10538 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 10539 {
a7812ae4
PB
10540 TCGv_i64 fp0 = tcg_temp_new_i64();
10541 TCGv_i64 fp1 = tcg_temp_new_i64();
10542 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10543
10544 gen_load_fpr64(ctx, fp0, fs);
10545 gen_load_fpr64(ctx, fp1, ft);
10546 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10547 gen_helper_float_madd_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10548 tcg_temp_free_i64(fp0);
10549 tcg_temp_free_i64(fp1);
b6d96bed 10550 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10551 tcg_temp_free_i64(fp2);
b6d96bed 10552 }
5a5012ec
TS
10553 break;
10554 case OPC_MADD_PS:
e29c9628 10555 check_ps(ctx);
b6d96bed 10556 {
a7812ae4
PB
10557 TCGv_i64 fp0 = tcg_temp_new_i64();
10558 TCGv_i64 fp1 = tcg_temp_new_i64();
10559 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10560
10561 gen_load_fpr64(ctx, fp0, fs);
10562 gen_load_fpr64(ctx, fp1, ft);
10563 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10564 gen_helper_float_madd_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10565 tcg_temp_free_i64(fp0);
10566 tcg_temp_free_i64(fp1);
b6d96bed 10567 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10568 tcg_temp_free_i64(fp2);
b6d96bed 10569 }
5a5012ec
TS
10570 break;
10571 case OPC_MSUB_S:
b8aa4598 10572 check_cop1x(ctx);
b6d96bed 10573 {
a7812ae4
PB
10574 TCGv_i32 fp0 = tcg_temp_new_i32();
10575 TCGv_i32 fp1 = tcg_temp_new_i32();
10576 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed 10577
7c979afd
LA
10578 gen_load_fpr32(ctx, fp0, fs);
10579 gen_load_fpr32(ctx, fp1, ft);
10580 gen_load_fpr32(ctx, fp2, fr);
b3d6cd44 10581 gen_helper_float_msub_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10582 tcg_temp_free_i32(fp0);
10583 tcg_temp_free_i32(fp1);
7c979afd 10584 gen_store_fpr32(ctx, fp2, fd);
a7812ae4 10585 tcg_temp_free_i32(fp2);
b6d96bed 10586 }
5a5012ec
TS
10587 break;
10588 case OPC_MSUB_D:
b8aa4598
TS
10589 check_cop1x(ctx);
10590 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 10591 {
a7812ae4
PB
10592 TCGv_i64 fp0 = tcg_temp_new_i64();
10593 TCGv_i64 fp1 = tcg_temp_new_i64();
10594 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10595
10596 gen_load_fpr64(ctx, fp0, fs);
10597 gen_load_fpr64(ctx, fp1, ft);
10598 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10599 gen_helper_float_msub_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10600 tcg_temp_free_i64(fp0);
10601 tcg_temp_free_i64(fp1);
b6d96bed 10602 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10603 tcg_temp_free_i64(fp2);
b6d96bed 10604 }
5a5012ec
TS
10605 break;
10606 case OPC_MSUB_PS:
e29c9628 10607 check_ps(ctx);
b6d96bed 10608 {
a7812ae4
PB
10609 TCGv_i64 fp0 = tcg_temp_new_i64();
10610 TCGv_i64 fp1 = tcg_temp_new_i64();
10611 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10612
10613 gen_load_fpr64(ctx, fp0, fs);
10614 gen_load_fpr64(ctx, fp1, ft);
10615 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10616 gen_helper_float_msub_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10617 tcg_temp_free_i64(fp0);
10618 tcg_temp_free_i64(fp1);
b6d96bed 10619 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10620 tcg_temp_free_i64(fp2);
b6d96bed 10621 }
5a5012ec
TS
10622 break;
10623 case OPC_NMADD_S:
b8aa4598 10624 check_cop1x(ctx);
b6d96bed 10625 {
a7812ae4
PB
10626 TCGv_i32 fp0 = tcg_temp_new_i32();
10627 TCGv_i32 fp1 = tcg_temp_new_i32();
10628 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed 10629
7c979afd
LA
10630 gen_load_fpr32(ctx, fp0, fs);
10631 gen_load_fpr32(ctx, fp1, ft);
10632 gen_load_fpr32(ctx, fp2, fr);
b3d6cd44 10633 gen_helper_float_nmadd_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10634 tcg_temp_free_i32(fp0);
10635 tcg_temp_free_i32(fp1);
7c979afd 10636 gen_store_fpr32(ctx, fp2, fd);
a7812ae4 10637 tcg_temp_free_i32(fp2);
b6d96bed 10638 }
5a5012ec
TS
10639 break;
10640 case OPC_NMADD_D:
b8aa4598
TS
10641 check_cop1x(ctx);
10642 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 10643 {
a7812ae4
PB
10644 TCGv_i64 fp0 = tcg_temp_new_i64();
10645 TCGv_i64 fp1 = tcg_temp_new_i64();
10646 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10647
10648 gen_load_fpr64(ctx, fp0, fs);
10649 gen_load_fpr64(ctx, fp1, ft);
10650 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10651 gen_helper_float_nmadd_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10652 tcg_temp_free_i64(fp0);
10653 tcg_temp_free_i64(fp1);
b6d96bed 10654 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10655 tcg_temp_free_i64(fp2);
b6d96bed 10656 }
5a5012ec
TS
10657 break;
10658 case OPC_NMADD_PS:
e29c9628 10659 check_ps(ctx);
b6d96bed 10660 {
a7812ae4
PB
10661 TCGv_i64 fp0 = tcg_temp_new_i64();
10662 TCGv_i64 fp1 = tcg_temp_new_i64();
10663 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10664
10665 gen_load_fpr64(ctx, fp0, fs);
10666 gen_load_fpr64(ctx, fp1, ft);
10667 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10668 gen_helper_float_nmadd_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10669 tcg_temp_free_i64(fp0);
10670 tcg_temp_free_i64(fp1);
b6d96bed 10671 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10672 tcg_temp_free_i64(fp2);
b6d96bed 10673 }
5a5012ec
TS
10674 break;
10675 case OPC_NMSUB_S:
b8aa4598 10676 check_cop1x(ctx);
b6d96bed 10677 {
a7812ae4
PB
10678 TCGv_i32 fp0 = tcg_temp_new_i32();
10679 TCGv_i32 fp1 = tcg_temp_new_i32();
10680 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed 10681
7c979afd
LA
10682 gen_load_fpr32(ctx, fp0, fs);
10683 gen_load_fpr32(ctx, fp1, ft);
10684 gen_load_fpr32(ctx, fp2, fr);
b3d6cd44 10685 gen_helper_float_nmsub_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10686 tcg_temp_free_i32(fp0);
10687 tcg_temp_free_i32(fp1);
7c979afd 10688 gen_store_fpr32(ctx, fp2, fd);
a7812ae4 10689 tcg_temp_free_i32(fp2);
b6d96bed 10690 }
5a5012ec
TS
10691 break;
10692 case OPC_NMSUB_D:
b8aa4598
TS
10693 check_cop1x(ctx);
10694 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 10695 {
a7812ae4
PB
10696 TCGv_i64 fp0 = tcg_temp_new_i64();
10697 TCGv_i64 fp1 = tcg_temp_new_i64();
10698 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10699
10700 gen_load_fpr64(ctx, fp0, fs);
10701 gen_load_fpr64(ctx, fp1, ft);
10702 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10703 gen_helper_float_nmsub_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10704 tcg_temp_free_i64(fp0);
10705 tcg_temp_free_i64(fp1);
b6d96bed 10706 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10707 tcg_temp_free_i64(fp2);
b6d96bed 10708 }
5a5012ec
TS
10709 break;
10710 case OPC_NMSUB_PS:
e29c9628 10711 check_ps(ctx);
b6d96bed 10712 {
a7812ae4
PB
10713 TCGv_i64 fp0 = tcg_temp_new_i64();
10714 TCGv_i64 fp1 = tcg_temp_new_i64();
10715 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10716
10717 gen_load_fpr64(ctx, fp0, fs);
10718 gen_load_fpr64(ctx, fp1, ft);
10719 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10720 gen_helper_float_nmsub_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10721 tcg_temp_free_i64(fp0);
10722 tcg_temp_free_i64(fp1);
b6d96bed 10723 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10724 tcg_temp_free_i64(fp2);
b6d96bed 10725 }
5a5012ec 10726 break;
923617a3 10727 default:
9d68ac14 10728 MIPS_INVAL("flt3_arith");
9c708c7f 10729 generate_exception_end(ctx, EXCP_RI);
5a5012ec
TS
10730 return;
10731 }
7a387fff
TS
10732}
10733
b00c7218 10734static void gen_rdhwr(DisasContext *ctx, int rt, int rd, int sel)
26ebe468
NF
10735{
10736 TCGv t0;
10737
b3167288
RH
10738#if !defined(CONFIG_USER_ONLY)
10739 /* The Linux kernel will emulate rdhwr if it's not supported natively.
10740 Therefore only check the ISA in system mode. */
d75c135e 10741 check_insn(ctx, ISA_MIPS32R2);
b3167288 10742#endif
26ebe468
NF
10743 t0 = tcg_temp_new();
10744
10745 switch (rd) {
10746 case 0:
895c2d04 10747 gen_helper_rdhwr_cpunum(t0, cpu_env);
26ebe468
NF
10748 gen_store_gpr(t0, rt);
10749 break;
10750 case 1:
895c2d04 10751 gen_helper_rdhwr_synci_step(t0, cpu_env);
26ebe468
NF
10752 gen_store_gpr(t0, rt);
10753 break;
10754 case 2:
eeb3bba8 10755 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
d673a68d
JH
10756 gen_io_start();
10757 }
895c2d04 10758 gen_helper_rdhwr_cc(t0, cpu_env);
eeb3bba8 10759 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
d673a68d
JH
10760 gen_io_end();
10761 }
26ebe468 10762 gen_store_gpr(t0, rt);
d673a68d 10763 /* Break the TB to be able to take timer interrupts immediately
b28425ba 10764 after reading count. DISAS_STOP isn't sufficient, we need to ensure
d673a68d 10765 we break completely out of translated code. */
eeb3bba8
EC
10766 gen_save_pc(ctx->base.pc_next + 4);
10767 ctx->base.is_jmp = DISAS_EXIT;
26ebe468
NF
10768 break;
10769 case 3:
895c2d04 10770 gen_helper_rdhwr_ccres(t0, cpu_env);
26ebe468
NF
10771 gen_store_gpr(t0, rt);
10772 break;
b00c7218
YK
10773 case 4:
10774 check_insn(ctx, ISA_MIPS32R6);
10775 if (sel != 0) {
10776 /* Performance counter registers are not implemented other than
10777 * control register 0.
10778 */
10779 generate_exception(ctx, EXCP_RI);
10780 }
10781 gen_helper_rdhwr_performance(t0, cpu_env);
10782 gen_store_gpr(t0, rt);
10783 break;
10784 case 5:
10785 check_insn(ctx, ISA_MIPS32R6);
10786 gen_helper_rdhwr_xnp(t0, cpu_env);
10787 gen_store_gpr(t0, rt);
10788 break;
26ebe468
NF
10789 case 29:
10790#if defined(CONFIG_USER_ONLY)
d279279e
PJ
10791 tcg_gen_ld_tl(t0, cpu_env,
10792 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
26ebe468
NF
10793 gen_store_gpr(t0, rt);
10794 break;
10795#else
d279279e
PJ
10796 if ((ctx->hflags & MIPS_HFLAG_CP0) ||
10797 (ctx->hflags & MIPS_HFLAG_HWRENA_ULR)) {
10798 tcg_gen_ld_tl(t0, cpu_env,
10799 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
10800 gen_store_gpr(t0, rt);
10801 } else {
9c708c7f 10802 generate_exception_end(ctx, EXCP_RI);
d279279e
PJ
10803 }
10804 break;
26ebe468
NF
10805#endif
10806 default: /* Invalid */
10807 MIPS_INVAL("rdhwr");
9c708c7f 10808 generate_exception_end(ctx, EXCP_RI);
26ebe468
NF
10809 break;
10810 }
10811 tcg_temp_free(t0);
10812}
10813
a5f53390
LA
10814static inline void clear_branch_hflags(DisasContext *ctx)
10815{
10816 ctx->hflags &= ~MIPS_HFLAG_BMASK;
eeb3bba8 10817 if (ctx->base.is_jmp == DISAS_NEXT) {
a5f53390
LA
10818 save_cpu_state(ctx, 0);
10819 } else {
10820 /* it is not safe to save ctx->hflags as hflags may be changed
10821 in execution time by the instruction in delay / forbidden slot. */
10822 tcg_gen_andi_i32(hflags, hflags, ~MIPS_HFLAG_BMASK);
10823 }
10824}
10825
31837be3 10826static void gen_branch(DisasContext *ctx, int insn_bytes)
c9602061
NF
10827{
10828 if (ctx->hflags & MIPS_HFLAG_BMASK) {
364d4831 10829 int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
c9602061 10830 /* Branches completion */
a5f53390 10831 clear_branch_hflags(ctx);
eeb3bba8 10832 ctx->base.is_jmp = DISAS_NORETURN;
c9602061 10833 /* FIXME: Need to clear can_do_io. */
364d4831 10834 switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
339cd2a8 10835 case MIPS_HFLAG_FBNSLOT:
eeb3bba8 10836 gen_goto_tb(ctx, 0, ctx->base.pc_next + insn_bytes);
339cd2a8 10837 break;
c9602061
NF
10838 case MIPS_HFLAG_B:
10839 /* unconditional branch */
364d4831
NF
10840 if (proc_hflags & MIPS_HFLAG_BX) {
10841 tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
10842 }
c9602061
NF
10843 gen_goto_tb(ctx, 0, ctx->btarget);
10844 break;
10845 case MIPS_HFLAG_BL:
10846 /* blikely taken case */
c9602061
NF
10847 gen_goto_tb(ctx, 0, ctx->btarget);
10848 break;
10849 case MIPS_HFLAG_BC:
10850 /* Conditional branch */
c9602061 10851 {
42a268c2 10852 TCGLabel *l1 = gen_new_label();
c9602061
NF
10853
10854 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
eeb3bba8 10855 gen_goto_tb(ctx, 1, ctx->base.pc_next + insn_bytes);
c9602061
NF
10856 gen_set_label(l1);
10857 gen_goto_tb(ctx, 0, ctx->btarget);
10858 }
10859 break;
10860 case MIPS_HFLAG_BR:
10861 /* unconditional branch to register */
d75c135e 10862 if (ctx->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
364d4831
NF
10863 TCGv t0 = tcg_temp_new();
10864 TCGv_i32 t1 = tcg_temp_new_i32();
10865
10866 tcg_gen_andi_tl(t0, btarget, 0x1);
10867 tcg_gen_trunc_tl_i32(t1, t0);
10868 tcg_temp_free(t0);
10869 tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
10870 tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
10871 tcg_gen_or_i32(hflags, hflags, t1);
10872 tcg_temp_free_i32(t1);
10873
10874 tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
10875 } else {
10876 tcg_gen_mov_tl(cpu_PC, btarget);
10877 }
eeb3bba8 10878 if (ctx->base.singlestep_enabled) {
c9602061 10879 save_cpu_state(ctx, 0);
9c708c7f 10880 gen_helper_raise_exception_debug(cpu_env);
c9602061 10881 }
7f11636d 10882 tcg_gen_lookup_and_goto_ptr();
c9602061
NF
10883 break;
10884 default:
a5f53390
LA
10885 fprintf(stderr, "unknown branch 0x%x\n", proc_hflags);
10886 abort();
c9602061
NF
10887 }
10888 }
10889}
10890
6893f074
YK
10891/* Compact Branches */
10892static void gen_compute_compact_branch(DisasContext *ctx, uint32_t opc,
10893 int rs, int rt, int32_t offset)
10894{
10895 int bcond_compute = 0;
10896 TCGv t0 = tcg_temp_new();
10897 TCGv t1 = tcg_temp_new();
65935f07 10898 int m16_lowbit = (ctx->hflags & MIPS_HFLAG_M16) != 0;
6893f074
YK
10899
10900 if (ctx->hflags & MIPS_HFLAG_BMASK) {
10901#ifdef MIPS_DEBUG_DISAS
10902 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
eeb3bba8 10903 "\n", ctx->base.pc_next);
6893f074 10904#endif
9c708c7f 10905 generate_exception_end(ctx, EXCP_RI);
6893f074
YK
10906 goto out;
10907 }
10908
10909 /* Load needed operands and calculate btarget */
10910 switch (opc) {
10911 /* compact branch */
10912 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
10913 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
10914 gen_load_gpr(t0, rs);
10915 gen_load_gpr(t1, rt);
10916 bcond_compute = 1;
eeb3bba8 10917 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
6893f074
YK
10918 if (rs <= rt && rs == 0) {
10919 /* OPC_BEQZALC, OPC_BNEZALC */
eeb3bba8 10920 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
6893f074
YK
10921 }
10922 break;
10923 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
10924 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
10925 gen_load_gpr(t0, rs);
10926 gen_load_gpr(t1, rt);
10927 bcond_compute = 1;
eeb3bba8 10928 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
6893f074
YK
10929 break;
10930 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
10931 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
10932 if (rs == 0 || rs == rt) {
10933 /* OPC_BLEZALC, OPC_BGEZALC */
10934 /* OPC_BGTZALC, OPC_BLTZALC */
eeb3bba8 10935 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
6893f074
YK
10936 }
10937 gen_load_gpr(t0, rs);
10938 gen_load_gpr(t1, rt);
10939 bcond_compute = 1;
eeb3bba8 10940 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
6893f074
YK
10941 break;
10942 case OPC_BC:
10943 case OPC_BALC:
eeb3bba8 10944 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
6893f074
YK
10945 break;
10946 case OPC_BEQZC:
10947 case OPC_BNEZC:
10948 if (rs != 0) {
10949 /* OPC_BEQZC, OPC_BNEZC */
10950 gen_load_gpr(t0, rs);
10951 bcond_compute = 1;
eeb3bba8 10952 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
6893f074
YK
10953 } else {
10954 /* OPC_JIC, OPC_JIALC */
10955 TCGv tbase = tcg_temp_new();
10956 TCGv toffset = tcg_temp_new();
10957
10958 gen_load_gpr(tbase, rt);
10959 tcg_gen_movi_tl(toffset, offset);
10960 gen_op_addr_add(ctx, btarget, tbase, toffset);
10961 tcg_temp_free(tbase);
10962 tcg_temp_free(toffset);
10963 }
10964 break;
10965 default:
10966 MIPS_INVAL("Compact branch/jump");
9c708c7f 10967 generate_exception_end(ctx, EXCP_RI);
6893f074
YK
10968 goto out;
10969 }
10970
10971 if (bcond_compute == 0) {
10972 /* Uncoditional compact branch */
10973 switch (opc) {
10974 case OPC_JIALC:
eeb3bba8 10975 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
6893f074
YK
10976 /* Fallthrough */
10977 case OPC_JIC:
10978 ctx->hflags |= MIPS_HFLAG_BR;
10979 break;
10980 case OPC_BALC:
eeb3bba8 10981 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
6893f074
YK
10982 /* Fallthrough */
10983 case OPC_BC:
10984 ctx->hflags |= MIPS_HFLAG_B;
10985 break;
10986 default:
10987 MIPS_INVAL("Compact branch/jump");
9c708c7f 10988 generate_exception_end(ctx, EXCP_RI);
6893f074
YK
10989 goto out;
10990 }
10991
10992 /* Generating branch here as compact branches don't have delay slot */
10993 gen_branch(ctx, 4);
10994 } else {
10995 /* Conditional compact branch */
10996 TCGLabel *fs = gen_new_label();
10997 save_cpu_state(ctx, 0);
10998
10999 switch (opc) {
11000 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
11001 if (rs == 0 && rt != 0) {
11002 /* OPC_BLEZALC */
11003 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
11004 } else if (rs != 0 && rt != 0 && rs == rt) {
11005 /* OPC_BGEZALC */
11006 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
11007 } else {
11008 /* OPC_BGEUC */
11009 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU), t0, t1, fs);
11010 }
11011 break;
11012 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
11013 if (rs == 0 && rt != 0) {
11014 /* OPC_BGTZALC */
11015 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
11016 } else if (rs != 0 && rt != 0 && rs == rt) {
11017 /* OPC_BLTZALC */
11018 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
11019 } else {
11020 /* OPC_BLTUC */
11021 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU), t0, t1, fs);
11022 }
11023 break;
11024 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
11025 if (rs == 0 && rt != 0) {
11026 /* OPC_BLEZC */
11027 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
11028 } else if (rs != 0 && rt != 0 && rs == rt) {
11029 /* OPC_BGEZC */
11030 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
11031 } else {
11032 /* OPC_BGEC */
11033 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE), t0, t1, fs);
11034 }
11035 break;
11036 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
11037 if (rs == 0 && rt != 0) {
11038 /* OPC_BGTZC */
11039 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
11040 } else if (rs != 0 && rt != 0 && rs == rt) {
11041 /* OPC_BLTZC */
11042 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
11043 } else {
11044 /* OPC_BLTC */
11045 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT), t0, t1, fs);
11046 }
11047 break;
11048 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
11049 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
11050 if (rs >= rt) {
11051 /* OPC_BOVC, OPC_BNVC */
11052 TCGv t2 = tcg_temp_new();
11053 TCGv t3 = tcg_temp_new();
11054 TCGv t4 = tcg_temp_new();
11055 TCGv input_overflow = tcg_temp_new();
11056
11057 gen_load_gpr(t0, rs);
11058 gen_load_gpr(t1, rt);
11059 tcg_gen_ext32s_tl(t2, t0);
11060 tcg_gen_setcond_tl(TCG_COND_NE, input_overflow, t2, t0);
11061 tcg_gen_ext32s_tl(t3, t1);
11062 tcg_gen_setcond_tl(TCG_COND_NE, t4, t3, t1);
11063 tcg_gen_or_tl(input_overflow, input_overflow, t4);
11064
11065 tcg_gen_add_tl(t4, t2, t3);
11066 tcg_gen_ext32s_tl(t4, t4);
11067 tcg_gen_xor_tl(t2, t2, t3);
11068 tcg_gen_xor_tl(t3, t4, t3);
11069 tcg_gen_andc_tl(t2, t3, t2);
11070 tcg_gen_setcondi_tl(TCG_COND_LT, t4, t2, 0);
11071 tcg_gen_or_tl(t4, t4, input_overflow);
11072 if (opc == OPC_BOVC) {
11073 /* OPC_BOVC */
11074 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t4, 0, fs);
11075 } else {
11076 /* OPC_BNVC */
11077 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t4, 0, fs);
11078 }
11079 tcg_temp_free(input_overflow);
11080 tcg_temp_free(t4);
11081 tcg_temp_free(t3);
11082 tcg_temp_free(t2);
11083 } else if (rs < rt && rs == 0) {
11084 /* OPC_BEQZALC, OPC_BNEZALC */
11085 if (opc == OPC_BEQZALC) {
11086 /* OPC_BEQZALC */
11087 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t1, 0, fs);
11088 } else {
11089 /* OPC_BNEZALC */
11090 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t1, 0, fs);
11091 }
11092 } else {
11093 /* OPC_BEQC, OPC_BNEC */
11094 if (opc == OPC_BEQC) {
11095 /* OPC_BEQC */
11096 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_EQ), t0, t1, fs);
11097 } else {
11098 /* OPC_BNEC */
11099 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_NE), t0, t1, fs);
11100 }
11101 }
11102 break;
11103 case OPC_BEQZC:
11104 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t0, 0, fs);
11105 break;
11106 case OPC_BNEZC:
11107 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t0, 0, fs);
11108 break;
11109 default:
11110 MIPS_INVAL("Compact conditional branch/jump");
9c708c7f 11111 generate_exception_end(ctx, EXCP_RI);
6893f074
YK
11112 goto out;
11113 }
11114
11115 /* Generating branch here as compact branches don't have delay slot */
11116 gen_goto_tb(ctx, 1, ctx->btarget);
11117 gen_set_label(fs);
11118
11119 ctx->hflags |= MIPS_HFLAG_FBNSLOT;
6893f074
YK
11120 }
11121
11122out:
11123 tcg_temp_free(t0);
11124 tcg_temp_free(t1);
11125}
11126
7a387fff 11127/* ISA extensions (ASEs) */
6af0bf9c 11128/* MIPS16 extension to MIPS32 */
6ea219d0
NF
11129
11130/* MIPS16 major opcodes */
11131enum {
11132 M16_OPC_ADDIUSP = 0x00,
11133 M16_OPC_ADDIUPC = 0x01,
11134 M16_OPC_B = 0x02,
11135 M16_OPC_JAL = 0x03,
11136 M16_OPC_BEQZ = 0x04,
11137 M16_OPC_BNEQZ = 0x05,
11138 M16_OPC_SHIFT = 0x06,
11139 M16_OPC_LD = 0x07,
11140 M16_OPC_RRIA = 0x08,
11141 M16_OPC_ADDIU8 = 0x09,
11142 M16_OPC_SLTI = 0x0a,
11143 M16_OPC_SLTIU = 0x0b,
11144 M16_OPC_I8 = 0x0c,
11145 M16_OPC_LI = 0x0d,
11146 M16_OPC_CMPI = 0x0e,
11147 M16_OPC_SD = 0x0f,
11148 M16_OPC_LB = 0x10,
11149 M16_OPC_LH = 0x11,
11150 M16_OPC_LWSP = 0x12,
11151 M16_OPC_LW = 0x13,
11152 M16_OPC_LBU = 0x14,
11153 M16_OPC_LHU = 0x15,
11154 M16_OPC_LWPC = 0x16,
11155 M16_OPC_LWU = 0x17,
11156 M16_OPC_SB = 0x18,
11157 M16_OPC_SH = 0x19,
11158 M16_OPC_SWSP = 0x1a,
11159 M16_OPC_SW = 0x1b,
11160 M16_OPC_RRR = 0x1c,
11161 M16_OPC_RR = 0x1d,
11162 M16_OPC_EXTEND = 0x1e,
11163 M16_OPC_I64 = 0x1f
11164};
11165
11166/* I8 funct field */
11167enum {
11168 I8_BTEQZ = 0x0,
11169 I8_BTNEZ = 0x1,
11170 I8_SWRASP = 0x2,
11171 I8_ADJSP = 0x3,
11172 I8_SVRS = 0x4,
11173 I8_MOV32R = 0x5,
11174 I8_MOVR32 = 0x7
11175};
11176
11177/* RRR f field */
11178enum {
11179 RRR_DADDU = 0x0,
11180 RRR_ADDU = 0x1,
11181 RRR_DSUBU = 0x2,
11182 RRR_SUBU = 0x3
11183};
11184
11185/* RR funct field */
11186enum {
11187 RR_JR = 0x00,
11188 RR_SDBBP = 0x01,
11189 RR_SLT = 0x02,
11190 RR_SLTU = 0x03,
11191 RR_SLLV = 0x04,
11192 RR_BREAK = 0x05,
11193 RR_SRLV = 0x06,
11194 RR_SRAV = 0x07,
11195 RR_DSRL = 0x08,
11196 RR_CMP = 0x0a,
11197 RR_NEG = 0x0b,
11198 RR_AND = 0x0c,
11199 RR_OR = 0x0d,
11200 RR_XOR = 0x0e,
11201 RR_NOT = 0x0f,
11202 RR_MFHI = 0x10,
11203 RR_CNVT = 0x11,
11204 RR_MFLO = 0x12,
11205 RR_DSRA = 0x13,
11206 RR_DSLLV = 0x14,
11207 RR_DSRLV = 0x16,
11208 RR_DSRAV = 0x17,
11209 RR_MULT = 0x18,
11210 RR_MULTU = 0x19,
11211 RR_DIV = 0x1a,
11212 RR_DIVU = 0x1b,
11213 RR_DMULT = 0x1c,
11214 RR_DMULTU = 0x1d,
11215 RR_DDIV = 0x1e,
11216 RR_DDIVU = 0x1f
11217};
11218
11219/* I64 funct field */
11220enum {
11221 I64_LDSP = 0x0,
11222 I64_SDSP = 0x1,
11223 I64_SDRASP = 0x2,
11224 I64_DADJSP = 0x3,
11225 I64_LDPC = 0x4,
364d4831 11226 I64_DADDIU5 = 0x5,
6ea219d0
NF
11227 I64_DADDIUPC = 0x6,
11228 I64_DADDIUSP = 0x7
11229};
11230
11231/* RR ry field for CNVT */
11232enum {
11233 RR_RY_CNVT_ZEB = 0x0,
11234 RR_RY_CNVT_ZEH = 0x1,
11235 RR_RY_CNVT_ZEW = 0x2,
11236 RR_RY_CNVT_SEB = 0x4,
11237 RR_RY_CNVT_SEH = 0x5,
11238 RR_RY_CNVT_SEW = 0x6,
11239};
11240
364d4831
NF
11241static int xlat (int r)
11242{
11243 static int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
11244
11245 return map[r];
11246}
11247
11248static void gen_mips16_save (DisasContext *ctx,
11249 int xsregs, int aregs,
11250 int do_ra, int do_s0, int do_s1,
11251 int framesize)
11252{
11253 TCGv t0 = tcg_temp_new();
11254 TCGv t1 = tcg_temp_new();
c48245f0 11255 TCGv t2 = tcg_temp_new();
364d4831
NF
11256 int args, astatic;
11257
11258 switch (aregs) {
11259 case 0:
11260 case 1:
11261 case 2:
11262 case 3:
11263 case 11:
11264 args = 0;
11265 break;
11266 case 4:
11267 case 5:
11268 case 6:
11269 case 7:
11270 args = 1;
11271 break;
11272 case 8:
11273 case 9:
11274 case 10:
11275 args = 2;
11276 break;
11277 case 12:
11278 case 13:
11279 args = 3;
11280 break;
11281 case 14:
11282 args = 4;
11283 break;
11284 default:
9c708c7f 11285 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
11286 return;
11287 }
11288
11289 switch (args) {
11290 case 4:
11291 gen_base_offset_addr(ctx, t0, 29, 12);
11292 gen_load_gpr(t1, 7);
5f68f5ae 11293 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
364d4831
NF
11294 /* Fall through */
11295 case 3:
11296 gen_base_offset_addr(ctx, t0, 29, 8);
11297 gen_load_gpr(t1, 6);
5f68f5ae 11298 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
364d4831
NF
11299 /* Fall through */
11300 case 2:
11301 gen_base_offset_addr(ctx, t0, 29, 4);
11302 gen_load_gpr(t1, 5);
5f68f5ae 11303 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
364d4831
NF
11304 /* Fall through */
11305 case 1:
11306 gen_base_offset_addr(ctx, t0, 29, 0);
11307 gen_load_gpr(t1, 4);
5f68f5ae 11308 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
364d4831
NF
11309 }
11310
11311 gen_load_gpr(t0, 29);
11312
5f68f5ae 11313#define DECR_AND_STORE(reg) do { \
c48245f0
MR
11314 tcg_gen_movi_tl(t2, -4); \
11315 gen_op_addr_add(ctx, t0, t0, t2); \
5f68f5ae
AJ
11316 gen_load_gpr(t1, reg); \
11317 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); \
364d4831
NF
11318 } while (0)
11319
11320 if (do_ra) {
11321 DECR_AND_STORE(31);
11322 }
11323
11324 switch (xsregs) {
11325 case 7:
11326 DECR_AND_STORE(30);
11327 /* Fall through */
11328 case 6:
11329 DECR_AND_STORE(23);
11330 /* Fall through */
11331 case 5:
11332 DECR_AND_STORE(22);
11333 /* Fall through */
11334 case 4:
11335 DECR_AND_STORE(21);
11336 /* Fall through */
11337 case 3:
11338 DECR_AND_STORE(20);
11339 /* Fall through */
11340 case 2:
11341 DECR_AND_STORE(19);
11342 /* Fall through */
11343 case 1:
11344 DECR_AND_STORE(18);
11345 }
11346
11347 if (do_s1) {
11348 DECR_AND_STORE(17);
11349 }
11350 if (do_s0) {
11351 DECR_AND_STORE(16);
11352 }
11353
11354 switch (aregs) {
11355 case 0:
11356 case 4:
11357 case 8:
11358 case 12:
11359 case 14:
11360 astatic = 0;
11361 break;
11362 case 1:
11363 case 5:
11364 case 9:
11365 case 13:
11366 astatic = 1;
11367 break;
11368 case 2:
11369 case 6:
11370 case 10:
11371 astatic = 2;
11372 break;
11373 case 3:
11374 case 7:
11375 astatic = 3;
11376 break;
11377 case 11:
11378 astatic = 4;
11379 break;
11380 default:
9c708c7f 11381 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
11382 return;
11383 }
11384
11385 if (astatic > 0) {
11386 DECR_AND_STORE(7);
11387 if (astatic > 1) {
11388 DECR_AND_STORE(6);
11389 if (astatic > 2) {
11390 DECR_AND_STORE(5);
11391 if (astatic > 3) {
11392 DECR_AND_STORE(4);
11393 }
11394 }
11395 }
11396 }
11397#undef DECR_AND_STORE
11398
c48245f0
MR
11399 tcg_gen_movi_tl(t2, -framesize);
11400 gen_op_addr_add(ctx, cpu_gpr[29], cpu_gpr[29], t2);
364d4831
NF
11401 tcg_temp_free(t0);
11402 tcg_temp_free(t1);
c48245f0 11403 tcg_temp_free(t2);
364d4831
NF
11404}
11405
11406static void gen_mips16_restore (DisasContext *ctx,
11407 int xsregs, int aregs,
11408 int do_ra, int do_s0, int do_s1,
11409 int framesize)
11410{
11411 int astatic;
11412 TCGv t0 = tcg_temp_new();
11413 TCGv t1 = tcg_temp_new();
c48245f0 11414 TCGv t2 = tcg_temp_new();
364d4831 11415
c48245f0
MR
11416 tcg_gen_movi_tl(t2, framesize);
11417 gen_op_addr_add(ctx, t0, cpu_gpr[29], t2);
364d4831 11418
5f68f5ae 11419#define DECR_AND_LOAD(reg) do { \
c48245f0
MR
11420 tcg_gen_movi_tl(t2, -4); \
11421 gen_op_addr_add(ctx, t0, t0, t2); \
5f68f5ae
AJ
11422 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL); \
11423 gen_store_gpr(t1, reg); \
364d4831
NF
11424 } while (0)
11425
11426 if (do_ra) {
11427 DECR_AND_LOAD(31);
11428 }
11429
11430 switch (xsregs) {
11431 case 7:
11432 DECR_AND_LOAD(30);
11433 /* Fall through */
11434 case 6:
11435 DECR_AND_LOAD(23);
11436 /* Fall through */
11437 case 5:
11438 DECR_AND_LOAD(22);
11439 /* Fall through */
11440 case 4:
11441 DECR_AND_LOAD(21);
11442 /* Fall through */
11443 case 3:
11444 DECR_AND_LOAD(20);
11445 /* Fall through */
11446 case 2:
11447 DECR_AND_LOAD(19);
11448 /* Fall through */
11449 case 1:
11450 DECR_AND_LOAD(18);
11451 }
11452
11453 if (do_s1) {
11454 DECR_AND_LOAD(17);
11455 }
11456 if (do_s0) {
11457 DECR_AND_LOAD(16);
11458 }
11459
11460 switch (aregs) {
11461 case 0:
11462 case 4:
11463 case 8:
11464 case 12:
11465 case 14:
11466 astatic = 0;
11467 break;
11468 case 1:
11469 case 5:
11470 case 9:
11471 case 13:
11472 astatic = 1;
11473 break;
11474 case 2:
11475 case 6:
11476 case 10:
11477 astatic = 2;
11478 break;
11479 case 3:
11480 case 7:
11481 astatic = 3;
11482 break;
11483 case 11:
11484 astatic = 4;
11485 break;
11486 default:
9c708c7f 11487 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
11488 return;
11489 }
11490
11491 if (astatic > 0) {
11492 DECR_AND_LOAD(7);
11493 if (astatic > 1) {
11494 DECR_AND_LOAD(6);
11495 if (astatic > 2) {
11496 DECR_AND_LOAD(5);
11497 if (astatic > 3) {
11498 DECR_AND_LOAD(4);
11499 }
11500 }
11501 }
11502 }
11503#undef DECR_AND_LOAD
11504
c48245f0
MR
11505 tcg_gen_movi_tl(t2, framesize);
11506 gen_op_addr_add(ctx, cpu_gpr[29], cpu_gpr[29], t2);
364d4831
NF
11507 tcg_temp_free(t0);
11508 tcg_temp_free(t1);
c48245f0 11509 tcg_temp_free(t2);
364d4831
NF
11510}
11511
11512static void gen_addiupc (DisasContext *ctx, int rx, int imm,
11513 int is_64_bit, int extended)
11514{
11515 TCGv t0;
11516
11517 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9c708c7f 11518 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
11519 return;
11520 }
11521
11522 t0 = tcg_temp_new();
11523
11524 tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
11525 tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
11526 if (!is_64_bit) {
11527 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
11528 }
11529
11530 tcg_temp_free(t0);
11531}
11532
0d74a222
LA
11533static void gen_cache_operation(DisasContext *ctx, uint32_t op, int base,
11534 int16_t offset)
11535{
11536 TCGv_i32 t0 = tcg_const_i32(op);
11537 TCGv t1 = tcg_temp_new();
11538 gen_base_offset_addr(ctx, t1, base, offset);
11539 gen_helper_cache(cpu_env, t1, t0);
11540}
11541
364d4831 11542#if defined(TARGET_MIPS64)
d75c135e 11543static void decode_i64_mips16 (DisasContext *ctx,
364d4831
NF
11544 int ry, int funct, int16_t offset,
11545 int extended)
11546{
11547 switch (funct) {
11548 case I64_LDSP:
d9224450 11549 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11550 check_mips_64(ctx);
11551 offset = extended ? offset : offset << 3;
d75c135e 11552 gen_ld(ctx, OPC_LD, ry, 29, offset);
364d4831
NF
11553 break;
11554 case I64_SDSP:
d9224450 11555 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11556 check_mips_64(ctx);
11557 offset = extended ? offset : offset << 3;
5c13fdfd 11558 gen_st(ctx, OPC_SD, ry, 29, offset);
364d4831
NF
11559 break;
11560 case I64_SDRASP:
d9224450 11561 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11562 check_mips_64(ctx);
11563 offset = extended ? offset : (ctx->opcode & 0xff) << 3;
5c13fdfd 11564 gen_st(ctx, OPC_SD, 31, 29, offset);
364d4831
NF
11565 break;
11566 case I64_DADJSP:
d9224450 11567 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11568 check_mips_64(ctx);
11569 offset = extended ? offset : ((int8_t)ctx->opcode) << 3;
d75c135e 11570 gen_arith_imm(ctx, OPC_DADDIU, 29, 29, offset);
364d4831
NF
11571 break;
11572 case I64_LDPC:
d9224450
MR
11573 check_insn(ctx, ISA_MIPS3);
11574 check_mips_64(ctx);
364d4831 11575 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9c708c7f 11576 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
11577 } else {
11578 offset = extended ? offset : offset << 3;
d75c135e 11579 gen_ld(ctx, OPC_LDPC, ry, 0, offset);
364d4831
NF
11580 }
11581 break;
11582 case I64_DADDIU5:
d9224450 11583 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11584 check_mips_64(ctx);
11585 offset = extended ? offset : ((int8_t)(offset << 3)) >> 3;
d75c135e 11586 gen_arith_imm(ctx, OPC_DADDIU, ry, ry, offset);
364d4831
NF
11587 break;
11588 case I64_DADDIUPC:
d9224450 11589 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11590 check_mips_64(ctx);
11591 offset = extended ? offset : offset << 2;
11592 gen_addiupc(ctx, ry, offset, 1, extended);
11593 break;
11594 case I64_DADDIUSP:
d9224450 11595 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11596 check_mips_64(ctx);
11597 offset = extended ? offset : offset << 2;
d75c135e 11598 gen_arith_imm(ctx, OPC_DADDIU, ry, 29, offset);
364d4831
NF
11599 break;
11600 }
11601}
11602#endif
11603
240ce26a 11604static int decode_extended_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
364d4831 11605{
eeb3bba8 11606 int extend = cpu_lduw_code(env, ctx->base.pc_next + 2);
364d4831
NF
11607 int op, rx, ry, funct, sa;
11608 int16_t imm, offset;
11609
11610 ctx->opcode = (ctx->opcode << 16) | extend;
11611 op = (ctx->opcode >> 11) & 0x1f;
11612 sa = (ctx->opcode >> 22) & 0x1f;
11613 funct = (ctx->opcode >> 8) & 0x7;
11614 rx = xlat((ctx->opcode >> 8) & 0x7);
11615 ry = xlat((ctx->opcode >> 5) & 0x7);
11616 offset = imm = (int16_t) (((ctx->opcode >> 16) & 0x1f) << 11
11617 | ((ctx->opcode >> 21) & 0x3f) << 5
11618 | (ctx->opcode & 0x1f));
11619
11620 /* The extended opcodes cleverly reuse the opcodes from their 16-bit
11621 counterparts. */
11622 switch (op) {
11623 case M16_OPC_ADDIUSP:
d75c135e 11624 gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
364d4831
NF
11625 break;
11626 case M16_OPC_ADDIUPC:
11627 gen_addiupc(ctx, rx, imm, 0, 1);
11628 break;
11629 case M16_OPC_B:
b231c103 11630 gen_compute_branch(ctx, OPC_BEQ, 4, 0, 0, offset << 1, 0);
364d4831
NF
11631 /* No delay slot, so just process as a normal instruction */
11632 break;
11633 case M16_OPC_BEQZ:
b231c103 11634 gen_compute_branch(ctx, OPC_BEQ, 4, rx, 0, offset << 1, 0);
364d4831
NF
11635 /* No delay slot, so just process as a normal instruction */
11636 break;
11637 case M16_OPC_BNEQZ:
b231c103 11638 gen_compute_branch(ctx, OPC_BNE, 4, rx, 0, offset << 1, 0);
364d4831
NF
11639 /* No delay slot, so just process as a normal instruction */
11640 break;
11641 case M16_OPC_SHIFT:
11642 switch (ctx->opcode & 0x3) {
11643 case 0x0:
d75c135e 11644 gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
364d4831
NF
11645 break;
11646 case 0x1:
11647#if defined(TARGET_MIPS64)
11648 check_mips_64(ctx);
d75c135e 11649 gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
364d4831 11650#else
9c708c7f 11651 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
11652#endif
11653 break;
11654 case 0x2:
d75c135e 11655 gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
364d4831
NF
11656 break;
11657 case 0x3:
d75c135e 11658 gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
364d4831
NF
11659 break;
11660 }
11661 break;
11662#if defined(TARGET_MIPS64)
11663 case M16_OPC_LD:
d9224450 11664 check_insn(ctx, ISA_MIPS3);
d75de749 11665 check_mips_64(ctx);
d75c135e 11666 gen_ld(ctx, OPC_LD, ry, rx, offset);
364d4831
NF
11667 break;
11668#endif
11669 case M16_OPC_RRIA:
11670 imm = ctx->opcode & 0xf;
11671 imm = imm | ((ctx->opcode >> 20) & 0x7f) << 4;
11672 imm = imm | ((ctx->opcode >> 16) & 0xf) << 11;
11673 imm = (int16_t) (imm << 1) >> 1;
11674 if ((ctx->opcode >> 4) & 0x1) {
11675#if defined(TARGET_MIPS64)
11676 check_mips_64(ctx);
d75c135e 11677 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
364d4831 11678#else
9c708c7f 11679 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
11680#endif
11681 } else {
d75c135e 11682 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
364d4831
NF
11683 }
11684 break;
11685 case M16_OPC_ADDIU8:
d75c135e 11686 gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
364d4831
NF
11687 break;
11688 case M16_OPC_SLTI:
d75c135e 11689 gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
364d4831
NF
11690 break;
11691 case M16_OPC_SLTIU:
d75c135e 11692 gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
364d4831
NF
11693 break;
11694 case M16_OPC_I8:
11695 switch (funct) {
11696 case I8_BTEQZ:
b231c103 11697 gen_compute_branch(ctx, OPC_BEQ, 4, 24, 0, offset << 1, 0);
364d4831
NF
11698 break;
11699 case I8_BTNEZ:
b231c103 11700 gen_compute_branch(ctx, OPC_BNE, 4, 24, 0, offset << 1, 0);
364d4831
NF
11701 break;
11702 case I8_SWRASP:
5c13fdfd 11703 gen_st(ctx, OPC_SW, 31, 29, imm);
364d4831
NF
11704 break;
11705 case I8_ADJSP:
d75c135e 11706 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm);
364d4831
NF
11707 break;
11708 case I8_SVRS:
d9224450 11709 check_insn(ctx, ISA_MIPS32);
364d4831
NF
11710 {
11711 int xsregs = (ctx->opcode >> 24) & 0x7;
11712 int aregs = (ctx->opcode >> 16) & 0xf;
11713 int do_ra = (ctx->opcode >> 6) & 0x1;
11714 int do_s0 = (ctx->opcode >> 5) & 0x1;
11715 int do_s1 = (ctx->opcode >> 4) & 0x1;
11716 int framesize = (((ctx->opcode >> 20) & 0xf) << 4
11717 | (ctx->opcode & 0xf)) << 3;
11718
11719 if (ctx->opcode & (1 << 7)) {
11720 gen_mips16_save(ctx, xsregs, aregs,
11721 do_ra, do_s0, do_s1,
11722 framesize);
11723 } else {
11724 gen_mips16_restore(ctx, xsregs, aregs,
11725 do_ra, do_s0, do_s1,
11726 framesize);
11727 }
11728 }
11729 break;
11730 default:
9c708c7f 11731 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
11732 break;
11733 }
11734 break;
11735 case M16_OPC_LI:
11736 tcg_gen_movi_tl(cpu_gpr[rx], (uint16_t) imm);
11737 break;
11738 case M16_OPC_CMPI:
11739 tcg_gen_xori_tl(cpu_gpr[24], cpu_gpr[rx], (uint16_t) imm);
11740 break;
11741#if defined(TARGET_MIPS64)
11742 case M16_OPC_SD:
d9224450
MR
11743 check_insn(ctx, ISA_MIPS3);
11744 check_mips_64(ctx);
5c13fdfd 11745 gen_st(ctx, OPC_SD, ry, rx, offset);
364d4831
NF
11746 break;
11747#endif
11748 case M16_OPC_LB:
d75c135e 11749 gen_ld(ctx, OPC_LB, ry, rx, offset);
364d4831
NF
11750 break;
11751 case M16_OPC_LH:
d75c135e 11752 gen_ld(ctx, OPC_LH, ry, rx, offset);
364d4831
NF
11753 break;
11754 case M16_OPC_LWSP:
d75c135e 11755 gen_ld(ctx, OPC_LW, rx, 29, offset);
364d4831
NF
11756 break;
11757 case M16_OPC_LW:
d75c135e 11758 gen_ld(ctx, OPC_LW, ry, rx, offset);
364d4831
NF
11759 break;
11760 case M16_OPC_LBU:
d75c135e 11761 gen_ld(ctx, OPC_LBU, ry, rx, offset);
364d4831
NF
11762 break;
11763 case M16_OPC_LHU:
d75c135e 11764 gen_ld(ctx, OPC_LHU, ry, rx, offset);
364d4831
NF
11765 break;
11766 case M16_OPC_LWPC:
d75c135e 11767 gen_ld(ctx, OPC_LWPC, rx, 0, offset);
364d4831
NF
11768 break;
11769#if defined(TARGET_MIPS64)
11770 case M16_OPC_LWU:
d9224450
MR
11771 check_insn(ctx, ISA_MIPS3);
11772 check_mips_64(ctx);
d75c135e 11773 gen_ld(ctx, OPC_LWU, ry, rx, offset);
364d4831
NF
11774 break;
11775#endif
11776 case M16_OPC_SB:
5c13fdfd 11777 gen_st(ctx, OPC_SB, ry, rx, offset);
364d4831
NF
11778 break;
11779 case M16_OPC_SH:
5c13fdfd 11780 gen_st(ctx, OPC_SH, ry, rx, offset);
364d4831
NF
11781 break;
11782 case M16_OPC_SWSP:
5c13fdfd 11783 gen_st(ctx, OPC_SW, rx, 29, offset);
364d4831
NF
11784 break;
11785 case M16_OPC_SW:
5c13fdfd 11786 gen_st(ctx, OPC_SW, ry, rx, offset);
364d4831
NF
11787 break;
11788#if defined(TARGET_MIPS64)
11789 case M16_OPC_I64:
d75c135e 11790 decode_i64_mips16(ctx, ry, funct, offset, 1);
364d4831
NF
11791 break;
11792#endif
11793 default:
9c708c7f 11794 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
11795 break;
11796 }
11797
11798 return 4;
11799}
11800
3b3c1694
LA
11801static inline bool is_uhi(int sdbbp_code)
11802{
11803#ifdef CONFIG_USER_ONLY
11804 return false;
11805#else
11806 return semihosting_enabled() && sdbbp_code == 1;
11807#endif
11808}
11809
240ce26a 11810static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
364d4831
NF
11811{
11812 int rx, ry;
11813 int sa;
11814 int op, cnvt_op, op1, offset;
11815 int funct;
11816 int n_bytes;
11817
11818 op = (ctx->opcode >> 11) & 0x1f;
11819 sa = (ctx->opcode >> 2) & 0x7;
11820 sa = sa == 0 ? 8 : sa;
11821 rx = xlat((ctx->opcode >> 8) & 0x7);
11822 cnvt_op = (ctx->opcode >> 5) & 0x7;
11823 ry = xlat((ctx->opcode >> 5) & 0x7);
11824 op1 = offset = ctx->opcode & 0x1f;
11825
11826 n_bytes = 2;
11827
11828 switch (op) {
11829 case M16_OPC_ADDIUSP:
11830 {
11831 int16_t imm = ((uint8_t) ctx->opcode) << 2;
11832
d75c135e 11833 gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
364d4831
NF
11834 }
11835 break;
11836 case M16_OPC_ADDIUPC:
11837 gen_addiupc(ctx, rx, ((uint8_t) ctx->opcode) << 2, 0, 0);
11838 break;
11839 case M16_OPC_B:
11840 offset = (ctx->opcode & 0x7ff) << 1;
11841 offset = (int16_t)(offset << 4) >> 4;
b231c103 11842 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, offset, 0);
364d4831
NF
11843 /* No delay slot, so just process as a normal instruction */
11844 break;
11845 case M16_OPC_JAL:
eeb3bba8 11846 offset = cpu_lduw_code(env, ctx->base.pc_next + 2);
364d4831
NF
11847 offset = (((ctx->opcode & 0x1f) << 21)
11848 | ((ctx->opcode >> 5) & 0x1f) << 16
11849 | offset) << 2;
b231c103
YK
11850 op = ((ctx->opcode >> 10) & 0x1) ? OPC_JALX : OPC_JAL;
11851 gen_compute_branch(ctx, op, 4, rx, ry, offset, 2);
364d4831 11852 n_bytes = 4;
364d4831
NF
11853 break;
11854 case M16_OPC_BEQZ:
b231c103
YK
11855 gen_compute_branch(ctx, OPC_BEQ, 2, rx, 0,
11856 ((int8_t)ctx->opcode) << 1, 0);
364d4831
NF
11857 /* No delay slot, so just process as a normal instruction */
11858 break;
11859 case M16_OPC_BNEQZ:
b231c103
YK
11860 gen_compute_branch(ctx, OPC_BNE, 2, rx, 0,
11861 ((int8_t)ctx->opcode) << 1, 0);
364d4831
NF
11862 /* No delay slot, so just process as a normal instruction */
11863 break;
11864 case M16_OPC_SHIFT:
11865 switch (ctx->opcode & 0x3) {
11866 case 0x0:
d75c135e 11867 gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
364d4831
NF
11868 break;
11869 case 0x1:
11870#if defined(TARGET_MIPS64)
d9224450 11871 check_insn(ctx, ISA_MIPS3);
364d4831 11872 check_mips_64(ctx);
d75c135e 11873 gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
364d4831 11874#else
9c708c7f 11875 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
11876#endif
11877 break;
11878 case 0x2:
d75c135e 11879 gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
364d4831
NF
11880 break;
11881 case 0x3:
d75c135e 11882 gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
364d4831
NF
11883 break;
11884 }
11885 break;
11886#if defined(TARGET_MIPS64)
11887 case M16_OPC_LD:
d9224450 11888 check_insn(ctx, ISA_MIPS3);
364d4831 11889 check_mips_64(ctx);
d75c135e 11890 gen_ld(ctx, OPC_LD, ry, rx, offset << 3);
364d4831
NF
11891 break;
11892#endif
11893 case M16_OPC_RRIA:
11894 {
11895 int16_t imm = (int8_t)((ctx->opcode & 0xf) << 4) >> 4;
11896
11897 if ((ctx->opcode >> 4) & 1) {
11898#if defined(TARGET_MIPS64)
d9224450 11899 check_insn(ctx, ISA_MIPS3);
364d4831 11900 check_mips_64(ctx);
d75c135e 11901 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
364d4831 11902#else
9c708c7f 11903 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
11904#endif
11905 } else {
d75c135e 11906 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
364d4831
NF
11907 }
11908 }
11909 break;
11910 case M16_OPC_ADDIU8:
11911 {
11912 int16_t imm = (int8_t) ctx->opcode;
11913
d75c135e 11914 gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
364d4831
NF
11915 }
11916 break;
11917 case M16_OPC_SLTI:
11918 {
11919 int16_t imm = (uint8_t) ctx->opcode;
d75c135e 11920 gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
364d4831
NF
11921 }
11922 break;
11923 case M16_OPC_SLTIU:
11924 {
11925 int16_t imm = (uint8_t) ctx->opcode;
d75c135e 11926 gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
364d4831
NF
11927 }
11928 break;
11929 case M16_OPC_I8:
11930 {
11931 int reg32;
11932
11933 funct = (ctx->opcode >> 8) & 0x7;
11934 switch (funct) {
11935 case I8_BTEQZ:
11936 gen_compute_branch(ctx, OPC_BEQ, 2, 24, 0,
b231c103 11937 ((int8_t)ctx->opcode) << 1, 0);
364d4831
NF
11938 break;
11939 case I8_BTNEZ:
11940 gen_compute_branch(ctx, OPC_BNE, 2, 24, 0,
b231c103 11941 ((int8_t)ctx->opcode) << 1, 0);
364d4831
NF
11942 break;
11943 case I8_SWRASP:
5c13fdfd 11944 gen_st(ctx, OPC_SW, 31, 29, (ctx->opcode & 0xff) << 2);
364d4831
NF
11945 break;
11946 case I8_ADJSP:
d75c135e 11947 gen_arith_imm(ctx, OPC_ADDIU, 29, 29,
364d4831
NF
11948 ((int8_t)ctx->opcode) << 3);
11949 break;
11950 case I8_SVRS:
d9224450 11951 check_insn(ctx, ISA_MIPS32);
364d4831
NF
11952 {
11953 int do_ra = ctx->opcode & (1 << 6);
11954 int do_s0 = ctx->opcode & (1 << 5);
11955 int do_s1 = ctx->opcode & (1 << 4);
11956 int framesize = ctx->opcode & 0xf;
11957
11958 if (framesize == 0) {
11959 framesize = 128;
11960 } else {
11961 framesize = framesize << 3;
11962 }
11963
11964 if (ctx->opcode & (1 << 7)) {
11965 gen_mips16_save(ctx, 0, 0,
11966 do_ra, do_s0, do_s1, framesize);
11967 } else {
11968 gen_mips16_restore(ctx, 0, 0,
11969 do_ra, do_s0, do_s1, framesize);
11970 }
11971 }
11972 break;
11973 case I8_MOV32R:
11974 {
11975 int rz = xlat(ctx->opcode & 0x7);
11976
11977 reg32 = (((ctx->opcode >> 3) & 0x3) << 3) |
11978 ((ctx->opcode >> 5) & 0x7);
d75c135e 11979 gen_arith(ctx, OPC_ADDU, reg32, rz, 0);
364d4831
NF
11980 }
11981 break;
11982 case I8_MOVR32:
11983 reg32 = ctx->opcode & 0x1f;
d75c135e 11984 gen_arith(ctx, OPC_ADDU, ry, reg32, 0);
364d4831
NF
11985 break;
11986 default:
9c708c7f 11987 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
11988 break;
11989 }
11990 }
11991 break;
11992 case M16_OPC_LI:
11993 {
11994 int16_t imm = (uint8_t) ctx->opcode;
11995
d75c135e 11996 gen_arith_imm(ctx, OPC_ADDIU, rx, 0, imm);
364d4831
NF
11997 }
11998 break;
11999 case M16_OPC_CMPI:
12000 {
12001 int16_t imm = (uint8_t) ctx->opcode;
d75c135e 12002 gen_logic_imm(ctx, OPC_XORI, 24, rx, imm);
364d4831
NF
12003 }
12004 break;
12005#if defined(TARGET_MIPS64)
12006 case M16_OPC_SD:
d9224450 12007 check_insn(ctx, ISA_MIPS3);
364d4831 12008 check_mips_64(ctx);
5c13fdfd 12009 gen_st(ctx, OPC_SD, ry, rx, offset << 3);
364d4831
NF
12010 break;
12011#endif
12012 case M16_OPC_LB:
d75c135e 12013 gen_ld(ctx, OPC_LB, ry, rx, offset);
364d4831
NF
12014 break;
12015 case M16_OPC_LH:
d75c135e 12016 gen_ld(ctx, OPC_LH, ry, rx, offset << 1);
364d4831
NF
12017 break;
12018 case M16_OPC_LWSP:
d75c135e 12019 gen_ld(ctx, OPC_LW, rx, 29, ((uint8_t)ctx->opcode) << 2);
364d4831
NF
12020 break;
12021 case M16_OPC_LW:
d75c135e 12022 gen_ld(ctx, OPC_LW, ry, rx, offset << 2);
364d4831
NF
12023 break;
12024 case M16_OPC_LBU:
d75c135e 12025 gen_ld(ctx, OPC_LBU, ry, rx, offset);
364d4831
NF
12026 break;
12027 case M16_OPC_LHU:
d75c135e 12028 gen_ld(ctx, OPC_LHU, ry, rx, offset << 1);
364d4831
NF
12029 break;
12030 case M16_OPC_LWPC:
d75c135e 12031 gen_ld(ctx, OPC_LWPC, rx, 0, ((uint8_t)ctx->opcode) << 2);
364d4831
NF
12032 break;
12033#if defined (TARGET_MIPS64)
12034 case M16_OPC_LWU:
d9224450 12035 check_insn(ctx, ISA_MIPS3);
364d4831 12036 check_mips_64(ctx);
d75c135e 12037 gen_ld(ctx, OPC_LWU, ry, rx, offset << 2);
364d4831
NF
12038 break;
12039#endif
12040 case M16_OPC_SB:
5c13fdfd 12041 gen_st(ctx, OPC_SB, ry, rx, offset);
364d4831
NF
12042 break;
12043 case M16_OPC_SH:
5c13fdfd 12044 gen_st(ctx, OPC_SH, ry, rx, offset << 1);
364d4831
NF
12045 break;
12046 case M16_OPC_SWSP:
5c13fdfd 12047 gen_st(ctx, OPC_SW, rx, 29, ((uint8_t)ctx->opcode) << 2);
364d4831
NF
12048 break;
12049 case M16_OPC_SW:
5c13fdfd 12050 gen_st(ctx, OPC_SW, ry, rx, offset << 2);
364d4831
NF
12051 break;
12052 case M16_OPC_RRR:
12053 {
12054 int rz = xlat((ctx->opcode >> 2) & 0x7);
12055 int mips32_op;
12056
12057 switch (ctx->opcode & 0x3) {
12058 case RRR_ADDU:
12059 mips32_op = OPC_ADDU;
12060 break;
12061 case RRR_SUBU:
12062 mips32_op = OPC_SUBU;
12063 break;
12064#if defined(TARGET_MIPS64)
12065 case RRR_DADDU:
12066 mips32_op = OPC_DADDU;
d9224450 12067 check_insn(ctx, ISA_MIPS3);
364d4831
NF
12068 check_mips_64(ctx);
12069 break;
12070 case RRR_DSUBU:
12071 mips32_op = OPC_DSUBU;
d9224450 12072 check_insn(ctx, ISA_MIPS3);
364d4831
NF
12073 check_mips_64(ctx);
12074 break;
12075#endif
12076 default:
9c708c7f 12077 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
12078 goto done;
12079 }
12080
d75c135e 12081 gen_arith(ctx, mips32_op, rz, rx, ry);
364d4831
NF
12082 done:
12083 ;
12084 }
12085 break;
12086 case M16_OPC_RR:
12087 switch (op1) {
12088 case RR_JR:
12089 {
12090 int nd = (ctx->opcode >> 7) & 0x1;
12091 int link = (ctx->opcode >> 6) & 0x1;
12092 int ra = (ctx->opcode >> 5) & 0x1;
12093
d9224450
MR
12094 if (nd) {
12095 check_insn(ctx, ISA_MIPS32);
12096 }
12097
364d4831 12098 if (link) {
b231c103 12099 op = OPC_JALR;
364d4831
NF
12100 } else {
12101 op = OPC_JR;
12102 }
12103
b231c103
YK
12104 gen_compute_branch(ctx, op, 2, ra ? 31 : rx, 31, 0,
12105 (nd ? 0 : 2));
364d4831
NF
12106 }
12107 break;
12108 case RR_SDBBP:
3b3c1694
LA
12109 if (is_uhi(extract32(ctx->opcode, 5, 6))) {
12110 gen_helper_do_semihosting(cpu_env);
12111 } else {
12112 /* XXX: not clear which exception should be raised
12113 * when in debug mode...
12114 */
12115 check_insn(ctx, ISA_MIPS32);
9c708c7f 12116 generate_exception_end(ctx, EXCP_DBp);
3b3c1694 12117 }
364d4831
NF
12118 break;
12119 case RR_SLT:
d75c135e 12120 gen_slt(ctx, OPC_SLT, 24, rx, ry);
364d4831
NF
12121 break;
12122 case RR_SLTU:
d75c135e 12123 gen_slt(ctx, OPC_SLTU, 24, rx, ry);
364d4831
NF
12124 break;
12125 case RR_BREAK:
9c708c7f 12126 generate_exception_end(ctx, EXCP_BREAK);
364d4831
NF
12127 break;
12128 case RR_SLLV:
d75c135e 12129 gen_shift(ctx, OPC_SLLV, ry, rx, ry);
364d4831
NF
12130 break;
12131 case RR_SRLV:
d75c135e 12132 gen_shift(ctx, OPC_SRLV, ry, rx, ry);
364d4831
NF
12133 break;
12134 case RR_SRAV:
d75c135e 12135 gen_shift(ctx, OPC_SRAV, ry, rx, ry);
364d4831
NF
12136 break;
12137#if defined (TARGET_MIPS64)
12138 case RR_DSRL:
d9224450 12139 check_insn(ctx, ISA_MIPS3);
364d4831 12140 check_mips_64(ctx);
d75c135e 12141 gen_shift_imm(ctx, OPC_DSRL, ry, ry, sa);
364d4831
NF
12142 break;
12143#endif
12144 case RR_CMP:
d75c135e 12145 gen_logic(ctx, OPC_XOR, 24, rx, ry);
364d4831
NF
12146 break;
12147 case RR_NEG:
d75c135e 12148 gen_arith(ctx, OPC_SUBU, rx, 0, ry);
364d4831
NF
12149 break;
12150 case RR_AND:
d75c135e 12151 gen_logic(ctx, OPC_AND, rx, rx, ry);
364d4831
NF
12152 break;
12153 case RR_OR:
d75c135e 12154 gen_logic(ctx, OPC_OR, rx, rx, ry);
364d4831
NF
12155 break;
12156 case RR_XOR:
d75c135e 12157 gen_logic(ctx, OPC_XOR, rx, rx, ry);
364d4831
NF
12158 break;
12159 case RR_NOT:
d75c135e 12160 gen_logic(ctx, OPC_NOR, rx, ry, 0);
364d4831
NF
12161 break;
12162 case RR_MFHI:
26135ead 12163 gen_HILO(ctx, OPC_MFHI, 0, rx);
364d4831
NF
12164 break;
12165 case RR_CNVT:
d9224450 12166 check_insn(ctx, ISA_MIPS32);
364d4831
NF
12167 switch (cnvt_op) {
12168 case RR_RY_CNVT_ZEB:
12169 tcg_gen_ext8u_tl(cpu_gpr[rx], cpu_gpr[rx]);
12170 break;
12171 case RR_RY_CNVT_ZEH:
12172 tcg_gen_ext16u_tl(cpu_gpr[rx], cpu_gpr[rx]);
12173 break;
12174 case RR_RY_CNVT_SEB:
12175 tcg_gen_ext8s_tl(cpu_gpr[rx], cpu_gpr[rx]);
12176 break;
12177 case RR_RY_CNVT_SEH:
12178 tcg_gen_ext16s_tl(cpu_gpr[rx], cpu_gpr[rx]);
12179 break;
12180#if defined (TARGET_MIPS64)
12181 case RR_RY_CNVT_ZEW:
d9224450 12182 check_insn(ctx, ISA_MIPS64);
364d4831
NF
12183 check_mips_64(ctx);
12184 tcg_gen_ext32u_tl(cpu_gpr[rx], cpu_gpr[rx]);
12185 break;
12186 case RR_RY_CNVT_SEW:
d9224450 12187 check_insn(ctx, ISA_MIPS64);
364d4831
NF
12188 check_mips_64(ctx);
12189 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
12190 break;
12191#endif
12192 default:
9c708c7f 12193 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
12194 break;
12195 }
12196 break;
12197 case RR_MFLO:
26135ead 12198 gen_HILO(ctx, OPC_MFLO, 0, rx);
364d4831
NF
12199 break;
12200#if defined (TARGET_MIPS64)
12201 case RR_DSRA:
d9224450 12202 check_insn(ctx, ISA_MIPS3);
364d4831 12203 check_mips_64(ctx);
d75c135e 12204 gen_shift_imm(ctx, OPC_DSRA, ry, ry, sa);
364d4831
NF
12205 break;
12206 case RR_DSLLV:
d9224450 12207 check_insn(ctx, ISA_MIPS3);
364d4831 12208 check_mips_64(ctx);
d75c135e 12209 gen_shift(ctx, OPC_DSLLV, ry, rx, ry);
364d4831
NF
12210 break;
12211 case RR_DSRLV:
d9224450 12212 check_insn(ctx, ISA_MIPS3);
364d4831 12213 check_mips_64(ctx);
d75c135e 12214 gen_shift(ctx, OPC_DSRLV, ry, rx, ry);
364d4831
NF
12215 break;
12216 case RR_DSRAV:
d9224450 12217 check_insn(ctx, ISA_MIPS3);
364d4831 12218 check_mips_64(ctx);
d75c135e 12219 gen_shift(ctx, OPC_DSRAV, ry, rx, ry);
364d4831
NF
12220 break;
12221#endif
12222 case RR_MULT:
26135ead 12223 gen_muldiv(ctx, OPC_MULT, 0, rx, ry);
364d4831
NF
12224 break;
12225 case RR_MULTU:
26135ead 12226 gen_muldiv(ctx, OPC_MULTU, 0, rx, ry);
364d4831
NF
12227 break;
12228 case RR_DIV:
26135ead 12229 gen_muldiv(ctx, OPC_DIV, 0, rx, ry);
364d4831
NF
12230 break;
12231 case RR_DIVU:
26135ead 12232 gen_muldiv(ctx, OPC_DIVU, 0, rx, ry);
364d4831
NF
12233 break;
12234#if defined (TARGET_MIPS64)
12235 case RR_DMULT:
d9224450 12236 check_insn(ctx, ISA_MIPS3);
364d4831 12237 check_mips_64(ctx);
26135ead 12238 gen_muldiv(ctx, OPC_DMULT, 0, rx, ry);
364d4831
NF
12239 break;
12240 case RR_DMULTU:
d9224450 12241 check_insn(ctx, ISA_MIPS3);
364d4831 12242 check_mips_64(ctx);
26135ead 12243 gen_muldiv(ctx, OPC_DMULTU, 0, rx, ry);
364d4831
NF
12244 break;
12245 case RR_DDIV:
d9224450 12246 check_insn(ctx, ISA_MIPS3);
364d4831 12247 check_mips_64(ctx);
26135ead 12248 gen_muldiv(ctx, OPC_DDIV, 0, rx, ry);
364d4831
NF
12249 break;
12250 case RR_DDIVU:
d9224450 12251 check_insn(ctx, ISA_MIPS3);
364d4831 12252 check_mips_64(ctx);
26135ead 12253 gen_muldiv(ctx, OPC_DDIVU, 0, rx, ry);
364d4831
NF
12254 break;
12255#endif
12256 default:
9c708c7f 12257 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
12258 break;
12259 }
12260 break;
12261 case M16_OPC_EXTEND:
240ce26a 12262 decode_extended_mips16_opc(env, ctx);
364d4831
NF
12263 n_bytes = 4;
12264 break;
12265#if defined(TARGET_MIPS64)
12266 case M16_OPC_I64:
12267 funct = (ctx->opcode >> 8) & 0x7;
d75c135e 12268 decode_i64_mips16(ctx, ry, funct, offset, 0);
364d4831
NF
12269 break;
12270#endif
12271 default:
9c708c7f 12272 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
12273 break;
12274 }
12275
12276 return n_bytes;
12277}
12278
211da992 12279/* microMIPS extension to MIPS32/MIPS64 */
6af0bf9c 12280
211da992
CWR
12281/*
12282 * microMIPS32/microMIPS64 major opcodes
12283 *
12284 * 1. MIPS Architecture for Programmers Volume II-B:
12285 * The microMIPS32 Instruction Set (Revision 3.05)
12286 *
12287 * Table 6.2 microMIPS32 Encoding of Major Opcode Field
12288 *
12289 * 2. MIPS Architecture For Programmers Volume II-A:
12290 * The MIPS64 Instruction Set (Revision 3.51)
12291 */
6af0bf9c 12292
3c824109
NF
12293enum {
12294 POOL32A = 0x00,
12295 POOL16A = 0x01,
12296 LBU16 = 0x02,
12297 MOVE16 = 0x03,
12298 ADDI32 = 0x04,
3a1f4268
YK
12299 R6_LUI = 0x04,
12300 AUI = 0x04,
3c824109
NF
12301 LBU32 = 0x05,
12302 SB32 = 0x06,
12303 LB32 = 0x07,
12304
12305 POOL32B = 0x08,
12306 POOL16B = 0x09,
12307 LHU16 = 0x0a,
12308 ANDI16 = 0x0b,
12309 ADDIU32 = 0x0c,
12310 LHU32 = 0x0d,
12311 SH32 = 0x0e,
12312 LH32 = 0x0f,
12313
12314 POOL32I = 0x10,
12315 POOL16C = 0x11,
12316 LWSP16 = 0x12,
12317 POOL16D = 0x13,
12318 ORI32 = 0x14,
12319 POOL32F = 0x15,
211da992
CWR
12320 POOL32S = 0x16, /* MIPS64 */
12321 DADDIU32 = 0x17, /* MIPS64 */
3c824109
NF
12322
12323 POOL32C = 0x18,
12324 LWGP16 = 0x19,
12325 LW16 = 0x1a,
12326 POOL16E = 0x1b,
12327 XORI32 = 0x1c,
12328 JALS32 = 0x1d,
3a1f4268
YK
12329 BOVC = 0x1d,
12330 BEQC = 0x1d,
12331 BEQZALC = 0x1d,
3c824109 12332 ADDIUPC = 0x1e,
3a1f4268
YK
12333 PCREL = 0x1e,
12334 BNVC = 0x1f,
12335 BNEC = 0x1f,
12336 BNEZALC = 0x1f,
3c824109 12337
3a1f4268
YK
12338 R6_BEQZC = 0x20,
12339 JIC = 0x20,
3c824109
NF
12340 POOL16F = 0x21,
12341 SB16 = 0x22,
12342 BEQZ16 = 0x23,
3a1f4268 12343 BEQZC16 = 0x23,
3c824109
NF
12344 SLTI32 = 0x24,
12345 BEQ32 = 0x25,
3a1f4268 12346 BC = 0x25,
3c824109
NF
12347 SWC132 = 0x26,
12348 LWC132 = 0x27,
12349
3a1f4268 12350 /* 0x29 is reserved */
3c824109 12351 RES_29 = 0x29,
3a1f4268
YK
12352 R6_BNEZC = 0x28,
12353 JIALC = 0x28,
3c824109
NF
12354 SH16 = 0x2a,
12355 BNEZ16 = 0x2b,
3a1f4268 12356 BNEZC16 = 0x2b,
3c824109
NF
12357 SLTIU32 = 0x2c,
12358 BNE32 = 0x2d,
3a1f4268 12359 BALC = 0x2d,
3c824109
NF
12360 SDC132 = 0x2e,
12361 LDC132 = 0x2f,
12362
3a1f4268 12363 /* 0x31 is reserved */
3c824109 12364 RES_31 = 0x31,
3a1f4268
YK
12365 BLEZALC = 0x30,
12366 BGEZALC = 0x30,
12367 BGEUC = 0x30,
3c824109
NF
12368 SWSP16 = 0x32,
12369 B16 = 0x33,
3a1f4268 12370 BC16 = 0x33,
3c824109
NF
12371 ANDI32 = 0x34,
12372 J32 = 0x35,
3a1f4268
YK
12373 BGTZC = 0x35,
12374 BLTZC = 0x35,
12375 BLTC = 0x35,
211da992
CWR
12376 SD32 = 0x36, /* MIPS64 */
12377 LD32 = 0x37, /* MIPS64 */
3c824109 12378
3a1f4268 12379 /* 0x39 is reserved */
3c824109 12380 RES_39 = 0x39,
3a1f4268
YK
12381 BGTZALC = 0x38,
12382 BLTZALC = 0x38,
12383 BLTUC = 0x38,
3c824109
NF
12384 SW16 = 0x3a,
12385 LI16 = 0x3b,
12386 JALX32 = 0x3c,
12387 JAL32 = 0x3d,
3a1f4268
YK
12388 BLEZC = 0x3d,
12389 BGEZC = 0x3d,
12390 BGEC = 0x3d,
3c824109
NF
12391 SW32 = 0x3e,
12392 LW32 = 0x3f
12393};
12394
3a1f4268
YK
12395/* PCREL Instructions perform PC-Relative address calculation. bits 20..16 */
12396enum {
12397 ADDIUPC_00 = 0x00,
12398 ADDIUPC_07 = 0x07,
12399 AUIPC = 0x1e,
12400 ALUIPC = 0x1f,
12401 LWPC_08 = 0x08,
12402 LWPC_0F = 0x0F,
12403};
12404
3c824109
NF
12405/* POOL32A encoding of minor opcode field */
12406
12407enum {
12408 /* These opcodes are distinguished only by bits 9..6; those bits are
12409 * what are recorded below. */
12410 SLL32 = 0x0,
12411 SRL32 = 0x1,
12412 SRA = 0x2,
12413 ROTR = 0x3,
3a1f4268
YK
12414 SELEQZ = 0x5,
12415 SELNEZ = 0x6,
b00c7218 12416 R6_RDHWR = 0x7,
3c824109
NF
12417
12418 SLLV = 0x0,
12419 SRLV = 0x1,
12420 SRAV = 0x2,
12421 ROTRV = 0x3,
12422 ADD = 0x4,
12423 ADDU32 = 0x5,
12424 SUB = 0x6,
12425 SUBU32 = 0x7,
12426 MUL = 0x8,
12427 AND = 0x9,
12428 OR32 = 0xa,
12429 NOR = 0xb,
12430 XOR32 = 0xc,
12431 SLT = 0xd,
12432 SLTU = 0xe,
12433
12434 MOVN = 0x0,
3a1f4268 12435 R6_MUL = 0x0,
3c824109 12436 MOVZ = 0x1,
3a1f4268
YK
12437 MUH = 0x1,
12438 MULU = 0x2,
12439 MUHU = 0x3,
3c824109 12440 LWXS = 0x4,
3a1f4268
YK
12441 R6_DIV = 0x4,
12442 MOD = 0x5,
12443 R6_DIVU = 0x6,
12444 MODU = 0x7,
3c824109
NF
12445
12446 /* The following can be distinguished by their lower 6 bits. */
dbd8af98 12447 BREAK32 = 0x07,
3c824109 12448 INS = 0x0c,
3a1f4268
YK
12449 LSA = 0x0f,
12450 ALIGN = 0x1f,
3c824109 12451 EXT = 0x2c,
bb238210
YK
12452 POOL32AXF = 0x3c,
12453 SIGRIE = 0x3f
3c824109
NF
12454};
12455
12456/* POOL32AXF encoding of minor opcode field extension */
12457
d132c79f
CWR
12458/*
12459 * 1. MIPS Architecture for Programmers Volume II-B:
12460 * The microMIPS32 Instruction Set (Revision 3.05)
12461 *
12462 * Table 6.5 POOL32Axf Encoding of Minor Opcode Extension Field
12463 *
12464 * 2. MIPS Architecture for Programmers VolumeIV-e:
12465 * The MIPS DSP Application-Specific Extension
12466 * to the microMIPS32 Architecture (Revision 2.34)
12467 *
12468 * Table 5.5 POOL32Axf Encoding of Minor Opcode Extension Field
12469 */
12470
3c824109
NF
12471enum {
12472 /* bits 11..6 */
12473 TEQ = 0x00,
12474 TGE = 0x08,
12475 TGEU = 0x10,
12476 TLT = 0x20,
12477 TLTU = 0x28,
12478 TNE = 0x30,
12479
12480 MFC0 = 0x03,
12481 MTC0 = 0x0b,
12482
d132c79f
CWR
12483 /* begin of microMIPS32 DSP */
12484
3c824109
NF
12485 /* bits 13..12 for 0x01 */
12486 MFHI_ACC = 0x0,
12487 MFLO_ACC = 0x1,
12488 MTHI_ACC = 0x2,
12489 MTLO_ACC = 0x3,
12490
12491 /* bits 13..12 for 0x2a */
12492 MADD_ACC = 0x0,
12493 MADDU_ACC = 0x1,
12494 MSUB_ACC = 0x2,
12495 MSUBU_ACC = 0x3,
12496
12497 /* bits 13..12 for 0x32 */
12498 MULT_ACC = 0x0,
6801038b 12499 MULTU_ACC = 0x1,
3c824109 12500
d132c79f
CWR
12501 /* end of microMIPS32 DSP */
12502
3c824109 12503 /* bits 15..12 for 0x2c */
3a1f4268 12504 BITSWAP = 0x0,
3c824109
NF
12505 SEB = 0x2,
12506 SEH = 0x3,
12507 CLO = 0x4,
12508 CLZ = 0x5,
12509 RDHWR = 0x6,
12510 WSBH = 0x7,
12511 MULT = 0x8,
12512 MULTU = 0x9,
12513 DIV = 0xa,
12514 DIVU = 0xb,
12515 MADD = 0xc,
12516 MADDU = 0xd,
12517 MSUB = 0xe,
12518 MSUBU = 0xf,
12519
12520 /* bits 15..12 for 0x34 */
12521 MFC2 = 0x4,
12522 MTC2 = 0x5,
12523 MFHC2 = 0x8,
12524 MTHC2 = 0x9,
12525 CFC2 = 0xc,
12526 CTC2 = 0xd,
12527
12528 /* bits 15..12 for 0x3c */
12529 JALR = 0x0,
12530 JR = 0x0, /* alias */
3a1f4268
YK
12531 JALRC = 0x0,
12532 JRC = 0x0,
3c824109 12533 JALR_HB = 0x1,
3a1f4268 12534 JALRC_HB = 0x1,
3c824109
NF
12535 JALRS = 0x4,
12536 JALRS_HB = 0x5,
12537
12538 /* bits 15..12 for 0x05 */
12539 RDPGPR = 0xe,
12540 WRPGPR = 0xf,
12541
12542 /* bits 15..12 for 0x0d */
12543 TLBP = 0x0,
12544 TLBR = 0x1,
12545 TLBWI = 0x2,
12546 TLBWR = 0x3,
e60ec063
YK
12547 TLBINV = 0x4,
12548 TLBINVF = 0x5,
3c824109
NF
12549 WAIT = 0x9,
12550 IRET = 0xd,
12551 DERET = 0xe,
12552 ERET = 0xf,
12553
12554 /* bits 15..12 for 0x15 */
12555 DMT = 0x0,
12556 DVPE = 0x1,
12557 EMT = 0x2,
12558 EVPE = 0x3,
12559
12560 /* bits 15..12 for 0x1d */
12561 DI = 0x4,
12562 EI = 0x5,
12563
12564 /* bits 15..12 for 0x2d */
12565 SYNC = 0x6,
12566 SYSCALL = 0x8,
12567 SDBBP = 0xd,
12568
12569 /* bits 15..12 for 0x35 */
12570 MFHI32 = 0x0,
12571 MFLO32 = 0x1,
12572 MTHI32 = 0x2,
12573 MTLO32 = 0x3,
12574};
12575
12576/* POOL32B encoding of minor opcode field (bits 15..12) */
12577
12578enum {
12579 LWC2 = 0x0,
12580 LWP = 0x1,
12581 LDP = 0x4,
12582 LWM32 = 0x5,
12583 CACHE = 0x6,
12584 LDM = 0x7,
12585 SWC2 = 0x8,
12586 SWP = 0x9,
12587 SDP = 0xc,
12588 SWM32 = 0xd,
12589 SDM = 0xf
12590};
12591
12592/* POOL32C encoding of minor opcode field (bits 15..12) */
12593
12594enum {
12595 LWL = 0x0,
12596 SWL = 0x8,
12597 LWR = 0x1,
12598 SWR = 0x9,
12599 PREF = 0x2,
8fffc646 12600 ST_EVA = 0xa,
3c824109
NF
12601 LL = 0x3,
12602 SC = 0xb,
12603 LDL = 0x4,
12604 SDL = 0xc,
12605 LDR = 0x5,
12606 SDR = 0xd,
8fffc646 12607 LD_EVA = 0x6,
3c824109
NF
12608 LWU = 0xe,
12609 LLD = 0x7,
12610 SCD = 0xf
12611};
12612
8fffc646
JH
12613/* POOL32C LD-EVA encoding of minor opcode field (bits 11..9) */
12614
12615enum {
12616 LBUE = 0x0,
12617 LHUE = 0x1,
12618 LWLE = 0x2,
12619 LWRE = 0x3,
12620 LBE = 0x4,
12621 LHE = 0x5,
12622 LLE = 0x6,
12623 LWE = 0x7,
12624};
12625
12626/* POOL32C ST-EVA encoding of minor opcode field (bits 11..9) */
12627
12628enum {
12629 SWLE = 0x0,
12630 SWRE = 0x1,
12631 PREFE = 0x2,
12632 CACHEE = 0x3,
12633 SBE = 0x4,
12634 SHE = 0x5,
12635 SCE = 0x6,
12636 SWE = 0x7,
12637};
12638
3c824109
NF
12639/* POOL32F encoding of minor opcode field (bits 5..0) */
12640
12641enum {
12642 /* These are the bit 7..6 values */
12643 ADD_FMT = 0x0,
3c824109
NF
12644
12645 SUB_FMT = 0x1,
3c824109
NF
12646
12647 MUL_FMT = 0x2,
12648
12649 DIV_FMT = 0x3,
12650
12651 /* These are the bit 8..6 values */
3a1f4268 12652 MOVN_FMT = 0x0,
3c824109
NF
12653 RSQRT2_FMT = 0x0,
12654 MOVF_FMT = 0x0,
3a1f4268
YK
12655 RINT_FMT = 0x0,
12656 SELNEZ_FMT = 0x0,
3c824109 12657
3a1f4268 12658 MOVZ_FMT = 0x1,
3c824109
NF
12659 LWXC1 = 0x1,
12660 MOVT_FMT = 0x1,
3a1f4268
YK
12661 CLASS_FMT = 0x1,
12662 SELEQZ_FMT = 0x1,
3c824109
NF
12663
12664 PLL_PS = 0x2,
12665 SWXC1 = 0x2,
3a1f4268 12666 SEL_FMT = 0x2,
3c824109
NF
12667
12668 PLU_PS = 0x3,
12669 LDXC1 = 0x3,
12670
3a1f4268 12671 MOVN_FMT_04 = 0x4,
3c824109
NF
12672 PUL_PS = 0x4,
12673 SDXC1 = 0x4,
12674 RECIP2_FMT = 0x4,
12675
3a1f4268 12676 MOVZ_FMT_05 = 0x05,
3c824109
NF
12677 PUU_PS = 0x5,
12678 LUXC1 = 0x5,
12679
12680 CVT_PS_S = 0x6,
12681 SUXC1 = 0x6,
12682 ADDR_PS = 0x6,
12683 PREFX = 0x6,
3a1f4268 12684 MADDF_FMT = 0x6,
3c824109
NF
12685
12686 MULR_PS = 0x7,
3a1f4268 12687 MSUBF_FMT = 0x7,
3c824109
NF
12688
12689 MADD_S = 0x01,
12690 MADD_D = 0x09,
12691 MADD_PS = 0x11,
12692 ALNV_PS = 0x19,
12693 MSUB_S = 0x21,
12694 MSUB_D = 0x29,
12695 MSUB_PS = 0x31,
12696
12697 NMADD_S = 0x02,
12698 NMADD_D = 0x0a,
12699 NMADD_PS = 0x12,
12700 NMSUB_S = 0x22,
12701 NMSUB_D = 0x2a,
12702 NMSUB_PS = 0x32,
12703
3a1f4268
YK
12704 MIN_FMT = 0x3,
12705 MAX_FMT = 0xb,
12706 MINA_FMT = 0x23,
12707 MAXA_FMT = 0x2b,
3c824109
NF
12708 POOL32FXF = 0x3b,
12709
12710 CABS_COND_FMT = 0x1c, /* MIPS3D */
3a1f4268
YK
12711 C_COND_FMT = 0x3c,
12712
12713 CMP_CONDN_S = 0x5,
12714 CMP_CONDN_D = 0x15
3c824109
NF
12715};
12716
12717/* POOL32Fxf encoding of minor opcode extension field */
12718
12719enum {
12720 CVT_L = 0x04,
12721 RSQRT_FMT = 0x08,
12722 FLOOR_L = 0x0c,
12723 CVT_PW_PS = 0x1c,
12724 CVT_W = 0x24,
12725 SQRT_FMT = 0x28,
12726 FLOOR_W = 0x2c,
12727 CVT_PS_PW = 0x3c,
12728 CFC1 = 0x40,
12729 RECIP_FMT = 0x48,
12730 CEIL_L = 0x4c,
12731 CTC1 = 0x60,
12732 CEIL_W = 0x6c,
12733 MFC1 = 0x80,
12734 CVT_S_PL = 0x84,
12735 TRUNC_L = 0x8c,
12736 MTC1 = 0xa0,
12737 CVT_S_PU = 0xa4,
12738 TRUNC_W = 0xac,
12739 MFHC1 = 0xc0,
12740 ROUND_L = 0xcc,
12741 MTHC1 = 0xe0,
12742 ROUND_W = 0xec,
12743
12744 MOV_FMT = 0x01,
12745 MOVF = 0x05,
12746 ABS_FMT = 0x0d,
12747 RSQRT1_FMT = 0x1d,
12748 MOVT = 0x25,
12749 NEG_FMT = 0x2d,
12750 CVT_D = 0x4d,
12751 RECIP1_FMT = 0x5d,
12752 CVT_S = 0x6d
12753};
12754
12755/* POOL32I encoding of minor opcode field (bits 25..21) */
12756
12757enum {
12758 BLTZ = 0x00,
12759 BLTZAL = 0x01,
12760 BGEZ = 0x02,
12761 BGEZAL = 0x03,
12762 BLEZ = 0x04,
12763 BNEZC = 0x05,
12764 BGTZ = 0x06,
12765 BEQZC = 0x07,
12766 TLTI = 0x08,
3a1f4268 12767 BC1EQZC = 0x08,
3c824109 12768 TGEI = 0x09,
3a1f4268 12769 BC1NEZC = 0x09,
3c824109 12770 TLTIU = 0x0a,
3a1f4268 12771 BC2EQZC = 0x0a,
3c824109 12772 TGEIU = 0x0b,
3a1f4268 12773 BC2NEZC = 0x0a,
3c824109 12774 TNEI = 0x0c,
3a1f4268 12775 R6_SYNCI = 0x0c,
3c824109
NF
12776 LUI = 0x0d,
12777 TEQI = 0x0e,
12778 SYNCI = 0x10,
12779 BLTZALS = 0x11,
12780 BGEZALS = 0x13,
12781 BC2F = 0x14,
12782 BC2T = 0x15,
12783 BPOSGE64 = 0x1a,
12784 BPOSGE32 = 0x1b,
12785 /* These overlap and are distinguished by bit16 of the instruction */
12786 BC1F = 0x1c,
12787 BC1T = 0x1d,
12788 BC1ANY2F = 0x1c,
12789 BC1ANY2T = 0x1d,
12790 BC1ANY4F = 0x1e,
12791 BC1ANY4T = 0x1f
12792};
12793
12794/* POOL16A encoding of minor opcode field */
12795
12796enum {
12797 ADDU16 = 0x0,
12798 SUBU16 = 0x1
12799};
12800
12801/* POOL16B encoding of minor opcode field */
12802
12803enum {
12804 SLL16 = 0x0,
12805 SRL16 = 0x1
12806};
12807
12808/* POOL16C encoding of minor opcode field */
12809
12810enum {
12811 NOT16 = 0x00,
12812 XOR16 = 0x04,
12813 AND16 = 0x08,
12814 OR16 = 0x0c,
12815 LWM16 = 0x10,
12816 SWM16 = 0x14,
12817 JR16 = 0x18,
12818 JRC16 = 0x1a,
12819 JALR16 = 0x1c,
12820 JALR16S = 0x1e,
12821 MFHI16 = 0x20,
12822 MFLO16 = 0x24,
12823 BREAK16 = 0x28,
12824 SDBBP16 = 0x2c,
12825 JRADDIUSP = 0x30
12826};
12827
3a1f4268
YK
12828/* R6 POOL16C encoding of minor opcode field (bits 0..5) */
12829
12830enum {
12831 R6_NOT16 = 0x00,
12832 R6_AND16 = 0x01,
12833 R6_LWM16 = 0x02,
12834 R6_JRC16 = 0x03,
12835 MOVEP = 0x04,
12836 MOVEP_07 = 0x07,
12837 R6_XOR16 = 0x08,
12838 R6_OR16 = 0x09,
12839 R6_SWM16 = 0x0a,
12840 JALRC16 = 0x0b,
12841 MOVEP_0C = 0x0c,
12842 MOVEP_0F = 0x0f,
12843 JRCADDIUSP = 0x13,
12844 R6_BREAK16 = 0x1b,
12845 R6_SDBBP16 = 0x3b
12846};
12847
3c824109
NF
12848/* POOL16D encoding of minor opcode field */
12849
12850enum {
12851 ADDIUS5 = 0x0,
12852 ADDIUSP = 0x1
12853};
12854
12855/* POOL16E encoding of minor opcode field */
12856
12857enum {
12858 ADDIUR2 = 0x0,
12859 ADDIUR1SP = 0x1
12860};
12861
12862static int mmreg (int r)
12863{
12864 static const int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
12865
12866 return map[r];
12867}
12868
12869/* Used for 16-bit store instructions. */
12870static int mmreg2 (int r)
12871{
12872 static const int map[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
12873
12874 return map[r];
12875}
12876
12877#define uMIPS_RD(op) ((op >> 7) & 0x7)
12878#define uMIPS_RS(op) ((op >> 4) & 0x7)
12879#define uMIPS_RS2(op) uMIPS_RS(op)
12880#define uMIPS_RS1(op) ((op >> 1) & 0x7)
12881#define uMIPS_RD5(op) ((op >> 5) & 0x1f)
12882#define uMIPS_RS5(op) (op & 0x1f)
12883
12884/* Signed immediate */
12885#define SIMM(op, start, width) \
12886 ((int32_t)(((op >> start) & ((~0U) >> (32-width))) \
12887 << (32-width)) \
12888 >> (32-width))
12889/* Zero-extended immediate */
12890#define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
12891
d75c135e 12892static void gen_addiur1sp(DisasContext *ctx)
3c824109
NF
12893{
12894 int rd = mmreg(uMIPS_RD(ctx->opcode));
12895
d75c135e 12896 gen_arith_imm(ctx, OPC_ADDIU, rd, 29, ((ctx->opcode >> 1) & 0x3f) << 2);
3c824109
NF
12897}
12898
d75c135e 12899static void gen_addiur2(DisasContext *ctx)
3c824109
NF
12900{
12901 static const int decoded_imm[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
12902 int rd = mmreg(uMIPS_RD(ctx->opcode));
12903 int rs = mmreg(uMIPS_RS(ctx->opcode));
12904
d75c135e 12905 gen_arith_imm(ctx, OPC_ADDIU, rd, rs, decoded_imm[ZIMM(ctx->opcode, 1, 3)]);
3c824109
NF
12906}
12907
d75c135e 12908static void gen_addiusp(DisasContext *ctx)
3c824109
NF
12909{
12910 int encoded = ZIMM(ctx->opcode, 1, 9);
12911 int decoded;
12912
12913 if (encoded <= 1) {
12914 decoded = 256 + encoded;
12915 } else if (encoded <= 255) {
12916 decoded = encoded;
12917 } else if (encoded <= 509) {
12918 decoded = encoded - 512;
12919 } else {
12920 decoded = encoded - 768;
12921 }
12922
d75c135e 12923 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, decoded << 2);
3c824109
NF
12924}
12925
d75c135e 12926static void gen_addius5(DisasContext *ctx)
3c824109
NF
12927{
12928 int imm = SIMM(ctx->opcode, 1, 4);
12929 int rd = (ctx->opcode >> 5) & 0x1f;
12930
d75c135e 12931 gen_arith_imm(ctx, OPC_ADDIU, rd, rd, imm);
3c824109
NF
12932}
12933
d75c135e 12934static void gen_andi16(DisasContext *ctx)
3c824109
NF
12935{
12936 static const int decoded_imm[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
12937 31, 32, 63, 64, 255, 32768, 65535 };
12938 int rd = mmreg(uMIPS_RD(ctx->opcode));
12939 int rs = mmreg(uMIPS_RS(ctx->opcode));
12940 int encoded = ZIMM(ctx->opcode, 0, 4);
12941
d75c135e 12942 gen_logic_imm(ctx, OPC_ANDI, rd, rs, decoded_imm[encoded]);
3c824109
NF
12943}
12944
12945static void gen_ldst_multiple (DisasContext *ctx, uint32_t opc, int reglist,
12946 int base, int16_t offset)
12947{
12948 TCGv t0, t1;
12949 TCGv_i32 t2;
12950
12951 if (ctx->hflags & MIPS_HFLAG_BMASK) {
9c708c7f 12952 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
12953 return;
12954 }
12955
12956 t0 = tcg_temp_new();
12957
12958 gen_base_offset_addr(ctx, t0, base, offset);
12959
12960 t1 = tcg_const_tl(reglist);
12961 t2 = tcg_const_i32(ctx->mem_idx);
6af0bf9c 12962
3c824109
NF
12963 save_cpu_state(ctx, 1);
12964 switch (opc) {
12965 case LWM32:
895c2d04 12966 gen_helper_lwm(cpu_env, t0, t1, t2);
3c824109
NF
12967 break;
12968 case SWM32:
895c2d04 12969 gen_helper_swm(cpu_env, t0, t1, t2);
3c824109
NF
12970 break;
12971#ifdef TARGET_MIPS64
12972 case LDM:
895c2d04 12973 gen_helper_ldm(cpu_env, t0, t1, t2);
3c824109
NF
12974 break;
12975 case SDM:
895c2d04 12976 gen_helper_sdm(cpu_env, t0, t1, t2);
3c824109 12977 break;
6af0bf9c 12978#endif
3c824109 12979 }
3c824109 12980 tcg_temp_free(t0);
33087598 12981 tcg_temp_free(t1);
3c824109
NF
12982 tcg_temp_free_i32(t2);
12983}
6af0bf9c 12984
3c824109 12985
240ce26a 12986static void gen_pool16c_insn(DisasContext *ctx)
6af0bf9c 12987{
3c824109
NF
12988 int rd = mmreg((ctx->opcode >> 3) & 0x7);
12989 int rs = mmreg(ctx->opcode & 0x7);
6af0bf9c 12990
3c824109
NF
12991 switch (((ctx->opcode) >> 4) & 0x3f) {
12992 case NOT16 + 0:
12993 case NOT16 + 1:
12994 case NOT16 + 2:
12995 case NOT16 + 3:
d75c135e 12996 gen_logic(ctx, OPC_NOR, rd, rs, 0);
3c824109
NF
12997 break;
12998 case XOR16 + 0:
12999 case XOR16 + 1:
13000 case XOR16 + 2:
13001 case XOR16 + 3:
d75c135e 13002 gen_logic(ctx, OPC_XOR, rd, rd, rs);
3c824109
NF
13003 break;
13004 case AND16 + 0:
13005 case AND16 + 1:
13006 case AND16 + 2:
13007 case AND16 + 3:
d75c135e 13008 gen_logic(ctx, OPC_AND, rd, rd, rs);
3c824109
NF
13009 break;
13010 case OR16 + 0:
13011 case OR16 + 1:
13012 case OR16 + 2:
13013 case OR16 + 3:
d75c135e 13014 gen_logic(ctx, OPC_OR, rd, rd, rs);
3c824109
NF
13015 break;
13016 case LWM16 + 0:
13017 case LWM16 + 1:
13018 case LWM16 + 2:
13019 case LWM16 + 3:
13020 {
13021 static const int lwm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
13022 int offset = ZIMM(ctx->opcode, 0, 4);
13023
13024 gen_ldst_multiple(ctx, LWM32, lwm_convert[(ctx->opcode >> 4) & 0x3],
13025 29, offset << 2);
13026 }
13027 break;
13028 case SWM16 + 0:
13029 case SWM16 + 1:
13030 case SWM16 + 2:
13031 case SWM16 + 3:
13032 {
13033 static const int swm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
13034 int offset = ZIMM(ctx->opcode, 0, 4);
13035
13036 gen_ldst_multiple(ctx, SWM32, swm_convert[(ctx->opcode >> 4) & 0x3],
13037 29, offset << 2);
13038 }
13039 break;
13040 case JR16 + 0:
13041 case JR16 + 1:
13042 {
13043 int reg = ctx->opcode & 0x1f;
13044
b231c103 13045 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 4);
3c824109 13046 }
3c824109
NF
13047 break;
13048 case JRC16 + 0:
13049 case JRC16 + 1:
13050 {
13051 int reg = ctx->opcode & 0x1f;
b231c103 13052 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 0);
3c824109
NF
13053 /* Let normal delay slot handling in our caller take us
13054 to the branch target. */
13055 }
13056 break;
13057 case JALR16 + 0:
13058 case JALR16 + 1:
b231c103
YK
13059 gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 4);
13060 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
13061 break;
3c824109
NF
13062 case JALR16S + 0:
13063 case JALR16S + 1:
b231c103
YK
13064 gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 2);
13065 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
3c824109
NF
13066 break;
13067 case MFHI16 + 0:
13068 case MFHI16 + 1:
26135ead 13069 gen_HILO(ctx, OPC_MFHI, 0, uMIPS_RS5(ctx->opcode));
3c824109
NF
13070 break;
13071 case MFLO16 + 0:
13072 case MFLO16 + 1:
26135ead 13073 gen_HILO(ctx, OPC_MFLO, 0, uMIPS_RS5(ctx->opcode));
3c824109
NF
13074 break;
13075 case BREAK16:
9c708c7f 13076 generate_exception_end(ctx, EXCP_BREAK);
3c824109
NF
13077 break;
13078 case SDBBP16:
3b3c1694
LA
13079 if (is_uhi(extract32(ctx->opcode, 0, 4))) {
13080 gen_helper_do_semihosting(cpu_env);
13081 } else {
13082 /* XXX: not clear which exception should be raised
13083 * when in debug mode...
13084 */
13085 check_insn(ctx, ISA_MIPS32);
9c708c7f 13086 generate_exception_end(ctx, EXCP_DBp);
3b3c1694 13087 }
3c824109
NF
13088 break;
13089 case JRADDIUSP + 0:
13090 case JRADDIUSP + 1:
13091 {
13092 int imm = ZIMM(ctx->opcode, 0, 5);
b231c103 13093 gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0, 0);
d75c135e 13094 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
3c824109
NF
13095 /* Let normal delay slot handling in our caller take us
13096 to the branch target. */
13097 }
13098 break;
13099 default:
9c708c7f 13100 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
13101 break;
13102 }
13103}
13104
ed7ce6c0
YK
13105static inline void gen_movep(DisasContext *ctx, int enc_dest, int enc_rt,
13106 int enc_rs)
13107{
13108 int rd, rs, re, rt;
13109 static const int rd_enc[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
13110 static const int re_enc[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
13111 static const int rs_rt_enc[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
13112 rd = rd_enc[enc_dest];
13113 re = re_enc[enc_dest];
13114 rs = rs_rt_enc[enc_rs];
13115 rt = rs_rt_enc[enc_rt];
13116 if (rs) {
13117 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
13118 } else {
13119 tcg_gen_movi_tl(cpu_gpr[rd], 0);
13120 }
13121 if (rt) {
13122 tcg_gen_mov_tl(cpu_gpr[re], cpu_gpr[rt]);
13123 } else {
13124 tcg_gen_movi_tl(cpu_gpr[re], 0);
13125 }
13126}
13127
13128static void gen_pool16c_r6_insn(DisasContext *ctx)
13129{
13130 int rt = mmreg((ctx->opcode >> 7) & 0x7);
13131 int rs = mmreg((ctx->opcode >> 4) & 0x7);
13132
13133 switch (ctx->opcode & 0xf) {
13134 case R6_NOT16:
13135 gen_logic(ctx, OPC_NOR, rt, rs, 0);
13136 break;
13137 case R6_AND16:
13138 gen_logic(ctx, OPC_AND, rt, rt, rs);
13139 break;
13140 case R6_LWM16:
13141 {
13142 int lwm_converted = 0x11 + extract32(ctx->opcode, 8, 2);
13143 int offset = extract32(ctx->opcode, 4, 4);
13144 gen_ldst_multiple(ctx, LWM32, lwm_converted, 29, offset << 2);
13145 }
13146 break;
13147 case R6_JRC16: /* JRCADDIUSP */
13148 if ((ctx->opcode >> 4) & 1) {
13149 /* JRCADDIUSP */
13150 int imm = extract32(ctx->opcode, 5, 5);
13151 gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0, 0);
13152 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
13153 } else {
13154 /* JRC16 */
13155 int rs = extract32(ctx->opcode, 5, 5);
13156 gen_compute_branch(ctx, OPC_JR, 2, rs, 0, 0, 0);
13157 }
13158 break;
13159 case MOVEP ... MOVEP_07:
13160 case MOVEP_0C ... MOVEP_0F:
13161 {
13162 int enc_dest = uMIPS_RD(ctx->opcode);
13163 int enc_rt = uMIPS_RS2(ctx->opcode);
13164 int enc_rs = (ctx->opcode & 3) | ((ctx->opcode >> 1) & 4);
13165 gen_movep(ctx, enc_dest, enc_rt, enc_rs);
13166 }
13167 break;
13168 case R6_XOR16:
13169 gen_logic(ctx, OPC_XOR, rt, rt, rs);
13170 break;
13171 case R6_OR16:
13172 gen_logic(ctx, OPC_OR, rt, rt, rs);
13173 break;
13174 case R6_SWM16:
13175 {
13176 int swm_converted = 0x11 + extract32(ctx->opcode, 8, 2);
13177 int offset = extract32(ctx->opcode, 4, 4);
13178 gen_ldst_multiple(ctx, SWM32, swm_converted, 29, offset << 2);
13179 }
13180 break;
13181 case JALRC16: /* BREAK16, SDBBP16 */
13182 switch (ctx->opcode & 0x3f) {
13183 case JALRC16:
13184 case JALRC16 + 0x20:
13185 /* JALRC16 */
13186 gen_compute_branch(ctx, OPC_JALR, 2, (ctx->opcode >> 5) & 0x1f,
13187 31, 0, 0);
13188 break;
13189 case R6_BREAK16:
13190 /* BREAK16 */
13191 generate_exception(ctx, EXCP_BREAK);
13192 break;
13193 case R6_SDBBP16:
13194 /* SDBBP16 */
060ebfef
LA
13195 if (is_uhi(extract32(ctx->opcode, 6, 4))) {
13196 gen_helper_do_semihosting(cpu_env);
ed7ce6c0 13197 } else {
060ebfef
LA
13198 if (ctx->hflags & MIPS_HFLAG_SBRI) {
13199 generate_exception(ctx, EXCP_RI);
13200 } else {
13201 generate_exception(ctx, EXCP_DBp);
13202 }
ed7ce6c0
YK
13203 }
13204 break;
13205 }
13206 break;
13207 default:
13208 generate_exception(ctx, EXCP_RI);
13209 break;
13210 }
13211}
13212
3c824109
NF
13213static void gen_ldxs (DisasContext *ctx, int base, int index, int rd)
13214{
13215 TCGv t0 = tcg_temp_new();
13216 TCGv t1 = tcg_temp_new();
13217
13218 gen_load_gpr(t0, base);
13219
13220 if (index != 0) {
13221 gen_load_gpr(t1, index);
13222 tcg_gen_shli_tl(t1, t1, 2);
13223 gen_op_addr_add(ctx, t0, t1, t0);
13224 }
13225
5f68f5ae 13226 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
3c824109
NF
13227 gen_store_gpr(t1, rd);
13228
13229 tcg_temp_free(t0);
13230 tcg_temp_free(t1);
13231}
13232
13233static void gen_ldst_pair (DisasContext *ctx, uint32_t opc, int rd,
13234 int base, int16_t offset)
13235{
3c824109
NF
13236 TCGv t0, t1;
13237
36c6711b 13238 if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31) {
9c708c7f 13239 generate_exception_end(ctx, EXCP_RI);
d796321b
FB
13240 return;
13241 }
13242
3c824109
NF
13243 t0 = tcg_temp_new();
13244 t1 = tcg_temp_new();
8e9ade68 13245
3c824109
NF
13246 gen_base_offset_addr(ctx, t0, base, offset);
13247
13248 switch (opc) {
13249 case LWP:
36c6711b 13250 if (rd == base) {
9c708c7f 13251 generate_exception_end(ctx, EXCP_RI);
36c6711b
EJ
13252 return;
13253 }
5f68f5ae 13254 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
3c824109
NF
13255 gen_store_gpr(t1, rd);
13256 tcg_gen_movi_tl(t1, 4);
13257 gen_op_addr_add(ctx, t0, t0, t1);
5f68f5ae 13258 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
3c824109 13259 gen_store_gpr(t1, rd+1);
3c824109
NF
13260 break;
13261 case SWP:
3c824109 13262 gen_load_gpr(t1, rd);
5f68f5ae 13263 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
3c824109
NF
13264 tcg_gen_movi_tl(t1, 4);
13265 gen_op_addr_add(ctx, t0, t0, t1);
13266 gen_load_gpr(t1, rd+1);
5f68f5ae 13267 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
3c824109
NF
13268 break;
13269#ifdef TARGET_MIPS64
13270 case LDP:
36c6711b 13271 if (rd == base) {
9c708c7f 13272 generate_exception_end(ctx, EXCP_RI);
36c6711b
EJ
13273 return;
13274 }
5f68f5ae 13275 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
3c824109
NF
13276 gen_store_gpr(t1, rd);
13277 tcg_gen_movi_tl(t1, 8);
13278 gen_op_addr_add(ctx, t0, t0, t1);
5f68f5ae 13279 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
3c824109 13280 gen_store_gpr(t1, rd+1);
3c824109
NF
13281 break;
13282 case SDP:
3c824109 13283 gen_load_gpr(t1, rd);
5f68f5ae 13284 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
3c824109
NF
13285 tcg_gen_movi_tl(t1, 8);
13286 gen_op_addr_add(ctx, t0, t0, t1);
13287 gen_load_gpr(t1, rd+1);
5f68f5ae 13288 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
3c824109
NF
13289 break;
13290#endif
6af0bf9c 13291 }
3c824109
NF
13292 tcg_temp_free(t0);
13293 tcg_temp_free(t1);
13294}
618b0fe9 13295
d208ac0c
LA
13296static void gen_sync(int stype)
13297{
13298 TCGBar tcg_mo = TCG_BAR_SC;
13299
13300 switch (stype) {
13301 case 0x4: /* SYNC_WMB */
13302 tcg_mo |= TCG_MO_ST_ST;
13303 break;
13304 case 0x10: /* SYNC_MB */
13305 tcg_mo |= TCG_MO_ALL;
13306 break;
13307 case 0x11: /* SYNC_ACQUIRE */
13308 tcg_mo |= TCG_MO_LD_LD | TCG_MO_LD_ST;
13309 break;
13310 case 0x12: /* SYNC_RELEASE */
13311 tcg_mo |= TCG_MO_ST_ST | TCG_MO_LD_ST;
13312 break;
13313 case 0x13: /* SYNC_RMB */
13314 tcg_mo |= TCG_MO_LD_LD;
13315 break;
13316 default:
13317 tcg_mo |= TCG_MO_ALL;
13318 break;
13319 }
13320
13321 tcg_gen_mb(tcg_mo);
13322}
13323
240ce26a 13324static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
3c824109
NF
13325{
13326 int extension = (ctx->opcode >> 6) & 0x3f;
13327 int minor = (ctx->opcode >> 12) & 0xf;
13328 uint32_t mips32_op;
13329
13330 switch (extension) {
13331 case TEQ:
13332 mips32_op = OPC_TEQ;
13333 goto do_trap;
13334 case TGE:
13335 mips32_op = OPC_TGE;
13336 goto do_trap;
13337 case TGEU:
13338 mips32_op = OPC_TGEU;
13339 goto do_trap;
13340 case TLT:
13341 mips32_op = OPC_TLT;
13342 goto do_trap;
13343 case TLTU:
13344 mips32_op = OPC_TLTU;
13345 goto do_trap;
13346 case TNE:
13347 mips32_op = OPC_TNE;
13348 do_trap:
13349 gen_trap(ctx, mips32_op, rs, rt, -1);
13350 break;
13351#ifndef CONFIG_USER_ONLY
13352 case MFC0:
13353 case MFC0 + 32:
2e15497c 13354 check_cp0_enabled(ctx);
3c824109
NF
13355 if (rt == 0) {
13356 /* Treat as NOP. */
13357 break;
13358 }
d75c135e 13359 gen_mfc0(ctx, cpu_gpr[rt], rs, (ctx->opcode >> 11) & 0x7);
3c824109
NF
13360 break;
13361 case MTC0:
13362 case MTC0 + 32:
2e15497c 13363 check_cp0_enabled(ctx);
3c824109
NF
13364 {
13365 TCGv t0 = tcg_temp_new();
618b0fe9 13366
3c824109 13367 gen_load_gpr(t0, rt);
d75c135e 13368 gen_mtc0(ctx, t0, rs, (ctx->opcode >> 11) & 0x7);
3c824109
NF
13369 tcg_temp_free(t0);
13370 }
13371 break;
13372#endif
a1fc6246
LA
13373 case 0x2a:
13374 switch (minor & 3) {
13375 case MADD_ACC:
13376 gen_muldiv(ctx, OPC_MADD, (ctx->opcode >> 14) & 3, rs, rt);
13377 break;
13378 case MADDU_ACC:
13379 gen_muldiv(ctx, OPC_MADDU, (ctx->opcode >> 14) & 3, rs, rt);
13380 break;
13381 case MSUB_ACC:
13382 gen_muldiv(ctx, OPC_MSUB, (ctx->opcode >> 14) & 3, rs, rt);
13383 break;
13384 case MSUBU_ACC:
13385 gen_muldiv(ctx, OPC_MSUBU, (ctx->opcode >> 14) & 3, rs, rt);
13386 break;
13387 default:
13388 goto pool32axf_invalid;
13389 }
13390 break;
13391 case 0x32:
13392 switch (minor & 3) {
13393 case MULT_ACC:
13394 gen_muldiv(ctx, OPC_MULT, (ctx->opcode >> 14) & 3, rs, rt);
13395 break;
13396 case MULTU_ACC:
13397 gen_muldiv(ctx, OPC_MULTU, (ctx->opcode >> 14) & 3, rs, rt);
13398 break;
13399 default:
13400 goto pool32axf_invalid;
13401 }
13402 break;
3c824109
NF
13403 case 0x2c:
13404 switch (minor) {
e0332095
YK
13405 case BITSWAP:
13406 check_insn(ctx, ISA_MIPS32R6);
13407 gen_bitswap(ctx, OPC_BITSWAP, rs, rt);
13408 break;
3c824109
NF
13409 case SEB:
13410 gen_bshfl(ctx, OPC_SEB, rs, rt);
13411 break;
13412 case SEH:
13413 gen_bshfl(ctx, OPC_SEH, rs, rt);
13414 break;
13415 case CLO:
13416 mips32_op = OPC_CLO;
13417 goto do_cl;
13418 case CLZ:
13419 mips32_op = OPC_CLZ;
13420 do_cl:
d75c135e 13421 check_insn(ctx, ISA_MIPS32);
3c824109
NF
13422 gen_cl(ctx, mips32_op, rt, rs);
13423 break;
13424 case RDHWR:
b00c7218
YK
13425 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13426 gen_rdhwr(ctx, rt, rs, 0);
3c824109
NF
13427 break;
13428 case WSBH:
13429 gen_bshfl(ctx, OPC_WSBH, rs, rt);
13430 break;
13431 case MULT:
9e8f441a 13432 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 13433 mips32_op = OPC_MULT;
26135ead 13434 goto do_mul;
3c824109 13435 case MULTU:
9e8f441a 13436 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 13437 mips32_op = OPC_MULTU;
26135ead 13438 goto do_mul;
3c824109 13439 case DIV:
9e8f441a 13440 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 13441 mips32_op = OPC_DIV;
26135ead 13442 goto do_div;
3c824109 13443 case DIVU:
9e8f441a 13444 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 13445 mips32_op = OPC_DIVU;
26135ead
RS
13446 goto do_div;
13447 do_div:
13448 check_insn(ctx, ISA_MIPS32);
13449 gen_muldiv(ctx, mips32_op, 0, rs, rt);
13450 break;
3c824109 13451 case MADD:
9e8f441a 13452 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 13453 mips32_op = OPC_MADD;
26135ead 13454 goto do_mul;
3c824109 13455 case MADDU:
9e8f441a 13456 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 13457 mips32_op = OPC_MADDU;
26135ead 13458 goto do_mul;
3c824109 13459 case MSUB:
9e8f441a 13460 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 13461 mips32_op = OPC_MSUB;
26135ead 13462 goto do_mul;
3c824109 13463 case MSUBU:
9e8f441a 13464 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 13465 mips32_op = OPC_MSUBU;
26135ead 13466 do_mul:
d75c135e 13467 check_insn(ctx, ISA_MIPS32);
a1fc6246 13468 gen_muldiv(ctx, mips32_op, 0, rs, rt);
3c824109
NF
13469 break;
13470 default:
13471 goto pool32axf_invalid;
13472 }
13473 break;
13474 case 0x34:
13475 switch (minor) {
13476 case MFC2:
13477 case MTC2:
13478 case MFHC2:
13479 case MTHC2:
13480 case CFC2:
13481 case CTC2:
13482 generate_exception_err(ctx, EXCP_CpU, 2);
13483 break;
13484 default:
13485 goto pool32axf_invalid;
13486 }
13487 break;
13488 case 0x3c:
13489 switch (minor) {
65935f07
YK
13490 case JALR: /* JALRC */
13491 case JALR_HB: /* JALRC_HB */
13492 if (ctx->insn_flags & ISA_MIPS32R6) {
13493 /* JALRC, JALRC_HB */
13494 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 0);
13495 } else {
13496 /* JALR, JALR_HB */
13497 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 4);
13498 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
13499 }
3c824109
NF
13500 break;
13501 case JALRS:
13502 case JALRS_HB:
9e8f441a 13503 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
13504 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 2);
13505 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
3c824109
NF
13506 break;
13507 default:
13508 goto pool32axf_invalid;
13509 }
13510 break;
13511 case 0x05:
13512 switch (minor) {
13513 case RDPGPR:
2e15497c 13514 check_cp0_enabled(ctx);
d75c135e 13515 check_insn(ctx, ISA_MIPS32R2);
1bf5902d 13516 gen_load_srsgpr(rs, rt);
3c824109
NF
13517 break;
13518 case WRPGPR:
2e15497c 13519 check_cp0_enabled(ctx);
d75c135e 13520 check_insn(ctx, ISA_MIPS32R2);
1bf5902d 13521 gen_store_srsgpr(rs, rt);
3c824109
NF
13522 break;
13523 default:
13524 goto pool32axf_invalid;
13525 }
13526 break;
13527#ifndef CONFIG_USER_ONLY
13528 case 0x0d:
13529 switch (minor) {
13530 case TLBP:
13531 mips32_op = OPC_TLBP;
13532 goto do_cp0;
13533 case TLBR:
13534 mips32_op = OPC_TLBR;
13535 goto do_cp0;
13536 case TLBWI:
13537 mips32_op = OPC_TLBWI;
13538 goto do_cp0;
13539 case TLBWR:
13540 mips32_op = OPC_TLBWR;
13541 goto do_cp0;
e60ec063
YK
13542 case TLBINV:
13543 mips32_op = OPC_TLBINV;
13544 goto do_cp0;
13545 case TLBINVF:
13546 mips32_op = OPC_TLBINVF;
13547 goto do_cp0;
3c824109
NF
13548 case WAIT:
13549 mips32_op = OPC_WAIT;
13550 goto do_cp0;
13551 case DERET:
13552 mips32_op = OPC_DERET;
13553 goto do_cp0;
13554 case ERET:
13555 mips32_op = OPC_ERET;
13556 do_cp0:
13557 gen_cp0(env, ctx, mips32_op, rt, rs);
13558 break;
13559 default:
13560 goto pool32axf_invalid;
13561 }
13562 break;
13563 case 0x1d:
13564 switch (minor) {
13565 case DI:
2e15497c 13566 check_cp0_enabled(ctx);
3c824109
NF
13567 {
13568 TCGv t0 = tcg_temp_new();
13569
13570 save_cpu_state(ctx, 1);
895c2d04 13571 gen_helper_di(t0, cpu_env);
3c824109
NF
13572 gen_store_gpr(t0, rs);
13573 /* Stop translation as we may have switched the execution mode */
eeb3bba8 13574 ctx->base.is_jmp = DISAS_STOP;
3c824109
NF
13575 tcg_temp_free(t0);
13576 }
13577 break;
13578 case EI:
2e15497c 13579 check_cp0_enabled(ctx);
3c824109
NF
13580 {
13581 TCGv t0 = tcg_temp_new();
13582
13583 save_cpu_state(ctx, 1);
895c2d04 13584 gen_helper_ei(t0, cpu_env);
3c824109 13585 gen_store_gpr(t0, rs);
b28425ba 13586 /* DISAS_STOP isn't sufficient, we need to ensure we break out
b74cddcb 13587 of translated code to check for pending interrupts. */
eeb3bba8
EC
13588 gen_save_pc(ctx->base.pc_next + 4);
13589 ctx->base.is_jmp = DISAS_EXIT;
3c824109
NF
13590 tcg_temp_free(t0);
13591 }
13592 break;
13593 default:
13594 goto pool32axf_invalid;
13595 }
13596 break;
13597#endif
13598 case 0x2d:
13599 switch (minor) {
13600 case SYNC:
d208ac0c 13601 gen_sync(extract32(ctx->opcode, 16, 5));
3c824109
NF
13602 break;
13603 case SYSCALL:
9c708c7f 13604 generate_exception_end(ctx, EXCP_SYSCALL);
3c824109
NF
13605 break;
13606 case SDBBP:
3b3c1694
LA
13607 if (is_uhi(extract32(ctx->opcode, 16, 10))) {
13608 gen_helper_do_semihosting(cpu_env);
13609 } else {
13610 check_insn(ctx, ISA_MIPS32);
e0332095 13611 if (ctx->hflags & MIPS_HFLAG_SBRI) {
9c708c7f 13612 generate_exception_end(ctx, EXCP_RI);
e0332095 13613 } else {
9c708c7f 13614 generate_exception_end(ctx, EXCP_DBp);
e0332095 13615 }
3b3c1694 13616 }
3c824109
NF
13617 break;
13618 default:
13619 goto pool32axf_invalid;
13620 }
13621 break;
a1fc6246 13622 case 0x01:
26135ead 13623 switch (minor & 3) {
a1fc6246 13624 case MFHI_ACC:
26135ead 13625 gen_HILO(ctx, OPC_MFHI, minor >> 2, rs);
3c824109 13626 break;
a1fc6246 13627 case MFLO_ACC:
26135ead 13628 gen_HILO(ctx, OPC_MFLO, minor >> 2, rs);
3c824109 13629 break;
a1fc6246 13630 case MTHI_ACC:
26135ead 13631 gen_HILO(ctx, OPC_MTHI, minor >> 2, rs);
3c824109 13632 break;
a1fc6246 13633 case MTLO_ACC:
26135ead 13634 gen_HILO(ctx, OPC_MTLO, minor >> 2, rs);
3c824109
NF
13635 break;
13636 default:
13637 goto pool32axf_invalid;
13638 }
13639 break;
a1fc6246 13640 case 0x35:
9e8f441a 13641 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a1fc6246
LA
13642 switch (minor) {
13643 case MFHI32:
13644 gen_HILO(ctx, OPC_MFHI, 0, rs);
13645 break;
13646 case MFLO32:
13647 gen_HILO(ctx, OPC_MFLO, 0, rs);
13648 break;
13649 case MTHI32:
13650 gen_HILO(ctx, OPC_MTHI, 0, rs);
13651 break;
13652 case MTLO32:
13653 gen_HILO(ctx, OPC_MTLO, 0, rs);
13654 break;
13655 default:
13656 goto pool32axf_invalid;
13657 }
13658 break;
3c824109
NF
13659 default:
13660 pool32axf_invalid:
13661 MIPS_INVAL("pool32axf");
9c708c7f 13662 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
13663 break;
13664 }
13665}
13666
13667/* Values for microMIPS fmt field. Variable-width, depending on which
13668 formats the instruction supports. */
13669
13670enum {
13671 FMT_SD_S = 0,
13672 FMT_SD_D = 1,
13673
13674 FMT_SDPS_S = 0,
13675 FMT_SDPS_D = 1,
13676 FMT_SDPS_PS = 2,
13677
13678 FMT_SWL_S = 0,
13679 FMT_SWL_W = 1,
13680 FMT_SWL_L = 2,
13681
13682 FMT_DWL_D = 0,
13683 FMT_DWL_W = 1,
13684 FMT_DWL_L = 2
13685};
13686
d75c135e 13687static void gen_pool32fxf(DisasContext *ctx, int rt, int rs)
3c824109
NF
13688{
13689 int extension = (ctx->opcode >> 6) & 0x3ff;
13690 uint32_t mips32_op;
13691
13692#define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
13693#define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
13694#define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
13695
13696 switch (extension) {
13697 case FLOAT_1BIT_FMT(CFC1, 0):
13698 mips32_op = OPC_CFC1;
13699 goto do_cp1;
13700 case FLOAT_1BIT_FMT(CTC1, 0):
13701 mips32_op = OPC_CTC1;
13702 goto do_cp1;
13703 case FLOAT_1BIT_FMT(MFC1, 0):
13704 mips32_op = OPC_MFC1;
13705 goto do_cp1;
13706 case FLOAT_1BIT_FMT(MTC1, 0):
13707 mips32_op = OPC_MTC1;
13708 goto do_cp1;
13709 case FLOAT_1BIT_FMT(MFHC1, 0):
13710 mips32_op = OPC_MFHC1;
13711 goto do_cp1;
13712 case FLOAT_1BIT_FMT(MTHC1, 0):
13713 mips32_op = OPC_MTHC1;
13714 do_cp1:
13715 gen_cp1(ctx, mips32_op, rt, rs);
13716 break;
13717
13718 /* Reciprocal square root */
13719 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_S):
13720 mips32_op = OPC_RSQRT_S;
13721 goto do_unaryfp;
13722 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_D):
13723 mips32_op = OPC_RSQRT_D;
13724 goto do_unaryfp;
13725
13726 /* Square root */
13727 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_S):
13728 mips32_op = OPC_SQRT_S;
13729 goto do_unaryfp;
13730 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_D):
13731 mips32_op = OPC_SQRT_D;
13732 goto do_unaryfp;
13733
13734 /* Reciprocal */
13735 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_S):
13736 mips32_op = OPC_RECIP_S;
13737 goto do_unaryfp;
13738 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_D):
13739 mips32_op = OPC_RECIP_D;
13740 goto do_unaryfp;
13741
13742 /* Floor */
13743 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_S):
13744 mips32_op = OPC_FLOOR_L_S;
13745 goto do_unaryfp;
13746 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_D):
13747 mips32_op = OPC_FLOOR_L_D;
13748 goto do_unaryfp;
13749 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_S):
13750 mips32_op = OPC_FLOOR_W_S;
13751 goto do_unaryfp;
13752 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_D):
13753 mips32_op = OPC_FLOOR_W_D;
13754 goto do_unaryfp;
13755
13756 /* Ceiling */
13757 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_S):
13758 mips32_op = OPC_CEIL_L_S;
13759 goto do_unaryfp;
13760 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_D):
13761 mips32_op = OPC_CEIL_L_D;
13762 goto do_unaryfp;
13763 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_S):
13764 mips32_op = OPC_CEIL_W_S;
13765 goto do_unaryfp;
13766 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_D):
13767 mips32_op = OPC_CEIL_W_D;
13768 goto do_unaryfp;
13769
13770 /* Truncation */
13771 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_S):
13772 mips32_op = OPC_TRUNC_L_S;
13773 goto do_unaryfp;
13774 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_D):
13775 mips32_op = OPC_TRUNC_L_D;
13776 goto do_unaryfp;
13777 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_S):
13778 mips32_op = OPC_TRUNC_W_S;
13779 goto do_unaryfp;
13780 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_D):
13781 mips32_op = OPC_TRUNC_W_D;
13782 goto do_unaryfp;
13783
13784 /* Round */
13785 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_S):
13786 mips32_op = OPC_ROUND_L_S;
13787 goto do_unaryfp;
13788 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_D):
13789 mips32_op = OPC_ROUND_L_D;
13790 goto do_unaryfp;
13791 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_S):
13792 mips32_op = OPC_ROUND_W_S;
13793 goto do_unaryfp;
13794 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_D):
13795 mips32_op = OPC_ROUND_W_D;
13796 goto do_unaryfp;
13797
13798 /* Integer to floating-point conversion */
13799 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_S):
13800 mips32_op = OPC_CVT_L_S;
13801 goto do_unaryfp;
13802 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_D):
13803 mips32_op = OPC_CVT_L_D;
13804 goto do_unaryfp;
13805 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_S):
13806 mips32_op = OPC_CVT_W_S;
13807 goto do_unaryfp;
13808 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_D):
13809 mips32_op = OPC_CVT_W_D;
13810 goto do_unaryfp;
13811
13812 /* Paired-foo conversions */
13813 case FLOAT_1BIT_FMT(CVT_S_PL, 0):
13814 mips32_op = OPC_CVT_S_PL;
13815 goto do_unaryfp;
13816 case FLOAT_1BIT_FMT(CVT_S_PU, 0):
13817 mips32_op = OPC_CVT_S_PU;
13818 goto do_unaryfp;
13819 case FLOAT_1BIT_FMT(CVT_PW_PS, 0):
13820 mips32_op = OPC_CVT_PW_PS;
13821 goto do_unaryfp;
13822 case FLOAT_1BIT_FMT(CVT_PS_PW, 0):
13823 mips32_op = OPC_CVT_PS_PW;
13824 goto do_unaryfp;
13825
13826 /* Floating-point moves */
13827 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_S):
13828 mips32_op = OPC_MOV_S;
13829 goto do_unaryfp;
13830 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_D):
13831 mips32_op = OPC_MOV_D;
13832 goto do_unaryfp;
13833 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_PS):
13834 mips32_op = OPC_MOV_PS;
13835 goto do_unaryfp;
13836
13837 /* Absolute value */
13838 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_S):
13839 mips32_op = OPC_ABS_S;
13840 goto do_unaryfp;
13841 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_D):
13842 mips32_op = OPC_ABS_D;
13843 goto do_unaryfp;
13844 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_PS):
13845 mips32_op = OPC_ABS_PS;
13846 goto do_unaryfp;
13847
13848 /* Negation */
13849 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_S):
13850 mips32_op = OPC_NEG_S;
13851 goto do_unaryfp;
13852 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_D):
13853 mips32_op = OPC_NEG_D;
13854 goto do_unaryfp;
13855 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_PS):
13856 mips32_op = OPC_NEG_PS;
13857 goto do_unaryfp;
13858
13859 /* Reciprocal square root step */
13860 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_S):
13861 mips32_op = OPC_RSQRT1_S;
13862 goto do_unaryfp;
13863 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_D):
13864 mips32_op = OPC_RSQRT1_D;
13865 goto do_unaryfp;
13866 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_PS):
13867 mips32_op = OPC_RSQRT1_PS;
13868 goto do_unaryfp;
13869
13870 /* Reciprocal step */
13871 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_S):
13872 mips32_op = OPC_RECIP1_S;
13873 goto do_unaryfp;
13874 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_D):
13875 mips32_op = OPC_RECIP1_S;
13876 goto do_unaryfp;
13877 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_PS):
13878 mips32_op = OPC_RECIP1_PS;
13879 goto do_unaryfp;
13880
13881 /* Conversions from double */
13882 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_S):
13883 mips32_op = OPC_CVT_D_S;
13884 goto do_unaryfp;
13885 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_W):
13886 mips32_op = OPC_CVT_D_W;
13887 goto do_unaryfp;
13888 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_L):
13889 mips32_op = OPC_CVT_D_L;
13890 goto do_unaryfp;
13891
13892 /* Conversions from single */
13893 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_D):
13894 mips32_op = OPC_CVT_S_D;
13895 goto do_unaryfp;
13896 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_W):
13897 mips32_op = OPC_CVT_S_W;
13898 goto do_unaryfp;
13899 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_L):
13900 mips32_op = OPC_CVT_S_L;
13901 do_unaryfp:
13902 gen_farith(ctx, mips32_op, -1, rs, rt, 0);
13903 break;
13904
13905 /* Conditional moves on floating-point codes */
13906 case COND_FLOAT_MOV(MOVT, 0):
13907 case COND_FLOAT_MOV(MOVT, 1):
13908 case COND_FLOAT_MOV(MOVT, 2):
13909 case COND_FLOAT_MOV(MOVT, 3):
13910 case COND_FLOAT_MOV(MOVT, 4):
13911 case COND_FLOAT_MOV(MOVT, 5):
13912 case COND_FLOAT_MOV(MOVT, 6):
13913 case COND_FLOAT_MOV(MOVT, 7):
9e8f441a 13914 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
13915 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 1);
13916 break;
13917 case COND_FLOAT_MOV(MOVF, 0):
13918 case COND_FLOAT_MOV(MOVF, 1):
13919 case COND_FLOAT_MOV(MOVF, 2):
13920 case COND_FLOAT_MOV(MOVF, 3):
13921 case COND_FLOAT_MOV(MOVF, 4):
13922 case COND_FLOAT_MOV(MOVF, 5):
13923 case COND_FLOAT_MOV(MOVF, 6):
13924 case COND_FLOAT_MOV(MOVF, 7):
9e8f441a 13925 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
13926 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 0);
13927 break;
13928 default:
13929 MIPS_INVAL("pool32fxf");
9c708c7f 13930 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
13931 break;
13932 }
13933}
13934
f60eeb0c 13935static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx)
3c824109
NF
13936{
13937 int32_t offset;
13938 uint16_t insn;
13939 int rt, rs, rd, rr;
13940 int16_t imm;
8fffc646 13941 uint32_t op, minor, minor2, mips32_op;
3c824109
NF
13942 uint32_t cond, fmt, cc;
13943
eeb3bba8 13944 insn = cpu_lduw_code(env, ctx->base.pc_next + 2);
3c824109
NF
13945 ctx->opcode = (ctx->opcode << 16) | insn;
13946
13947 rt = (ctx->opcode >> 21) & 0x1f;
13948 rs = (ctx->opcode >> 16) & 0x1f;
13949 rd = (ctx->opcode >> 11) & 0x1f;
13950 rr = (ctx->opcode >> 6) & 0x1f;
13951 imm = (int16_t) ctx->opcode;
13952
13953 op = (ctx->opcode >> 26) & 0x3f;
13954 switch (op) {
13955 case POOL32A:
13956 minor = ctx->opcode & 0x3f;
13957 switch (minor) {
13958 case 0x00:
13959 minor = (ctx->opcode >> 6) & 0xf;
13960 switch (minor) {
13961 case SLL32:
13962 mips32_op = OPC_SLL;
13963 goto do_shifti;
13964 case SRA:
13965 mips32_op = OPC_SRA;
13966 goto do_shifti;
13967 case SRL32:
13968 mips32_op = OPC_SRL;
13969 goto do_shifti;
13970 case ROTR:
13971 mips32_op = OPC_ROTR;
13972 do_shifti:
d75c135e 13973 gen_shift_imm(ctx, mips32_op, rt, rs, rd);
3c824109 13974 break;
e0332095
YK
13975 case SELEQZ:
13976 check_insn(ctx, ISA_MIPS32R6);
13977 gen_cond_move(ctx, OPC_SELEQZ, rd, rs, rt);
13978 break;
13979 case SELNEZ:
13980 check_insn(ctx, ISA_MIPS32R6);
13981 gen_cond_move(ctx, OPC_SELNEZ, rd, rs, rt);
13982 break;
b00c7218
YK
13983 case R6_RDHWR:
13984 check_insn(ctx, ISA_MIPS32R6);
13985 gen_rdhwr(ctx, rt, rs, extract32(ctx->opcode, 11, 3));
13986 break;
3c824109
NF
13987 default:
13988 goto pool32a_invalid;
13989 }
13990 break;
13991 case 0x10:
13992 minor = (ctx->opcode >> 6) & 0xf;
13993 switch (minor) {
13994 /* Arithmetic */
13995 case ADD:
13996 mips32_op = OPC_ADD;
13997 goto do_arith;
13998 case ADDU32:
13999 mips32_op = OPC_ADDU;
14000 goto do_arith;
14001 case SUB:
14002 mips32_op = OPC_SUB;
14003 goto do_arith;
14004 case SUBU32:
14005 mips32_op = OPC_SUBU;
14006 goto do_arith;
14007 case MUL:
9e8f441a 14008 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14009 mips32_op = OPC_MUL;
14010 do_arith:
d75c135e 14011 gen_arith(ctx, mips32_op, rd, rs, rt);
3c824109
NF
14012 break;
14013 /* Shifts */
14014 case SLLV:
14015 mips32_op = OPC_SLLV;
14016 goto do_shift;
14017 case SRLV:
14018 mips32_op = OPC_SRLV;
14019 goto do_shift;
14020 case SRAV:
14021 mips32_op = OPC_SRAV;
14022 goto do_shift;
14023 case ROTRV:
14024 mips32_op = OPC_ROTRV;
14025 do_shift:
d75c135e 14026 gen_shift(ctx, mips32_op, rd, rs, rt);
3c824109
NF
14027 break;
14028 /* Logical operations */
14029 case AND:
14030 mips32_op = OPC_AND;
14031 goto do_logic;
14032 case OR32:
14033 mips32_op = OPC_OR;
14034 goto do_logic;
14035 case NOR:
14036 mips32_op = OPC_NOR;
14037 goto do_logic;
14038 case XOR32:
14039 mips32_op = OPC_XOR;
14040 do_logic:
d75c135e 14041 gen_logic(ctx, mips32_op, rd, rs, rt);
3c824109
NF
14042 break;
14043 /* Set less than */
14044 case SLT:
14045 mips32_op = OPC_SLT;
14046 goto do_slt;
14047 case SLTU:
14048 mips32_op = OPC_SLTU;
14049 do_slt:
d75c135e 14050 gen_slt(ctx, mips32_op, rd, rs, rt);
3c824109
NF
14051 break;
14052 default:
14053 goto pool32a_invalid;
14054 }
14055 break;
14056 case 0x18:
14057 minor = (ctx->opcode >> 6) & 0xf;
14058 switch (minor) {
14059 /* Conditional moves */
e0332095
YK
14060 case MOVN: /* MUL */
14061 if (ctx->insn_flags & ISA_MIPS32R6) {
14062 /* MUL */
14063 gen_r6_muldiv(ctx, R6_OPC_MUL, rd, rs, rt);
14064 } else {
14065 /* MOVN */
14066 gen_cond_move(ctx, OPC_MOVN, rd, rs, rt);
14067 }
14068 break;
14069 case MOVZ: /* MUH */
14070 if (ctx->insn_flags & ISA_MIPS32R6) {
14071 /* MUH */
14072 gen_r6_muldiv(ctx, R6_OPC_MUH, rd, rs, rt);
14073 } else {
14074 /* MOVZ */
14075 gen_cond_move(ctx, OPC_MOVZ, rd, rs, rt);
14076 }
14077 break;
14078 case MULU:
14079 check_insn(ctx, ISA_MIPS32R6);
14080 gen_r6_muldiv(ctx, R6_OPC_MULU, rd, rs, rt);
14081 break;
14082 case MUHU:
14083 check_insn(ctx, ISA_MIPS32R6);
14084 gen_r6_muldiv(ctx, R6_OPC_MUHU, rd, rs, rt);
14085 break;
14086 case LWXS: /* DIV */
14087 if (ctx->insn_flags & ISA_MIPS32R6) {
14088 /* DIV */
14089 gen_r6_muldiv(ctx, R6_OPC_DIV, rd, rs, rt);
14090 } else {
14091 /* LWXS */
14092 gen_ldxs(ctx, rs, rt, rd);
14093 }
14094 break;
14095 case MOD:
14096 check_insn(ctx, ISA_MIPS32R6);
14097 gen_r6_muldiv(ctx, R6_OPC_MOD, rd, rs, rt);
14098 break;
14099 case R6_DIVU:
14100 check_insn(ctx, ISA_MIPS32R6);
14101 gen_r6_muldiv(ctx, R6_OPC_DIVU, rd, rs, rt);
3c824109 14102 break;
e0332095
YK
14103 case MODU:
14104 check_insn(ctx, ISA_MIPS32R6);
14105 gen_r6_muldiv(ctx, R6_OPC_MODU, rd, rs, rt);
3c824109
NF
14106 break;
14107 default:
14108 goto pool32a_invalid;
14109 }
14110 break;
14111 case INS:
14112 gen_bitops(ctx, OPC_INS, rt, rs, rr, rd);
14113 return;
e0332095
YK
14114 case LSA:
14115 check_insn(ctx, ISA_MIPS32R6);
14116 gen_lsa(ctx, OPC_LSA, rd, rs, rt,
14117 extract32(ctx->opcode, 9, 2));
14118 break;
14119 case ALIGN:
14120 check_insn(ctx, ISA_MIPS32R6);
14121 gen_align(ctx, OPC_ALIGN, rd, rs, rt,
14122 extract32(ctx->opcode, 9, 2));
14123 break;
3c824109
NF
14124 case EXT:
14125 gen_bitops(ctx, OPC_EXT, rt, rs, rr, rd);
14126 return;
14127 case POOL32AXF:
240ce26a 14128 gen_pool32axf(env, ctx, rt, rs);
3c824109 14129 break;
dbd8af98 14130 case BREAK32:
9c708c7f 14131 generate_exception_end(ctx, EXCP_BREAK);
3c824109 14132 break;
bb238210
YK
14133 case SIGRIE:
14134 check_insn(ctx, ISA_MIPS32R6);
14135 generate_exception_end(ctx, EXCP_RI);
14136 break;
3c824109
NF
14137 default:
14138 pool32a_invalid:
14139 MIPS_INVAL("pool32a");
9c708c7f 14140 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
14141 break;
14142 }
14143 break;
14144 case POOL32B:
14145 minor = (ctx->opcode >> 12) & 0xf;
14146 switch (minor) {
14147 case CACHE:
2e15497c 14148 check_cp0_enabled(ctx);
0d74a222
LA
14149 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
14150 gen_cache_operation(ctx, rt, rs, imm);
14151 }
3c824109
NF
14152 break;
14153 case LWC2:
14154 case SWC2:
14155 /* COP2: Not implemented. */
14156 generate_exception_err(ctx, EXCP_CpU, 2);
14157 break;
3c824109
NF
14158#ifdef TARGET_MIPS64
14159 case LDP:
14160 case SDP:
d9224450
MR
14161 check_insn(ctx, ISA_MIPS3);
14162 check_mips_64(ctx);
14163 /* Fallthrough */
3c824109 14164#endif
d9224450
MR
14165 case LWP:
14166 case SWP:
3c824109
NF
14167 gen_ldst_pair(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
14168 break;
3c824109
NF
14169#ifdef TARGET_MIPS64
14170 case LDM:
14171 case SDM:
d9224450
MR
14172 check_insn(ctx, ISA_MIPS3);
14173 check_mips_64(ctx);
14174 /* Fallthrough */
3c824109 14175#endif
d9224450
MR
14176 case LWM32:
14177 case SWM32:
3c824109
NF
14178 gen_ldst_multiple(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
14179 break;
14180 default:
14181 MIPS_INVAL("pool32b");
9c708c7f 14182 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
14183 break;
14184 }
14185 break;
14186 case POOL32F:
5ab5c041 14187 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
3c824109
NF
14188 minor = ctx->opcode & 0x3f;
14189 check_cp1_enabled(ctx);
14190 switch (minor) {
14191 case ALNV_PS:
9e8f441a 14192 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14193 mips32_op = OPC_ALNV_PS;
14194 goto do_madd;
14195 case MADD_S:
9e8f441a 14196 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14197 mips32_op = OPC_MADD_S;
14198 goto do_madd;
14199 case MADD_D:
9e8f441a 14200 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14201 mips32_op = OPC_MADD_D;
14202 goto do_madd;
14203 case MADD_PS:
9e8f441a 14204 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14205 mips32_op = OPC_MADD_PS;
14206 goto do_madd;
14207 case MSUB_S:
9e8f441a 14208 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14209 mips32_op = OPC_MSUB_S;
14210 goto do_madd;
14211 case MSUB_D:
9e8f441a 14212 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14213 mips32_op = OPC_MSUB_D;
14214 goto do_madd;
14215 case MSUB_PS:
9e8f441a 14216 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14217 mips32_op = OPC_MSUB_PS;
14218 goto do_madd;
14219 case NMADD_S:
9e8f441a 14220 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14221 mips32_op = OPC_NMADD_S;
14222 goto do_madd;
14223 case NMADD_D:
9e8f441a 14224 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14225 mips32_op = OPC_NMADD_D;
14226 goto do_madd;
14227 case NMADD_PS:
9e8f441a 14228 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14229 mips32_op = OPC_NMADD_PS;
14230 goto do_madd;
14231 case NMSUB_S:
9e8f441a 14232 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14233 mips32_op = OPC_NMSUB_S;
14234 goto do_madd;
14235 case NMSUB_D:
9e8f441a 14236 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14237 mips32_op = OPC_NMSUB_D;
14238 goto do_madd;
14239 case NMSUB_PS:
9e8f441a 14240 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14241 mips32_op = OPC_NMSUB_PS;
14242 do_madd:
14243 gen_flt3_arith(ctx, mips32_op, rd, rr, rs, rt);
14244 break;
14245 case CABS_COND_FMT:
9e8f441a 14246 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14247 cond = (ctx->opcode >> 6) & 0xf;
14248 cc = (ctx->opcode >> 13) & 0x7;
14249 fmt = (ctx->opcode >> 10) & 0x3;
14250 switch (fmt) {
14251 case 0x0:
14252 gen_cmpabs_s(ctx, cond, rt, rs, cc);
14253 break;
14254 case 0x1:
14255 gen_cmpabs_d(ctx, cond, rt, rs, cc);
14256 break;
14257 case 0x2:
14258 gen_cmpabs_ps(ctx, cond, rt, rs, cc);
14259 break;
14260 default:
14261 goto pool32f_invalid;
14262 }
14263 break;
14264 case C_COND_FMT:
9e8f441a 14265 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14266 cond = (ctx->opcode >> 6) & 0xf;
14267 cc = (ctx->opcode >> 13) & 0x7;
14268 fmt = (ctx->opcode >> 10) & 0x3;
14269 switch (fmt) {
14270 case 0x0:
14271 gen_cmp_s(ctx, cond, rt, rs, cc);
14272 break;
14273 case 0x1:
14274 gen_cmp_d(ctx, cond, rt, rs, cc);
14275 break;
14276 case 0x2:
14277 gen_cmp_ps(ctx, cond, rt, rs, cc);
14278 break;
14279 default:
14280 goto pool32f_invalid;
14281 }
14282 break;
2a24a7ba
YK
14283 case CMP_CONDN_S:
14284 check_insn(ctx, ISA_MIPS32R6);
14285 gen_r6_cmp_s(ctx, (ctx->opcode >> 6) & 0x1f, rt, rs, rd);
14286 break;
14287 case CMP_CONDN_D:
14288 check_insn(ctx, ISA_MIPS32R6);
14289 gen_r6_cmp_d(ctx, (ctx->opcode >> 6) & 0x1f, rt, rs, rd);
14290 break;
3c824109 14291 case POOL32FXF:
d75c135e 14292 gen_pool32fxf(ctx, rt, rs);
3c824109
NF
14293 break;
14294 case 0x00:
14295 /* PLL foo */
14296 switch ((ctx->opcode >> 6) & 0x7) {
14297 case PLL_PS:
14298 mips32_op = OPC_PLL_PS;
14299 goto do_ps;
14300 case PLU_PS:
14301 mips32_op = OPC_PLU_PS;
14302 goto do_ps;
14303 case PUL_PS:
14304 mips32_op = OPC_PUL_PS;
14305 goto do_ps;
14306 case PUU_PS:
14307 mips32_op = OPC_PUU_PS;
14308 goto do_ps;
14309 case CVT_PS_S:
9e8f441a 14310 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14311 mips32_op = OPC_CVT_PS_S;
14312 do_ps:
14313 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
14314 break;
14315 default:
14316 goto pool32f_invalid;
14317 }
14318 break;
2a24a7ba
YK
14319 case MIN_FMT:
14320 check_insn(ctx, ISA_MIPS32R6);
14321 switch ((ctx->opcode >> 9) & 0x3) {
14322 case FMT_SDPS_S:
14323 gen_farith(ctx, OPC_MIN_S, rt, rs, rd, 0);
14324 break;
14325 case FMT_SDPS_D:
14326 gen_farith(ctx, OPC_MIN_D, rt, rs, rd, 0);
14327 break;
14328 default:
14329 goto pool32f_invalid;
14330 }
14331 break;
3c824109
NF
14332 case 0x08:
14333 /* [LS][WDU]XC1 */
14334 switch ((ctx->opcode >> 6) & 0x7) {
14335 case LWXC1:
9e8f441a 14336 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14337 mips32_op = OPC_LWXC1;
14338 goto do_ldst_cp1;
14339 case SWXC1:
9e8f441a 14340 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14341 mips32_op = OPC_SWXC1;
14342 goto do_ldst_cp1;
14343 case LDXC1:
9e8f441a 14344 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14345 mips32_op = OPC_LDXC1;
14346 goto do_ldst_cp1;
14347 case SDXC1:
9e8f441a 14348 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14349 mips32_op = OPC_SDXC1;
14350 goto do_ldst_cp1;
14351 case LUXC1:
9e8f441a 14352 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14353 mips32_op = OPC_LUXC1;
14354 goto do_ldst_cp1;
14355 case SUXC1:
9e8f441a 14356 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14357 mips32_op = OPC_SUXC1;
14358 do_ldst_cp1:
14359 gen_flt3_ldst(ctx, mips32_op, rd, rd, rt, rs);
14360 break;
14361 default:
14362 goto pool32f_invalid;
14363 }
14364 break;
2a24a7ba
YK
14365 case MAX_FMT:
14366 check_insn(ctx, ISA_MIPS32R6);
14367 switch ((ctx->opcode >> 9) & 0x3) {
14368 case FMT_SDPS_S:
14369 gen_farith(ctx, OPC_MAX_S, rt, rs, rd, 0);
14370 break;
14371 case FMT_SDPS_D:
14372 gen_farith(ctx, OPC_MAX_D, rt, rs, rd, 0);
14373 break;
14374 default:
14375 goto pool32f_invalid;
14376 }
14377 break;
3c824109
NF
14378 case 0x18:
14379 /* 3D insns */
9e8f441a 14380 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14381 fmt = (ctx->opcode >> 9) & 0x3;
14382 switch ((ctx->opcode >> 6) & 0x7) {
14383 case RSQRT2_FMT:
14384 switch (fmt) {
14385 case FMT_SDPS_S:
14386 mips32_op = OPC_RSQRT2_S;
14387 goto do_3d;
14388 case FMT_SDPS_D:
14389 mips32_op = OPC_RSQRT2_D;
14390 goto do_3d;
14391 case FMT_SDPS_PS:
14392 mips32_op = OPC_RSQRT2_PS;
14393 goto do_3d;
14394 default:
14395 goto pool32f_invalid;
14396 }
14397 break;
14398 case RECIP2_FMT:
14399 switch (fmt) {
14400 case FMT_SDPS_S:
14401 mips32_op = OPC_RECIP2_S;
14402 goto do_3d;
14403 case FMT_SDPS_D:
14404 mips32_op = OPC_RECIP2_D;
14405 goto do_3d;
14406 case FMT_SDPS_PS:
14407 mips32_op = OPC_RECIP2_PS;
14408 goto do_3d;
14409 default:
14410 goto pool32f_invalid;
14411 }
14412 break;
14413 case ADDR_PS:
14414 mips32_op = OPC_ADDR_PS;
14415 goto do_3d;
14416 case MULR_PS:
14417 mips32_op = OPC_MULR_PS;
14418 do_3d:
14419 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
14420 break;
14421 default:
14422 goto pool32f_invalid;
14423 }
14424 break;
14425 case 0x20:
2a24a7ba 14426 /* MOV[FT].fmt, PREFX, RINT.fmt, CLASS.fmt*/
3c824109
NF
14427 cc = (ctx->opcode >> 13) & 0x7;
14428 fmt = (ctx->opcode >> 9) & 0x3;
14429 switch ((ctx->opcode >> 6) & 0x7) {
2a24a7ba
YK
14430 case MOVF_FMT: /* RINT_FMT */
14431 if (ctx->insn_flags & ISA_MIPS32R6) {
14432 /* RINT_FMT */
14433 switch (fmt) {
14434 case FMT_SDPS_S:
14435 gen_farith(ctx, OPC_RINT_S, 0, rt, rs, 0);
14436 break;
14437 case FMT_SDPS_D:
14438 gen_farith(ctx, OPC_RINT_D, 0, rt, rs, 0);
14439 break;
14440 default:
14441 goto pool32f_invalid;
14442 }
14443 } else {
14444 /* MOVF_FMT */
14445 switch (fmt) {
14446 case FMT_SDPS_S:
14447 gen_movcf_s(ctx, rs, rt, cc, 0);
14448 break;
14449 case FMT_SDPS_D:
14450 gen_movcf_d(ctx, rs, rt, cc, 0);
14451 break;
14452 case FMT_SDPS_PS:
14453 check_ps(ctx);
14454 gen_movcf_ps(ctx, rs, rt, cc, 0);
14455 break;
14456 default:
14457 goto pool32f_invalid;
14458 }
3c824109
NF
14459 }
14460 break;
2a24a7ba
YK
14461 case MOVT_FMT: /* CLASS_FMT */
14462 if (ctx->insn_flags & ISA_MIPS32R6) {
14463 /* CLASS_FMT */
14464 switch (fmt) {
14465 case FMT_SDPS_S:
14466 gen_farith(ctx, OPC_CLASS_S, 0, rt, rs, 0);
14467 break;
14468 case FMT_SDPS_D:
14469 gen_farith(ctx, OPC_CLASS_D, 0, rt, rs, 0);
14470 break;
14471 default:
14472 goto pool32f_invalid;
14473 }
14474 } else {
14475 /* MOVT_FMT */
14476 switch (fmt) {
14477 case FMT_SDPS_S:
14478 gen_movcf_s(ctx, rs, rt, cc, 1);
14479 break;
14480 case FMT_SDPS_D:
14481 gen_movcf_d(ctx, rs, rt, cc, 1);
14482 break;
14483 case FMT_SDPS_PS:
14484 check_ps(ctx);
14485 gen_movcf_ps(ctx, rs, rt, cc, 1);
14486 break;
14487 default:
14488 goto pool32f_invalid;
14489 }
3c824109
NF
14490 }
14491 break;
14492 case PREFX:
9e8f441a 14493 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14494 break;
14495 default:
14496 goto pool32f_invalid;
14497 }
14498 break;
14499#define FINSN_3ARG_SDPS(prfx) \
14500 switch ((ctx->opcode >> 8) & 0x3) { \
14501 case FMT_SDPS_S: \
14502 mips32_op = OPC_##prfx##_S; \
14503 goto do_fpop; \
14504 case FMT_SDPS_D: \
14505 mips32_op = OPC_##prfx##_D; \
14506 goto do_fpop; \
14507 case FMT_SDPS_PS: \
e29c9628 14508 check_ps(ctx); \
3c824109
NF
14509 mips32_op = OPC_##prfx##_PS; \
14510 goto do_fpop; \
14511 default: \
14512 goto pool32f_invalid; \
14513 }
2a24a7ba
YK
14514 case MINA_FMT:
14515 check_insn(ctx, ISA_MIPS32R6);
14516 switch ((ctx->opcode >> 9) & 0x3) {
14517 case FMT_SDPS_S:
14518 gen_farith(ctx, OPC_MINA_S, rt, rs, rd, 0);
14519 break;
14520 case FMT_SDPS_D:
14521 gen_farith(ctx, OPC_MINA_D, rt, rs, rd, 0);
14522 break;
14523 default:
14524 goto pool32f_invalid;
14525 }
14526 break;
14527 case MAXA_FMT:
14528 check_insn(ctx, ISA_MIPS32R6);
14529 switch ((ctx->opcode >> 9) & 0x3) {
14530 case FMT_SDPS_S:
14531 gen_farith(ctx, OPC_MAXA_S, rt, rs, rd, 0);
14532 break;
14533 case FMT_SDPS_D:
14534 gen_farith(ctx, OPC_MAXA_D, rt, rs, rd, 0);
14535 break;
14536 default:
14537 goto pool32f_invalid;
14538 }
14539 break;
3c824109
NF
14540 case 0x30:
14541 /* regular FP ops */
14542 switch ((ctx->opcode >> 6) & 0x3) {
14543 case ADD_FMT:
14544 FINSN_3ARG_SDPS(ADD);
14545 break;
14546 case SUB_FMT:
14547 FINSN_3ARG_SDPS(SUB);
14548 break;
14549 case MUL_FMT:
14550 FINSN_3ARG_SDPS(MUL);
14551 break;
14552 case DIV_FMT:
14553 fmt = (ctx->opcode >> 8) & 0x3;
14554 if (fmt == 1) {
14555 mips32_op = OPC_DIV_D;
14556 } else if (fmt == 0) {
14557 mips32_op = OPC_DIV_S;
14558 } else {
14559 goto pool32f_invalid;
14560 }
14561 goto do_fpop;
14562 default:
14563 goto pool32f_invalid;
14564 }
14565 break;
14566 case 0x38:
14567 /* cmovs */
2a24a7ba
YK
14568 switch ((ctx->opcode >> 6) & 0x7) {
14569 case MOVN_FMT: /* SELNEZ_FMT */
14570 if (ctx->insn_flags & ISA_MIPS32R6) {
14571 /* SELNEZ_FMT */
14572 switch ((ctx->opcode >> 9) & 0x3) {
14573 case FMT_SDPS_S:
14574 gen_sel_s(ctx, OPC_SELNEZ_S, rd, rt, rs);
14575 break;
14576 case FMT_SDPS_D:
14577 gen_sel_d(ctx, OPC_SELNEZ_D, rd, rt, rs);
14578 break;
14579 default:
14580 goto pool32f_invalid;
14581 }
14582 } else {
14583 /* MOVN_FMT */
14584 FINSN_3ARG_SDPS(MOVN);
14585 }
14586 break;
14587 case MOVN_FMT_04:
14588 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14589 FINSN_3ARG_SDPS(MOVN);
14590 break;
2a24a7ba
YK
14591 case MOVZ_FMT: /* SELEQZ_FMT */
14592 if (ctx->insn_flags & ISA_MIPS32R6) {
14593 /* SELEQZ_FMT */
14594 switch ((ctx->opcode >> 9) & 0x3) {
14595 case FMT_SDPS_S:
14596 gen_sel_s(ctx, OPC_SELEQZ_S, rd, rt, rs);
14597 break;
14598 case FMT_SDPS_D:
14599 gen_sel_d(ctx, OPC_SELEQZ_D, rd, rt, rs);
14600 break;
14601 default:
14602 goto pool32f_invalid;
14603 }
14604 } else {
14605 /* MOVZ_FMT */
14606 FINSN_3ARG_SDPS(MOVZ);
14607 }
14608 break;
14609 case MOVZ_FMT_05:
14610 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14611 FINSN_3ARG_SDPS(MOVZ);
14612 break;
2a24a7ba
YK
14613 case SEL_FMT:
14614 check_insn(ctx, ISA_MIPS32R6);
14615 switch ((ctx->opcode >> 9) & 0x3) {
14616 case FMT_SDPS_S:
14617 gen_sel_s(ctx, OPC_SEL_S, rd, rt, rs);
14618 break;
14619 case FMT_SDPS_D:
14620 gen_sel_d(ctx, OPC_SEL_D, rd, rt, rs);
14621 break;
14622 default:
14623 goto pool32f_invalid;
14624 }
14625 break;
14626 case MADDF_FMT:
14627 check_insn(ctx, ISA_MIPS32R6);
14628 switch ((ctx->opcode >> 9) & 0x3) {
14629 case FMT_SDPS_S:
14630 mips32_op = OPC_MADDF_S;
14631 goto do_fpop;
14632 case FMT_SDPS_D:
14633 mips32_op = OPC_MADDF_D;
14634 goto do_fpop;
14635 default:
14636 goto pool32f_invalid;
14637 }
14638 break;
14639 case MSUBF_FMT:
14640 check_insn(ctx, ISA_MIPS32R6);
14641 switch ((ctx->opcode >> 9) & 0x3) {
14642 case FMT_SDPS_S:
14643 mips32_op = OPC_MSUBF_S;
14644 goto do_fpop;
14645 case FMT_SDPS_D:
14646 mips32_op = OPC_MSUBF_D;
14647 goto do_fpop;
14648 default:
14649 goto pool32f_invalid;
14650 }
14651 break;
3c824109
NF
14652 default:
14653 goto pool32f_invalid;
14654 }
14655 break;
14656 do_fpop:
14657 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
14658 break;
14659 default:
14660 pool32f_invalid:
14661 MIPS_INVAL("pool32f");
9c708c7f 14662 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
14663 break;
14664 }
14665 } else {
14666 generate_exception_err(ctx, EXCP_CpU, 1);
14667 }
14668 break;
14669 case POOL32I:
14670 minor = (ctx->opcode >> 21) & 0x1f;
14671 switch (minor) {
14672 case BLTZ:
9e8f441a 14673 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
14674 gen_compute_branch(ctx, OPC_BLTZ, 4, rs, -1, imm << 1, 4);
14675 break;
3c824109 14676 case BLTZAL:
9e8f441a 14677 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
14678 gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 4);
14679 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14680 break;
3c824109 14681 case BLTZALS:
9e8f441a 14682 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
14683 gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 2);
14684 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14685 break;
3c824109 14686 case BGEZ:
9e8f441a 14687 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
14688 gen_compute_branch(ctx, OPC_BGEZ, 4, rs, -1, imm << 1, 4);
14689 break;
3c824109 14690 case BGEZAL:
9e8f441a 14691 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
14692 gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 4);
14693 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14694 break;
3c824109 14695 case BGEZALS:
9e8f441a 14696 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
14697 gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 2);
14698 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14699 break;
3c824109 14700 case BLEZ:
9e8f441a 14701 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
14702 gen_compute_branch(ctx, OPC_BLEZ, 4, rs, -1, imm << 1, 4);
14703 break;
3c824109 14704 case BGTZ:
9e8f441a 14705 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103 14706 gen_compute_branch(ctx, OPC_BGTZ, 4, rs, -1, imm << 1, 4);
3c824109
NF
14707 break;
14708
14709 /* Traps */
65935f07
YK
14710 case TLTI: /* BC1EQZC */
14711 if (ctx->insn_flags & ISA_MIPS32R6) {
14712 /* BC1EQZC */
14713 check_cp1_enabled(ctx);
14714 gen_compute_branch1_r6(ctx, OPC_BC1EQZ, rs, imm << 1, 0);
14715 } else {
14716 /* TLTI */
14717 mips32_op = OPC_TLTI;
14718 goto do_trapi;
14719 }
14720 break;
14721 case TGEI: /* BC1NEZC */
14722 if (ctx->insn_flags & ISA_MIPS32R6) {
14723 /* BC1NEZC */
14724 check_cp1_enabled(ctx);
14725 gen_compute_branch1_r6(ctx, OPC_BC1NEZ, rs, imm << 1, 0);
14726 } else {
14727 /* TGEI */
14728 mips32_op = OPC_TGEI;
14729 goto do_trapi;
14730 }
14731 break;
3c824109 14732 case TLTIU:
9e8f441a 14733 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14734 mips32_op = OPC_TLTIU;
14735 goto do_trapi;
14736 case TGEIU:
9e8f441a 14737 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14738 mips32_op = OPC_TGEIU;
14739 goto do_trapi;
3b4a5489
YK
14740 case TNEI: /* SYNCI */
14741 if (ctx->insn_flags & ISA_MIPS32R6) {
14742 /* SYNCI */
14743 /* Break the TB to be able to sync copied instructions
14744 immediately */
eeb3bba8 14745 ctx->base.is_jmp = DISAS_STOP;
3b4a5489
YK
14746 } else {
14747 /* TNEI */
14748 mips32_op = OPC_TNEI;
14749 goto do_trapi;
14750 }
14751 break;
3c824109 14752 case TEQI:
9e8f441a 14753 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14754 mips32_op = OPC_TEQI;
14755 do_trapi:
14756 gen_trap(ctx, mips32_op, rs, -1, imm);
14757 break;
14758
14759 case BNEZC:
14760 case BEQZC:
9e8f441a 14761 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 14762 gen_compute_branch(ctx, minor == BNEZC ? OPC_BNE : OPC_BEQ,
b231c103 14763 4, rs, 0, imm << 1, 0);
3c824109
NF
14764 /* Compact branches don't have a delay slot, so just let
14765 the normal delay slot handling take us to the branch
14766 target. */
14767 break;
14768 case LUI:
9e8f441a 14769 check_insn_opc_removed(ctx, ISA_MIPS32R6);
5e88759a 14770 gen_logic_imm(ctx, OPC_LUI, rs, 0, imm);
3c824109
NF
14771 break;
14772 case SYNCI:
9e8f441a 14773 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a83bddd6
DZ
14774 /* Break the TB to be able to sync copied instructions
14775 immediately */
eeb3bba8 14776 ctx->base.is_jmp = DISAS_STOP;
3c824109
NF
14777 break;
14778 case BC2F:
14779 case BC2T:
9e8f441a 14780 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14781 /* COP2: Not implemented. */
14782 generate_exception_err(ctx, EXCP_CpU, 2);
14783 break;
14784 case BC1F:
9e8f441a 14785 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14786 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1FANY2 : OPC_BC1F;
14787 goto do_cp1branch;
14788 case BC1T:
9e8f441a 14789 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14790 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1TANY2 : OPC_BC1T;
14791 goto do_cp1branch;
14792 case BC1ANY4F:
9e8f441a 14793 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14794 mips32_op = OPC_BC1FANY4;
14795 goto do_cp1mips3d;
14796 case BC1ANY4T:
9e8f441a 14797 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14798 mips32_op = OPC_BC1TANY4;
14799 do_cp1mips3d:
14800 check_cop1x(ctx);
d75c135e 14801 check_insn(ctx, ASE_MIPS3D);
3c824109
NF
14802 /* Fall through */
14803 do_cp1branch:
272f458d
MR
14804 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
14805 check_cp1_enabled(ctx);
14806 gen_compute_branch1(ctx, mips32_op,
14807 (ctx->opcode >> 18) & 0x7, imm << 1);
14808 } else {
14809 generate_exception_err(ctx, EXCP_CpU, 1);
14810 }
3c824109
NF
14811 break;
14812 case BPOSGE64:
14813 case BPOSGE32:
14814 /* MIPS DSP: not implemented */
14815 /* Fall through */
14816 default:
14817 MIPS_INVAL("pool32i");
9c708c7f 14818 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
14819 break;
14820 }
14821 break;
14822 case POOL32C:
14823 minor = (ctx->opcode >> 12) & 0xf;
3b4a5489
YK
14824 offset = sextract32(ctx->opcode, 0,
14825 (ctx->insn_flags & ISA_MIPS32R6) ? 9 : 12);
3c824109
NF
14826 switch (minor) {
14827 case LWL:
9e8f441a 14828 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 14829 mips32_op = OPC_LWL;
5c13fdfd 14830 goto do_ld_lr;
3c824109 14831 case SWL:
9e8f441a 14832 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 14833 mips32_op = OPC_SWL;
5c13fdfd 14834 goto do_st_lr;
3c824109 14835 case LWR:
9e8f441a 14836 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 14837 mips32_op = OPC_LWR;
5c13fdfd 14838 goto do_ld_lr;
3c824109 14839 case SWR:
9e8f441a 14840 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 14841 mips32_op = OPC_SWR;
5c13fdfd 14842 goto do_st_lr;
3c824109
NF
14843#if defined(TARGET_MIPS64)
14844 case LDL:
d9224450
MR
14845 check_insn(ctx, ISA_MIPS3);
14846 check_mips_64(ctx);
9e8f441a 14847 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 14848 mips32_op = OPC_LDL;
5c13fdfd 14849 goto do_ld_lr;
3c824109 14850 case SDL:
d9224450
MR
14851 check_insn(ctx, ISA_MIPS3);
14852 check_mips_64(ctx);
9e8f441a 14853 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 14854 mips32_op = OPC_SDL;
5c13fdfd 14855 goto do_st_lr;
3c824109 14856 case LDR:
d9224450
MR
14857 check_insn(ctx, ISA_MIPS3);
14858 check_mips_64(ctx);
9e8f441a 14859 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 14860 mips32_op = OPC_LDR;
5c13fdfd 14861 goto do_ld_lr;
3c824109 14862 case SDR:
d9224450
MR
14863 check_insn(ctx, ISA_MIPS3);
14864 check_mips_64(ctx);
9e8f441a 14865 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 14866 mips32_op = OPC_SDR;
5c13fdfd 14867 goto do_st_lr;
3c824109 14868 case LWU:
d9224450
MR
14869 check_insn(ctx, ISA_MIPS3);
14870 check_mips_64(ctx);
3c824109 14871 mips32_op = OPC_LWU;
5c13fdfd 14872 goto do_ld_lr;
3c824109 14873 case LLD:
d9224450
MR
14874 check_insn(ctx, ISA_MIPS3);
14875 check_mips_64(ctx);
3c824109 14876 mips32_op = OPC_LLD;
5c13fdfd 14877 goto do_ld_lr;
3c824109
NF
14878#endif
14879 case LL:
14880 mips32_op = OPC_LL;
5c13fdfd
AJ
14881 goto do_ld_lr;
14882 do_ld_lr:
3b4a5489 14883 gen_ld(ctx, mips32_op, rt, rs, offset);
5c13fdfd
AJ
14884 break;
14885 do_st_lr:
8fffc646 14886 gen_st(ctx, mips32_op, rt, rs, offset);
3c824109
NF
14887 break;
14888 case SC:
3b4a5489 14889 gen_st_cond(ctx, OPC_SC, rt, rs, offset);
3c824109
NF
14890 break;
14891#if defined(TARGET_MIPS64)
14892 case SCD:
d9224450
MR
14893 check_insn(ctx, ISA_MIPS3);
14894 check_mips_64(ctx);
3b4a5489 14895 gen_st_cond(ctx, OPC_SCD, rt, rs, offset);
3c824109
NF
14896 break;
14897#endif
8fffc646
JH
14898 case LD_EVA:
14899 if (!ctx->eva) {
14900 MIPS_INVAL("pool32c ld-eva");
14901 generate_exception_end(ctx, EXCP_RI);
14902 break;
14903 }
14904 check_cp0_enabled(ctx);
14905
14906 minor2 = (ctx->opcode >> 9) & 0x7;
14907 offset = sextract32(ctx->opcode, 0, 9);
14908 switch (minor2) {
14909 case LBUE:
14910 mips32_op = OPC_LBUE;
14911 goto do_ld_lr;
14912 case LHUE:
14913 mips32_op = OPC_LHUE;
14914 goto do_ld_lr;
14915 case LWLE:
14916 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14917 mips32_op = OPC_LWLE;
14918 goto do_ld_lr;
14919 case LWRE:
14920 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14921 mips32_op = OPC_LWRE;
14922 goto do_ld_lr;
14923 case LBE:
14924 mips32_op = OPC_LBE;
14925 goto do_ld_lr;
14926 case LHE:
14927 mips32_op = OPC_LHE;
14928 goto do_ld_lr;
14929 case LLE:
14930 mips32_op = OPC_LLE;
14931 goto do_ld_lr;
14932 case LWE:
14933 mips32_op = OPC_LWE;
14934 goto do_ld_lr;
14935 };
14936 break;
14937 case ST_EVA:
14938 if (!ctx->eva) {
14939 MIPS_INVAL("pool32c st-eva");
14940 generate_exception_end(ctx, EXCP_RI);
14941 break;
14942 }
14943 check_cp0_enabled(ctx);
14944
14945 minor2 = (ctx->opcode >> 9) & 0x7;
14946 offset = sextract32(ctx->opcode, 0, 9);
14947 switch (minor2) {
14948 case SWLE:
14949 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14950 mips32_op = OPC_SWLE;
14951 goto do_st_lr;
14952 case SWRE:
14953 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14954 mips32_op = OPC_SWRE;
14955 goto do_st_lr;
14956 case PREFE:
14957 /* Treat as no-op */
14958 if ((ctx->insn_flags & ISA_MIPS32R6) && (rt >= 24)) {
14959 /* hint codes 24-31 are reserved and signal RI */
14960 generate_exception(ctx, EXCP_RI);
14961 }
14962 break;
14963 case CACHEE:
14964 /* Treat as no-op */
14965 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
14966 gen_cache_operation(ctx, rt, rs, offset);
14967 }
14968 break;
14969 case SBE:
14970 mips32_op = OPC_SBE;
14971 goto do_st_lr;
14972 case SHE:
14973 mips32_op = OPC_SHE;
14974 goto do_st_lr;
14975 case SCE:
14976 gen_st_cond(ctx, OPC_SCE, rt, rs, offset);
14977 break;
14978 case SWE:
14979 mips32_op = OPC_SWE;
14980 goto do_st_lr;
14981 };
14982 break;
3c824109
NF
14983 case PREF:
14984 /* Treat as no-op */
3b4a5489
YK
14985 if ((ctx->insn_flags & ISA_MIPS32R6) && (rt >= 24)) {
14986 /* hint codes 24-31 are reserved and signal RI */
14987 generate_exception(ctx, EXCP_RI);
14988 }
3c824109
NF
14989 break;
14990 default:
14991 MIPS_INVAL("pool32c");
9c708c7f 14992 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
14993 break;
14994 }
14995 break;
ab39ee45
YK
14996 case ADDI32: /* AUI, LUI */
14997 if (ctx->insn_flags & ISA_MIPS32R6) {
14998 /* AUI, LUI */
14999 gen_logic_imm(ctx, OPC_LUI, rt, rs, imm);
15000 } else {
15001 /* ADDI32 */
15002 mips32_op = OPC_ADDI;
15003 goto do_addi;
15004 }
15005 break;
3c824109
NF
15006 case ADDIU32:
15007 mips32_op = OPC_ADDIU;
15008 do_addi:
d75c135e 15009 gen_arith_imm(ctx, mips32_op, rt, rs, imm);
3c824109
NF
15010 break;
15011
15012 /* Logical operations */
15013 case ORI32:
15014 mips32_op = OPC_ORI;
15015 goto do_logici;
15016 case XORI32:
15017 mips32_op = OPC_XORI;
15018 goto do_logici;
15019 case ANDI32:
15020 mips32_op = OPC_ANDI;
15021 do_logici:
d75c135e 15022 gen_logic_imm(ctx, mips32_op, rt, rs, imm);
3c824109
NF
15023 break;
15024
15025 /* Set less than immediate */
15026 case SLTI32:
15027 mips32_op = OPC_SLTI;
15028 goto do_slti;
15029 case SLTIU32:
15030 mips32_op = OPC_SLTIU;
15031 do_slti:
d75c135e 15032 gen_slt_imm(ctx, mips32_op, rt, rs, imm);
3c824109
NF
15033 break;
15034 case JALX32:
9e8f441a 15035 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 15036 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
b231c103
YK
15037 gen_compute_branch(ctx, OPC_JALX, 4, rt, rs, offset, 4);
15038 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
3c824109 15039 break;
65935f07
YK
15040 case JALS32: /* BOVC, BEQC, BEQZALC */
15041 if (ctx->insn_flags & ISA_MIPS32R6) {
15042 if (rs >= rt) {
15043 /* BOVC */
15044 mips32_op = OPC_BOVC;
15045 } else if (rs < rt && rs == 0) {
15046 /* BEQZALC */
15047 mips32_op = OPC_BEQZALC;
15048 } else {
15049 /* BEQC */
15050 mips32_op = OPC_BEQC;
15051 }
15052 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
15053 } else {
15054 /* JALS32 */
15055 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 1;
15056 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs, offset, 2);
15057 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
15058 }
3c824109 15059 break;
65935f07
YK
15060 case BEQ32: /* BC */
15061 if (ctx->insn_flags & ISA_MIPS32R6) {
15062 /* BC */
15063 gen_compute_compact_branch(ctx, OPC_BC, 0, 0,
15064 sextract32(ctx->opcode << 1, 0, 27));
15065 } else {
15066 /* BEQ32 */
15067 gen_compute_branch(ctx, OPC_BEQ, 4, rt, rs, imm << 1, 4);
15068 }
3c824109 15069 break;
65935f07
YK
15070 case BNE32: /* BALC */
15071 if (ctx->insn_flags & ISA_MIPS32R6) {
15072 /* BALC */
15073 gen_compute_compact_branch(ctx, OPC_BALC, 0, 0,
15074 sextract32(ctx->opcode << 1, 0, 27));
15075 } else {
15076 /* BNE32 */
15077 gen_compute_branch(ctx, OPC_BNE, 4, rt, rs, imm << 1, 4);
15078 }
3c824109 15079 break;
65935f07
YK
15080 case J32: /* BGTZC, BLTZC, BLTC */
15081 if (ctx->insn_flags & ISA_MIPS32R6) {
15082 if (rs == 0 && rt != 0) {
15083 /* BGTZC */
15084 mips32_op = OPC_BGTZC;
15085 } else if (rs != 0 && rt != 0 && rs == rt) {
15086 /* BLTZC */
15087 mips32_op = OPC_BLTZC;
15088 } else {
15089 /* BLTC */
15090 mips32_op = OPC_BLTC;
15091 }
15092 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
15093 } else {
15094 /* J32 */
15095 gen_compute_branch(ctx, OPC_J, 4, rt, rs,
15096 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
15097 }
3c824109 15098 break;
65935f07
YK
15099 case JAL32: /* BLEZC, BGEZC, BGEC */
15100 if (ctx->insn_flags & ISA_MIPS32R6) {
15101 if (rs == 0 && rt != 0) {
15102 /* BLEZC */
15103 mips32_op = OPC_BLEZC;
15104 } else if (rs != 0 && rt != 0 && rs == rt) {
15105 /* BGEZC */
15106 mips32_op = OPC_BGEZC;
15107 } else {
15108 /* BGEC */
15109 mips32_op = OPC_BGEC;
15110 }
15111 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
15112 } else {
15113 /* JAL32 */
15114 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs,
15115 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
15116 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
15117 }
3c824109
NF
15118 break;
15119 /* Floating point (COP1) */
15120 case LWC132:
15121 mips32_op = OPC_LWC1;
15122 goto do_cop1;
15123 case LDC132:
15124 mips32_op = OPC_LDC1;
15125 goto do_cop1;
15126 case SWC132:
15127 mips32_op = OPC_SWC1;
15128 goto do_cop1;
15129 case SDC132:
15130 mips32_op = OPC_SDC1;
15131 do_cop1:
5ab5c041 15132 gen_cop1_ldst(ctx, mips32_op, rt, rs, imm);
3c824109 15133 break;
ab39ee45
YK
15134 case ADDIUPC: /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
15135 if (ctx->insn_flags & ISA_MIPS32R6) {
15136 /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
15137 switch ((ctx->opcode >> 16) & 0x1f) {
15138 case ADDIUPC_00 ... ADDIUPC_07:
eeb3bba8 15139 gen_pcrel(ctx, OPC_ADDIUPC, ctx->base.pc_next & ~0x3, rt);
ab39ee45
YK
15140 break;
15141 case AUIPC:
eeb3bba8 15142 gen_pcrel(ctx, OPC_AUIPC, ctx->base.pc_next, rt);
ab39ee45
YK
15143 break;
15144 case ALUIPC:
eeb3bba8 15145 gen_pcrel(ctx, OPC_ALUIPC, ctx->base.pc_next, rt);
ab39ee45
YK
15146 break;
15147 case LWPC_08 ... LWPC_0F:
eeb3bba8 15148 gen_pcrel(ctx, R6_OPC_LWPC, ctx->base.pc_next & ~0x3, rt);
ab39ee45
YK
15149 break;
15150 default:
15151 generate_exception(ctx, EXCP_RI);
15152 break;
15153 }
15154 } else {
15155 /* ADDIUPC */
3c824109
NF
15156 int reg = mmreg(ZIMM(ctx->opcode, 23, 3));
15157 int offset = SIMM(ctx->opcode, 0, 23) << 2;
15158
15159 gen_addiupc(ctx, reg, offset, 0, 0);
15160 }
15161 break;
65935f07
YK
15162 case BNVC: /* BNEC, BNEZALC */
15163 check_insn(ctx, ISA_MIPS32R6);
15164 if (rs >= rt) {
15165 /* BNVC */
15166 mips32_op = OPC_BNVC;
15167 } else if (rs < rt && rs == 0) {
15168 /* BNEZALC */
15169 mips32_op = OPC_BNEZALC;
15170 } else {
15171 /* BNEC */
15172 mips32_op = OPC_BNEC;
15173 }
15174 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
15175 break;
15176 case R6_BNEZC: /* JIALC */
15177 check_insn(ctx, ISA_MIPS32R6);
15178 if (rt != 0) {
15179 /* BNEZC */
15180 gen_compute_compact_branch(ctx, OPC_BNEZC, rt, 0,
15181 sextract32(ctx->opcode << 1, 0, 22));
15182 } else {
15183 /* JIALC */
15184 gen_compute_compact_branch(ctx, OPC_JIALC, 0, rs, imm);
15185 }
15186 break;
15187 case R6_BEQZC: /* JIC */
15188 check_insn(ctx, ISA_MIPS32R6);
15189 if (rt != 0) {
15190 /* BEQZC */
15191 gen_compute_compact_branch(ctx, OPC_BEQZC, rt, 0,
15192 sextract32(ctx->opcode << 1, 0, 22));
15193 } else {
15194 /* JIC */
15195 gen_compute_compact_branch(ctx, OPC_JIC, 0, rs, imm);
15196 }
15197 break;
15198 case BLEZALC: /* BGEZALC, BGEUC */
15199 check_insn(ctx, ISA_MIPS32R6);
15200 if (rs == 0 && rt != 0) {
15201 /* BLEZALC */
15202 mips32_op = OPC_BLEZALC;
15203 } else if (rs != 0 && rt != 0 && rs == rt) {
15204 /* BGEZALC */
15205 mips32_op = OPC_BGEZALC;
15206 } else {
15207 /* BGEUC */
15208 mips32_op = OPC_BGEUC;
15209 }
15210 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
15211 break;
15212 case BGTZALC: /* BLTZALC, BLTUC */
15213 check_insn(ctx, ISA_MIPS32R6);
15214 if (rs == 0 && rt != 0) {
15215 /* BGTZALC */
15216 mips32_op = OPC_BGTZALC;
15217 } else if (rs != 0 && rt != 0 && rs == rt) {
15218 /* BLTZALC */
15219 mips32_op = OPC_BLTZALC;
15220 } else {
15221 /* BLTUC */
15222 mips32_op = OPC_BLTUC;
15223 }
15224 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
15225 break;
3c824109
NF
15226 /* Loads and stores */
15227 case LB32:
15228 mips32_op = OPC_LB;
5c13fdfd 15229 goto do_ld;
3c824109
NF
15230 case LBU32:
15231 mips32_op = OPC_LBU;
5c13fdfd 15232 goto do_ld;
3c824109
NF
15233 case LH32:
15234 mips32_op = OPC_LH;
5c13fdfd 15235 goto do_ld;
3c824109
NF
15236 case LHU32:
15237 mips32_op = OPC_LHU;
5c13fdfd 15238 goto do_ld;
3c824109
NF
15239 case LW32:
15240 mips32_op = OPC_LW;
5c13fdfd 15241 goto do_ld;
3c824109
NF
15242#ifdef TARGET_MIPS64
15243 case LD32:
d9224450
MR
15244 check_insn(ctx, ISA_MIPS3);
15245 check_mips_64(ctx);
3c824109 15246 mips32_op = OPC_LD;
5c13fdfd 15247 goto do_ld;
3c824109 15248 case SD32:
d9224450
MR
15249 check_insn(ctx, ISA_MIPS3);
15250 check_mips_64(ctx);
3c824109 15251 mips32_op = OPC_SD;
5c13fdfd 15252 goto do_st;
3c824109
NF
15253#endif
15254 case SB32:
15255 mips32_op = OPC_SB;
5c13fdfd 15256 goto do_st;
3c824109
NF
15257 case SH32:
15258 mips32_op = OPC_SH;
5c13fdfd 15259 goto do_st;
3c824109
NF
15260 case SW32:
15261 mips32_op = OPC_SW;
5c13fdfd
AJ
15262 goto do_st;
15263 do_ld:
d75c135e 15264 gen_ld(ctx, mips32_op, rt, rs, imm);
5c13fdfd
AJ
15265 break;
15266 do_st:
15267 gen_st(ctx, mips32_op, rt, rs, imm);
3c824109
NF
15268 break;
15269 default:
9c708c7f 15270 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
15271 break;
15272 }
15273}
15274
240ce26a 15275static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx)
3c824109
NF
15276{
15277 uint32_t op;
15278
15279 /* make sure instructions are on a halfword boundary */
eeb3bba8
EC
15280 if (ctx->base.pc_next & 0x1) {
15281 env->CP0_BadVAddr = ctx->base.pc_next;
9c708c7f 15282 generate_exception_end(ctx, EXCP_AdEL);
3c824109
NF
15283 return 2;
15284 }
15285
15286 op = (ctx->opcode >> 10) & 0x3f;
15287 /* Enforce properly-sized instructions in a delay slot */
b231c103
YK
15288 if (ctx->hflags & MIPS_HFLAG_BDS_STRICT) {
15289 switch (op & 0x7) { /* MSB-3..MSB-5 */
15290 case 0:
15291 /* POOL32A, POOL32B, POOL32I, POOL32C */
15292 case 4:
15293 /* ADDI32, ADDIU32, ORI32, XORI32, SLTI32, SLTIU32, ANDI32, JALX32 */
15294 case 5:
15295 /* LBU32, LHU32, POOL32F, JALS32, BEQ32, BNE32, J32, JAL32 */
15296 case 6:
15297 /* SB32, SH32, ADDIUPC, SWC132, SDC132, SW32 */
15298 case 7:
15299 /* LB32, LH32, LWC132, LDC132, LW32 */
15300 if (ctx->hflags & MIPS_HFLAG_BDS16) {
9c708c7f 15301 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
15302 return 2;
15303 }
15304 break;
b231c103
YK
15305 case 1:
15306 /* POOL16A, POOL16B, POOL16C, LWGP16, POOL16F */
15307 case 2:
15308 /* LBU16, LHU16, LWSP16, LW16, SB16, SH16, SWSP16, SW16 */
15309 case 3:
15310 /* MOVE16, ANDI16, POOL16D, POOL16E, BEQZ16, BNEZ16, B16, LI16 */
15311 if (ctx->hflags & MIPS_HFLAG_BDS32) {
9c708c7f 15312 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
15313 return 2;
15314 }
15315 break;
3c824109
NF
15316 }
15317 }
b231c103 15318
3c824109
NF
15319 switch (op) {
15320 case POOL16A:
15321 {
15322 int rd = mmreg(uMIPS_RD(ctx->opcode));
15323 int rs1 = mmreg(uMIPS_RS1(ctx->opcode));
15324 int rs2 = mmreg(uMIPS_RS2(ctx->opcode));
15325 uint32_t opc = 0;
15326
15327 switch (ctx->opcode & 0x1) {
15328 case ADDU16:
15329 opc = OPC_ADDU;
15330 break;
15331 case SUBU16:
15332 opc = OPC_SUBU;
15333 break;
15334 }
ed7ce6c0
YK
15335 if (ctx->insn_flags & ISA_MIPS32R6) {
15336 /* In the Release 6 the register number location in
15337 * the instruction encoding has changed.
15338 */
15339 gen_arith(ctx, opc, rs1, rd, rs2);
15340 } else {
15341 gen_arith(ctx, opc, rd, rs1, rs2);
15342 }
3c824109
NF
15343 }
15344 break;
15345 case POOL16B:
15346 {
15347 int rd = mmreg(uMIPS_RD(ctx->opcode));
15348 int rs = mmreg(uMIPS_RS(ctx->opcode));
15349 int amount = (ctx->opcode >> 1) & 0x7;
15350 uint32_t opc = 0;
15351 amount = amount == 0 ? 8 : amount;
15352
15353 switch (ctx->opcode & 0x1) {
15354 case SLL16:
15355 opc = OPC_SLL;
15356 break;
15357 case SRL16:
15358 opc = OPC_SRL;
15359 break;
15360 }
15361
d75c135e 15362 gen_shift_imm(ctx, opc, rd, rs, amount);
3c824109
NF
15363 }
15364 break;
15365 case POOL16C:
ed7ce6c0
YK
15366 if (ctx->insn_flags & ISA_MIPS32R6) {
15367 gen_pool16c_r6_insn(ctx);
15368 } else {
15369 gen_pool16c_insn(ctx);
15370 }
3c824109
NF
15371 break;
15372 case LWGP16:
15373 {
15374 int rd = mmreg(uMIPS_RD(ctx->opcode));
15375 int rb = 28; /* GP */
15376 int16_t offset = SIMM(ctx->opcode, 0, 7) << 2;
15377
d75c135e 15378 gen_ld(ctx, OPC_LW, rd, rb, offset);
3c824109
NF
15379 }
15380 break;
15381 case POOL16F:
9e8f441a 15382 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 15383 if (ctx->opcode & 1) {
9c708c7f 15384 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
15385 } else {
15386 /* MOVEP */
15387 int enc_dest = uMIPS_RD(ctx->opcode);
15388 int enc_rt = uMIPS_RS2(ctx->opcode);
15389 int enc_rs = uMIPS_RS1(ctx->opcode);
ed7ce6c0 15390 gen_movep(ctx, enc_dest, enc_rt, enc_rs);
3c824109
NF
15391 }
15392 break;
15393 case LBU16:
15394 {
15395 int rd = mmreg(uMIPS_RD(ctx->opcode));
15396 int rb = mmreg(uMIPS_RS(ctx->opcode));
15397 int16_t offset = ZIMM(ctx->opcode, 0, 4);
15398 offset = (offset == 0xf ? -1 : offset);
15399
d75c135e 15400 gen_ld(ctx, OPC_LBU, rd, rb, offset);
3c824109
NF
15401 }
15402 break;
15403 case LHU16:
15404 {
15405 int rd = mmreg(uMIPS_RD(ctx->opcode));
15406 int rb = mmreg(uMIPS_RS(ctx->opcode));
15407 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
15408
d75c135e 15409 gen_ld(ctx, OPC_LHU, rd, rb, offset);
3c824109
NF
15410 }
15411 break;
15412 case LWSP16:
15413 {
15414 int rd = (ctx->opcode >> 5) & 0x1f;
15415 int rb = 29; /* SP */
15416 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
15417
d75c135e 15418 gen_ld(ctx, OPC_LW, rd, rb, offset);
3c824109
NF
15419 }
15420 break;
15421 case LW16:
15422 {
15423 int rd = mmreg(uMIPS_RD(ctx->opcode));
15424 int rb = mmreg(uMIPS_RS(ctx->opcode));
15425 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
15426
d75c135e 15427 gen_ld(ctx, OPC_LW, rd, rb, offset);
3c824109
NF
15428 }
15429 break;
15430 case SB16:
15431 {
15432 int rd = mmreg2(uMIPS_RD(ctx->opcode));
15433 int rb = mmreg(uMIPS_RS(ctx->opcode));
15434 int16_t offset = ZIMM(ctx->opcode, 0, 4);
15435
5c13fdfd 15436 gen_st(ctx, OPC_SB, rd, rb, offset);
3c824109
NF
15437 }
15438 break;
15439 case SH16:
15440 {
15441 int rd = mmreg2(uMIPS_RD(ctx->opcode));
15442 int rb = mmreg(uMIPS_RS(ctx->opcode));
15443 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
15444
5c13fdfd 15445 gen_st(ctx, OPC_SH, rd, rb, offset);
3c824109
NF
15446 }
15447 break;
15448 case SWSP16:
15449 {
15450 int rd = (ctx->opcode >> 5) & 0x1f;
15451 int rb = 29; /* SP */
15452 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
15453
5c13fdfd 15454 gen_st(ctx, OPC_SW, rd, rb, offset);
3c824109
NF
15455 }
15456 break;
15457 case SW16:
15458 {
15459 int rd = mmreg2(uMIPS_RD(ctx->opcode));
15460 int rb = mmreg(uMIPS_RS(ctx->opcode));
15461 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
15462
5c13fdfd 15463 gen_st(ctx, OPC_SW, rd, rb, offset);
3c824109
NF
15464 }
15465 break;
15466 case MOVE16:
15467 {
15468 int rd = uMIPS_RD5(ctx->opcode);
15469 int rs = uMIPS_RS5(ctx->opcode);
15470
7215d7e7 15471 gen_arith(ctx, OPC_ADDU, rd, rs, 0);
3c824109
NF
15472 }
15473 break;
15474 case ANDI16:
d75c135e 15475 gen_andi16(ctx);
3c824109
NF
15476 break;
15477 case POOL16D:
15478 switch (ctx->opcode & 0x1) {
15479 case ADDIUS5:
d75c135e 15480 gen_addius5(ctx);
3c824109
NF
15481 break;
15482 case ADDIUSP:
d75c135e 15483 gen_addiusp(ctx);
3c824109
NF
15484 break;
15485 }
15486 break;
15487 case POOL16E:
15488 switch (ctx->opcode & 0x1) {
15489 case ADDIUR2:
d75c135e 15490 gen_addiur2(ctx);
3c824109
NF
15491 break;
15492 case ADDIUR1SP:
d75c135e 15493 gen_addiur1sp(ctx);
3c824109
NF
15494 break;
15495 }
15496 break;
65935f07 15497 case B16: /* BC16 */
3c824109 15498 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0,
65935f07
YK
15499 sextract32(ctx->opcode, 0, 10) << 1,
15500 (ctx->insn_flags & ISA_MIPS32R6) ? 0 : 4);
3c824109 15501 break;
65935f07
YK
15502 case BNEZ16: /* BNEZC16 */
15503 case BEQZ16: /* BEQZC16 */
3c824109
NF
15504 gen_compute_branch(ctx, op == BNEZ16 ? OPC_BNE : OPC_BEQ, 2,
15505 mmreg(uMIPS_RD(ctx->opcode)),
65935f07
YK
15506 0, sextract32(ctx->opcode, 0, 7) << 1,
15507 (ctx->insn_flags & ISA_MIPS32R6) ? 0 : 4);
15508
3c824109
NF
15509 break;
15510 case LI16:
15511 {
15512 int reg = mmreg(uMIPS_RD(ctx->opcode));
15513 int imm = ZIMM(ctx->opcode, 0, 7);
15514
15515 imm = (imm == 0x7f ? -1 : imm);
15516 tcg_gen_movi_tl(cpu_gpr[reg], imm);
15517 }
15518 break;
3c824109 15519 case RES_29:
3c824109 15520 case RES_31:
3c824109 15521 case RES_39:
9c708c7f 15522 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
15523 break;
15524 default:
f60eeb0c 15525 decode_micromips32_opc(env, ctx);
3c824109
NF
15526 return 4;
15527 }
15528
15529 return 2;
15530}
15531
15532/* SmartMIPS extension to MIPS32 */
15533
15534#if defined(TARGET_MIPS64)
15535
15536/* MDMX extension to MIPS64 */
15537
15538#endif
15539
9b1a1d68 15540/* MIPSDSP functions. */
d75c135e 15541static void gen_mipsdsp_ld(DisasContext *ctx, uint32_t opc,
9b1a1d68
JL
15542 int rd, int base, int offset)
15543{
9b1a1d68
JL
15544 TCGv t0;
15545
9b1a1d68
JL
15546 check_dsp(ctx);
15547 t0 = tcg_temp_new();
15548
15549 if (base == 0) {
15550 gen_load_gpr(t0, offset);
15551 } else if (offset == 0) {
15552 gen_load_gpr(t0, base);
15553 } else {
15554 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[offset]);
15555 }
15556
9b1a1d68
JL
15557 switch (opc) {
15558 case OPC_LBUX:
5f68f5ae 15559 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB);
9b1a1d68 15560 gen_store_gpr(t0, rd);
9b1a1d68
JL
15561 break;
15562 case OPC_LHX:
5f68f5ae 15563 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW);
9b1a1d68 15564 gen_store_gpr(t0, rd);
9b1a1d68
JL
15565 break;
15566 case OPC_LWX:
5f68f5ae 15567 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
9b1a1d68 15568 gen_store_gpr(t0, rd);
9b1a1d68
JL
15569 break;
15570#if defined(TARGET_MIPS64)
15571 case OPC_LDX:
5f68f5ae 15572 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
9b1a1d68 15573 gen_store_gpr(t0, rd);
9b1a1d68
JL
15574 break;
15575#endif
15576 }
9b1a1d68
JL
15577 tcg_temp_free(t0);
15578}
15579
461c08df
JL
15580static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
15581 int ret, int v1, int v2)
15582{
461c08df
JL
15583 TCGv v1_t;
15584 TCGv v2_t;
15585
15586 if (ret == 0) {
15587 /* Treat as NOP. */
461c08df
JL
15588 return;
15589 }
15590
15591 v1_t = tcg_temp_new();
15592 v2_t = tcg_temp_new();
15593
15594 gen_load_gpr(v1_t, v1);
15595 gen_load_gpr(v2_t, v2);
15596
15597 switch (op1) {
15598 /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
15599 case OPC_MULT_G_2E:
15600 check_dspr2(ctx);
15601 switch (op2) {
15602 case OPC_ADDUH_QB:
15603 gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t);
15604 break;
15605 case OPC_ADDUH_R_QB:
15606 gen_helper_adduh_r_qb(cpu_gpr[ret], v1_t, v2_t);
15607 break;
15608 case OPC_ADDQH_PH:
15609 gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t);
15610 break;
15611 case OPC_ADDQH_R_PH:
15612 gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
15613 break;
15614 case OPC_ADDQH_W:
15615 gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t);
15616 break;
15617 case OPC_ADDQH_R_W:
15618 gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t);
15619 break;
15620 case OPC_SUBUH_QB:
15621 gen_helper_subuh_qb(cpu_gpr[ret], v1_t, v2_t);
15622 break;
15623 case OPC_SUBUH_R_QB:
15624 gen_helper_subuh_r_qb(cpu_gpr[ret], v1_t, v2_t);
15625 break;
15626 case OPC_SUBQH_PH:
15627 gen_helper_subqh_ph(cpu_gpr[ret], v1_t, v2_t);
15628 break;
15629 case OPC_SUBQH_R_PH:
15630 gen_helper_subqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
15631 break;
15632 case OPC_SUBQH_W:
15633 gen_helper_subqh_w(cpu_gpr[ret], v1_t, v2_t);
15634 break;
15635 case OPC_SUBQH_R_W:
15636 gen_helper_subqh_r_w(cpu_gpr[ret], v1_t, v2_t);
15637 break;
15638 }
15639 break;
15640 case OPC_ABSQ_S_PH_DSP:
15641 switch (op2) {
15642 case OPC_ABSQ_S_QB:
15643 check_dspr2(ctx);
15644 gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, cpu_env);
15645 break;
15646 case OPC_ABSQ_S_PH:
15647 check_dsp(ctx);
15648 gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, cpu_env);
15649 break;
15650 case OPC_ABSQ_S_W:
15651 check_dsp(ctx);
15652 gen_helper_absq_s_w(cpu_gpr[ret], v2_t, cpu_env);
15653 break;
15654 case OPC_PRECEQ_W_PHL:
15655 check_dsp(ctx);
15656 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000);
15657 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
15658 break;
15659 case OPC_PRECEQ_W_PHR:
15660 check_dsp(ctx);
15661 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF);
15662 tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16);
15663 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
15664 break;
15665 case OPC_PRECEQU_PH_QBL:
15666 check_dsp(ctx);
15667 gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t);
15668 break;
15669 case OPC_PRECEQU_PH_QBR:
15670 check_dsp(ctx);
15671 gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t);
15672 break;
15673 case OPC_PRECEQU_PH_QBLA:
15674 check_dsp(ctx);
15675 gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t);
15676 break;
15677 case OPC_PRECEQU_PH_QBRA:
15678 check_dsp(ctx);
15679 gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t);
15680 break;
15681 case OPC_PRECEU_PH_QBL:
15682 check_dsp(ctx);
15683 gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t);
15684 break;
15685 case OPC_PRECEU_PH_QBR:
15686 check_dsp(ctx);
15687 gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t);
15688 break;
15689 case OPC_PRECEU_PH_QBLA:
15690 check_dsp(ctx);
15691 gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t);
15692 break;
15693 case OPC_PRECEU_PH_QBRA:
15694 check_dsp(ctx);
15695 gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t);
15696 break;
15697 }
15698 break;
15699 case OPC_ADDU_QB_DSP:
15700 switch (op2) {
15701 case OPC_ADDQ_PH:
15702 check_dsp(ctx);
15703 gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15704 break;
15705 case OPC_ADDQ_S_PH:
15706 check_dsp(ctx);
15707 gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15708 break;
15709 case OPC_ADDQ_S_W:
15710 check_dsp(ctx);
15711 gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15712 break;
15713 case OPC_ADDU_QB:
15714 check_dsp(ctx);
15715 gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15716 break;
15717 case OPC_ADDU_S_QB:
15718 check_dsp(ctx);
15719 gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15720 break;
15721 case OPC_ADDU_PH:
15722 check_dspr2(ctx);
15723 gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15724 break;
15725 case OPC_ADDU_S_PH:
15726 check_dspr2(ctx);
15727 gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15728 break;
15729 case OPC_SUBQ_PH:
15730 check_dsp(ctx);
15731 gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15732 break;
15733 case OPC_SUBQ_S_PH:
15734 check_dsp(ctx);
15735 gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15736 break;
15737 case OPC_SUBQ_S_W:
15738 check_dsp(ctx);
15739 gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15740 break;
15741 case OPC_SUBU_QB:
15742 check_dsp(ctx);
15743 gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15744 break;
15745 case OPC_SUBU_S_QB:
15746 check_dsp(ctx);
15747 gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15748 break;
15749 case OPC_SUBU_PH:
15750 check_dspr2(ctx);
15751 gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15752 break;
15753 case OPC_SUBU_S_PH:
15754 check_dspr2(ctx);
15755 gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15756 break;
15757 case OPC_ADDSC:
15758 check_dsp(ctx);
15759 gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15760 break;
15761 case OPC_ADDWC:
15762 check_dsp(ctx);
15763 gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15764 break;
15765 case OPC_MODSUB:
15766 check_dsp(ctx);
15767 gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t);
15768 break;
15769 case OPC_RADDU_W_QB:
15770 check_dsp(ctx);
15771 gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t);
15772 break;
15773 }
15774 break;
15775 case OPC_CMPU_EQ_QB_DSP:
15776 switch (op2) {
15777 case OPC_PRECR_QB_PH:
15778 check_dspr2(ctx);
15779 gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t);
15780 break;
15781 case OPC_PRECRQ_QB_PH:
15782 check_dsp(ctx);
15783 gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t);
15784 break;
15785 case OPC_PRECR_SRA_PH_W:
15786 check_dspr2(ctx);
15787 {
15788 TCGv_i32 sa_t = tcg_const_i32(v2);
15789 gen_helper_precr_sra_ph_w(cpu_gpr[ret], sa_t, v1_t,
15790 cpu_gpr[ret]);
15791 tcg_temp_free_i32(sa_t);
15792 break;
15793 }
15794 case OPC_PRECR_SRA_R_PH_W:
15795 check_dspr2(ctx);
15796 {
15797 TCGv_i32 sa_t = tcg_const_i32(v2);
15798 gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t,
15799 cpu_gpr[ret]);
15800 tcg_temp_free_i32(sa_t);
15801 break;
15802 }
15803 case OPC_PRECRQ_PH_W:
15804 check_dsp(ctx);
15805 gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t);
15806 break;
15807 case OPC_PRECRQ_RS_PH_W:
15808 check_dsp(ctx);
15809 gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15810 break;
15811 case OPC_PRECRQU_S_QB_PH:
15812 check_dsp(ctx);
15813 gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15814 break;
15815 }
15816 break;
15817#ifdef TARGET_MIPS64
15818 case OPC_ABSQ_S_QH_DSP:
15819 switch (op2) {
15820 case OPC_PRECEQ_L_PWL:
15821 check_dsp(ctx);
15822 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull);
15823 break;
15824 case OPC_PRECEQ_L_PWR:
15825 check_dsp(ctx);
15826 tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32);
15827 break;
15828 case OPC_PRECEQ_PW_QHL:
15829 check_dsp(ctx);
15830 gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t);
15831 break;
15832 case OPC_PRECEQ_PW_QHR:
15833 check_dsp(ctx);
15834 gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t);
15835 break;
15836 case OPC_PRECEQ_PW_QHLA:
15837 check_dsp(ctx);
15838 gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t);
15839 break;
15840 case OPC_PRECEQ_PW_QHRA:
15841 check_dsp(ctx);
15842 gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t);
15843 break;
15844 case OPC_PRECEQU_QH_OBL:
15845 check_dsp(ctx);
15846 gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t);
15847 break;
15848 case OPC_PRECEQU_QH_OBR:
15849 check_dsp(ctx);
15850 gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t);
15851 break;
15852 case OPC_PRECEQU_QH_OBLA:
15853 check_dsp(ctx);
15854 gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t);
15855 break;
15856 case OPC_PRECEQU_QH_OBRA:
15857 check_dsp(ctx);
15858 gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t);
15859 break;
15860 case OPC_PRECEU_QH_OBL:
15861 check_dsp(ctx);
15862 gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t);
15863 break;
15864 case OPC_PRECEU_QH_OBR:
15865 check_dsp(ctx);
15866 gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t);
15867 break;
15868 case OPC_PRECEU_QH_OBLA:
15869 check_dsp(ctx);
15870 gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t);
15871 break;
15872 case OPC_PRECEU_QH_OBRA:
15873 check_dsp(ctx);
15874 gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t);
15875 break;
15876 case OPC_ABSQ_S_OB:
15877 check_dspr2(ctx);
15878 gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, cpu_env);
15879 break;
15880 case OPC_ABSQ_S_PW:
15881 check_dsp(ctx);
15882 gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, cpu_env);
15883 break;
15884 case OPC_ABSQ_S_QH:
15885 check_dsp(ctx);
15886 gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, cpu_env);
15887 break;
15888 }
15889 break;
15890 case OPC_ADDU_OB_DSP:
15891 switch (op2) {
15892 case OPC_RADDU_L_OB:
15893 check_dsp(ctx);
15894 gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t);
15895 break;
15896 case OPC_SUBQ_PW:
15897 check_dsp(ctx);
15898 gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15899 break;
15900 case OPC_SUBQ_S_PW:
15901 check_dsp(ctx);
15902 gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15903 break;
15904 case OPC_SUBQ_QH:
15905 check_dsp(ctx);
15906 gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15907 break;
15908 case OPC_SUBQ_S_QH:
15909 check_dsp(ctx);
15910 gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15911 break;
15912 case OPC_SUBU_OB:
15913 check_dsp(ctx);
15914 gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15915 break;
15916 case OPC_SUBU_S_OB:
15917 check_dsp(ctx);
15918 gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15919 break;
15920 case OPC_SUBU_QH:
15921 check_dspr2(ctx);
15922 gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15923 break;
15924 case OPC_SUBU_S_QH:
15925 check_dspr2(ctx);
15926 gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15927 break;
15928 case OPC_SUBUH_OB:
15929 check_dspr2(ctx);
15930 gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t);
15931 break;
15932 case OPC_SUBUH_R_OB:
15933 check_dspr2(ctx);
15934 gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t);
15935 break;
15936 case OPC_ADDQ_PW:
15937 check_dsp(ctx);
15938 gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15939 break;
15940 case OPC_ADDQ_S_PW:
15941 check_dsp(ctx);
15942 gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15943 break;
15944 case OPC_ADDQ_QH:
15945 check_dsp(ctx);
15946 gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15947 break;
15948 case OPC_ADDQ_S_QH:
15949 check_dsp(ctx);
15950 gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15951 break;
15952 case OPC_ADDU_OB:
15953 check_dsp(ctx);
15954 gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15955 break;
15956 case OPC_ADDU_S_OB:
15957 check_dsp(ctx);
15958 gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15959 break;
15960 case OPC_ADDU_QH:
15961 check_dspr2(ctx);
15962 gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15963 break;
15964 case OPC_ADDU_S_QH:
15965 check_dspr2(ctx);
15966 gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15967 break;
15968 case OPC_ADDUH_OB:
15969 check_dspr2(ctx);
15970 gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t);
15971 break;
15972 case OPC_ADDUH_R_OB:
15973 check_dspr2(ctx);
15974 gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t);
15975 break;
15976 }
15977 break;
15978 case OPC_CMPU_EQ_OB_DSP:
15979 switch (op2) {
15980 case OPC_PRECR_OB_QH:
15981 check_dspr2(ctx);
15982 gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t);
15983 break;
15984 case OPC_PRECR_SRA_QH_PW:
15985 check_dspr2(ctx);
15986 {
15987 TCGv_i32 ret_t = tcg_const_i32(ret);
15988 gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t);
15989 tcg_temp_free_i32(ret_t);
15990 break;
15991 }
15992 case OPC_PRECR_SRA_R_QH_PW:
15993 check_dspr2(ctx);
15994 {
15995 TCGv_i32 sa_v = tcg_const_i32(ret);
15996 gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v);
15997 tcg_temp_free_i32(sa_v);
15998 break;
15999 }
16000 case OPC_PRECRQ_OB_QH:
16001 check_dsp(ctx);
16002 gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t);
16003 break;
16004 case OPC_PRECRQ_PW_L:
16005 check_dsp(ctx);
16006 gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t);
16007 break;
16008 case OPC_PRECRQ_QH_PW:
16009 check_dsp(ctx);
16010 gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t);
16011 break;
16012 case OPC_PRECRQ_RS_QH_PW:
16013 check_dsp(ctx);
16014 gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16015 break;
16016 case OPC_PRECRQU_S_OB_QH:
16017 check_dsp(ctx);
16018 gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16019 break;
16020 }
16021 break;
16022#endif
16023 }
16024
16025 tcg_temp_free(v1_t);
16026 tcg_temp_free(v2_t);
461c08df 16027}
9b1a1d68 16028
77c5fa8b
JL
16029static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc,
16030 int ret, int v1, int v2)
16031{
16032 uint32_t op2;
77c5fa8b
JL
16033 TCGv t0;
16034 TCGv v1_t;
16035 TCGv v2_t;
16036
16037 if (ret == 0) {
16038 /* Treat as NOP. */
77c5fa8b
JL
16039 return;
16040 }
16041
16042 t0 = tcg_temp_new();
16043 v1_t = tcg_temp_new();
16044 v2_t = tcg_temp_new();
16045
16046 tcg_gen_movi_tl(t0, v1);
16047 gen_load_gpr(v1_t, v1);
16048 gen_load_gpr(v2_t, v2);
16049
16050 switch (opc) {
16051 case OPC_SHLL_QB_DSP:
16052 {
16053 op2 = MASK_SHLL_QB(ctx->opcode);
16054 switch (op2) {
16055 case OPC_SHLL_QB:
16056 check_dsp(ctx);
16057 gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, cpu_env);
16058 break;
16059 case OPC_SHLLV_QB:
16060 check_dsp(ctx);
16061 gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16062 break;
16063 case OPC_SHLL_PH:
16064 check_dsp(ctx);
16065 gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
16066 break;
16067 case OPC_SHLLV_PH:
16068 check_dsp(ctx);
16069 gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16070 break;
16071 case OPC_SHLL_S_PH:
16072 check_dsp(ctx);
16073 gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
16074 break;
16075 case OPC_SHLLV_S_PH:
16076 check_dsp(ctx);
16077 gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16078 break;
16079 case OPC_SHLL_S_W:
16080 check_dsp(ctx);
16081 gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, cpu_env);
16082 break;
16083 case OPC_SHLLV_S_W:
16084 check_dsp(ctx);
16085 gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16086 break;
16087 case OPC_SHRL_QB:
16088 check_dsp(ctx);
16089 gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t);
16090 break;
16091 case OPC_SHRLV_QB:
16092 check_dsp(ctx);
16093 gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t);
16094 break;
16095 case OPC_SHRL_PH:
16096 check_dspr2(ctx);
16097 gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t);
16098 break;
16099 case OPC_SHRLV_PH:
16100 check_dspr2(ctx);
16101 gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t);
16102 break;
16103 case OPC_SHRA_QB:
16104 check_dspr2(ctx);
16105 gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t);
16106 break;
16107 case OPC_SHRA_R_QB:
16108 check_dspr2(ctx);
16109 gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t);
16110 break;
16111 case OPC_SHRAV_QB:
16112 check_dspr2(ctx);
16113 gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t);
16114 break;
16115 case OPC_SHRAV_R_QB:
16116 check_dspr2(ctx);
16117 gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t);
16118 break;
16119 case OPC_SHRA_PH:
16120 check_dsp(ctx);
16121 gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t);
16122 break;
16123 case OPC_SHRA_R_PH:
16124 check_dsp(ctx);
16125 gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t);
16126 break;
16127 case OPC_SHRAV_PH:
16128 check_dsp(ctx);
16129 gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t);
16130 break;
16131 case OPC_SHRAV_R_PH:
16132 check_dsp(ctx);
16133 gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t);
16134 break;
16135 case OPC_SHRA_R_W:
16136 check_dsp(ctx);
16137 gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t);
16138 break;
16139 case OPC_SHRAV_R_W:
16140 check_dsp(ctx);
16141 gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t);
16142 break;
16143 default: /* Invalid */
16144 MIPS_INVAL("MASK SHLL.QB");
9c708c7f 16145 generate_exception_end(ctx, EXCP_RI);
77c5fa8b
JL
16146 break;
16147 }
16148 break;
16149 }
16150#ifdef TARGET_MIPS64
16151 case OPC_SHLL_OB_DSP:
16152 op2 = MASK_SHLL_OB(ctx->opcode);
16153 switch (op2) {
16154 case OPC_SHLL_PW:
16155 check_dsp(ctx);
16156 gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
16157 break;
16158 case OPC_SHLLV_PW:
16159 check_dsp(ctx);
16160 gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
16161 break;
16162 case OPC_SHLL_S_PW:
16163 check_dsp(ctx);
16164 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
16165 break;
16166 case OPC_SHLLV_S_PW:
16167 check_dsp(ctx);
16168 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
16169 break;
16170 case OPC_SHLL_OB:
16171 check_dsp(ctx);
16172 gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, cpu_env);
16173 break;
16174 case OPC_SHLLV_OB:
16175 check_dsp(ctx);
16176 gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, cpu_env);
16177 break;
16178 case OPC_SHLL_QH:
16179 check_dsp(ctx);
16180 gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
16181 break;
16182 case OPC_SHLLV_QH:
16183 check_dsp(ctx);
16184 gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
16185 break;
16186 case OPC_SHLL_S_QH:
16187 check_dsp(ctx);
16188 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
16189 break;
16190 case OPC_SHLLV_S_QH:
16191 check_dsp(ctx);
16192 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
16193 break;
16194 case OPC_SHRA_OB:
16195 check_dspr2(ctx);
16196 gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0);
16197 break;
16198 case OPC_SHRAV_OB:
16199 check_dspr2(ctx);
16200 gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t);
16201 break;
16202 case OPC_SHRA_R_OB:
16203 check_dspr2(ctx);
16204 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0);
16205 break;
16206 case OPC_SHRAV_R_OB:
16207 check_dspr2(ctx);
16208 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t);
16209 break;
16210 case OPC_SHRA_PW:
16211 check_dsp(ctx);
16212 gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0);
16213 break;
16214 case OPC_SHRAV_PW:
16215 check_dsp(ctx);
16216 gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t);
16217 break;
16218 case OPC_SHRA_R_PW:
16219 check_dsp(ctx);
16220 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0);
16221 break;
16222 case OPC_SHRAV_R_PW:
16223 check_dsp(ctx);
16224 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t);
16225 break;
16226 case OPC_SHRA_QH:
16227 check_dsp(ctx);
16228 gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0);
16229 break;
16230 case OPC_SHRAV_QH:
16231 check_dsp(ctx);
16232 gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t);
16233 break;
16234 case OPC_SHRA_R_QH:
16235 check_dsp(ctx);
16236 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0);
16237 break;
16238 case OPC_SHRAV_R_QH:
16239 check_dsp(ctx);
16240 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t);
16241 break;
16242 case OPC_SHRL_OB:
16243 check_dsp(ctx);
16244 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0);
16245 break;
16246 case OPC_SHRLV_OB:
16247 check_dsp(ctx);
16248 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t);
16249 break;
16250 case OPC_SHRL_QH:
16251 check_dspr2(ctx);
16252 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0);
16253 break;
16254 case OPC_SHRLV_QH:
16255 check_dspr2(ctx);
16256 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t);
16257 break;
16258 default: /* Invalid */
16259 MIPS_INVAL("MASK SHLL.OB");
9c708c7f 16260 generate_exception_end(ctx, EXCP_RI);
77c5fa8b
JL
16261 break;
16262 }
16263 break;
16264#endif
16265 }
16266
16267 tcg_temp_free(t0);
16268 tcg_temp_free(v1_t);
16269 tcg_temp_free(v2_t);
77c5fa8b
JL
16270}
16271
a22260ae
JL
16272static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2,
16273 int ret, int v1, int v2, int check_ret)
16274{
a22260ae
JL
16275 TCGv_i32 t0;
16276 TCGv v1_t;
16277 TCGv v2_t;
16278
16279 if ((ret == 0) && (check_ret == 1)) {
16280 /* Treat as NOP. */
a22260ae
JL
16281 return;
16282 }
16283
16284 t0 = tcg_temp_new_i32();
16285 v1_t = tcg_temp_new();
16286 v2_t = tcg_temp_new();
16287
16288 tcg_gen_movi_i32(t0, ret);
16289 gen_load_gpr(v1_t, v1);
16290 gen_load_gpr(v2_t, v2);
16291
16292 switch (op1) {
16293 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
16294 * the same mask and op1. */
16295 case OPC_MULT_G_2E:
639eadb9 16296 check_dspr2(ctx);
a22260ae
JL
16297 switch (op2) {
16298 case OPC_MUL_PH:
16299 gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16300 break;
16301 case OPC_MUL_S_PH:
16302 gen_helper_mul_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16303 break;
16304 case OPC_MULQ_S_W:
16305 gen_helper_mulq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16306 break;
16307 case OPC_MULQ_RS_W:
16308 gen_helper_mulq_rs_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16309 break;
16310 }
16311 break;
16312 case OPC_DPA_W_PH_DSP:
16313 switch (op2) {
16314 case OPC_DPAU_H_QBL:
16315 check_dsp(ctx);
16316 gen_helper_dpau_h_qbl(t0, v1_t, v2_t, cpu_env);
16317 break;
16318 case OPC_DPAU_H_QBR:
16319 check_dsp(ctx);
16320 gen_helper_dpau_h_qbr(t0, v1_t, v2_t, cpu_env);
16321 break;
16322 case OPC_DPSU_H_QBL:
16323 check_dsp(ctx);
16324 gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, cpu_env);
16325 break;
16326 case OPC_DPSU_H_QBR:
16327 check_dsp(ctx);
16328 gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, cpu_env);
16329 break;
16330 case OPC_DPA_W_PH:
16331 check_dspr2(ctx);
16332 gen_helper_dpa_w_ph(t0, v1_t, v2_t, cpu_env);
16333 break;
16334 case OPC_DPAX_W_PH:
16335 check_dspr2(ctx);
16336 gen_helper_dpax_w_ph(t0, v1_t, v2_t, cpu_env);
16337 break;
16338 case OPC_DPAQ_S_W_PH:
16339 check_dsp(ctx);
16340 gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
16341 break;
16342 case OPC_DPAQX_S_W_PH:
16343 check_dspr2(ctx);
16344 gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
16345 break;
16346 case OPC_DPAQX_SA_W_PH:
16347 check_dspr2(ctx);
16348 gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
16349 break;
16350 case OPC_DPS_W_PH:
16351 check_dspr2(ctx);
16352 gen_helper_dps_w_ph(t0, v1_t, v2_t, cpu_env);
16353 break;
16354 case OPC_DPSX_W_PH:
16355 check_dspr2(ctx);
16356 gen_helper_dpsx_w_ph(t0, v1_t, v2_t, cpu_env);
16357 break;
16358 case OPC_DPSQ_S_W_PH:
16359 check_dsp(ctx);
16360 gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, cpu_env);
16361 break;
16362 case OPC_DPSQX_S_W_PH:
16363 check_dspr2(ctx);
16364 gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
16365 break;
16366 case OPC_DPSQX_SA_W_PH:
16367 check_dspr2(ctx);
16368 gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
16369 break;
16370 case OPC_MULSAQ_S_W_PH:
16371 check_dsp(ctx);
16372 gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
16373 break;
16374 case OPC_DPAQ_SA_L_W:
16375 check_dsp(ctx);
16376 gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, cpu_env);
16377 break;
16378 case OPC_DPSQ_SA_L_W:
16379 check_dsp(ctx);
16380 gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, cpu_env);
16381 break;
16382 case OPC_MAQ_S_W_PHL:
16383 check_dsp(ctx);
16384 gen_helper_maq_s_w_phl(t0, v1_t, v2_t, cpu_env);
16385 break;
16386 case OPC_MAQ_S_W_PHR:
16387 check_dsp(ctx);
16388 gen_helper_maq_s_w_phr(t0, v1_t, v2_t, cpu_env);
16389 break;
16390 case OPC_MAQ_SA_W_PHL:
16391 check_dsp(ctx);
16392 gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, cpu_env);
16393 break;
16394 case OPC_MAQ_SA_W_PHR:
16395 check_dsp(ctx);
16396 gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, cpu_env);
16397 break;
16398 case OPC_MULSA_W_PH:
16399 check_dspr2(ctx);
16400 gen_helper_mulsa_w_ph(t0, v1_t, v2_t, cpu_env);
16401 break;
16402 }
16403 break;
16404#ifdef TARGET_MIPS64
16405 case OPC_DPAQ_W_QH_DSP:
16406 {
16407 int ac = ret & 0x03;
16408 tcg_gen_movi_i32(t0, ac);
16409
16410 switch (op2) {
16411 case OPC_DMADD:
16412 check_dsp(ctx);
16413 gen_helper_dmadd(v1_t, v2_t, t0, cpu_env);
16414 break;
16415 case OPC_DMADDU:
16416 check_dsp(ctx);
16417 gen_helper_dmaddu(v1_t, v2_t, t0, cpu_env);
16418 break;
16419 case OPC_DMSUB:
16420 check_dsp(ctx);
16421 gen_helper_dmsub(v1_t, v2_t, t0, cpu_env);
16422 break;
16423 case OPC_DMSUBU:
16424 check_dsp(ctx);
16425 gen_helper_dmsubu(v1_t, v2_t, t0, cpu_env);
16426 break;
16427 case OPC_DPA_W_QH:
16428 check_dspr2(ctx);
16429 gen_helper_dpa_w_qh(v1_t, v2_t, t0, cpu_env);
16430 break;
16431 case OPC_DPAQ_S_W_QH:
16432 check_dsp(ctx);
16433 gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
16434 break;
16435 case OPC_DPAQ_SA_L_PW:
16436 check_dsp(ctx);
16437 gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
16438 break;
16439 case OPC_DPAU_H_OBL:
16440 check_dsp(ctx);
16441 gen_helper_dpau_h_obl(v1_t, v2_t, t0, cpu_env);
16442 break;
16443 case OPC_DPAU_H_OBR:
16444 check_dsp(ctx);
16445 gen_helper_dpau_h_obr(v1_t, v2_t, t0, cpu_env);
16446 break;
16447 case OPC_DPS_W_QH:
16448 check_dspr2(ctx);
16449 gen_helper_dps_w_qh(v1_t, v2_t, t0, cpu_env);
16450 break;
16451 case OPC_DPSQ_S_W_QH:
16452 check_dsp(ctx);
16453 gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, cpu_env);
16454 break;
16455 case OPC_DPSQ_SA_L_PW:
16456 check_dsp(ctx);
16457 gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
16458 break;
16459 case OPC_DPSU_H_OBL:
16460 check_dsp(ctx);
16461 gen_helper_dpsu_h_obl(v1_t, v2_t, t0, cpu_env);
16462 break;
16463 case OPC_DPSU_H_OBR:
16464 check_dsp(ctx);
16465 gen_helper_dpsu_h_obr(v1_t, v2_t, t0, cpu_env);
16466 break;
16467 case OPC_MAQ_S_L_PWL:
16468 check_dsp(ctx);
16469 gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, cpu_env);
16470 break;
16471 case OPC_MAQ_S_L_PWR:
16472 check_dsp(ctx);
16473 gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, cpu_env);
16474 break;
16475 case OPC_MAQ_S_W_QHLL:
16476 check_dsp(ctx);
16477 gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, cpu_env);
16478 break;
16479 case OPC_MAQ_SA_W_QHLL:
16480 check_dsp(ctx);
16481 gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, cpu_env);
16482 break;
16483 case OPC_MAQ_S_W_QHLR:
16484 check_dsp(ctx);
16485 gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, cpu_env);
16486 break;
16487 case OPC_MAQ_SA_W_QHLR:
16488 check_dsp(ctx);
16489 gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, cpu_env);
16490 break;
16491 case OPC_MAQ_S_W_QHRL:
16492 check_dsp(ctx);
16493 gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, cpu_env);
16494 break;
16495 case OPC_MAQ_SA_W_QHRL:
16496 check_dsp(ctx);
16497 gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, cpu_env);
16498 break;
16499 case OPC_MAQ_S_W_QHRR:
16500 check_dsp(ctx);
16501 gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, cpu_env);
16502 break;
16503 case OPC_MAQ_SA_W_QHRR:
16504 check_dsp(ctx);
16505 gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, cpu_env);
16506 break;
16507 case OPC_MULSAQ_S_L_PW:
16508 check_dsp(ctx);
16509 gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, cpu_env);
16510 break;
16511 case OPC_MULSAQ_S_W_QH:
16512 check_dsp(ctx);
16513 gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
16514 break;
16515 }
16516 }
16517 break;
16518#endif
16519 case OPC_ADDU_QB_DSP:
16520 switch (op2) {
16521 case OPC_MULEU_S_PH_QBL:
16522 check_dsp(ctx);
16523 gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16524 break;
16525 case OPC_MULEU_S_PH_QBR:
16526 check_dsp(ctx);
16527 gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16528 break;
16529 case OPC_MULQ_RS_PH:
16530 check_dsp(ctx);
16531 gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16532 break;
16533 case OPC_MULEQ_S_W_PHL:
16534 check_dsp(ctx);
16535 gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16536 break;
16537 case OPC_MULEQ_S_W_PHR:
16538 check_dsp(ctx);
16539 gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16540 break;
16541 case OPC_MULQ_S_PH:
16542 check_dspr2(ctx);
16543 gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16544 break;
16545 }
16546 break;
16547#ifdef TARGET_MIPS64
16548 case OPC_ADDU_OB_DSP:
16549 switch (op2) {
16550 case OPC_MULEQ_S_PW_QHL:
16551 check_dsp(ctx);
16552 gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16553 break;
16554 case OPC_MULEQ_S_PW_QHR:
16555 check_dsp(ctx);
16556 gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16557 break;
16558 case OPC_MULEU_S_QH_OBL:
16559 check_dsp(ctx);
16560 gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16561 break;
16562 case OPC_MULEU_S_QH_OBR:
16563 check_dsp(ctx);
16564 gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16565 break;
16566 case OPC_MULQ_RS_QH:
16567 check_dsp(ctx);
16568 gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16569 break;
16570 }
16571 break;
16572#endif
16573 }
16574
16575 tcg_temp_free_i32(t0);
16576 tcg_temp_free(v1_t);
16577 tcg_temp_free(v2_t);
a22260ae
JL
16578}
16579
d75c135e 16580static void gen_mipsdsp_bitinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
1cb6686c
JL
16581 int ret, int val)
16582{
1cb6686c
JL
16583 int16_t imm;
16584 TCGv t0;
16585 TCGv val_t;
16586
16587 if (ret == 0) {
16588 /* Treat as NOP. */
1cb6686c
JL
16589 return;
16590 }
16591
16592 t0 = tcg_temp_new();
16593 val_t = tcg_temp_new();
16594 gen_load_gpr(val_t, val);
16595
16596 switch (op1) {
16597 case OPC_ABSQ_S_PH_DSP:
16598 switch (op2) {
16599 case OPC_BITREV:
16600 check_dsp(ctx);
16601 gen_helper_bitrev(cpu_gpr[ret], val_t);
16602 break;
16603 case OPC_REPL_QB:
16604 check_dsp(ctx);
16605 {
16606 target_long result;
16607 imm = (ctx->opcode >> 16) & 0xFF;
16608 result = (uint32_t)imm << 24 |
16609 (uint32_t)imm << 16 |
16610 (uint32_t)imm << 8 |
16611 (uint32_t)imm;
16612 result = (int32_t)result;
16613 tcg_gen_movi_tl(cpu_gpr[ret], result);
16614 }
16615 break;
16616 case OPC_REPLV_QB:
16617 check_dsp(ctx);
16618 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
16619 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
16620 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16621 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
16622 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16623 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
16624 break;
16625 case OPC_REPL_PH:
16626 check_dsp(ctx);
16627 {
16628 imm = (ctx->opcode >> 16) & 0x03FF;
c4aaba92 16629 imm = (int16_t)(imm << 6) >> 6;
1cb6686c
JL
16630 tcg_gen_movi_tl(cpu_gpr[ret], \
16631 (target_long)((int32_t)imm << 16 | \
c4aaba92 16632 (uint16_t)imm));
1cb6686c
JL
16633 }
16634 break;
16635 case OPC_REPLV_PH:
16636 check_dsp(ctx);
16637 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
16638 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
16639 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16640 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
16641 break;
16642 }
16643 break;
16644#ifdef TARGET_MIPS64
16645 case OPC_ABSQ_S_QH_DSP:
16646 switch (op2) {
16647 case OPC_REPL_OB:
16648 check_dsp(ctx);
16649 {
16650 target_long temp;
16651
16652 imm = (ctx->opcode >> 16) & 0xFF;
16653 temp = ((uint64_t)imm << 8) | (uint64_t)imm;
16654 temp = (temp << 16) | temp;
16655 temp = (temp << 32) | temp;
16656 tcg_gen_movi_tl(cpu_gpr[ret], temp);
16657 break;
16658 }
16659 case OPC_REPL_PW:
16660 check_dsp(ctx);
16661 {
16662 target_long temp;
16663
16664 imm = (ctx->opcode >> 16) & 0x03FF;
16665 imm = (int16_t)(imm << 6) >> 6;
16666 temp = ((target_long)imm << 32) \
16667 | ((target_long)imm & 0xFFFFFFFF);
16668 tcg_gen_movi_tl(cpu_gpr[ret], temp);
16669 break;
16670 }
16671 case OPC_REPL_QH:
16672 check_dsp(ctx);
16673 {
16674 target_long temp;
16675
16676 imm = (ctx->opcode >> 16) & 0x03FF;
16677 imm = (int16_t)(imm << 6) >> 6;
16678
16679 temp = ((uint64_t)(uint16_t)imm << 48) |
16680 ((uint64_t)(uint16_t)imm << 32) |
16681 ((uint64_t)(uint16_t)imm << 16) |
16682 (uint64_t)(uint16_t)imm;
16683 tcg_gen_movi_tl(cpu_gpr[ret], temp);
16684 break;
16685 }
16686 case OPC_REPLV_OB:
16687 check_dsp(ctx);
16688 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
16689 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
16690 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16691 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
16692 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16693 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
16694 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16695 break;
16696 case OPC_REPLV_PW:
16697 check_dsp(ctx);
16698 tcg_gen_ext32u_i64(cpu_gpr[ret], val_t);
16699 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
16700 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16701 break;
16702 case OPC_REPLV_QH:
16703 check_dsp(ctx);
16704 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
16705 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
16706 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16707 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
16708 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16709 break;
16710 }
16711 break;
16712#endif
16713 }
16714 tcg_temp_free(t0);
16715 tcg_temp_free(val_t);
1cb6686c
JL
16716}
16717
26690560
JL
16718static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx,
16719 uint32_t op1, uint32_t op2,
16720 int ret, int v1, int v2, int check_ret)
16721{
26690560
JL
16722 TCGv t1;
16723 TCGv v1_t;
16724 TCGv v2_t;
16725
16726 if ((ret == 0) && (check_ret == 1)) {
16727 /* Treat as NOP. */
26690560
JL
16728 return;
16729 }
16730
26690560
JL
16731 t1 = tcg_temp_new();
16732 v1_t = tcg_temp_new();
16733 v2_t = tcg_temp_new();
16734
16735 gen_load_gpr(v1_t, v1);
16736 gen_load_gpr(v2_t, v2);
16737
16738 switch (op1) {
26690560
JL
16739 case OPC_CMPU_EQ_QB_DSP:
16740 switch (op2) {
16741 case OPC_CMPU_EQ_QB:
16742 check_dsp(ctx);
16743 gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
16744 break;
16745 case OPC_CMPU_LT_QB:
16746 check_dsp(ctx);
16747 gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
16748 break;
16749 case OPC_CMPU_LE_QB:
16750 check_dsp(ctx);
16751 gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
16752 break;
16753 case OPC_CMPGU_EQ_QB:
16754 check_dsp(ctx);
16755 gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t);
16756 break;
16757 case OPC_CMPGU_LT_QB:
16758 check_dsp(ctx);
16759 gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t);
16760 break;
16761 case OPC_CMPGU_LE_QB:
16762 check_dsp(ctx);
16763 gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t);
16764 break;
16765 case OPC_CMPGDU_EQ_QB:
16766 check_dspr2(ctx);
16767 gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t);
16768 tcg_gen_mov_tl(cpu_gpr[ret], t1);
16769 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
16770 tcg_gen_shli_tl(t1, t1, 24);
16771 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
16772 break;
16773 case OPC_CMPGDU_LT_QB:
16774 check_dspr2(ctx);
16775 gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t);
16776 tcg_gen_mov_tl(cpu_gpr[ret], t1);
16777 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
16778 tcg_gen_shli_tl(t1, t1, 24);
16779 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
16780 break;
16781 case OPC_CMPGDU_LE_QB:
16782 check_dspr2(ctx);
16783 gen_helper_cmpgu_le_qb(t1, v1_t, v2_t);
16784 tcg_gen_mov_tl(cpu_gpr[ret], t1);
16785 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
16786 tcg_gen_shli_tl(t1, t1, 24);
16787 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
16788 break;
16789 case OPC_CMP_EQ_PH:
16790 check_dsp(ctx);
16791 gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
16792 break;
16793 case OPC_CMP_LT_PH:
16794 check_dsp(ctx);
16795 gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
16796 break;
16797 case OPC_CMP_LE_PH:
16798 check_dsp(ctx);
16799 gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
16800 break;
16801 case OPC_PICK_QB:
16802 check_dsp(ctx);
16803 gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16804 break;
16805 case OPC_PICK_PH:
16806 check_dsp(ctx);
16807 gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16808 break;
16809 case OPC_PACKRL_PH:
16810 check_dsp(ctx);
16811 gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t);
16812 break;
16813 }
16814 break;
16815#ifdef TARGET_MIPS64
16816 case OPC_CMPU_EQ_OB_DSP:
16817 switch (op2) {
16818 case OPC_CMP_EQ_PW:
16819 check_dsp(ctx);
16820 gen_helper_cmp_eq_pw(v1_t, v2_t, cpu_env);
16821 break;
16822 case OPC_CMP_LT_PW:
16823 check_dsp(ctx);
16824 gen_helper_cmp_lt_pw(v1_t, v2_t, cpu_env);
16825 break;
16826 case OPC_CMP_LE_PW:
16827 check_dsp(ctx);
16828 gen_helper_cmp_le_pw(v1_t, v2_t, cpu_env);
16829 break;
16830 case OPC_CMP_EQ_QH:
16831 check_dsp(ctx);
16832 gen_helper_cmp_eq_qh(v1_t, v2_t, cpu_env);
16833 break;
16834 case OPC_CMP_LT_QH:
16835 check_dsp(ctx);
16836 gen_helper_cmp_lt_qh(v1_t, v2_t, cpu_env);
16837 break;
16838 case OPC_CMP_LE_QH:
16839 check_dsp(ctx);
16840 gen_helper_cmp_le_qh(v1_t, v2_t, cpu_env);
16841 break;
16842 case OPC_CMPGDU_EQ_OB:
16843 check_dspr2(ctx);
16844 gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16845 break;
16846 case OPC_CMPGDU_LT_OB:
16847 check_dspr2(ctx);
16848 gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16849 break;
16850 case OPC_CMPGDU_LE_OB:
16851 check_dspr2(ctx);
16852 gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16853 break;
16854 case OPC_CMPGU_EQ_OB:
16855 check_dsp(ctx);
16856 gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t);
16857 break;
16858 case OPC_CMPGU_LT_OB:
16859 check_dsp(ctx);
16860 gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t);
16861 break;
16862 case OPC_CMPGU_LE_OB:
16863 check_dsp(ctx);
16864 gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t);
16865 break;
16866 case OPC_CMPU_EQ_OB:
16867 check_dsp(ctx);
16868 gen_helper_cmpu_eq_ob(v1_t, v2_t, cpu_env);
16869 break;
16870 case OPC_CMPU_LT_OB:
16871 check_dsp(ctx);
16872 gen_helper_cmpu_lt_ob(v1_t, v2_t, cpu_env);
16873 break;
16874 case OPC_CMPU_LE_OB:
16875 check_dsp(ctx);
16876 gen_helper_cmpu_le_ob(v1_t, v2_t, cpu_env);
16877 break;
16878 case OPC_PACKRL_PW:
16879 check_dsp(ctx);
16880 gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t);
16881 break;
16882 case OPC_PICK_OB:
16883 check_dsp(ctx);
16884 gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16885 break;
16886 case OPC_PICK_PW:
16887 check_dsp(ctx);
16888 gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16889 break;
16890 case OPC_PICK_QH:
16891 check_dsp(ctx);
16892 gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16893 break;
16894 }
16895 break;
df6126a7
AJ
16896#endif
16897 }
16898
16899 tcg_temp_free(t1);
16900 tcg_temp_free(v1_t);
16901 tcg_temp_free(v2_t);
df6126a7
AJ
16902}
16903
16904static void gen_mipsdsp_append(CPUMIPSState *env, DisasContext *ctx,
16905 uint32_t op1, int rt, int rs, int sa)
16906{
df6126a7
AJ
16907 TCGv t0;
16908
16909 check_dspr2(ctx);
16910
16911 if (rt == 0) {
16912 /* Treat as NOP. */
df6126a7
AJ
16913 return;
16914 }
16915
16916 t0 = tcg_temp_new();
16917 gen_load_gpr(t0, rs);
16918
16919 switch (op1) {
16920 case OPC_APPEND_DSP:
16921 switch (MASK_APPEND(ctx->opcode)) {
16922 case OPC_APPEND:
16923 if (sa != 0) {
16924 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 32 - sa);
16925 }
16926 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
16927 break;
16928 case OPC_PREPEND:
16929 if (sa != 0) {
16930 tcg_gen_ext32u_tl(cpu_gpr[rt], cpu_gpr[rt]);
16931 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
16932 tcg_gen_shli_tl(t0, t0, 32 - sa);
16933 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
16934 }
16935 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
16936 break;
16937 case OPC_BALIGN:
16938 sa &= 3;
16939 if (sa != 0 && sa != 2) {
16940 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
16941 tcg_gen_ext32u_tl(t0, t0);
16942 tcg_gen_shri_tl(t0, t0, 8 * (4 - sa));
16943 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
16944 }
16945 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
16946 break;
16947 default: /* Invalid */
16948 MIPS_INVAL("MASK APPEND");
9c708c7f 16949 generate_exception_end(ctx, EXCP_RI);
df6126a7
AJ
16950 break;
16951 }
16952 break;
16953#ifdef TARGET_MIPS64
26690560 16954 case OPC_DAPPEND_DSP:
df6126a7 16955 switch (MASK_DAPPEND(ctx->opcode)) {
26690560 16956 case OPC_DAPPEND:
df6126a7
AJ
16957 if (sa != 0) {
16958 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 64 - sa);
16959 }
26690560
JL
16960 break;
16961 case OPC_PREPENDD:
df6126a7
AJ
16962 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], 0x20 | sa);
16963 tcg_gen_shli_tl(t0, t0, 64 - (0x20 | sa));
16964 tcg_gen_or_tl(cpu_gpr[rt], t0, t0);
26690560
JL
16965 break;
16966 case OPC_PREPENDW:
df6126a7
AJ
16967 if (sa != 0) {
16968 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
16969 tcg_gen_shli_tl(t0, t0, 64 - sa);
16970 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
16971 }
26690560
JL
16972 break;
16973 case OPC_DBALIGN:
df6126a7
AJ
16974 sa &= 7;
16975 if (sa != 0 && sa != 2 && sa != 4) {
16976 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
16977 tcg_gen_shri_tl(t0, t0, 8 * (8 - sa));
16978 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
16979 }
26690560
JL
16980 break;
16981 default: /* Invalid */
16982 MIPS_INVAL("MASK DAPPEND");
9c708c7f 16983 generate_exception_end(ctx, EXCP_RI);
26690560
JL
16984 break;
16985 }
16986 break;
16987#endif
16988 }
df6126a7 16989 tcg_temp_free(t0);
26690560
JL
16990}
16991
b53371ed
JL
16992static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
16993 int ret, int v1, int v2, int check_ret)
16994
16995{
b53371ed
JL
16996 TCGv t0;
16997 TCGv t1;
16998 TCGv v1_t;
16999 TCGv v2_t;
17000 int16_t imm;
17001
17002 if ((ret == 0) && (check_ret == 1)) {
17003 /* Treat as NOP. */
b53371ed
JL
17004 return;
17005 }
17006
17007 t0 = tcg_temp_new();
17008 t1 = tcg_temp_new();
17009 v1_t = tcg_temp_new();
17010 v2_t = tcg_temp_new();
17011
17012 gen_load_gpr(v1_t, v1);
17013 gen_load_gpr(v2_t, v2);
17014
17015 switch (op1) {
17016 case OPC_EXTR_W_DSP:
17017 check_dsp(ctx);
17018 switch (op2) {
17019 case OPC_EXTR_W:
17020 tcg_gen_movi_tl(t0, v2);
17021 tcg_gen_movi_tl(t1, v1);
17022 gen_helper_extr_w(cpu_gpr[ret], t0, t1, cpu_env);
17023 break;
17024 case OPC_EXTR_R_W:
17025 tcg_gen_movi_tl(t0, v2);
17026 tcg_gen_movi_tl(t1, v1);
17027 gen_helper_extr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
17028 break;
17029 case OPC_EXTR_RS_W:
17030 tcg_gen_movi_tl(t0, v2);
17031 tcg_gen_movi_tl(t1, v1);
17032 gen_helper_extr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
17033 break;
17034 case OPC_EXTR_S_H:
17035 tcg_gen_movi_tl(t0, v2);
17036 tcg_gen_movi_tl(t1, v1);
17037 gen_helper_extr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
17038 break;
17039 case OPC_EXTRV_S_H:
17040 tcg_gen_movi_tl(t0, v2);
17041 gen_helper_extr_s_h(cpu_gpr[ret], t0, v1_t, cpu_env);
17042 break;
17043 case OPC_EXTRV_W:
17044 tcg_gen_movi_tl(t0, v2);
17045 gen_helper_extr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
17046 break;
17047 case OPC_EXTRV_R_W:
17048 tcg_gen_movi_tl(t0, v2);
17049 gen_helper_extr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
17050 break;
17051 case OPC_EXTRV_RS_W:
17052 tcg_gen_movi_tl(t0, v2);
17053 gen_helper_extr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
17054 break;
17055 case OPC_EXTP:
17056 tcg_gen_movi_tl(t0, v2);
17057 tcg_gen_movi_tl(t1, v1);
17058 gen_helper_extp(cpu_gpr[ret], t0, t1, cpu_env);
17059 break;
17060 case OPC_EXTPV:
17061 tcg_gen_movi_tl(t0, v2);
17062 gen_helper_extp(cpu_gpr[ret], t0, v1_t, cpu_env);
17063 break;
17064 case OPC_EXTPDP:
17065 tcg_gen_movi_tl(t0, v2);
17066 tcg_gen_movi_tl(t1, v1);
17067 gen_helper_extpdp(cpu_gpr[ret], t0, t1, cpu_env);
17068 break;
17069 case OPC_EXTPDPV:
17070 tcg_gen_movi_tl(t0, v2);
17071 gen_helper_extpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
17072 break;
17073 case OPC_SHILO:
17074 imm = (ctx->opcode >> 20) & 0x3F;
17075 tcg_gen_movi_tl(t0, ret);
17076 tcg_gen_movi_tl(t1, imm);
17077 gen_helper_shilo(t0, t1, cpu_env);
17078 break;
17079 case OPC_SHILOV:
17080 tcg_gen_movi_tl(t0, ret);
17081 gen_helper_shilo(t0, v1_t, cpu_env);
17082 break;
17083 case OPC_MTHLIP:
17084 tcg_gen_movi_tl(t0, ret);
17085 gen_helper_mthlip(t0, v1_t, cpu_env);
17086 break;
17087 case OPC_WRDSP:
17088 imm = (ctx->opcode >> 11) & 0x3FF;
17089 tcg_gen_movi_tl(t0, imm);
17090 gen_helper_wrdsp(v1_t, t0, cpu_env);
17091 break;
17092 case OPC_RDDSP:
17093 imm = (ctx->opcode >> 16) & 0x03FF;
17094 tcg_gen_movi_tl(t0, imm);
17095 gen_helper_rddsp(cpu_gpr[ret], t0, cpu_env);
17096 break;
17097 }
17098 break;
17099#ifdef TARGET_MIPS64
17100 case OPC_DEXTR_W_DSP:
17101 check_dsp(ctx);
17102 switch (op2) {
17103 case OPC_DMTHLIP:
17104 tcg_gen_movi_tl(t0, ret);
17105 gen_helper_dmthlip(v1_t, t0, cpu_env);
17106 break;
17107 case OPC_DSHILO:
17108 {
17109 int shift = (ctx->opcode >> 19) & 0x7F;
17110 int ac = (ctx->opcode >> 11) & 0x03;
17111 tcg_gen_movi_tl(t0, shift);
17112 tcg_gen_movi_tl(t1, ac);
17113 gen_helper_dshilo(t0, t1, cpu_env);
17114 break;
17115 }
17116 case OPC_DSHILOV:
17117 {
17118 int ac = (ctx->opcode >> 11) & 0x03;
17119 tcg_gen_movi_tl(t0, ac);
17120 gen_helper_dshilo(v1_t, t0, cpu_env);
17121 break;
17122 }
17123 case OPC_DEXTP:
17124 tcg_gen_movi_tl(t0, v2);
17125 tcg_gen_movi_tl(t1, v1);
17126
17127 gen_helper_dextp(cpu_gpr[ret], t0, t1, cpu_env);
17128 break;
17129 case OPC_DEXTPV:
17130 tcg_gen_movi_tl(t0, v2);
17131 gen_helper_dextp(cpu_gpr[ret], t0, v1_t, cpu_env);
17132 break;
17133 case OPC_DEXTPDP:
17134 tcg_gen_movi_tl(t0, v2);
17135 tcg_gen_movi_tl(t1, v1);
17136 gen_helper_dextpdp(cpu_gpr[ret], t0, t1, cpu_env);
17137 break;
17138 case OPC_DEXTPDPV:
17139 tcg_gen_movi_tl(t0, v2);
17140 gen_helper_dextpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
17141 break;
17142 case OPC_DEXTR_L:
17143 tcg_gen_movi_tl(t0, v2);
17144 tcg_gen_movi_tl(t1, v1);
17145 gen_helper_dextr_l(cpu_gpr[ret], t0, t1, cpu_env);
17146 break;
17147 case OPC_DEXTR_R_L:
17148 tcg_gen_movi_tl(t0, v2);
17149 tcg_gen_movi_tl(t1, v1);
17150 gen_helper_dextr_r_l(cpu_gpr[ret], t0, t1, cpu_env);
17151 break;
17152 case OPC_DEXTR_RS_L:
17153 tcg_gen_movi_tl(t0, v2);
17154 tcg_gen_movi_tl(t1, v1);
17155 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, t1, cpu_env);
17156 break;
17157 case OPC_DEXTR_W:
17158 tcg_gen_movi_tl(t0, v2);
17159 tcg_gen_movi_tl(t1, v1);
17160 gen_helper_dextr_w(cpu_gpr[ret], t0, t1, cpu_env);
17161 break;
17162 case OPC_DEXTR_R_W:
17163 tcg_gen_movi_tl(t0, v2);
17164 tcg_gen_movi_tl(t1, v1);
17165 gen_helper_dextr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
17166 break;
17167 case OPC_DEXTR_RS_W:
17168 tcg_gen_movi_tl(t0, v2);
17169 tcg_gen_movi_tl(t1, v1);
17170 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
17171 break;
17172 case OPC_DEXTR_S_H:
17173 tcg_gen_movi_tl(t0, v2);
17174 tcg_gen_movi_tl(t1, v1);
17175 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
17176 break;
17177 case OPC_DEXTRV_S_H:
17178 tcg_gen_movi_tl(t0, v2);
17179 tcg_gen_movi_tl(t1, v1);
17180 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
17181 break;
17182 case OPC_DEXTRV_L:
17183 tcg_gen_movi_tl(t0, v2);
17184 gen_helper_dextr_l(cpu_gpr[ret], t0, v1_t, cpu_env);
17185 break;
17186 case OPC_DEXTRV_R_L:
17187 tcg_gen_movi_tl(t0, v2);
17188 gen_helper_dextr_r_l(cpu_gpr[ret], t0, v1_t, cpu_env);
17189 break;
17190 case OPC_DEXTRV_RS_L:
17191 tcg_gen_movi_tl(t0, v2);
17192 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, v1_t, cpu_env);
17193 break;
17194 case OPC_DEXTRV_W:
17195 tcg_gen_movi_tl(t0, v2);
17196 gen_helper_dextr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
17197 break;
17198 case OPC_DEXTRV_R_W:
17199 tcg_gen_movi_tl(t0, v2);
17200 gen_helper_dextr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
17201 break;
17202 case OPC_DEXTRV_RS_W:
17203 tcg_gen_movi_tl(t0, v2);
17204 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
17205 break;
17206 }
17207 break;
17208#endif
17209 }
17210
17211 tcg_temp_free(t0);
17212 tcg_temp_free(t1);
17213 tcg_temp_free(v1_t);
17214 tcg_temp_free(v2_t);
b53371ed
JL
17215}
17216
9b1a1d68
JL
17217/* End MIPSDSP functions. */
17218
10dc65db
LA
17219static void decode_opc_special_r6(CPUMIPSState *env, DisasContext *ctx)
17220{
4267d3e6 17221 int rs, rt, rd, sa;
b42ee5e1 17222 uint32_t op1, op2;
10dc65db
LA
17223
17224 rs = (ctx->opcode >> 21) & 0x1f;
17225 rt = (ctx->opcode >> 16) & 0x1f;
17226 rd = (ctx->opcode >> 11) & 0x1f;
4267d3e6 17227 sa = (ctx->opcode >> 6) & 0x1f;
10dc65db
LA
17228
17229 op1 = MASK_SPECIAL(ctx->opcode);
17230 switch (op1) {
d4ea6acd 17231 case OPC_LSA:
1f1b4c00 17232 gen_lsa(ctx, op1, rd, rs, rt, extract32(ctx->opcode, 6, 2));
d4ea6acd 17233 break;
b42ee5e1
LA
17234 case OPC_MULT ... OPC_DIVU:
17235 op2 = MASK_R6_MULDIV(ctx->opcode);
17236 switch (op2) {
17237 case R6_OPC_MUL:
17238 case R6_OPC_MUH:
17239 case R6_OPC_MULU:
17240 case R6_OPC_MUHU:
17241 case R6_OPC_DIV:
17242 case R6_OPC_MOD:
17243 case R6_OPC_DIVU:
17244 case R6_OPC_MODU:
17245 gen_r6_muldiv(ctx, op2, rd, rs, rt);
17246 break;
17247 default:
17248 MIPS_INVAL("special_r6 muldiv");
9c708c7f 17249 generate_exception_end(ctx, EXCP_RI);
b42ee5e1
LA
17250 break;
17251 }
17252 break;
10dc65db
LA
17253 case OPC_SELEQZ:
17254 case OPC_SELNEZ:
17255 gen_cond_move(ctx, op1, rd, rs, rt);
17256 break;
4267d3e6
LA
17257 case R6_OPC_CLO:
17258 case R6_OPC_CLZ:
17259 if (rt == 0 && sa == 1) {
17260 /* Major opcode and function field is shared with preR6 MFHI/MTHI.
17261 We need additionally to check other fields */
17262 gen_cl(ctx, op1, rd, rs);
17263 } else {
9c708c7f 17264 generate_exception_end(ctx, EXCP_RI);
4267d3e6
LA
17265 }
17266 break;
17267 case R6_OPC_SDBBP:
3b3c1694
LA
17268 if (is_uhi(extract32(ctx->opcode, 6, 20))) {
17269 gen_helper_do_semihosting(cpu_env);
faf1f68b 17270 } else {
3b3c1694 17271 if (ctx->hflags & MIPS_HFLAG_SBRI) {
9c708c7f 17272 generate_exception_end(ctx, EXCP_RI);
3b3c1694 17273 } else {
9c708c7f 17274 generate_exception_end(ctx, EXCP_DBp);
3b3c1694 17275 }
faf1f68b 17276 }
4267d3e6 17277 break;
b42ee5e1 17278#if defined(TARGET_MIPS64)
d4ea6acd
LA
17279 case OPC_DLSA:
17280 check_mips_64(ctx);
1f1b4c00 17281 gen_lsa(ctx, op1, rd, rs, rt, extract32(ctx->opcode, 6, 2));
d4ea6acd 17282 break;
4267d3e6
LA
17283 case R6_OPC_DCLO:
17284 case R6_OPC_DCLZ:
17285 if (rt == 0 && sa == 1) {
17286 /* Major opcode and function field is shared with preR6 MFHI/MTHI.
17287 We need additionally to check other fields */
17288 check_mips_64(ctx);
17289 gen_cl(ctx, op1, rd, rs);
17290 } else {
9c708c7f 17291 generate_exception_end(ctx, EXCP_RI);
4267d3e6
LA
17292 }
17293 break;
b42ee5e1
LA
17294 case OPC_DMULT ... OPC_DDIVU:
17295 op2 = MASK_R6_MULDIV(ctx->opcode);
17296 switch (op2) {
17297 case R6_OPC_DMUL:
17298 case R6_OPC_DMUH:
17299 case R6_OPC_DMULU:
17300 case R6_OPC_DMUHU:
17301 case R6_OPC_DDIV:
17302 case R6_OPC_DMOD:
17303 case R6_OPC_DDIVU:
17304 case R6_OPC_DMODU:
17305 check_mips_64(ctx);
17306 gen_r6_muldiv(ctx, op2, rd, rs, rt);
17307 break;
17308 default:
17309 MIPS_INVAL("special_r6 muldiv");
9c708c7f 17310 generate_exception_end(ctx, EXCP_RI);
b42ee5e1
LA
17311 break;
17312 }
17313 break;
17314#endif
10dc65db
LA
17315 default: /* Invalid */
17316 MIPS_INVAL("special_r6");
9c708c7f 17317 generate_exception_end(ctx, EXCP_RI);
10dc65db
LA
17318 break;
17319 }
17320}
17321
17322static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx)
17323{
b42ee5e1 17324 int rs, rt, rd, sa;
10dc65db
LA
17325 uint32_t op1;
17326
17327 rs = (ctx->opcode >> 21) & 0x1f;
17328 rt = (ctx->opcode >> 16) & 0x1f;
17329 rd = (ctx->opcode >> 11) & 0x1f;
b42ee5e1 17330 sa = (ctx->opcode >> 6) & 0x1f;
10dc65db
LA
17331
17332 op1 = MASK_SPECIAL(ctx->opcode);
17333 switch (op1) {
17334 case OPC_MOVN: /* Conditional move */
17335 case OPC_MOVZ:
17336 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32 |
17337 INSN_LOONGSON2E | INSN_LOONGSON2F);
17338 gen_cond_move(ctx, op1, rd, rs, rt);
17339 break;
17340 case OPC_MFHI: /* Move from HI/LO */
17341 case OPC_MFLO:
17342 gen_HILO(ctx, op1, rs & 3, rd);
17343 break;
17344 case OPC_MTHI:
17345 case OPC_MTLO: /* Move to HI/LO */
17346 gen_HILO(ctx, op1, rd & 3, rs);
17347 break;
17348 case OPC_MOVCI:
17349 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
17350 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
17351 check_cp1_enabled(ctx);
17352 gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
17353 (ctx->opcode >> 16) & 1);
17354 } else {
17355 generate_exception_err(ctx, EXCP_CpU, 1);
17356 }
17357 break;
b42ee5e1
LA
17358 case OPC_MULT:
17359 case OPC_MULTU:
17360 if (sa) {
17361 check_insn(ctx, INSN_VR54XX);
17362 op1 = MASK_MUL_VR54XX(ctx->opcode);
17363 gen_mul_vr54xx(ctx, op1, rd, rs, rt);
17364 } else {
17365 gen_muldiv(ctx, op1, rd & 3, rs, rt);
17366 }
17367 break;
17368 case OPC_DIV:
17369 case OPC_DIVU:
17370 gen_muldiv(ctx, op1, 0, rs, rt);
17371 break;
17372#if defined(TARGET_MIPS64)
17373 case OPC_DMULT ... OPC_DDIVU:
17374 check_insn(ctx, ISA_MIPS3);
17375 check_mips_64(ctx);
17376 gen_muldiv(ctx, op1, 0, rs, rt);
17377 break;
17378#endif
0aefa333 17379 case OPC_JR:
b231c103 17380 gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
0aefa333 17381 break;
4267d3e6
LA
17382 case OPC_SPIM:
17383#ifdef MIPS_STRICT_STANDARD
17384 MIPS_INVAL("SPIM");
9c708c7f 17385 generate_exception_end(ctx, EXCP_RI);
4267d3e6
LA
17386#else
17387 /* Implemented as RI exception for now. */
17388 MIPS_INVAL("spim (unofficial)");
9c708c7f 17389 generate_exception_end(ctx, EXCP_RI);
4267d3e6
LA
17390#endif
17391 break;
10dc65db
LA
17392 default: /* Invalid */
17393 MIPS_INVAL("special_legacy");
9c708c7f 17394 generate_exception_end(ctx, EXCP_RI);
10dc65db
LA
17395 break;
17396 }
17397}
17398
099e5b4d 17399static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx)
3c824109 17400{
3c824109 17401 int rs, rt, rd, sa;
099e5b4d 17402 uint32_t op1;
3c824109 17403
3c824109
NF
17404 rs = (ctx->opcode >> 21) & 0x1f;
17405 rt = (ctx->opcode >> 16) & 0x1f;
17406 rd = (ctx->opcode >> 11) & 0x1f;
17407 sa = (ctx->opcode >> 6) & 0x1f;
099e5b4d
LA
17408
17409 op1 = MASK_SPECIAL(ctx->opcode);
17410 switch (op1) {
17411 case OPC_SLL: /* Shift with immediate */
339cd2a8
LA
17412 if (sa == 5 && rd == 0 &&
17413 rs == 0 && rt == 0) { /* PAUSE */
17414 if ((ctx->insn_flags & ISA_MIPS32R6) &&
17415 (ctx->hflags & MIPS_HFLAG_BMASK)) {
9c708c7f 17416 generate_exception_end(ctx, EXCP_RI);
339cd2a8
LA
17417 break;
17418 }
17419 }
17420 /* Fallthrough */
099e5b4d
LA
17421 case OPC_SRA:
17422 gen_shift_imm(ctx, op1, rd, rt, sa);
17423 break;
17424 case OPC_SRL:
17425 switch ((ctx->opcode >> 21) & 0x1f) {
17426 case 1:
17427 /* rotr is decoded as srl on non-R2 CPUs */
17428 if (ctx->insn_flags & ISA_MIPS32R2) {
17429 op1 = OPC_ROTR;
ea63e2c3 17430 }
099e5b4d
LA
17431 /* Fallthrough */
17432 case 0:
17433 gen_shift_imm(ctx, op1, rd, rt, sa);
ea63e2c3 17434 break;
099e5b4d 17435 default:
9c708c7f 17436 generate_exception_end(ctx, EXCP_RI);
ea63e2c3 17437 break;
099e5b4d
LA
17438 }
17439 break;
099e5b4d
LA
17440 case OPC_ADD ... OPC_SUBU:
17441 gen_arith(ctx, op1, rd, rs, rt);
17442 break;
17443 case OPC_SLLV: /* Shifts */
17444 case OPC_SRAV:
17445 gen_shift(ctx, op1, rd, rs, rt);
17446 break;
17447 case OPC_SRLV:
17448 switch ((ctx->opcode >> 6) & 0x1f) {
17449 case 1:
17450 /* rotrv is decoded as srlv on non-R2 CPUs */
17451 if (ctx->insn_flags & ISA_MIPS32R2) {
17452 op1 = OPC_ROTRV;
26135ead 17453 }
099e5b4d
LA
17454 /* Fallthrough */
17455 case 0:
17456 gen_shift(ctx, op1, rd, rs, rt);
26135ead 17457 break;
099e5b4d 17458 default:
9c708c7f 17459 generate_exception_end(ctx, EXCP_RI);
6af0bf9c 17460 break;
099e5b4d
LA
17461 }
17462 break;
17463 case OPC_SLT: /* Set on less than */
17464 case OPC_SLTU:
17465 gen_slt(ctx, op1, rd, rs, rt);
17466 break;
17467 case OPC_AND: /* Logic*/
17468 case OPC_OR:
17469 case OPC_NOR:
17470 case OPC_XOR:
17471 gen_logic(ctx, op1, rd, rs, rt);
17472 break;
0aefa333 17473 case OPC_JALR:
b231c103 17474 gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
099e5b4d
LA
17475 break;
17476 case OPC_TGE ... OPC_TEQ: /* Traps */
17477 case OPC_TNE:
d9224450 17478 check_insn(ctx, ISA_MIPS2);
099e5b4d
LA
17479 gen_trap(ctx, op1, rs, rt, -1);
17480 break;
d4ea6acd 17481 case OPC_LSA: /* OPC_PMON */
f7685877
YK
17482 if ((ctx->insn_flags & ISA_MIPS32R6) ||
17483 (env->CP0_Config3 & (1 << CP0C3_MSAP))) {
d4ea6acd
LA
17484 decode_opc_special_r6(env, ctx);
17485 } else {
17486 /* Pmon entry point, also R4010 selsl */
b48cfdff 17487#ifdef MIPS_STRICT_STANDARD
d4ea6acd 17488 MIPS_INVAL("PMON / selsl");
9c708c7f 17489 generate_exception_end(ctx, EXCP_RI);
b48cfdff 17490#else
d4ea6acd 17491 gen_helper_0e0i(pmon, sa);
b48cfdff 17492#endif
d4ea6acd 17493 }
099e5b4d
LA
17494 break;
17495 case OPC_SYSCALL:
9c708c7f 17496 generate_exception_end(ctx, EXCP_SYSCALL);
099e5b4d
LA
17497 break;
17498 case OPC_BREAK:
9c708c7f 17499 generate_exception_end(ctx, EXCP_BREAK);
099e5b4d 17500 break;
099e5b4d 17501 case OPC_SYNC:
d9224450 17502 check_insn(ctx, ISA_MIPS2);
d208ac0c 17503 gen_sync(extract32(ctx->opcode, 6, 5));
099e5b4d 17504 break;
4ad40f36 17505
d26bc211 17506#if defined(TARGET_MIPS64)
099e5b4d
LA
17507 /* MIPS64 specific opcodes */
17508 case OPC_DSLL:
17509 case OPC_DSRA:
17510 case OPC_DSLL32:
17511 case OPC_DSRA32:
17512 check_insn(ctx, ISA_MIPS3);
17513 check_mips_64(ctx);
17514 gen_shift_imm(ctx, op1, rd, rt, sa);
17515 break;
17516 case OPC_DSRL:
17517 switch ((ctx->opcode >> 21) & 0x1f) {
17518 case 1:
17519 /* drotr is decoded as dsrl on non-R2 CPUs */
17520 if (ctx->insn_flags & ISA_MIPS32R2) {
17521 op1 = OPC_DROTR;
ea63e2c3 17522 }
099e5b4d
LA
17523 /* Fallthrough */
17524 case 0:
d75c135e 17525 check_insn(ctx, ISA_MIPS3);
e189e748 17526 check_mips_64(ctx);
099e5b4d 17527 gen_shift_imm(ctx, op1, rd, rt, sa);
7a387fff 17528 break;
099e5b4d 17529 default:
9c708c7f 17530 generate_exception_end(ctx, EXCP_RI);
460f00c4 17531 break;
099e5b4d
LA
17532 }
17533 break;
17534 case OPC_DSRL32:
17535 switch ((ctx->opcode >> 21) & 0x1f) {
17536 case 1:
17537 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
17538 if (ctx->insn_flags & ISA_MIPS32R2) {
17539 op1 = OPC_DROTR32;
ea63e2c3 17540 }
099e5b4d
LA
17541 /* Fallthrough */
17542 case 0:
d75c135e 17543 check_insn(ctx, ISA_MIPS3);
e189e748 17544 check_mips_64(ctx);
099e5b4d 17545 gen_shift_imm(ctx, op1, rd, rt, sa);
7a387fff 17546 break;
099e5b4d 17547 default:
9c708c7f 17548 generate_exception_end(ctx, EXCP_RI);
6af0bf9c
FB
17549 break;
17550 }
17551 break;
099e5b4d
LA
17552 case OPC_DADD ... OPC_DSUBU:
17553 check_insn(ctx, ISA_MIPS3);
17554 check_mips_64(ctx);
17555 gen_arith(ctx, op1, rd, rs, rt);
17556 break;
17557 case OPC_DSLLV:
17558 case OPC_DSRAV:
17559 check_insn(ctx, ISA_MIPS3);
17560 check_mips_64(ctx);
17561 gen_shift(ctx, op1, rd, rs, rt);
17562 break;
17563 case OPC_DSRLV:
17564 switch ((ctx->opcode >> 6) & 0x1f) {
17565 case 1:
17566 /* drotrv is decoded as dsrlv on non-R2 CPUs */
17567 if (ctx->insn_flags & ISA_MIPS32R2) {
17568 op1 = OPC_DROTRV;
6af0bf9c 17569 }
099e5b4d
LA
17570 /* Fallthrough */
17571 case 0:
17572 check_insn(ctx, ISA_MIPS3);
e189e748 17573 check_mips_64(ctx);
099e5b4d 17574 gen_shift(ctx, op1, rd, rs, rt);
161f85e6 17575 break;
099e5b4d 17576 default:
9c708c7f 17577 generate_exception_end(ctx, EXCP_RI);
6af0bf9c
FB
17578 break;
17579 }
17580 break;
f7685877
YK
17581 case OPC_DLSA:
17582 if ((ctx->insn_flags & ISA_MIPS32R6) ||
17583 (env->CP0_Config3 & (1 << CP0C3_MSAP))) {
17584 decode_opc_special_r6(env, ctx);
17585 }
17586 break;
099e5b4d 17587#endif
10dc65db
LA
17588 default:
17589 if (ctx->insn_flags & ISA_MIPS32R6) {
17590 decode_opc_special_r6(env, ctx);
17591 } else {
17592 decode_opc_special_legacy(env, ctx);
17593 }
17594 }
17595}
17596
10dc65db 17597static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx)
099e5b4d
LA
17598{
17599 int rs, rt, rd;
17600 uint32_t op1;
6c5c1e20 17601
4267d3e6
LA
17602 check_insn_opc_removed(ctx, ISA_MIPS32R6);
17603
099e5b4d
LA
17604 rs = (ctx->opcode >> 21) & 0x1f;
17605 rt = (ctx->opcode >> 16) & 0x1f;
17606 rd = (ctx->opcode >> 11) & 0x1f;
17607
17608 op1 = MASK_SPECIAL2(ctx->opcode);
17609 switch (op1) {
17610 case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
17611 case OPC_MSUB ... OPC_MSUBU:
099e5b4d
LA
17612 check_insn(ctx, ISA_MIPS32);
17613 gen_muldiv(ctx, op1, rd & 3, rs, rt);
17614 break;
17615 case OPC_MUL:
099e5b4d
LA
17616 gen_arith(ctx, op1, rd, rs, rt);
17617 break;
fac5a073
LA
17618 case OPC_DIV_G_2F:
17619 case OPC_DIVU_G_2F:
17620 case OPC_MULT_G_2F:
17621 case OPC_MULTU_G_2F:
17622 case OPC_MOD_G_2F:
17623 case OPC_MODU_G_2F:
17624 check_insn(ctx, INSN_LOONGSON2F);
17625 gen_loongson_integer(ctx, op1, rd, rs, rt);
17626 break;
099e5b4d
LA
17627 case OPC_CLO:
17628 case OPC_CLZ:
17629 check_insn(ctx, ISA_MIPS32);
17630 gen_cl(ctx, op1, rd, rs);
17631 break;
17632 case OPC_SDBBP:
3b3c1694
LA
17633 if (is_uhi(extract32(ctx->opcode, 6, 20))) {
17634 gen_helper_do_semihosting(cpu_env);
17635 } else {
17636 /* XXX: not clear which exception should be raised
17637 * when in debug mode...
17638 */
17639 check_insn(ctx, ISA_MIPS32);
9c708c7f 17640 generate_exception_end(ctx, EXCP_DBp);
3b3c1694 17641 }
099e5b4d 17642 break;
9b1a1d68 17643#if defined(TARGET_MIPS64)
099e5b4d
LA
17644 case OPC_DCLO:
17645 case OPC_DCLZ:
17646 check_insn(ctx, ISA_MIPS64);
17647 check_mips_64(ctx);
17648 gen_cl(ctx, op1, rd, rs);
17649 break;
4267d3e6
LA
17650 case OPC_DMULT_G_2F:
17651 case OPC_DMULTU_G_2F:
17652 case OPC_DDIV_G_2F:
17653 case OPC_DDIVU_G_2F:
17654 case OPC_DMOD_G_2F:
17655 case OPC_DMODU_G_2F:
17656 check_insn(ctx, INSN_LOONGSON2F);
17657 gen_loongson_integer(ctx, op1, rd, rs, rt);
17658 break;
10dc65db 17659#endif
4267d3e6
LA
17660 default: /* Invalid */
17661 MIPS_INVAL("special2_legacy");
9c708c7f 17662 generate_exception_end(ctx, EXCP_RI);
4267d3e6 17663 break;
10dc65db
LA
17664 }
17665}
17666
17667static void decode_opc_special3_r6(CPUMIPSState *env, DisasContext *ctx)
17668{
15eacb9b
YK
17669 int rs, rt, rd, sa;
17670 uint32_t op1, op2;
10dc65db
LA
17671 int16_t imm;
17672
17673 rs = (ctx->opcode >> 21) & 0x1f;
17674 rt = (ctx->opcode >> 16) & 0x1f;
15eacb9b
YK
17675 rd = (ctx->opcode >> 11) & 0x1f;
17676 sa = (ctx->opcode >> 6) & 0x1f;
10dc65db
LA
17677 imm = (int16_t)ctx->opcode >> 7;
17678
17679 op1 = MASK_SPECIAL3(ctx->opcode);
17680 switch (op1) {
bf7910c6
LA
17681 case R6_OPC_PREF:
17682 if (rt >= 24) {
17683 /* hint codes 24-31 are reserved and signal RI */
9c708c7f 17684 generate_exception_end(ctx, EXCP_RI);
bf7910c6
LA
17685 }
17686 /* Treat as NOP. */
17687 break;
17688 case R6_OPC_CACHE:
40d48212 17689 check_cp0_enabled(ctx);
0d74a222
LA
17690 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
17691 gen_cache_operation(ctx, rt, rs, imm);
17692 }
bf7910c6 17693 break;
10dc65db
LA
17694 case R6_OPC_SC:
17695 gen_st_cond(ctx, op1, rt, rs, imm);
17696 break;
17697 case R6_OPC_LL:
17698 gen_ld(ctx, op1, rt, rs, imm);
17699 break;
15eacb9b
YK
17700 case OPC_BSHFL:
17701 {
17702 if (rd == 0) {
17703 /* Treat as NOP. */
17704 break;
17705 }
15eacb9b
YK
17706 op2 = MASK_BSHFL(ctx->opcode);
17707 switch (op2) {
17708 case OPC_ALIGN ... OPC_ALIGN_END:
1f1b4c00 17709 gen_align(ctx, OPC_ALIGN, rd, rs, rt, sa & 3);
15eacb9b
YK
17710 break;
17711 case OPC_BITSWAP:
1f1b4c00 17712 gen_bitswap(ctx, op2, rd, rt);
15eacb9b
YK
17713 break;
17714 }
15eacb9b
YK
17715 }
17716 break;
bf7910c6
LA
17717#if defined(TARGET_MIPS64)
17718 case R6_OPC_SCD:
17719 gen_st_cond(ctx, op1, rt, rs, imm);
17720 break;
17721 case R6_OPC_LLD:
17722 gen_ld(ctx, op1, rt, rs, imm);
17723 break;
15eacb9b
YK
17724 case OPC_DBSHFL:
17725 check_mips_64(ctx);
17726 {
17727 if (rd == 0) {
17728 /* Treat as NOP. */
17729 break;
17730 }
15eacb9b
YK
17731 op2 = MASK_DBSHFL(ctx->opcode);
17732 switch (op2) {
17733 case OPC_DALIGN ... OPC_DALIGN_END:
1f1b4c00 17734 gen_align(ctx, OPC_DALIGN, rd, rs, rt, sa & 7);
15eacb9b
YK
17735 break;
17736 case OPC_DBITSWAP:
1f1b4c00 17737 gen_bitswap(ctx, op2, rd, rt);
15eacb9b
YK
17738 break;
17739 }
1f1b4c00 17740
15eacb9b
YK
17741 }
17742 break;
bf7910c6 17743#endif
10dc65db
LA
17744 default: /* Invalid */
17745 MIPS_INVAL("special3_r6");
9c708c7f 17746 generate_exception_end(ctx, EXCP_RI);
10dc65db
LA
17747 break;
17748 }
17749}
17750
17751static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx)
17752{
fac5a073 17753 int rs, rt, rd;
099e5b4d 17754 uint32_t op1, op2;
099e5b4d
LA
17755
17756 rs = (ctx->opcode >> 21) & 0x1f;
17757 rt = (ctx->opcode >> 16) & 0x1f;
17758 rd = (ctx->opcode >> 11) & 0x1f;
099e5b4d
LA
17759
17760 op1 = MASK_SPECIAL3(ctx->opcode);
17761 switch (op1) {
099e5b4d
LA
17762 case OPC_DIV_G_2E ... OPC_DIVU_G_2E:
17763 case OPC_MOD_G_2E ... OPC_MODU_G_2E:
17764 case OPC_MULT_G_2E ... OPC_MULTU_G_2E:
17765 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
17766 * the same mask and op1. */
17767 if ((ctx->insn_flags & ASE_DSPR2) && (op1 == OPC_MULT_G_2E)) {
17768 op2 = MASK_ADDUH_QB(ctx->opcode);
461c08df 17769 switch (op2) {
099e5b4d
LA
17770 case OPC_ADDUH_QB:
17771 case OPC_ADDUH_R_QB:
17772 case OPC_ADDQH_PH:
17773 case OPC_ADDQH_R_PH:
17774 case OPC_ADDQH_W:
17775 case OPC_ADDQH_R_W:
17776 case OPC_SUBUH_QB:
17777 case OPC_SUBUH_R_QB:
17778 case OPC_SUBQH_PH:
17779 case OPC_SUBQH_R_PH:
17780 case OPC_SUBQH_W:
17781 case OPC_SUBQH_R_W:
461c08df
JL
17782 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
17783 break;
099e5b4d
LA
17784 case OPC_MUL_PH:
17785 case OPC_MUL_S_PH:
17786 case OPC_MULQ_S_W:
17787 case OPC_MULQ_RS_W:
17788 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
1cb6686c 17789 break;
461c08df 17790 default:
099e5b4d 17791 MIPS_INVAL("MASK ADDUH.QB");
9c708c7f 17792 generate_exception_end(ctx, EXCP_RI);
461c08df
JL
17793 break;
17794 }
099e5b4d
LA
17795 } else if (ctx->insn_flags & INSN_LOONGSON2E) {
17796 gen_loongson_integer(ctx, op1, rd, rs, rt);
17797 } else {
9c708c7f 17798 generate_exception_end(ctx, EXCP_RI);
099e5b4d
LA
17799 }
17800 break;
17801 case OPC_LX_DSP:
17802 op2 = MASK_LX(ctx->opcode);
17803 switch (op2) {
17804#if defined(TARGET_MIPS64)
17805 case OPC_LDX:
17806#endif
17807 case OPC_LBUX:
17808 case OPC_LHX:
17809 case OPC_LWX:
17810 gen_mipsdsp_ld(ctx, op2, rd, rs, rt);
17811 break;
17812 default: /* Invalid */
17813 MIPS_INVAL("MASK LX");
9c708c7f 17814 generate_exception_end(ctx, EXCP_RI);
099e5b4d
LA
17815 break;
17816 }
17817 break;
17818 case OPC_ABSQ_S_PH_DSP:
17819 op2 = MASK_ABSQ_S_PH(ctx->opcode);
17820 switch (op2) {
17821 case OPC_ABSQ_S_QB:
17822 case OPC_ABSQ_S_PH:
17823 case OPC_ABSQ_S_W:
17824 case OPC_PRECEQ_W_PHL:
17825 case OPC_PRECEQ_W_PHR:
17826 case OPC_PRECEQU_PH_QBL:
17827 case OPC_PRECEQU_PH_QBR:
17828 case OPC_PRECEQU_PH_QBLA:
17829 case OPC_PRECEQU_PH_QBRA:
17830 case OPC_PRECEU_PH_QBL:
17831 case OPC_PRECEU_PH_QBR:
17832 case OPC_PRECEU_PH_QBLA:
17833 case OPC_PRECEU_PH_QBRA:
17834 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
17835 break;
17836 case OPC_BITREV:
17837 case OPC_REPL_QB:
17838 case OPC_REPLV_QB:
17839 case OPC_REPL_PH:
17840 case OPC_REPLV_PH:
17841 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
17842 break;
17843 default:
17844 MIPS_INVAL("MASK ABSQ_S.PH");
9c708c7f 17845 generate_exception_end(ctx, EXCP_RI);
099e5b4d
LA
17846 break;
17847 }
17848 break;
17849 case OPC_ADDU_QB_DSP:
17850 op2 = MASK_ADDU_QB(ctx->opcode);
17851 switch (op2) {
17852 case OPC_ADDQ_PH:
17853 case OPC_ADDQ_S_PH:
17854 case OPC_ADDQ_S_W:
17855 case OPC_ADDU_QB:
17856 case OPC_ADDU_S_QB:
17857 case OPC_ADDU_PH:
17858 case OPC_ADDU_S_PH:
17859 case OPC_SUBQ_PH:
17860 case OPC_SUBQ_S_PH:
17861 case OPC_SUBQ_S_W:
17862 case OPC_SUBU_QB:
17863 case OPC_SUBU_S_QB:
17864 case OPC_SUBU_PH:
17865 case OPC_SUBU_S_PH:
17866 case OPC_ADDSC:
17867 case OPC_ADDWC:
17868 case OPC_MODSUB:
17869 case OPC_RADDU_W_QB:
17870 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
17871 break;
17872 case OPC_MULEU_S_PH_QBL:
17873 case OPC_MULEU_S_PH_QBR:
17874 case OPC_MULQ_RS_PH:
17875 case OPC_MULEQ_S_W_PHL:
17876 case OPC_MULEQ_S_W_PHR:
17877 case OPC_MULQ_S_PH:
17878 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
17879 break;
17880 default: /* Invalid */
17881 MIPS_INVAL("MASK ADDU.QB");
9c708c7f 17882 generate_exception_end(ctx, EXCP_RI);
461c08df 17883 break;
461c08df 17884
099e5b4d
LA
17885 }
17886 break;
17887 case OPC_CMPU_EQ_QB_DSP:
17888 op2 = MASK_CMPU_EQ_QB(ctx->opcode);
17889 switch (op2) {
17890 case OPC_PRECR_SRA_PH_W:
17891 case OPC_PRECR_SRA_R_PH_W:
17892 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
461c08df 17893 break;
099e5b4d
LA
17894 case OPC_PRECR_QB_PH:
17895 case OPC_PRECRQ_QB_PH:
17896 case OPC_PRECRQ_PH_W:
17897 case OPC_PRECRQ_RS_PH_W:
17898 case OPC_PRECRQU_S_QB_PH:
17899 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
461c08df 17900 break;
099e5b4d
LA
17901 case OPC_CMPU_EQ_QB:
17902 case OPC_CMPU_LT_QB:
17903 case OPC_CMPU_LE_QB:
17904 case OPC_CMP_EQ_PH:
17905 case OPC_CMP_LT_PH:
17906 case OPC_CMP_LE_PH:
17907 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
77c5fa8b 17908 break;
099e5b4d
LA
17909 case OPC_CMPGU_EQ_QB:
17910 case OPC_CMPGU_LT_QB:
17911 case OPC_CMPGU_LE_QB:
17912 case OPC_CMPGDU_EQ_QB:
17913 case OPC_CMPGDU_LT_QB:
17914 case OPC_CMPGDU_LE_QB:
17915 case OPC_PICK_QB:
17916 case OPC_PICK_PH:
17917 case OPC_PACKRL_PH:
17918 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
17919 break;
17920 default: /* Invalid */
17921 MIPS_INVAL("MASK CMPU.EQ.QB");
9c708c7f 17922 generate_exception_end(ctx, EXCP_RI);
099e5b4d
LA
17923 break;
17924 }
17925 break;
17926 case OPC_SHLL_QB_DSP:
17927 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
17928 break;
17929 case OPC_DPA_W_PH_DSP:
17930 op2 = MASK_DPA_W_PH(ctx->opcode);
17931 switch (op2) {
17932 case OPC_DPAU_H_QBL:
17933 case OPC_DPAU_H_QBR:
17934 case OPC_DPSU_H_QBL:
17935 case OPC_DPSU_H_QBR:
17936 case OPC_DPA_W_PH:
17937 case OPC_DPAX_W_PH:
17938 case OPC_DPAQ_S_W_PH:
17939 case OPC_DPAQX_S_W_PH:
17940 case OPC_DPAQX_SA_W_PH:
17941 case OPC_DPS_W_PH:
17942 case OPC_DPSX_W_PH:
17943 case OPC_DPSQ_S_W_PH:
17944 case OPC_DPSQX_S_W_PH:
17945 case OPC_DPSQX_SA_W_PH:
17946 case OPC_MULSAQ_S_W_PH:
17947 case OPC_DPAQ_SA_L_W:
17948 case OPC_DPSQ_SA_L_W:
17949 case OPC_MAQ_S_W_PHL:
17950 case OPC_MAQ_S_W_PHR:
17951 case OPC_MAQ_SA_W_PHL:
17952 case OPC_MAQ_SA_W_PHR:
17953 case OPC_MULSA_W_PH:
17954 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
17955 break;
17956 default: /* Invalid */
17957 MIPS_INVAL("MASK DPAW.PH");
9c708c7f 17958 generate_exception_end(ctx, EXCP_RI);
099e5b4d
LA
17959 break;
17960 }
17961 break;
17962 case OPC_INSV_DSP:
17963 op2 = MASK_INSV(ctx->opcode);
17964 switch (op2) {
17965 case OPC_INSV:
17966 check_dsp(ctx);
17967 {
17968 TCGv t0, t1;
17969
17970 if (rt == 0) {
099e5b4d
LA
17971 break;
17972 }
17973
17974 t0 = tcg_temp_new();
17975 t1 = tcg_temp_new();
17976
17977 gen_load_gpr(t0, rt);
17978 gen_load_gpr(t1, rs);
17979
17980 gen_helper_insv(cpu_gpr[rt], cpu_env, t1, t0);
17981
17982 tcg_temp_free(t0);
17983 tcg_temp_free(t1);
a22260ae
JL
17984 break;
17985 }
099e5b4d
LA
17986 default: /* Invalid */
17987 MIPS_INVAL("MASK INSV");
9c708c7f 17988 generate_exception_end(ctx, EXCP_RI);
099e5b4d
LA
17989 break;
17990 }
17991 break;
17992 case OPC_APPEND_DSP:
17993 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
17994 break;
17995 case OPC_EXTR_W_DSP:
17996 op2 = MASK_EXTR_W(ctx->opcode);
17997 switch (op2) {
17998 case OPC_EXTR_W:
17999 case OPC_EXTR_R_W:
18000 case OPC_EXTR_RS_W:
18001 case OPC_EXTR_S_H:
18002 case OPC_EXTRV_S_H:
18003 case OPC_EXTRV_W:
18004 case OPC_EXTRV_R_W:
18005 case OPC_EXTRV_RS_W:
18006 case OPC_EXTP:
18007 case OPC_EXTPV:
18008 case OPC_EXTPDP:
18009 case OPC_EXTPDPV:
18010 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
18011 break;
18012 case OPC_RDDSP:
18013 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 1);
18014 break;
18015 case OPC_SHILO:
18016 case OPC_SHILOV:
18017 case OPC_MTHLIP:
18018 case OPC_WRDSP:
18019 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
18020 break;
18021 default: /* Invalid */
18022 MIPS_INVAL("MASK EXTR.W");
9c708c7f 18023 generate_exception_end(ctx, EXCP_RI);
099e5b4d
LA
18024 break;
18025 }
18026 break;
099e5b4d 18027#if defined(TARGET_MIPS64)
fac5a073
LA
18028 case OPC_DDIV_G_2E ... OPC_DDIVU_G_2E:
18029 case OPC_DMULT_G_2E ... OPC_DMULTU_G_2E:
18030 case OPC_DMOD_G_2E ... OPC_DMODU_G_2E:
18031 check_insn(ctx, INSN_LOONGSON2E);
18032 gen_loongson_integer(ctx, op1, rd, rs, rt);
099e5b4d 18033 break;
099e5b4d
LA
18034 case OPC_ABSQ_S_QH_DSP:
18035 op2 = MASK_ABSQ_S_QH(ctx->opcode);
18036 switch (op2) {
18037 case OPC_PRECEQ_L_PWL:
18038 case OPC_PRECEQ_L_PWR:
18039 case OPC_PRECEQ_PW_QHL:
18040 case OPC_PRECEQ_PW_QHR:
18041 case OPC_PRECEQ_PW_QHLA:
18042 case OPC_PRECEQ_PW_QHRA:
18043 case OPC_PRECEQU_QH_OBL:
18044 case OPC_PRECEQU_QH_OBR:
18045 case OPC_PRECEQU_QH_OBLA:
18046 case OPC_PRECEQU_QH_OBRA:
18047 case OPC_PRECEU_QH_OBL:
18048 case OPC_PRECEU_QH_OBR:
18049 case OPC_PRECEU_QH_OBLA:
18050 case OPC_PRECEU_QH_OBRA:
18051 case OPC_ABSQ_S_OB:
18052 case OPC_ABSQ_S_PW:
18053 case OPC_ABSQ_S_QH:
18054 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
18055 break;
18056 case OPC_REPL_OB:
18057 case OPC_REPL_PW:
18058 case OPC_REPL_QH:
18059 case OPC_REPLV_OB:
18060 case OPC_REPLV_PW:
18061 case OPC_REPLV_QH:
18062 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
18063 break;
18064 default: /* Invalid */
18065 MIPS_INVAL("MASK ABSQ_S.QH");
9c708c7f 18066 generate_exception_end(ctx, EXCP_RI);
099e5b4d
LA
18067 break;
18068 }
18069 break;
18070 case OPC_ADDU_OB_DSP:
18071 op2 = MASK_ADDU_OB(ctx->opcode);
18072 switch (op2) {
18073 case OPC_RADDU_L_OB:
18074 case OPC_SUBQ_PW:
18075 case OPC_SUBQ_S_PW:
18076 case OPC_SUBQ_QH:
18077 case OPC_SUBQ_S_QH:
18078 case OPC_SUBU_OB:
18079 case OPC_SUBU_S_OB:
18080 case OPC_SUBU_QH:
18081 case OPC_SUBU_S_QH:
18082 case OPC_SUBUH_OB:
18083 case OPC_SUBUH_R_OB:
18084 case OPC_ADDQ_PW:
18085 case OPC_ADDQ_S_PW:
18086 case OPC_ADDQ_QH:
18087 case OPC_ADDQ_S_QH:
18088 case OPC_ADDU_OB:
18089 case OPC_ADDU_S_OB:
18090 case OPC_ADDU_QH:
18091 case OPC_ADDU_S_QH:
18092 case OPC_ADDUH_OB:
18093 case OPC_ADDUH_R_OB:
18094 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
a22260ae 18095 break;
099e5b4d
LA
18096 case OPC_MULEQ_S_PW_QHL:
18097 case OPC_MULEQ_S_PW_QHR:
18098 case OPC_MULEU_S_QH_OBL:
18099 case OPC_MULEU_S_QH_OBR:
18100 case OPC_MULQ_RS_QH:
18101 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
1cb6686c 18102 break;
099e5b4d
LA
18103 default: /* Invalid */
18104 MIPS_INVAL("MASK ADDU.OB");
9c708c7f 18105 generate_exception_end(ctx, EXCP_RI);
26690560 18106 break;
099e5b4d
LA
18107 }
18108 break;
18109 case OPC_CMPU_EQ_OB_DSP:
18110 op2 = MASK_CMPU_EQ_OB(ctx->opcode);
18111 switch (op2) {
18112 case OPC_PRECR_SRA_QH_PW:
18113 case OPC_PRECR_SRA_R_QH_PW:
18114 /* Return value is rt. */
18115 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
b53371ed 18116 break;
099e5b4d
LA
18117 case OPC_PRECR_OB_QH:
18118 case OPC_PRECRQ_OB_QH:
18119 case OPC_PRECRQ_PW_L:
18120 case OPC_PRECRQ_QH_PW:
18121 case OPC_PRECRQ_RS_QH_PW:
18122 case OPC_PRECRQU_S_OB_QH:
18123 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
4368b29a 18124 break;
099e5b4d
LA
18125 case OPC_CMPU_EQ_OB:
18126 case OPC_CMPU_LT_OB:
18127 case OPC_CMPU_LE_OB:
18128 case OPC_CMP_EQ_QH:
18129 case OPC_CMP_LT_QH:
18130 case OPC_CMP_LE_QH:
18131 case OPC_CMP_EQ_PW:
18132 case OPC_CMP_LT_PW:
18133 case OPC_CMP_LE_PW:
18134 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
7a387fff 18135 break;
099e5b4d
LA
18136 case OPC_CMPGDU_EQ_OB:
18137 case OPC_CMPGDU_LT_OB:
18138 case OPC_CMPGDU_LE_OB:
18139 case OPC_CMPGU_EQ_OB:
18140 case OPC_CMPGU_LT_OB:
18141 case OPC_CMPGU_LE_OB:
18142 case OPC_PACKRL_PW:
18143 case OPC_PICK_OB:
18144 case OPC_PICK_PW:
18145 case OPC_PICK_QH:
18146 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
c6d6dd7c 18147 break;
099e5b4d
LA
18148 default: /* Invalid */
18149 MIPS_INVAL("MASK CMPU_EQ.OB");
9c708c7f 18150 generate_exception_end(ctx, EXCP_RI);
161f85e6 18151 break;
099e5b4d
LA
18152 }
18153 break;
18154 case OPC_DAPPEND_DSP:
18155 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
18156 break;
18157 case OPC_DEXTR_W_DSP:
18158 op2 = MASK_DEXTR_W(ctx->opcode);
18159 switch (op2) {
18160 case OPC_DEXTP:
18161 case OPC_DEXTPDP:
18162 case OPC_DEXTPDPV:
18163 case OPC_DEXTPV:
18164 case OPC_DEXTR_L:
18165 case OPC_DEXTR_R_L:
18166 case OPC_DEXTR_RS_L:
18167 case OPC_DEXTR_W:
18168 case OPC_DEXTR_R_W:
18169 case OPC_DEXTR_RS_W:
18170 case OPC_DEXTR_S_H:
18171 case OPC_DEXTRV_L:
18172 case OPC_DEXTRV_R_L:
18173 case OPC_DEXTRV_RS_L:
18174 case OPC_DEXTRV_S_H:
18175 case OPC_DEXTRV_W:
18176 case OPC_DEXTRV_R_W:
18177 case OPC_DEXTRV_RS_W:
18178 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
461c08df 18179 break;
099e5b4d
LA
18180 case OPC_DMTHLIP:
18181 case OPC_DSHILO:
18182 case OPC_DSHILOV:
18183 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
461c08df 18184 break;
099e5b4d
LA
18185 default: /* Invalid */
18186 MIPS_INVAL("MASK EXTR.W");
9c708c7f 18187 generate_exception_end(ctx, EXCP_RI);
461c08df 18188 break;
099e5b4d
LA
18189 }
18190 break;
18191 case OPC_DPAQ_W_QH_DSP:
18192 op2 = MASK_DPAQ_W_QH(ctx->opcode);
18193 switch (op2) {
18194 case OPC_DPAU_H_OBL:
18195 case OPC_DPAU_H_OBR:
18196 case OPC_DPSU_H_OBL:
18197 case OPC_DPSU_H_OBR:
18198 case OPC_DPA_W_QH:
18199 case OPC_DPAQ_S_W_QH:
18200 case OPC_DPS_W_QH:
18201 case OPC_DPSQ_S_W_QH:
18202 case OPC_MULSAQ_S_W_QH:
18203 case OPC_DPAQ_SA_L_PW:
18204 case OPC_DPSQ_SA_L_PW:
18205 case OPC_MULSAQ_S_L_PW:
18206 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
18207 break;
18208 case OPC_MAQ_S_W_QHLL:
18209 case OPC_MAQ_S_W_QHLR:
18210 case OPC_MAQ_S_W_QHRL:
18211 case OPC_MAQ_S_W_QHRR:
18212 case OPC_MAQ_SA_W_QHLL:
18213 case OPC_MAQ_SA_W_QHLR:
18214 case OPC_MAQ_SA_W_QHRL:
18215 case OPC_MAQ_SA_W_QHRR:
18216 case OPC_MAQ_S_L_PWL:
18217 case OPC_MAQ_S_L_PWR:
18218 case OPC_DMADD:
18219 case OPC_DMADDU:
18220 case OPC_DMSUB:
18221 case OPC_DMSUBU:
18222 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
26690560 18223 break;
099e5b4d
LA
18224 default: /* Invalid */
18225 MIPS_INVAL("MASK DPAQ.W.QH");
9c708c7f 18226 generate_exception_end(ctx, EXCP_RI);
b53371ed 18227 break;
099e5b4d
LA
18228 }
18229 break;
18230 case OPC_DINSV_DSP:
18231 op2 = MASK_INSV(ctx->opcode);
18232 switch (op2) {
18233 case OPC_DINSV:
18234 {
18235 TCGv t0, t1;
18236
18237 if (rt == 0) {
a22260ae
JL
18238 break;
18239 }
099e5b4d 18240 check_dsp(ctx);
1cb6686c 18241
099e5b4d
LA
18242 t0 = tcg_temp_new();
18243 t1 = tcg_temp_new();
1cb6686c 18244
099e5b4d
LA
18245 gen_load_gpr(t0, rt);
18246 gen_load_gpr(t1, rs);
1cb6686c 18247
099e5b4d 18248 gen_helper_dinsv(cpu_gpr[rt], cpu_env, t1, t0);
62eb3b9a 18249
099e5b4d
LA
18250 tcg_temp_free(t0);
18251 tcg_temp_free(t1);
77c5fa8b 18252 break;
099e5b4d 18253 }
7a387fff 18254 default: /* Invalid */
099e5b4d 18255 MIPS_INVAL("MASK DINSV");
9c708c7f 18256 generate_exception_end(ctx, EXCP_RI);
7a387fff
TS
18257 break;
18258 }
18259 break;
099e5b4d
LA
18260 case OPC_SHLL_OB_DSP:
18261 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
18262 break;
18263#endif
fac5a073
LA
18264 default: /* Invalid */
18265 MIPS_INVAL("special3_legacy");
9c708c7f 18266 generate_exception_end(ctx, EXCP_RI);
fac5a073
LA
18267 break;
18268 }
18269}
18270
18271static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx)
18272{
18273 int rs, rt, rd, sa;
18274 uint32_t op1, op2;
76964147 18275 int16_t imm;
fac5a073
LA
18276
18277 rs = (ctx->opcode >> 21) & 0x1f;
18278 rt = (ctx->opcode >> 16) & 0x1f;
18279 rd = (ctx->opcode >> 11) & 0x1f;
18280 sa = (ctx->opcode >> 6) & 0x1f;
76964147 18281 imm = sextract32(ctx->opcode, 7, 9);
fac5a073
LA
18282
18283 op1 = MASK_SPECIAL3(ctx->opcode);
76964147
JH
18284
18285 /*
18286 * EVA loads and stores overlap Loongson 2E instructions decoded by
18287 * decode_opc_special3_legacy(), so be careful to allow their decoding when
18288 * EVA is absent.
18289 */
18290 if (ctx->eva) {
18291 switch (op1) {
18292 case OPC_LWLE ... OPC_LWRE:
18293 check_insn_opc_removed(ctx, ISA_MIPS32R6);
18294 /* fall through */
18295 case OPC_LBUE ... OPC_LHUE:
18296 case OPC_LBE ... OPC_LWE:
18297 check_cp0_enabled(ctx);
18298 gen_ld(ctx, op1, rt, rs, imm);
18299 return;
18300 case OPC_SWLE ... OPC_SWRE:
18301 check_insn_opc_removed(ctx, ISA_MIPS32R6);
18302 /* fall through */
18303 case OPC_SBE ... OPC_SHE:
18304 case OPC_SWE:
18305 check_cp0_enabled(ctx);
18306 gen_st(ctx, op1, rt, rs, imm);
18307 return;
18308 case OPC_SCE:
18309 check_cp0_enabled(ctx);
18310 gen_st_cond(ctx, op1, rt, rs, imm);
18311 return;
18312 case OPC_CACHEE:
18313 check_cp0_enabled(ctx);
18314 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
18315 gen_cache_operation(ctx, rt, rs, imm);
18316 }
18317 /* Treat as NOP. */
18318 return;
18319 case OPC_PREFE:
18320 check_cp0_enabled(ctx);
18321 /* Treat as NOP. */
18322 return;
18323 }
18324 }
18325
fac5a073
LA
18326 switch (op1) {
18327 case OPC_EXT:
18328 case OPC_INS:
18329 check_insn(ctx, ISA_MIPS32R2);
18330 gen_bitops(ctx, op1, rt, rs, sa, rd);
18331 break;
18332 case OPC_BSHFL:
fac5a073 18333 op2 = MASK_BSHFL(ctx->opcode);
15eacb9b
YK
18334 switch (op2) {
18335 case OPC_ALIGN ... OPC_ALIGN_END:
18336 case OPC_BITSWAP:
18337 check_insn(ctx, ISA_MIPS32R6);
18338 decode_opc_special3_r6(env, ctx);
18339 break;
18340 default:
18341 check_insn(ctx, ISA_MIPS32R2);
18342 gen_bshfl(ctx, op2, rt, rd);
18343 break;
18344 }
fac5a073
LA
18345 break;
18346#if defined(TARGET_MIPS64)
18347 case OPC_DEXTM ... OPC_DEXT:
18348 case OPC_DINSM ... OPC_DINS:
18349 check_insn(ctx, ISA_MIPS64R2);
18350 check_mips_64(ctx);
18351 gen_bitops(ctx, op1, rt, rs, sa, rd);
18352 break;
18353 case OPC_DBSHFL:
fac5a073 18354 op2 = MASK_DBSHFL(ctx->opcode);
15eacb9b
YK
18355 switch (op2) {
18356 case OPC_DALIGN ... OPC_DALIGN_END:
18357 case OPC_DBITSWAP:
18358 check_insn(ctx, ISA_MIPS32R6);
18359 decode_opc_special3_r6(env, ctx);
18360 break;
18361 default:
18362 check_insn(ctx, ISA_MIPS64R2);
18363 check_mips_64(ctx);
18364 op2 = MASK_DBSHFL(ctx->opcode);
18365 gen_bshfl(ctx, op2, rt, rd);
18366 break;
18367 }
fac5a073
LA
18368 break;
18369#endif
18370 case OPC_RDHWR:
b00c7218 18371 gen_rdhwr(ctx, rt, rd, extract32(ctx->opcode, 6, 3));
fac5a073
LA
18372 break;
18373 case OPC_FORK:
18374 check_insn(ctx, ASE_MT);
18375 {
18376 TCGv t0 = tcg_temp_new();
18377 TCGv t1 = tcg_temp_new();
18378
18379 gen_load_gpr(t0, rt);
18380 gen_load_gpr(t1, rs);
18381 gen_helper_fork(t0, t1);
18382 tcg_temp_free(t0);
18383 tcg_temp_free(t1);
18384 }
18385 break;
18386 case OPC_YIELD:
18387 check_insn(ctx, ASE_MT);
18388 {
18389 TCGv t0 = tcg_temp_new();
18390
fac5a073
LA
18391 gen_load_gpr(t0, rs);
18392 gen_helper_yield(t0, cpu_env, t0);
18393 gen_store_gpr(t0, rd);
18394 tcg_temp_free(t0);
18395 }
18396 break;
10dc65db
LA
18397 default:
18398 if (ctx->insn_flags & ISA_MIPS32R6) {
18399 decode_opc_special3_r6(env, ctx);
18400 } else {
18401 decode_opc_special3_legacy(env, ctx);
18402 }
099e5b4d
LA
18403 }
18404}
18405
863f264d
YK
18406/* MIPS SIMD Architecture (MSA) */
18407static inline int check_msa_access(DisasContext *ctx)
18408{
18409 if (unlikely((ctx->hflags & MIPS_HFLAG_FPU) &&
18410 !(ctx->hflags & MIPS_HFLAG_F64))) {
9c708c7f 18411 generate_exception_end(ctx, EXCP_RI);
863f264d
YK
18412 return 0;
18413 }
18414
18415 if (unlikely(!(ctx->hflags & MIPS_HFLAG_MSA))) {
18416 if (ctx->insn_flags & ASE_MSA) {
9c708c7f 18417 generate_exception_end(ctx, EXCP_MSADIS);
863f264d
YK
18418 return 0;
18419 } else {
9c708c7f 18420 generate_exception_end(ctx, EXCP_RI);
863f264d
YK
18421 return 0;
18422 }
18423 }
18424 return 1;
18425}
18426
5692c6e1
YK
18427static void gen_check_zero_element(TCGv tresult, uint8_t df, uint8_t wt)
18428{
18429 /* generates tcg ops to check if any element is 0 */
18430 /* Note this function only works with MSA_WRLEN = 128 */
18431 uint64_t eval_zero_or_big = 0;
18432 uint64_t eval_big = 0;
18433 TCGv_i64 t0 = tcg_temp_new_i64();
18434 TCGv_i64 t1 = tcg_temp_new_i64();
18435 switch (df) {
18436 case DF_BYTE:
18437 eval_zero_or_big = 0x0101010101010101ULL;
18438 eval_big = 0x8080808080808080ULL;
18439 break;
18440 case DF_HALF:
18441 eval_zero_or_big = 0x0001000100010001ULL;
18442 eval_big = 0x8000800080008000ULL;
18443 break;
18444 case DF_WORD:
18445 eval_zero_or_big = 0x0000000100000001ULL;
18446 eval_big = 0x8000000080000000ULL;
18447 break;
18448 case DF_DOUBLE:
18449 eval_zero_or_big = 0x0000000000000001ULL;
18450 eval_big = 0x8000000000000000ULL;
18451 break;
18452 }
18453 tcg_gen_subi_i64(t0, msa_wr_d[wt<<1], eval_zero_or_big);
18454 tcg_gen_andc_i64(t0, t0, msa_wr_d[wt<<1]);
18455 tcg_gen_andi_i64(t0, t0, eval_big);
18456 tcg_gen_subi_i64(t1, msa_wr_d[(wt<<1)+1], eval_zero_or_big);
18457 tcg_gen_andc_i64(t1, t1, msa_wr_d[(wt<<1)+1]);
18458 tcg_gen_andi_i64(t1, t1, eval_big);
18459 tcg_gen_or_i64(t0, t0, t1);
18460 /* if all bits are zero then all elements are not zero */
18461 /* if some bit is non-zero then some element is zero */
18462 tcg_gen_setcondi_i64(TCG_COND_NE, t0, t0, 0);
18463 tcg_gen_trunc_i64_tl(tresult, t0);
18464 tcg_temp_free_i64(t0);
18465 tcg_temp_free_i64(t1);
18466}
18467
18468static void gen_msa_branch(CPUMIPSState *env, DisasContext *ctx, uint32_t op1)
18469{
18470 uint8_t df = (ctx->opcode >> 21) & 0x3;
18471 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
18472 int64_t s16 = (int16_t)ctx->opcode;
18473
18474 check_msa_access(ctx);
18475
075a1fe7 18476 if (ctx->hflags & MIPS_HFLAG_BMASK) {
9c708c7f 18477 generate_exception_end(ctx, EXCP_RI);
5692c6e1
YK
18478 return;
18479 }
18480 switch (op1) {
18481 case OPC_BZ_V:
18482 case OPC_BNZ_V:
18483 {
18484 TCGv_i64 t0 = tcg_temp_new_i64();
18485 tcg_gen_or_i64(t0, msa_wr_d[wt<<1], msa_wr_d[(wt<<1)+1]);
18486 tcg_gen_setcondi_i64((op1 == OPC_BZ_V) ?
18487 TCG_COND_EQ : TCG_COND_NE, t0, t0, 0);
18488 tcg_gen_trunc_i64_tl(bcond, t0);
18489 tcg_temp_free_i64(t0);
18490 }
18491 break;
18492 case OPC_BZ_B:
18493 case OPC_BZ_H:
18494 case OPC_BZ_W:
18495 case OPC_BZ_D:
18496 gen_check_zero_element(bcond, df, wt);
18497 break;
18498 case OPC_BNZ_B:
18499 case OPC_BNZ_H:
18500 case OPC_BNZ_W:
18501 case OPC_BNZ_D:
18502 gen_check_zero_element(bcond, df, wt);
18503 tcg_gen_setcondi_tl(TCG_COND_EQ, bcond, bcond, 0);
18504 break;
18505 }
18506
eeb3bba8 18507 ctx->btarget = ctx->base.pc_next + (s16 << 2) + 4;
5692c6e1
YK
18508
18509 ctx->hflags |= MIPS_HFLAG_BC;
18510 ctx->hflags |= MIPS_HFLAG_BDS32;
18511}
18512
4c789546
YK
18513static void gen_msa_i8(CPUMIPSState *env, DisasContext *ctx)
18514{
18515#define MASK_MSA_I8(op) (MASK_MSA_MINOR(op) | (op & (0x03 << 24)))
18516 uint8_t i8 = (ctx->opcode >> 16) & 0xff;
18517 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18518 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18519
18520 TCGv_i32 twd = tcg_const_i32(wd);
18521 TCGv_i32 tws = tcg_const_i32(ws);
18522 TCGv_i32 ti8 = tcg_const_i32(i8);
18523
18524 switch (MASK_MSA_I8(ctx->opcode)) {
18525 case OPC_ANDI_B:
18526 gen_helper_msa_andi_b(cpu_env, twd, tws, ti8);
18527 break;
18528 case OPC_ORI_B:
18529 gen_helper_msa_ori_b(cpu_env, twd, tws, ti8);
18530 break;
18531 case OPC_NORI_B:
18532 gen_helper_msa_nori_b(cpu_env, twd, tws, ti8);
18533 break;
18534 case OPC_XORI_B:
18535 gen_helper_msa_xori_b(cpu_env, twd, tws, ti8);
18536 break;
18537 case OPC_BMNZI_B:
18538 gen_helper_msa_bmnzi_b(cpu_env, twd, tws, ti8);
18539 break;
18540 case OPC_BMZI_B:
18541 gen_helper_msa_bmzi_b(cpu_env, twd, tws, ti8);
18542 break;
18543 case OPC_BSELI_B:
18544 gen_helper_msa_bseli_b(cpu_env, twd, tws, ti8);
18545 break;
18546 case OPC_SHF_B:
18547 case OPC_SHF_H:
18548 case OPC_SHF_W:
18549 {
18550 uint8_t df = (ctx->opcode >> 24) & 0x3;
18551 if (df == DF_DOUBLE) {
9c708c7f 18552 generate_exception_end(ctx, EXCP_RI);
4c789546
YK
18553 } else {
18554 TCGv_i32 tdf = tcg_const_i32(df);
18555 gen_helper_msa_shf_df(cpu_env, tdf, twd, tws, ti8);
18556 tcg_temp_free_i32(tdf);
18557 }
18558 }
18559 break;
18560 default:
18561 MIPS_INVAL("MSA instruction");
9c708c7f 18562 generate_exception_end(ctx, EXCP_RI);
4c789546
YK
18563 break;
18564 }
18565
18566 tcg_temp_free_i32(twd);
18567 tcg_temp_free_i32(tws);
18568 tcg_temp_free_i32(ti8);
18569}
18570
80e71591
YK
18571static void gen_msa_i5(CPUMIPSState *env, DisasContext *ctx)
18572{
18573#define MASK_MSA_I5(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
18574 uint8_t df = (ctx->opcode >> 21) & 0x3;
18575 int8_t s5 = (int8_t) sextract32(ctx->opcode, 16, 5);
18576 uint8_t u5 = (ctx->opcode >> 16) & 0x1f;
18577 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18578 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18579
18580 TCGv_i32 tdf = tcg_const_i32(df);
18581 TCGv_i32 twd = tcg_const_i32(wd);
18582 TCGv_i32 tws = tcg_const_i32(ws);
18583 TCGv_i32 timm = tcg_temp_new_i32();
18584 tcg_gen_movi_i32(timm, u5);
18585
18586 switch (MASK_MSA_I5(ctx->opcode)) {
18587 case OPC_ADDVI_df:
18588 gen_helper_msa_addvi_df(cpu_env, tdf, twd, tws, timm);
18589 break;
18590 case OPC_SUBVI_df:
18591 gen_helper_msa_subvi_df(cpu_env, tdf, twd, tws, timm);
18592 break;
18593 case OPC_MAXI_S_df:
18594 tcg_gen_movi_i32(timm, s5);
18595 gen_helper_msa_maxi_s_df(cpu_env, tdf, twd, tws, timm);
18596 break;
18597 case OPC_MAXI_U_df:
18598 gen_helper_msa_maxi_u_df(cpu_env, tdf, twd, tws, timm);
18599 break;
18600 case OPC_MINI_S_df:
18601 tcg_gen_movi_i32(timm, s5);
18602 gen_helper_msa_mini_s_df(cpu_env, tdf, twd, tws, timm);
18603 break;
18604 case OPC_MINI_U_df:
18605 gen_helper_msa_mini_u_df(cpu_env, tdf, twd, tws, timm);
18606 break;
18607 case OPC_CEQI_df:
18608 tcg_gen_movi_i32(timm, s5);
18609 gen_helper_msa_ceqi_df(cpu_env, tdf, twd, tws, timm);
18610 break;
18611 case OPC_CLTI_S_df:
18612 tcg_gen_movi_i32(timm, s5);
18613 gen_helper_msa_clti_s_df(cpu_env, tdf, twd, tws, timm);
18614 break;
18615 case OPC_CLTI_U_df:
18616 gen_helper_msa_clti_u_df(cpu_env, tdf, twd, tws, timm);
18617 break;
18618 case OPC_CLEI_S_df:
18619 tcg_gen_movi_i32(timm, s5);
18620 gen_helper_msa_clei_s_df(cpu_env, tdf, twd, tws, timm);
18621 break;
18622 case OPC_CLEI_U_df:
18623 gen_helper_msa_clei_u_df(cpu_env, tdf, twd, tws, timm);
18624 break;
18625 case OPC_LDI_df:
18626 {
18627 int32_t s10 = sextract32(ctx->opcode, 11, 10);
18628 tcg_gen_movi_i32(timm, s10);
18629 gen_helper_msa_ldi_df(cpu_env, tdf, twd, timm);
18630 }
18631 break;
18632 default:
18633 MIPS_INVAL("MSA instruction");
9c708c7f 18634 generate_exception_end(ctx, EXCP_RI);
80e71591
YK
18635 break;
18636 }
18637
18638 tcg_temp_free_i32(tdf);
18639 tcg_temp_free_i32(twd);
18640 tcg_temp_free_i32(tws);
18641 tcg_temp_free_i32(timm);
18642}
18643
d4cf28de
YK
18644static void gen_msa_bit(CPUMIPSState *env, DisasContext *ctx)
18645{
18646#define MASK_MSA_BIT(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
18647 uint8_t dfm = (ctx->opcode >> 16) & 0x7f;
18648 uint32_t df = 0, m = 0;
18649 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18650 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18651
18652 TCGv_i32 tdf;
18653 TCGv_i32 tm;
18654 TCGv_i32 twd;
18655 TCGv_i32 tws;
18656
18657 if ((dfm & 0x40) == 0x00) {
18658 m = dfm & 0x3f;
18659 df = DF_DOUBLE;
18660 } else if ((dfm & 0x60) == 0x40) {
18661 m = dfm & 0x1f;
18662 df = DF_WORD;
18663 } else if ((dfm & 0x70) == 0x60) {
18664 m = dfm & 0x0f;
18665 df = DF_HALF;
18666 } else if ((dfm & 0x78) == 0x70) {
18667 m = dfm & 0x7;
18668 df = DF_BYTE;
18669 } else {
9c708c7f 18670 generate_exception_end(ctx, EXCP_RI);
d4cf28de
YK
18671 return;
18672 }
18673
18674 tdf = tcg_const_i32(df);
18675 tm = tcg_const_i32(m);
18676 twd = tcg_const_i32(wd);
18677 tws = tcg_const_i32(ws);
18678
18679 switch (MASK_MSA_BIT(ctx->opcode)) {
18680 case OPC_SLLI_df:
18681 gen_helper_msa_slli_df(cpu_env, tdf, twd, tws, tm);
18682 break;
18683 case OPC_SRAI_df:
18684 gen_helper_msa_srai_df(cpu_env, tdf, twd, tws, tm);
18685 break;
18686 case OPC_SRLI_df:
18687 gen_helper_msa_srli_df(cpu_env, tdf, twd, tws, tm);
18688 break;
18689 case OPC_BCLRI_df:
18690 gen_helper_msa_bclri_df(cpu_env, tdf, twd, tws, tm);
18691 break;
18692 case OPC_BSETI_df:
18693 gen_helper_msa_bseti_df(cpu_env, tdf, twd, tws, tm);
18694 break;
18695 case OPC_BNEGI_df:
18696 gen_helper_msa_bnegi_df(cpu_env, tdf, twd, tws, tm);
18697 break;
18698 case OPC_BINSLI_df:
18699 gen_helper_msa_binsli_df(cpu_env, tdf, twd, tws, tm);
18700 break;
18701 case OPC_BINSRI_df:
18702 gen_helper_msa_binsri_df(cpu_env, tdf, twd, tws, tm);
18703 break;
18704 case OPC_SAT_S_df:
18705 gen_helper_msa_sat_s_df(cpu_env, tdf, twd, tws, tm);
18706 break;
18707 case OPC_SAT_U_df:
18708 gen_helper_msa_sat_u_df(cpu_env, tdf, twd, tws, tm);
18709 break;
18710 case OPC_SRARI_df:
18711 gen_helper_msa_srari_df(cpu_env, tdf, twd, tws, tm);
18712 break;
18713 case OPC_SRLRI_df:
18714 gen_helper_msa_srlri_df(cpu_env, tdf, twd, tws, tm);
18715 break;
18716 default:
18717 MIPS_INVAL("MSA instruction");
9c708c7f 18718 generate_exception_end(ctx, EXCP_RI);
d4cf28de
YK
18719 break;
18720 }
18721
18722 tcg_temp_free_i32(tdf);
18723 tcg_temp_free_i32(tm);
18724 tcg_temp_free_i32(twd);
18725 tcg_temp_free_i32(tws);
18726}
18727
28f99f08
YK
18728static void gen_msa_3r(CPUMIPSState *env, DisasContext *ctx)
18729{
18730#define MASK_MSA_3R(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
18731 uint8_t df = (ctx->opcode >> 21) & 0x3;
18732 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
18733 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18734 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18735
18736 TCGv_i32 tdf = tcg_const_i32(df);
18737 TCGv_i32 twd = tcg_const_i32(wd);
18738 TCGv_i32 tws = tcg_const_i32(ws);
18739 TCGv_i32 twt = tcg_const_i32(wt);
18740
18741 switch (MASK_MSA_3R(ctx->opcode)) {
18742 case OPC_SLL_df:
18743 gen_helper_msa_sll_df(cpu_env, tdf, twd, tws, twt);
18744 break;
18745 case OPC_ADDV_df:
18746 gen_helper_msa_addv_df(cpu_env, tdf, twd, tws, twt);
18747 break;
18748 case OPC_CEQ_df:
18749 gen_helper_msa_ceq_df(cpu_env, tdf, twd, tws, twt);
18750 break;
18751 case OPC_ADD_A_df:
18752 gen_helper_msa_add_a_df(cpu_env, tdf, twd, tws, twt);
18753 break;
18754 case OPC_SUBS_S_df:
18755 gen_helper_msa_subs_s_df(cpu_env, tdf, twd, tws, twt);
18756 break;
18757 case OPC_MULV_df:
18758 gen_helper_msa_mulv_df(cpu_env, tdf, twd, tws, twt);
18759 break;
18760 case OPC_SLD_df:
18761 gen_helper_msa_sld_df(cpu_env, tdf, twd, tws, twt);
18762 break;
18763 case OPC_VSHF_df:
18764 gen_helper_msa_vshf_df(cpu_env, tdf, twd, tws, twt);
18765 break;
18766 case OPC_SRA_df:
18767 gen_helper_msa_sra_df(cpu_env, tdf, twd, tws, twt);
18768 break;
18769 case OPC_SUBV_df:
18770 gen_helper_msa_subv_df(cpu_env, tdf, twd, tws, twt);
18771 break;
18772 case OPC_ADDS_A_df:
18773 gen_helper_msa_adds_a_df(cpu_env, tdf, twd, tws, twt);
18774 break;
18775 case OPC_SUBS_U_df:
18776 gen_helper_msa_subs_u_df(cpu_env, tdf, twd, tws, twt);
18777 break;
18778 case OPC_MADDV_df:
18779 gen_helper_msa_maddv_df(cpu_env, tdf, twd, tws, twt);
18780 break;
18781 case OPC_SPLAT_df:
18782 gen_helper_msa_splat_df(cpu_env, tdf, twd, tws, twt);
18783 break;
18784 case OPC_SRAR_df:
18785 gen_helper_msa_srar_df(cpu_env, tdf, twd, tws, twt);
18786 break;
18787 case OPC_SRL_df:
18788 gen_helper_msa_srl_df(cpu_env, tdf, twd, tws, twt);
18789 break;
18790 case OPC_MAX_S_df:
18791 gen_helper_msa_max_s_df(cpu_env, tdf, twd, tws, twt);
18792 break;
18793 case OPC_CLT_S_df:
18794 gen_helper_msa_clt_s_df(cpu_env, tdf, twd, tws, twt);
18795 break;
18796 case OPC_ADDS_S_df:
18797 gen_helper_msa_adds_s_df(cpu_env, tdf, twd, tws, twt);
18798 break;
18799 case OPC_SUBSUS_U_df:
18800 gen_helper_msa_subsus_u_df(cpu_env, tdf, twd, tws, twt);
18801 break;
18802 case OPC_MSUBV_df:
18803 gen_helper_msa_msubv_df(cpu_env, tdf, twd, tws, twt);
18804 break;
18805 case OPC_PCKEV_df:
18806 gen_helper_msa_pckev_df(cpu_env, tdf, twd, tws, twt);
18807 break;
18808 case OPC_SRLR_df:
18809 gen_helper_msa_srlr_df(cpu_env, tdf, twd, tws, twt);
18810 break;
18811 case OPC_BCLR_df:
18812 gen_helper_msa_bclr_df(cpu_env, tdf, twd, tws, twt);
18813 break;
18814 case OPC_MAX_U_df:
18815 gen_helper_msa_max_u_df(cpu_env, tdf, twd, tws, twt);
18816 break;
18817 case OPC_CLT_U_df:
18818 gen_helper_msa_clt_u_df(cpu_env, tdf, twd, tws, twt);
18819 break;
18820 case OPC_ADDS_U_df:
18821 gen_helper_msa_adds_u_df(cpu_env, tdf, twd, tws, twt);
18822 break;
18823 case OPC_SUBSUU_S_df:
18824 gen_helper_msa_subsuu_s_df(cpu_env, tdf, twd, tws, twt);
18825 break;
18826 case OPC_PCKOD_df:
18827 gen_helper_msa_pckod_df(cpu_env, tdf, twd, tws, twt);
18828 break;
18829 case OPC_BSET_df:
18830 gen_helper_msa_bset_df(cpu_env, tdf, twd, tws, twt);
18831 break;
18832 case OPC_MIN_S_df:
18833 gen_helper_msa_min_s_df(cpu_env, tdf, twd, tws, twt);
18834 break;
18835 case OPC_CLE_S_df:
18836 gen_helper_msa_cle_s_df(cpu_env, tdf, twd, tws, twt);
18837 break;
18838 case OPC_AVE_S_df:
18839 gen_helper_msa_ave_s_df(cpu_env, tdf, twd, tws, twt);
18840 break;
18841 case OPC_ASUB_S_df:
18842 gen_helper_msa_asub_s_df(cpu_env, tdf, twd, tws, twt);
18843 break;
18844 case OPC_DIV_S_df:
18845 gen_helper_msa_div_s_df(cpu_env, tdf, twd, tws, twt);
18846 break;
18847 case OPC_ILVL_df:
18848 gen_helper_msa_ilvl_df(cpu_env, tdf, twd, tws, twt);
18849 break;
18850 case OPC_BNEG_df:
18851 gen_helper_msa_bneg_df(cpu_env, tdf, twd, tws, twt);
18852 break;
18853 case OPC_MIN_U_df:
18854 gen_helper_msa_min_u_df(cpu_env, tdf, twd, tws, twt);
18855 break;
18856 case OPC_CLE_U_df:
18857 gen_helper_msa_cle_u_df(cpu_env, tdf, twd, tws, twt);
18858 break;
18859 case OPC_AVE_U_df:
18860 gen_helper_msa_ave_u_df(cpu_env, tdf, twd, tws, twt);
18861 break;
18862 case OPC_ASUB_U_df:
18863 gen_helper_msa_asub_u_df(cpu_env, tdf, twd, tws, twt);
18864 break;
18865 case OPC_DIV_U_df:
18866 gen_helper_msa_div_u_df(cpu_env, tdf, twd, tws, twt);
18867 break;
18868 case OPC_ILVR_df:
18869 gen_helper_msa_ilvr_df(cpu_env, tdf, twd, tws, twt);
18870 break;
18871 case OPC_BINSL_df:
18872 gen_helper_msa_binsl_df(cpu_env, tdf, twd, tws, twt);
18873 break;
18874 case OPC_MAX_A_df:
18875 gen_helper_msa_max_a_df(cpu_env, tdf, twd, tws, twt);
18876 break;
18877 case OPC_AVER_S_df:
18878 gen_helper_msa_aver_s_df(cpu_env, tdf, twd, tws, twt);
18879 break;
18880 case OPC_MOD_S_df:
18881 gen_helper_msa_mod_s_df(cpu_env, tdf, twd, tws, twt);
18882 break;
18883 case OPC_ILVEV_df:
18884 gen_helper_msa_ilvev_df(cpu_env, tdf, twd, tws, twt);
18885 break;
18886 case OPC_BINSR_df:
18887 gen_helper_msa_binsr_df(cpu_env, tdf, twd, tws, twt);
18888 break;
18889 case OPC_MIN_A_df:
18890 gen_helper_msa_min_a_df(cpu_env, tdf, twd, tws, twt);
18891 break;
18892 case OPC_AVER_U_df:
18893 gen_helper_msa_aver_u_df(cpu_env, tdf, twd, tws, twt);
18894 break;
18895 case OPC_MOD_U_df:
18896 gen_helper_msa_mod_u_df(cpu_env, tdf, twd, tws, twt);
18897 break;
18898 case OPC_ILVOD_df:
18899 gen_helper_msa_ilvod_df(cpu_env, tdf, twd, tws, twt);
18900 break;
18901
18902 case OPC_DOTP_S_df:
18903 case OPC_DOTP_U_df:
18904 case OPC_DPADD_S_df:
18905 case OPC_DPADD_U_df:
18906 case OPC_DPSUB_S_df:
18907 case OPC_HADD_S_df:
18908 case OPC_DPSUB_U_df:
18909 case OPC_HADD_U_df:
18910 case OPC_HSUB_S_df:
18911 case OPC_HSUB_U_df:
18912 if (df == DF_BYTE) {
9c708c7f
PD
18913 generate_exception_end(ctx, EXCP_RI);
18914 break;
28f99f08
YK
18915 }
18916 switch (MASK_MSA_3R(ctx->opcode)) {
18917 case OPC_DOTP_S_df:
18918 gen_helper_msa_dotp_s_df(cpu_env, tdf, twd, tws, twt);
18919 break;
18920 case OPC_DOTP_U_df:
18921 gen_helper_msa_dotp_u_df(cpu_env, tdf, twd, tws, twt);
18922 break;
18923 case OPC_DPADD_S_df:
18924 gen_helper_msa_dpadd_s_df(cpu_env, tdf, twd, tws, twt);
18925 break;
18926 case OPC_DPADD_U_df:
18927 gen_helper_msa_dpadd_u_df(cpu_env, tdf, twd, tws, twt);
18928 break;
18929 case OPC_DPSUB_S_df:
18930 gen_helper_msa_dpsub_s_df(cpu_env, tdf, twd, tws, twt);
18931 break;
18932 case OPC_HADD_S_df:
18933 gen_helper_msa_hadd_s_df(cpu_env, tdf, twd, tws, twt);
18934 break;
18935 case OPC_DPSUB_U_df:
18936 gen_helper_msa_dpsub_u_df(cpu_env, tdf, twd, tws, twt);
18937 break;
18938 case OPC_HADD_U_df:
18939 gen_helper_msa_hadd_u_df(cpu_env, tdf, twd, tws, twt);
18940 break;
18941 case OPC_HSUB_S_df:
18942 gen_helper_msa_hsub_s_df(cpu_env, tdf, twd, tws, twt);
18943 break;
18944 case OPC_HSUB_U_df:
18945 gen_helper_msa_hsub_u_df(cpu_env, tdf, twd, tws, twt);
18946 break;
18947 }
18948 break;
18949 default:
18950 MIPS_INVAL("MSA instruction");
9c708c7f 18951 generate_exception_end(ctx, EXCP_RI);
28f99f08
YK
18952 break;
18953 }
18954 tcg_temp_free_i32(twd);
18955 tcg_temp_free_i32(tws);
18956 tcg_temp_free_i32(twt);
18957 tcg_temp_free_i32(tdf);
18958}
18959
1e608ec1
YK
18960static void gen_msa_elm_3e(CPUMIPSState *env, DisasContext *ctx)
18961{
18962#define MASK_MSA_ELM_DF3E(op) (MASK_MSA_MINOR(op) | (op & (0x3FF << 16)))
18963 uint8_t source = (ctx->opcode >> 11) & 0x1f;
18964 uint8_t dest = (ctx->opcode >> 6) & 0x1f;
18965 TCGv telm = tcg_temp_new();
18966 TCGv_i32 tsr = tcg_const_i32(source);
18967 TCGv_i32 tdt = tcg_const_i32(dest);
18968
18969 switch (MASK_MSA_ELM_DF3E(ctx->opcode)) {
18970 case OPC_CTCMSA:
18971 gen_load_gpr(telm, source);
18972 gen_helper_msa_ctcmsa(cpu_env, telm, tdt);
18973 break;
18974 case OPC_CFCMSA:
18975 gen_helper_msa_cfcmsa(telm, cpu_env, tsr);
18976 gen_store_gpr(telm, dest);
18977 break;
18978 case OPC_MOVE_V:
18979 gen_helper_msa_move_v(cpu_env, tdt, tsr);
18980 break;
18981 default:
18982 MIPS_INVAL("MSA instruction");
9c708c7f 18983 generate_exception_end(ctx, EXCP_RI);
1e608ec1
YK
18984 break;
18985 }
18986
18987 tcg_temp_free(telm);
18988 tcg_temp_free_i32(tdt);
18989 tcg_temp_free_i32(tsr);
18990}
18991
18992static void gen_msa_elm_df(CPUMIPSState *env, DisasContext *ctx, uint32_t df,
18993 uint32_t n)
18994{
18995#define MASK_MSA_ELM(op) (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
18996 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18997 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18998
18999 TCGv_i32 tws = tcg_const_i32(ws);
19000 TCGv_i32 twd = tcg_const_i32(wd);
19001 TCGv_i32 tn = tcg_const_i32(n);
19002 TCGv_i32 tdf = tcg_const_i32(df);
19003
19004 switch (MASK_MSA_ELM(ctx->opcode)) {
19005 case OPC_SLDI_df:
19006 gen_helper_msa_sldi_df(cpu_env, tdf, twd, tws, tn);
19007 break;
19008 case OPC_SPLATI_df:
19009 gen_helper_msa_splati_df(cpu_env, tdf, twd, tws, tn);
19010 break;
19011 case OPC_INSVE_df:
19012 gen_helper_msa_insve_df(cpu_env, tdf, twd, tws, tn);
19013 break;
19014 case OPC_COPY_S_df:
19015 case OPC_COPY_U_df:
19016 case OPC_INSERT_df:
19017#if !defined(TARGET_MIPS64)
19018 /* Double format valid only for MIPS64 */
19019 if (df == DF_DOUBLE) {
9c708c7f 19020 generate_exception_end(ctx, EXCP_RI);
1e608ec1
YK
19021 break;
19022 }
19023#endif
19024 switch (MASK_MSA_ELM(ctx->opcode)) {
19025 case OPC_COPY_S_df:
cab48881
MD
19026 if (likely(wd != 0)) {
19027 gen_helper_msa_copy_s_df(cpu_env, tdf, twd, tws, tn);
19028 }
1e608ec1
YK
19029 break;
19030 case OPC_COPY_U_df:
cab48881
MD
19031 if (likely(wd != 0)) {
19032 gen_helper_msa_copy_u_df(cpu_env, tdf, twd, tws, tn);
19033 }
1e608ec1
YK
19034 break;
19035 case OPC_INSERT_df:
19036 gen_helper_msa_insert_df(cpu_env, tdf, twd, tws, tn);
19037 break;
19038 }
19039 break;
19040 default:
19041 MIPS_INVAL("MSA instruction");
9c708c7f 19042 generate_exception_end(ctx, EXCP_RI);
1e608ec1
YK
19043 }
19044 tcg_temp_free_i32(twd);
19045 tcg_temp_free_i32(tws);
19046 tcg_temp_free_i32(tn);
19047 tcg_temp_free_i32(tdf);
19048}
19049
19050static void gen_msa_elm(CPUMIPSState *env, DisasContext *ctx)
19051{
19052 uint8_t dfn = (ctx->opcode >> 16) & 0x3f;
19053 uint32_t df = 0, n = 0;
19054
19055 if ((dfn & 0x30) == 0x00) {
19056 n = dfn & 0x0f;
19057 df = DF_BYTE;
19058 } else if ((dfn & 0x38) == 0x20) {
19059 n = dfn & 0x07;
19060 df = DF_HALF;
19061 } else if ((dfn & 0x3c) == 0x30) {
19062 n = dfn & 0x03;
19063 df = DF_WORD;
19064 } else if ((dfn & 0x3e) == 0x38) {
19065 n = dfn & 0x01;
19066 df = DF_DOUBLE;
19067 } else if (dfn == 0x3E) {
19068 /* CTCMSA, CFCMSA, MOVE.V */
19069 gen_msa_elm_3e(env, ctx);
19070 return;
19071 } else {
9c708c7f 19072 generate_exception_end(ctx, EXCP_RI);
1e608ec1
YK
19073 return;
19074 }
19075
19076 gen_msa_elm_df(env, ctx, df, n);
19077}
19078
7d05b9c8
YK
19079static void gen_msa_3rf(CPUMIPSState *env, DisasContext *ctx)
19080{
19081#define MASK_MSA_3RF(op) (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
19082 uint8_t df = (ctx->opcode >> 21) & 0x1;
19083 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
19084 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
19085 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
19086
19087 TCGv_i32 twd = tcg_const_i32(wd);
19088 TCGv_i32 tws = tcg_const_i32(ws);
19089 TCGv_i32 twt = tcg_const_i32(wt);
19090 TCGv_i32 tdf = tcg_temp_new_i32();
19091
19092 /* adjust df value for floating-point instruction */
19093 tcg_gen_movi_i32(tdf, df + 2);
19094
19095 switch (MASK_MSA_3RF(ctx->opcode)) {
19096 case OPC_FCAF_df:
19097 gen_helper_msa_fcaf_df(cpu_env, tdf, twd, tws, twt);
19098 break;
19099 case OPC_FADD_df:
19100 gen_helper_msa_fadd_df(cpu_env, tdf, twd, tws, twt);
19101 break;
19102 case OPC_FCUN_df:
19103 gen_helper_msa_fcun_df(cpu_env, tdf, twd, tws, twt);
19104 break;
19105 case OPC_FSUB_df:
19106 gen_helper_msa_fsub_df(cpu_env, tdf, twd, tws, twt);
19107 break;
19108 case OPC_FCOR_df:
19109 gen_helper_msa_fcor_df(cpu_env, tdf, twd, tws, twt);
19110 break;
19111 case OPC_FCEQ_df:
19112 gen_helper_msa_fceq_df(cpu_env, tdf, twd, tws, twt);
19113 break;
19114 case OPC_FMUL_df:
19115 gen_helper_msa_fmul_df(cpu_env, tdf, twd, tws, twt);
19116 break;
19117 case OPC_FCUNE_df:
19118 gen_helper_msa_fcune_df(cpu_env, tdf, twd, tws, twt);
19119 break;
19120 case OPC_FCUEQ_df:
19121 gen_helper_msa_fcueq_df(cpu_env, tdf, twd, tws, twt);
19122 break;
19123 case OPC_FDIV_df:
19124 gen_helper_msa_fdiv_df(cpu_env, tdf, twd, tws, twt);
19125 break;
19126 case OPC_FCNE_df:
19127 gen_helper_msa_fcne_df(cpu_env, tdf, twd, tws, twt);
19128 break;
19129 case OPC_FCLT_df:
19130 gen_helper_msa_fclt_df(cpu_env, tdf, twd, tws, twt);
19131 break;
19132 case OPC_FMADD_df:
19133 gen_helper_msa_fmadd_df(cpu_env, tdf, twd, tws, twt);
19134 break;
19135 case OPC_MUL_Q_df:
19136 tcg_gen_movi_i32(tdf, df + 1);
19137 gen_helper_msa_mul_q_df(cpu_env, tdf, twd, tws, twt);
19138 break;
19139 case OPC_FCULT_df:
19140 gen_helper_msa_fcult_df(cpu_env, tdf, twd, tws, twt);
19141 break;
19142 case OPC_FMSUB_df:
19143 gen_helper_msa_fmsub_df(cpu_env, tdf, twd, tws, twt);
19144 break;
19145 case OPC_MADD_Q_df:
19146 tcg_gen_movi_i32(tdf, df + 1);
19147 gen_helper_msa_madd_q_df(cpu_env, tdf, twd, tws, twt);
19148 break;
19149 case OPC_FCLE_df:
19150 gen_helper_msa_fcle_df(cpu_env, tdf, twd, tws, twt);
19151 break;
19152 case OPC_MSUB_Q_df:
19153 tcg_gen_movi_i32(tdf, df + 1);
19154 gen_helper_msa_msub_q_df(cpu_env, tdf, twd, tws, twt);
19155 break;
19156 case OPC_FCULE_df:
19157 gen_helper_msa_fcule_df(cpu_env, tdf, twd, tws, twt);
19158 break;
19159 case OPC_FEXP2_df:
19160 gen_helper_msa_fexp2_df(cpu_env, tdf, twd, tws, twt);
19161 break;
19162 case OPC_FSAF_df:
19163 gen_helper_msa_fsaf_df(cpu_env, tdf, twd, tws, twt);
19164 break;
19165 case OPC_FEXDO_df:
19166 gen_helper_msa_fexdo_df(cpu_env, tdf, twd, tws, twt);
19167 break;
19168 case OPC_FSUN_df:
19169 gen_helper_msa_fsun_df(cpu_env, tdf, twd, tws, twt);
19170 break;
19171 case OPC_FSOR_df:
19172 gen_helper_msa_fsor_df(cpu_env, tdf, twd, tws, twt);
19173 break;
19174 case OPC_FSEQ_df:
19175 gen_helper_msa_fseq_df(cpu_env, tdf, twd, tws, twt);
19176 break;
19177 case OPC_FTQ_df:
19178 gen_helper_msa_ftq_df(cpu_env, tdf, twd, tws, twt);
19179 break;
19180 case OPC_FSUNE_df:
19181 gen_helper_msa_fsune_df(cpu_env, tdf, twd, tws, twt);
19182 break;
19183 case OPC_FSUEQ_df:
19184 gen_helper_msa_fsueq_df(cpu_env, tdf, twd, tws, twt);
19185 break;
19186 case OPC_FSNE_df:
19187 gen_helper_msa_fsne_df(cpu_env, tdf, twd, tws, twt);
19188 break;
19189 case OPC_FSLT_df:
19190 gen_helper_msa_fslt_df(cpu_env, tdf, twd, tws, twt);
19191 break;
19192 case OPC_FMIN_df:
19193 gen_helper_msa_fmin_df(cpu_env, tdf, twd, tws, twt);
19194 break;
19195 case OPC_MULR_Q_df:
19196 tcg_gen_movi_i32(tdf, df + 1);
19197 gen_helper_msa_mulr_q_df(cpu_env, tdf, twd, tws, twt);
19198 break;
19199 case OPC_FSULT_df:
19200 gen_helper_msa_fsult_df(cpu_env, tdf, twd, tws, twt);
19201 break;
19202 case OPC_FMIN_A_df:
19203 gen_helper_msa_fmin_a_df(cpu_env, tdf, twd, tws, twt);
19204 break;
19205 case OPC_MADDR_Q_df:
19206 tcg_gen_movi_i32(tdf, df + 1);
19207 gen_helper_msa_maddr_q_df(cpu_env, tdf, twd, tws, twt);
19208 break;
19209 case OPC_FSLE_df:
19210 gen_helper_msa_fsle_df(cpu_env, tdf, twd, tws, twt);
19211 break;
19212 case OPC_FMAX_df:
19213 gen_helper_msa_fmax_df(cpu_env, tdf, twd, tws, twt);
19214 break;
19215 case OPC_MSUBR_Q_df:
19216 tcg_gen_movi_i32(tdf, df + 1);
19217 gen_helper_msa_msubr_q_df(cpu_env, tdf, twd, tws, twt);
19218 break;
19219 case OPC_FSULE_df:
19220 gen_helper_msa_fsule_df(cpu_env, tdf, twd, tws, twt);
19221 break;
19222 case OPC_FMAX_A_df:
19223 gen_helper_msa_fmax_a_df(cpu_env, tdf, twd, tws, twt);
19224 break;
19225 default:
19226 MIPS_INVAL("MSA instruction");
9c708c7f 19227 generate_exception_end(ctx, EXCP_RI);
7d05b9c8
YK
19228 break;
19229 }
19230
19231 tcg_temp_free_i32(twd);
19232 tcg_temp_free_i32(tws);
19233 tcg_temp_free_i32(twt);
19234 tcg_temp_free_i32(tdf);
19235}
19236
cbe50b9a
YK
19237static void gen_msa_2r(CPUMIPSState *env, DisasContext *ctx)
19238{
19239#define MASK_MSA_2R(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
19240 (op & (0x7 << 18)))
19241 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
19242 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
19243 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
19244 uint8_t df = (ctx->opcode >> 16) & 0x3;
19245 TCGv_i32 twd = tcg_const_i32(wd);
19246 TCGv_i32 tws = tcg_const_i32(ws);
19247 TCGv_i32 twt = tcg_const_i32(wt);
19248 TCGv_i32 tdf = tcg_const_i32(df);
19249
19250 switch (MASK_MSA_2R(ctx->opcode)) {
19251 case OPC_FILL_df:
19252#if !defined(TARGET_MIPS64)
19253 /* Double format valid only for MIPS64 */
19254 if (df == DF_DOUBLE) {
9c708c7f 19255 generate_exception_end(ctx, EXCP_RI);
cbe50b9a
YK
19256 break;
19257 }
19258#endif
19259 gen_helper_msa_fill_df(cpu_env, tdf, twd, tws); /* trs */
19260 break;
19261 case OPC_PCNT_df:
19262 gen_helper_msa_pcnt_df(cpu_env, tdf, twd, tws);
19263 break;
19264 case OPC_NLOC_df:
19265 gen_helper_msa_nloc_df(cpu_env, tdf, twd, tws);
19266 break;
19267 case OPC_NLZC_df:
19268 gen_helper_msa_nlzc_df(cpu_env, tdf, twd, tws);
19269 break;
19270 default:
19271 MIPS_INVAL("MSA instruction");
9c708c7f 19272 generate_exception_end(ctx, EXCP_RI);
cbe50b9a
YK
19273 break;
19274 }
19275
19276 tcg_temp_free_i32(twd);
19277 tcg_temp_free_i32(tws);
19278 tcg_temp_free_i32(twt);
19279 tcg_temp_free_i32(tdf);
19280}
19281
3bdeb688
YK
19282static void gen_msa_2rf(CPUMIPSState *env, DisasContext *ctx)
19283{
19284#define MASK_MSA_2RF(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
19285 (op & (0xf << 17)))
19286 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
19287 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
19288 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
19289 uint8_t df = (ctx->opcode >> 16) & 0x1;
19290 TCGv_i32 twd = tcg_const_i32(wd);
19291 TCGv_i32 tws = tcg_const_i32(ws);
19292 TCGv_i32 twt = tcg_const_i32(wt);
19293 /* adjust df value for floating-point instruction */
19294 TCGv_i32 tdf = tcg_const_i32(df + 2);
19295
19296 switch (MASK_MSA_2RF(ctx->opcode)) {
19297 case OPC_FCLASS_df:
19298 gen_helper_msa_fclass_df(cpu_env, tdf, twd, tws);
19299 break;
19300 case OPC_FTRUNC_S_df:
19301 gen_helper_msa_ftrunc_s_df(cpu_env, tdf, twd, tws);
19302 break;
19303 case OPC_FTRUNC_U_df:
19304 gen_helper_msa_ftrunc_u_df(cpu_env, tdf, twd, tws);
19305 break;
19306 case OPC_FSQRT_df:
19307 gen_helper_msa_fsqrt_df(cpu_env, tdf, twd, tws);
19308 break;
19309 case OPC_FRSQRT_df:
19310 gen_helper_msa_frsqrt_df(cpu_env, tdf, twd, tws);
19311 break;
19312 case OPC_FRCP_df:
19313 gen_helper_msa_frcp_df(cpu_env, tdf, twd, tws);
19314 break;
19315 case OPC_FRINT_df:
19316 gen_helper_msa_frint_df(cpu_env, tdf, twd, tws);
19317 break;
19318 case OPC_FLOG2_df:
19319 gen_helper_msa_flog2_df(cpu_env, tdf, twd, tws);
19320 break;
19321 case OPC_FEXUPL_df:
19322 gen_helper_msa_fexupl_df(cpu_env, tdf, twd, tws);
19323 break;
19324 case OPC_FEXUPR_df:
19325 gen_helper_msa_fexupr_df(cpu_env, tdf, twd, tws);
19326 break;
19327 case OPC_FFQL_df:
19328 gen_helper_msa_ffql_df(cpu_env, tdf, twd, tws);
19329 break;
19330 case OPC_FFQR_df:
19331 gen_helper_msa_ffqr_df(cpu_env, tdf, twd, tws);
19332 break;
19333 case OPC_FTINT_S_df:
19334 gen_helper_msa_ftint_s_df(cpu_env, tdf, twd, tws);
19335 break;
19336 case OPC_FTINT_U_df:
19337 gen_helper_msa_ftint_u_df(cpu_env, tdf, twd, tws);
19338 break;
19339 case OPC_FFINT_S_df:
19340 gen_helper_msa_ffint_s_df(cpu_env, tdf, twd, tws);
19341 break;
19342 case OPC_FFINT_U_df:
19343 gen_helper_msa_ffint_u_df(cpu_env, tdf, twd, tws);
19344 break;
19345 }
19346
19347 tcg_temp_free_i32(twd);
19348 tcg_temp_free_i32(tws);
19349 tcg_temp_free_i32(twt);
19350 tcg_temp_free_i32(tdf);
19351}
19352
cbe50b9a
YK
19353static void gen_msa_vec_v(CPUMIPSState *env, DisasContext *ctx)
19354{
19355#define MASK_MSA_VEC(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)))
19356 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
19357 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
19358 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
19359 TCGv_i32 twd = tcg_const_i32(wd);
19360 TCGv_i32 tws = tcg_const_i32(ws);
19361 TCGv_i32 twt = tcg_const_i32(wt);
19362
19363 switch (MASK_MSA_VEC(ctx->opcode)) {
19364 case OPC_AND_V:
19365 gen_helper_msa_and_v(cpu_env, twd, tws, twt);
19366 break;
19367 case OPC_OR_V:
19368 gen_helper_msa_or_v(cpu_env, twd, tws, twt);
19369 break;
19370 case OPC_NOR_V:
19371 gen_helper_msa_nor_v(cpu_env, twd, tws, twt);
19372 break;
19373 case OPC_XOR_V:
19374 gen_helper_msa_xor_v(cpu_env, twd, tws, twt);
19375 break;
19376 case OPC_BMNZ_V:
19377 gen_helper_msa_bmnz_v(cpu_env, twd, tws, twt);
19378 break;
19379 case OPC_BMZ_V:
19380 gen_helper_msa_bmz_v(cpu_env, twd, tws, twt);
19381 break;
19382 case OPC_BSEL_V:
19383 gen_helper_msa_bsel_v(cpu_env, twd, tws, twt);
19384 break;
19385 default:
19386 MIPS_INVAL("MSA instruction");
9c708c7f 19387 generate_exception_end(ctx, EXCP_RI);
cbe50b9a
YK
19388 break;
19389 }
19390
19391 tcg_temp_free_i32(twd);
19392 tcg_temp_free_i32(tws);
19393 tcg_temp_free_i32(twt);
19394}
19395
19396static void gen_msa_vec(CPUMIPSState *env, DisasContext *ctx)
19397{
19398 switch (MASK_MSA_VEC(ctx->opcode)) {
19399 case OPC_AND_V:
19400 case OPC_OR_V:
19401 case OPC_NOR_V:
19402 case OPC_XOR_V:
19403 case OPC_BMNZ_V:
19404 case OPC_BMZ_V:
19405 case OPC_BSEL_V:
19406 gen_msa_vec_v(env, ctx);
19407 break;
19408 case OPC_MSA_2R:
19409 gen_msa_2r(env, ctx);
19410 break;
3bdeb688
YK
19411 case OPC_MSA_2RF:
19412 gen_msa_2rf(env, ctx);
19413 break;
cbe50b9a
YK
19414 default:
19415 MIPS_INVAL("MSA instruction");
9c708c7f 19416 generate_exception_end(ctx, EXCP_RI);
cbe50b9a
YK
19417 break;
19418 }
19419}
19420
4c789546
YK
19421static void gen_msa(CPUMIPSState *env, DisasContext *ctx)
19422{
19423 uint32_t opcode = ctx->opcode;
19424 check_insn(ctx, ASE_MSA);
19425 check_msa_access(ctx);
19426
19427 switch (MASK_MSA_MINOR(opcode)) {
19428 case OPC_MSA_I8_00:
19429 case OPC_MSA_I8_01:
19430 case OPC_MSA_I8_02:
19431 gen_msa_i8(env, ctx);
19432 break;
80e71591
YK
19433 case OPC_MSA_I5_06:
19434 case OPC_MSA_I5_07:
19435 gen_msa_i5(env, ctx);
19436 break;
d4cf28de
YK
19437 case OPC_MSA_BIT_09:
19438 case OPC_MSA_BIT_0A:
19439 gen_msa_bit(env, ctx);
19440 break;
28f99f08
YK
19441 case OPC_MSA_3R_0D:
19442 case OPC_MSA_3R_0E:
19443 case OPC_MSA_3R_0F:
19444 case OPC_MSA_3R_10:
19445 case OPC_MSA_3R_11:
19446 case OPC_MSA_3R_12:
19447 case OPC_MSA_3R_13:
19448 case OPC_MSA_3R_14:
19449 case OPC_MSA_3R_15:
19450 gen_msa_3r(env, ctx);
19451 break;
1e608ec1
YK
19452 case OPC_MSA_ELM:
19453 gen_msa_elm(env, ctx);
19454 break;
7d05b9c8
YK
19455 case OPC_MSA_3RF_1A:
19456 case OPC_MSA_3RF_1B:
19457 case OPC_MSA_3RF_1C:
19458 gen_msa_3rf(env, ctx);
19459 break;
cbe50b9a
YK
19460 case OPC_MSA_VEC:
19461 gen_msa_vec(env, ctx);
19462 break;
f7685877
YK
19463 case OPC_LD_B:
19464 case OPC_LD_H:
19465 case OPC_LD_W:
19466 case OPC_LD_D:
19467 case OPC_ST_B:
19468 case OPC_ST_H:
19469 case OPC_ST_W:
19470 case OPC_ST_D:
19471 {
19472 int32_t s10 = sextract32(ctx->opcode, 16, 10);
19473 uint8_t rs = (ctx->opcode >> 11) & 0x1f;
19474 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
19475 uint8_t df = (ctx->opcode >> 0) & 0x3;
19476
f7685877 19477 TCGv_i32 twd = tcg_const_i32(wd);
adc370a4
YK
19478 TCGv taddr = tcg_temp_new();
19479 gen_base_offset_addr(ctx, taddr, rs, s10 << df);
f7685877
YK
19480
19481 switch (MASK_MSA_MINOR(opcode)) {
19482 case OPC_LD_B:
adc370a4
YK
19483 gen_helper_msa_ld_b(cpu_env, twd, taddr);
19484 break;
f7685877 19485 case OPC_LD_H:
adc370a4
YK
19486 gen_helper_msa_ld_h(cpu_env, twd, taddr);
19487 break;
f7685877 19488 case OPC_LD_W:
adc370a4
YK
19489 gen_helper_msa_ld_w(cpu_env, twd, taddr);
19490 break;
f7685877 19491 case OPC_LD_D:
adc370a4 19492 gen_helper_msa_ld_d(cpu_env, twd, taddr);
f7685877
YK
19493 break;
19494 case OPC_ST_B:
adc370a4
YK
19495 gen_helper_msa_st_b(cpu_env, twd, taddr);
19496 break;
f7685877 19497 case OPC_ST_H:
adc370a4
YK
19498 gen_helper_msa_st_h(cpu_env, twd, taddr);
19499 break;
f7685877 19500 case OPC_ST_W:
adc370a4
YK
19501 gen_helper_msa_st_w(cpu_env, twd, taddr);
19502 break;
f7685877 19503 case OPC_ST_D:
adc370a4 19504 gen_helper_msa_st_d(cpu_env, twd, taddr);
f7685877
YK
19505 break;
19506 }
19507
19508 tcg_temp_free_i32(twd);
adc370a4 19509 tcg_temp_free(taddr);
f7685877
YK
19510 }
19511 break;
4c789546
YK
19512 default:
19513 MIPS_INVAL("MSA instruction");
9c708c7f 19514 generate_exception_end(ctx, EXCP_RI);
4c789546
YK
19515 break;
19516 }
19517
19518}
19519
d2bfa6e6 19520static void decode_opc(CPUMIPSState *env, DisasContext *ctx)
099e5b4d
LA
19521{
19522 int32_t offset;
19523 int rs, rt, rd, sa;
19524 uint32_t op, op1;
19525 int16_t imm;
19526
19527 /* make sure instructions are on a word boundary */
eeb3bba8
EC
19528 if (ctx->base.pc_next & 0x3) {
19529 env->CP0_BadVAddr = ctx->base.pc_next;
aea14095 19530 generate_exception_err(ctx, EXCP_AdEL, EXCP_INST_NOTAVAIL);
099e5b4d
LA
19531 return;
19532 }
19533
19534 /* Handle blikely not taken case */
19535 if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
42a268c2 19536 TCGLabel *l1 = gen_new_label();
099e5b4d 19537
099e5b4d
LA
19538 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
19539 tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
eeb3bba8 19540 gen_goto_tb(ctx, 1, ctx->base.pc_next + 4);
099e5b4d
LA
19541 gen_set_label(l1);
19542 }
19543
099e5b4d
LA
19544 op = MASK_OP_MAJOR(ctx->opcode);
19545 rs = (ctx->opcode >> 21) & 0x1f;
19546 rt = (ctx->opcode >> 16) & 0x1f;
19547 rd = (ctx->opcode >> 11) & 0x1f;
19548 sa = (ctx->opcode >> 6) & 0x1f;
19549 imm = (int16_t)ctx->opcode;
19550 switch (op) {
19551 case OPC_SPECIAL:
19552 decode_opc_special(env, ctx);
19553 break;
19554 case OPC_SPECIAL2:
4267d3e6 19555 decode_opc_special2_legacy(env, ctx);
099e5b4d
LA
19556 break;
19557 case OPC_SPECIAL3:
19558 decode_opc_special3(env, ctx);
19559 break;
7a387fff
TS
19560 case OPC_REGIMM:
19561 op1 = MASK_REGIMM(ctx->opcode);
19562 switch (op1) {
fecd2646
LA
19563 case OPC_BLTZL: /* REGIMM branches */
19564 case OPC_BGEZL:
19565 case OPC_BLTZALL:
19566 case OPC_BGEZALL:
d9224450 19567 check_insn(ctx, ISA_MIPS2);
fecd2646 19568 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d9224450 19569 /* Fallthrough */
fecd2646
LA
19570 case OPC_BLTZ:
19571 case OPC_BGEZ:
b231c103 19572 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
0aefa333 19573 break;
fecd2646
LA
19574 case OPC_BLTZAL:
19575 case OPC_BGEZAL:
0aefa333
YK
19576 if (ctx->insn_flags & ISA_MIPS32R6) {
19577 if (rs == 0) {
19578 /* OPC_NAL, OPC_BAL */
b231c103 19579 gen_compute_branch(ctx, op1, 4, 0, -1, imm << 2, 4);
0aefa333 19580 } else {
9c708c7f 19581 generate_exception_end(ctx, EXCP_RI);
0aefa333
YK
19582 }
19583 } else {
b231c103 19584 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
0aefa333 19585 }
c9602061 19586 break;
7a387fff
TS
19587 case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
19588 case OPC_TNEI:
d9224450 19589 check_insn(ctx, ISA_MIPS2);
fecd2646 19590 check_insn_opc_removed(ctx, ISA_MIPS32R6);
7a387fff
TS
19591 gen_trap(ctx, op1, rs, -1, imm);
19592 break;
bb238210
YK
19593 case OPC_SIGRIE:
19594 check_insn(ctx, ISA_MIPS32R6);
19595 generate_exception_end(ctx, EXCP_RI);
19596 break;
7a387fff 19597 case OPC_SYNCI:
d75c135e 19598 check_insn(ctx, ISA_MIPS32R2);
a83bddd6
DZ
19599 /* Break the TB to be able to sync copied instructions
19600 immediately */
eeb3bba8 19601 ctx->base.is_jmp = DISAS_STOP;
6af0bf9c 19602 break;
e45a93e2
JL
19603 case OPC_BPOSGE32: /* MIPS DSP branch */
19604#if defined(TARGET_MIPS64)
19605 case OPC_BPOSGE64:
19606#endif
19607 check_dsp(ctx);
b231c103 19608 gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2, 4);
e45a93e2 19609 break;
d4ea6acd
LA
19610#if defined(TARGET_MIPS64)
19611 case OPC_DAHI:
19612 check_insn(ctx, ISA_MIPS32R6);
19613 check_mips_64(ctx);
19614 if (rs != 0) {
19615 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 32);
19616 }
d4ea6acd
LA
19617 break;
19618 case OPC_DATI:
19619 check_insn(ctx, ISA_MIPS32R6);
19620 check_mips_64(ctx);
19621 if (rs != 0) {
19622 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 48);
19623 }
d4ea6acd
LA
19624 break;
19625#endif
6af0bf9c 19626 default: /* Invalid */
923617a3 19627 MIPS_INVAL("regimm");
9c708c7f 19628 generate_exception_end(ctx, EXCP_RI);
6af0bf9c
FB
19629 break;
19630 }
19631 break;
7a387fff 19632 case OPC_CP0:
387a8fe5 19633 check_cp0_enabled(ctx);
7a387fff 19634 op1 = MASK_CP0(ctx->opcode);
6af0bf9c 19635 switch (op1) {
7a387fff
TS
19636 case OPC_MFC0:
19637 case OPC_MTC0:
ead9360e
TS
19638 case OPC_MFTR:
19639 case OPC_MTTR:
5204ea79
LA
19640 case OPC_MFHC0:
19641 case OPC_MTHC0:
d26bc211 19642#if defined(TARGET_MIPS64)
7a387fff
TS
19643 case OPC_DMFC0:
19644 case OPC_DMTC0:
19645#endif
f1aa6320 19646#ifndef CONFIG_USER_ONLY
932e71cd 19647 gen_cp0(env, ctx, op1, rt, rd);
0eaef5aa 19648#endif /* !CONFIG_USER_ONLY */
7a387fff
TS
19649 break;
19650 case OPC_C0_FIRST ... OPC_C0_LAST:
f1aa6320 19651#ifndef CONFIG_USER_ONLY
932e71cd 19652 gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
0eaef5aa 19653#endif /* !CONFIG_USER_ONLY */
7a387fff
TS
19654 break;
19655 case OPC_MFMC0:
8706c382 19656#ifndef CONFIG_USER_ONLY
932e71cd 19657 {
099e5b4d 19658 uint32_t op2;
35fbce2c 19659 TCGv t0 = tcg_temp_new();
6c5c1e20 19660
0eaef5aa 19661 op2 = MASK_MFMC0(ctx->opcode);
6c5c1e20
TS
19662 switch (op2) {
19663 case OPC_DMT:
d75c135e 19664 check_insn(ctx, ASE_MT);
9ed5726c 19665 gen_helper_dmt(t0);
35fbce2c 19666 gen_store_gpr(t0, rt);
6c5c1e20
TS
19667 break;
19668 case OPC_EMT:
d75c135e 19669 check_insn(ctx, ASE_MT);
9ed5726c 19670 gen_helper_emt(t0);
35fbce2c 19671 gen_store_gpr(t0, rt);
da80682b 19672 break;
6c5c1e20 19673 case OPC_DVPE:
d75c135e 19674 check_insn(ctx, ASE_MT);
895c2d04 19675 gen_helper_dvpe(t0, cpu_env);
35fbce2c 19676 gen_store_gpr(t0, rt);
6c5c1e20
TS
19677 break;
19678 case OPC_EVPE:
d75c135e 19679 check_insn(ctx, ASE_MT);
895c2d04 19680 gen_helper_evpe(t0, cpu_env);
35fbce2c 19681 gen_store_gpr(t0, rt);
6c5c1e20 19682 break;
01bc435b
YK
19683 case OPC_DVP:
19684 check_insn(ctx, ISA_MIPS32R6);
19685 if (ctx->vp) {
19686 gen_helper_dvp(t0, cpu_env);
19687 gen_store_gpr(t0, rt);
19688 }
19689 break;
19690 case OPC_EVP:
19691 check_insn(ctx, ISA_MIPS32R6);
19692 if (ctx->vp) {
19693 gen_helper_evp(t0, cpu_env);
19694 gen_store_gpr(t0, rt);
19695 }
19696 break;
6c5c1e20 19697 case OPC_DI:
d75c135e 19698 check_insn(ctx, ISA_MIPS32R2);
867abc7e 19699 save_cpu_state(ctx, 1);
895c2d04 19700 gen_helper_di(t0, cpu_env);
35fbce2c 19701 gen_store_gpr(t0, rt);
d2bfa6e6
MR
19702 /* Stop translation as we may have switched
19703 the execution mode. */
eeb3bba8 19704 ctx->base.is_jmp = DISAS_STOP;
6c5c1e20
TS
19705 break;
19706 case OPC_EI:
d75c135e 19707 check_insn(ctx, ISA_MIPS32R2);
867abc7e 19708 save_cpu_state(ctx, 1);
895c2d04 19709 gen_helper_ei(t0, cpu_env);
35fbce2c 19710 gen_store_gpr(t0, rt);
b28425ba
EC
19711 /* DISAS_STOP isn't sufficient, we need to ensure we break
19712 out of translated code to check for pending interrupts */
eeb3bba8
EC
19713 gen_save_pc(ctx->base.pc_next + 4);
19714 ctx->base.is_jmp = DISAS_EXIT;
6c5c1e20
TS
19715 break;
19716 default: /* Invalid */
19717 MIPS_INVAL("mfmc0");
9c708c7f 19718 generate_exception_end(ctx, EXCP_RI);
6c5c1e20
TS
19719 break;
19720 }
6c5c1e20 19721 tcg_temp_free(t0);
7a387fff 19722 }
0eaef5aa 19723#endif /* !CONFIG_USER_ONLY */
6af0bf9c 19724 break;
7a387fff 19725 case OPC_RDPGPR:
d75c135e 19726 check_insn(ctx, ISA_MIPS32R2);
be24bb4f 19727 gen_load_srsgpr(rt, rd);
ead9360e 19728 break;
7a387fff 19729 case OPC_WRPGPR:
d75c135e 19730 check_insn(ctx, ISA_MIPS32R2);
be24bb4f 19731 gen_store_srsgpr(rt, rd);
38121543 19732 break;
6af0bf9c 19733 default:
923617a3 19734 MIPS_INVAL("cp0");
9c708c7f 19735 generate_exception_end(ctx, EXCP_RI);
6af0bf9c
FB
19736 break;
19737 }
19738 break;
31837be3
YK
19739 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC, OPC_ADDI */
19740 if (ctx->insn_flags & ISA_MIPS32R6) {
19741 /* OPC_BOVC, OPC_BEQZALC, OPC_BEQC */
19742 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19743 } else {
19744 /* OPC_ADDI */
19745 /* Arithmetic with immediate opcode */
19746 gen_arith_imm(ctx, op, rt, rs, imm);
19747 }
19748 break;
324d9e32 19749 case OPC_ADDIU:
d75c135e 19750 gen_arith_imm(ctx, op, rt, rs, imm);
7a387fff 19751 break;
324d9e32
AJ
19752 case OPC_SLTI: /* Set on less than with immediate opcode */
19753 case OPC_SLTIU:
d75c135e 19754 gen_slt_imm(ctx, op, rt, rs, imm);
324d9e32
AJ
19755 break;
19756 case OPC_ANDI: /* Arithmetic with immediate opcode */
d4ea6acd 19757 case OPC_LUI: /* OPC_AUI */
324d9e32
AJ
19758 case OPC_ORI:
19759 case OPC_XORI:
d75c135e 19760 gen_logic_imm(ctx, op, rt, rs, imm);
324d9e32 19761 break;
7a387fff
TS
19762 case OPC_J ... OPC_JAL: /* Jump */
19763 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
b231c103 19764 gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
c9602061 19765 break;
31837be3
YK
19766 /* Branch */
19767 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC, OPC_BLEZL */
19768 if (ctx->insn_flags & ISA_MIPS32R6) {
19769 if (rt == 0) {
9c708c7f 19770 generate_exception_end(ctx, EXCP_RI);
31837be3
YK
19771 break;
19772 }
19773 /* OPC_BLEZC, OPC_BGEZC, OPC_BGEC */
19774 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19775 } else {
19776 /* OPC_BLEZL */
b231c103 19777 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
31837be3
YK
19778 }
19779 break;
19780 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC, OPC_BGTZL */
19781 if (ctx->insn_flags & ISA_MIPS32R6) {
19782 if (rt == 0) {
9c708c7f 19783 generate_exception_end(ctx, EXCP_RI);
31837be3
YK
19784 break;
19785 }
19786 /* OPC_BGTZC, OPC_BLTZC, OPC_BLTC */
19787 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19788 } else {
19789 /* OPC_BGTZL */
b231c103 19790 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
31837be3
YK
19791 }
19792 break;
19793 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC, OPC_BLEZ */
19794 if (rt == 0) {
19795 /* OPC_BLEZ */
b231c103 19796 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
31837be3
YK
19797 } else {
19798 check_insn(ctx, ISA_MIPS32R6);
19799 /* OPC_BLEZALC, OPC_BGEZALC, OPC_BGEUC */
19800 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19801 }
19802 break;
19803 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC, OPC_BGTZ */
19804 if (rt == 0) {
19805 /* OPC_BGTZ */
b231c103 19806 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
31837be3
YK
19807 } else {
19808 check_insn(ctx, ISA_MIPS32R6);
19809 /* OPC_BGTZALC, OPC_BLTZALC, OPC_BLTUC */
19810 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19811 }
19812 break;
19813 case OPC_BEQL:
19814 case OPC_BNEL:
d9224450 19815 check_insn(ctx, ISA_MIPS2);
fecd2646 19816 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d9224450 19817 /* Fallthrough */
31837be3
YK
19818 case OPC_BEQ:
19819 case OPC_BNE:
b231c103 19820 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
c9602061 19821 break;
d9224450
MR
19822 case OPC_LL: /* Load and stores */
19823 check_insn(ctx, ISA_MIPS2);
19824 /* Fallthrough */
19825 case OPC_LWL:
fecd2646
LA
19826 case OPC_LWR:
19827 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d9224450 19828 /* Fallthrough */
fecd2646
LA
19829 case OPC_LB ... OPC_LH:
19830 case OPC_LW ... OPC_LHU:
d75c135e 19831 gen_ld(ctx, op, rt, rs, imm);
5c13fdfd 19832 break;
fecd2646 19833 case OPC_SWL:
7a387fff 19834 case OPC_SWR:
fecd2646 19835 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b6f3b233 19836 /* fall through */
fecd2646
LA
19837 case OPC_SB ... OPC_SH:
19838 case OPC_SW:
5c13fdfd 19839 gen_st(ctx, op, rt, rs, imm);
7a387fff 19840 break;
d66c7132 19841 case OPC_SC:
d9224450 19842 check_insn(ctx, ISA_MIPS2);
4368b29a 19843 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d66c7132
AJ
19844 gen_st_cond(ctx, op, rt, rs, imm);
19845 break;
7a387fff 19846 case OPC_CACHE:
bf7910c6 19847 check_insn_opc_removed(ctx, ISA_MIPS32R6);
2e15497c 19848 check_cp0_enabled(ctx);
d75c135e 19849 check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
0d74a222
LA
19850 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
19851 gen_cache_operation(ctx, rt, rs, imm);
19852 }
ead9360e 19853 /* Treat as NOP. */
34ae7b51 19854 break;
7a387fff 19855 case OPC_PREF:
bf7910c6 19856 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d75c135e 19857 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
ead9360e 19858 /* Treat as NOP. */
6af0bf9c 19859 break;
4ad40f36 19860
923617a3 19861 /* Floating point (COP1). */
7a387fff
TS
19862 case OPC_LWC1:
19863 case OPC_LDC1:
19864 case OPC_SWC1:
19865 case OPC_SDC1:
5ab5c041 19866 gen_cop1_ldst(ctx, op, rt, rs, imm);
6ea83fed
FB
19867 break;
19868
7a387fff 19869 case OPC_CP1:
5692c6e1
YK
19870 op1 = MASK_CP1(ctx->opcode);
19871
19872 switch (op1) {
19873 case OPC_MFHC1:
19874 case OPC_MTHC1:
5e755519 19875 check_cp1_enabled(ctx);
5692c6e1
YK
19876 check_insn(ctx, ISA_MIPS32R2);
19877 case OPC_MFC1:
19878 case OPC_CFC1:
19879 case OPC_MTC1:
19880 case OPC_CTC1:
19881 check_cp1_enabled(ctx);
19882 gen_cp1(ctx, op1, rt, rd);
19883 break;
d26bc211 19884#if defined(TARGET_MIPS64)
5692c6e1
YK
19885 case OPC_DMFC1:
19886 case OPC_DMTC1:
19887 check_cp1_enabled(ctx);
19888 check_insn(ctx, ISA_MIPS3);
d9224450 19889 check_mips_64(ctx);
5692c6e1
YK
19890 gen_cp1(ctx, op1, rt, rd);
19891 break;
e189e748 19892#endif
5692c6e1
YK
19893 case OPC_BC1EQZ: /* OPC_BC1ANY2 */
19894 check_cp1_enabled(ctx);
19895 if (ctx->insn_flags & ISA_MIPS32R6) {
19896 /* OPC_BC1EQZ */
31837be3 19897 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
65935f07 19898 rt, imm << 2, 4);
5692c6e1
YK
19899 } else {
19900 /* OPC_BC1ANY2 */
b8aa4598 19901 check_cop1x(ctx);
d75c135e 19902 check_insn(ctx, ASE_MIPS3D);
d75c135e 19903 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
5a5012ec 19904 (rt >> 2) & 0x7, imm << 2);
5692c6e1
YK
19905 }
19906 break;
19907 case OPC_BC1NEZ:
19908 check_cp1_enabled(ctx);
19909 check_insn(ctx, ISA_MIPS32R6);
19910 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
65935f07 19911 rt, imm << 2, 4);
5692c6e1
YK
19912 break;
19913 case OPC_BC1ANY4:
19914 check_cp1_enabled(ctx);
19915 check_insn_opc_removed(ctx, ISA_MIPS32R6);
19916 check_cop1x(ctx);
19917 check_insn(ctx, ASE_MIPS3D);
19918 /* fall through */
19919 case OPC_BC1:
19920 check_cp1_enabled(ctx);
19921 check_insn_opc_removed(ctx, ISA_MIPS32R6);
19922 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
19923 (rt >> 2) & 0x7, imm << 2);
19924 break;
19925 case OPC_PS_FMT:
e29c9628 19926 check_ps(ctx);
b6f3b233 19927 /* fall through */
5692c6e1
YK
19928 case OPC_S_FMT:
19929 case OPC_D_FMT:
19930 check_cp1_enabled(ctx);
19931 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
19932 (imm >> 8) & 0x7);
19933 break;
19934 case OPC_W_FMT:
19935 case OPC_L_FMT:
19936 {
19937 int r6_op = ctx->opcode & FOP(0x3f, 0x1f);
19938 check_cp1_enabled(ctx);
19939 if (ctx->insn_flags & ISA_MIPS32R6) {
19940 switch (r6_op) {
19941 case R6_OPC_CMP_AF_S:
19942 case R6_OPC_CMP_UN_S:
19943 case R6_OPC_CMP_EQ_S:
19944 case R6_OPC_CMP_UEQ_S:
19945 case R6_OPC_CMP_LT_S:
19946 case R6_OPC_CMP_ULT_S:
19947 case R6_OPC_CMP_LE_S:
19948 case R6_OPC_CMP_ULE_S:
19949 case R6_OPC_CMP_SAF_S:
19950 case R6_OPC_CMP_SUN_S:
19951 case R6_OPC_CMP_SEQ_S:
19952 case R6_OPC_CMP_SEUQ_S:
19953 case R6_OPC_CMP_SLT_S:
19954 case R6_OPC_CMP_SULT_S:
19955 case R6_OPC_CMP_SLE_S:
19956 case R6_OPC_CMP_SULE_S:
19957 case R6_OPC_CMP_OR_S:
19958 case R6_OPC_CMP_UNE_S:
19959 case R6_OPC_CMP_NE_S:
19960 case R6_OPC_CMP_SOR_S:
19961 case R6_OPC_CMP_SUNE_S:
19962 case R6_OPC_CMP_SNE_S:
19963 gen_r6_cmp_s(ctx, ctx->opcode & 0x1f, rt, rd, sa);
19964 break;
19965 case R6_OPC_CMP_AF_D:
19966 case R6_OPC_CMP_UN_D:
19967 case R6_OPC_CMP_EQ_D:
19968 case R6_OPC_CMP_UEQ_D:
19969 case R6_OPC_CMP_LT_D:
19970 case R6_OPC_CMP_ULT_D:
19971 case R6_OPC_CMP_LE_D:
19972 case R6_OPC_CMP_ULE_D:
19973 case R6_OPC_CMP_SAF_D:
19974 case R6_OPC_CMP_SUN_D:
19975 case R6_OPC_CMP_SEQ_D:
19976 case R6_OPC_CMP_SEUQ_D:
19977 case R6_OPC_CMP_SLT_D:
19978 case R6_OPC_CMP_SULT_D:
19979 case R6_OPC_CMP_SLE_D:
19980 case R6_OPC_CMP_SULE_D:
19981 case R6_OPC_CMP_OR_D:
19982 case R6_OPC_CMP_UNE_D:
19983 case R6_OPC_CMP_NE_D:
19984 case R6_OPC_CMP_SOR_D:
19985 case R6_OPC_CMP_SUNE_D:
19986 case R6_OPC_CMP_SNE_D:
19987 gen_r6_cmp_d(ctx, ctx->opcode & 0x1f, rt, rd, sa);
19988 break;
19989 default:
d2bfa6e6
MR
19990 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f),
19991 rt, rd, sa, (imm >> 8) & 0x7);
19992
5692c6e1 19993 break;
3f493883 19994 }
5692c6e1
YK
19995 } else {
19996 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
19997 (imm >> 8) & 0x7);
36d23958 19998 }
5692c6e1
YK
19999 break;
20000 }
20001 case OPC_BZ_V:
20002 case OPC_BNZ_V:
20003 case OPC_BZ_B:
20004 case OPC_BZ_H:
20005 case OPC_BZ_W:
20006 case OPC_BZ_D:
20007 case OPC_BNZ_B:
20008 case OPC_BNZ_H:
20009 case OPC_BNZ_W:
20010 case OPC_BNZ_D:
20011 check_insn(ctx, ASE_MSA);
20012 gen_msa_branch(env, ctx, op1);
20013 break;
20014 default:
20015 MIPS_INVAL("cp1");
9c708c7f 20016 generate_exception_end(ctx, EXCP_RI);
5692c6e1 20017 break;
6ea83fed 20018 }
4ad40f36
FB
20019 break;
20020
31837be3
YK
20021 /* Compact branches [R6] and COP2 [non-R6] */
20022 case OPC_BC: /* OPC_LWC2 */
20023 case OPC_BALC: /* OPC_SWC2 */
20024 if (ctx->insn_flags & ISA_MIPS32R6) {
20025 /* OPC_BC, OPC_BALC */
20026 gen_compute_compact_branch(ctx, op, 0, 0,
20027 sextract32(ctx->opcode << 2, 0, 28));
20028 } else {
20029 /* OPC_LWC2, OPC_SWC2 */
20030 /* COP2: Not implemented. */
20031 generate_exception_err(ctx, EXCP_CpU, 2);
20032 }
20033 break;
20034 case OPC_BEQZC: /* OPC_JIC, OPC_LDC2 */
20035 case OPC_BNEZC: /* OPC_JIALC, OPC_SDC2 */
20036 if (ctx->insn_flags & ISA_MIPS32R6) {
20037 if (rs != 0) {
20038 /* OPC_BEQZC, OPC_BNEZC */
20039 gen_compute_compact_branch(ctx, op, rs, 0,
20040 sextract32(ctx->opcode << 2, 0, 23));
20041 } else {
20042 /* OPC_JIC, OPC_JIALC */
20043 gen_compute_compact_branch(ctx, op, 0, rt, imm);
20044 }
20045 } else {
20046 /* OPC_LWC2, OPC_SWC2 */
20047 /* COP2: Not implemented. */
20048 generate_exception_err(ctx, EXCP_CpU, 2);
20049 }
4ad40f36 20050 break;
bd277fa1 20051 case OPC_CP2:
d75c135e 20052 check_insn(ctx, INSN_LOONGSON2F);
bd277fa1
RH
20053 /* Note that these instructions use different fields. */
20054 gen_loongson_multimedia(ctx, sa, rd, rt);
20055 break;
4ad40f36 20056
7a387fff 20057 case OPC_CP3:
fecd2646 20058 check_insn_opc_removed(ctx, ISA_MIPS32R6);
5ab5c041 20059 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
5e755519 20060 check_cp1_enabled(ctx);
36d23958
TS
20061 op1 = MASK_CP3(ctx->opcode);
20062 switch (op1) {
d9224450
MR
20063 case OPC_LUXC1:
20064 case OPC_SUXC1:
20065 check_insn(ctx, ISA_MIPS5 | ISA_MIPS32R2);
20066 /* Fallthrough */
5a5012ec
TS
20067 case OPC_LWXC1:
20068 case OPC_LDXC1:
5a5012ec
TS
20069 case OPC_SWXC1:
20070 case OPC_SDXC1:
d9224450 20071 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
93b12ccc 20072 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
5a5012ec 20073 break;
e0c84da7 20074 case OPC_PREFX:
d9224450 20075 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
ead9360e 20076 /* Treat as NOP. */
e0c84da7 20077 break;
5a5012ec 20078 case OPC_ALNV_PS:
d9224450
MR
20079 check_insn(ctx, ISA_MIPS5 | ISA_MIPS32R2);
20080 /* Fallthrough */
5a5012ec
TS
20081 case OPC_MADD_S:
20082 case OPC_MADD_D:
20083 case OPC_MADD_PS:
20084 case OPC_MSUB_S:
20085 case OPC_MSUB_D:
20086 case OPC_MSUB_PS:
20087 case OPC_NMADD_S:
20088 case OPC_NMADD_D:
20089 case OPC_NMADD_PS:
20090 case OPC_NMSUB_S:
20091 case OPC_NMSUB_D:
20092 case OPC_NMSUB_PS:
d9224450 20093 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
5a5012ec
TS
20094 gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
20095 break;
36d23958 20096 default:
923617a3 20097 MIPS_INVAL("cp3");
9c708c7f 20098 generate_exception_end(ctx, EXCP_RI);
36d23958
TS
20099 break;
20100 }
20101 } else {
e397ee33 20102 generate_exception_err(ctx, EXCP_CpU, 1);
7a387fff 20103 }
4ad40f36
FB
20104 break;
20105
d26bc211 20106#if defined(TARGET_MIPS64)
7a387fff 20107 /* MIPS64 opcodes */
7a387fff 20108 case OPC_LDL ... OPC_LDR:
bf7910c6 20109 case OPC_LLD:
fecd2646 20110 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b6f3b233 20111 /* fall through */
fecd2646 20112 case OPC_LWU:
7a387fff 20113 case OPC_LD:
d75c135e 20114 check_insn(ctx, ISA_MIPS3);
5c13fdfd 20115 check_mips_64(ctx);
d75c135e 20116 gen_ld(ctx, op, rt, rs, imm);
5c13fdfd
AJ
20117 break;
20118 case OPC_SDL ... OPC_SDR:
fecd2646 20119 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b6f3b233 20120 /* fall through */
7a387fff 20121 case OPC_SD:
d75c135e 20122 check_insn(ctx, ISA_MIPS3);
e189e748 20123 check_mips_64(ctx);
5c13fdfd 20124 gen_st(ctx, op, rt, rs, imm);
7a387fff 20125 break;
d66c7132 20126 case OPC_SCD:
bf7910c6 20127 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d75c135e 20128 check_insn(ctx, ISA_MIPS3);
d66c7132
AJ
20129 check_mips_64(ctx);
20130 gen_st_cond(ctx, op, rt, rs, imm);
20131 break;
31837be3
YK
20132 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC, OPC_DADDI */
20133 if (ctx->insn_flags & ISA_MIPS32R6) {
20134 /* OPC_BNVC, OPC_BNEZALC, OPC_BNEC */
20135 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
20136 } else {
20137 /* OPC_DADDI */
20138 check_insn(ctx, ISA_MIPS3);
20139 check_mips_64(ctx);
20140 gen_arith_imm(ctx, op, rt, rs, imm);
20141 }
20142 break;
324d9e32 20143 case OPC_DADDIU:
d75c135e 20144 check_insn(ctx, ISA_MIPS3);
e189e748 20145 check_mips_64(ctx);
d75c135e 20146 gen_arith_imm(ctx, op, rt, rs, imm);
7a387fff 20147 break;
31837be3
YK
20148#else
20149 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
20150 if (ctx->insn_flags & ISA_MIPS32R6) {
20151 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
20152 } else {
20153 MIPS_INVAL("major opcode");
9c708c7f 20154 generate_exception_end(ctx, EXCP_RI);
31837be3
YK
20155 }
20156 break;
6af0bf9c 20157#endif
d4ea6acd
LA
20158 case OPC_DAUI: /* OPC_JALX */
20159 if (ctx->insn_flags & ISA_MIPS32R6) {
20160#if defined(TARGET_MIPS64)
20161 /* OPC_DAUI */
20162 check_mips_64(ctx);
db77d852
LA
20163 if (rs == 0) {
20164 generate_exception(ctx, EXCP_RI);
20165 } else if (rt != 0) {
d4ea6acd
LA
20166 TCGv t0 = tcg_temp_new();
20167 gen_load_gpr(t0, rs);
20168 tcg_gen_addi_tl(cpu_gpr[rt], t0, imm << 16);
20169 tcg_temp_free(t0);
20170 }
d4ea6acd 20171#else
9c708c7f 20172 generate_exception_end(ctx, EXCP_RI);
d4ea6acd
LA
20173 MIPS_INVAL("major opcode");
20174#endif
20175 } else {
20176 /* OPC_JALX */
20177 check_insn(ctx, ASE_MIPS16 | ASE_MICROMIPS);
20178 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
b231c103 20179 gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
d4ea6acd 20180 }
364d4831 20181 break;
4c789546 20182 case OPC_MSA: /* OPC_MDMX */
7a387fff 20183 /* MDMX: Not implemented. */
4c789546 20184 gen_msa(env, ctx);
d4ea6acd
LA
20185 break;
20186 case OPC_PCREL:
20187 check_insn(ctx, ISA_MIPS32R6);
eeb3bba8 20188 gen_pcrel(ctx, ctx->opcode, ctx->base.pc_next, rs);
d4ea6acd 20189 break;
6af0bf9c 20190 default: /* Invalid */
923617a3 20191 MIPS_INVAL("major opcode");
9c708c7f 20192 generate_exception_end(ctx, EXCP_RI);
6af0bf9c
FB
20193 break;
20194 }
6af0bf9c
FB
20195}
20196
9c489ea6 20197void gen_intermediate_code(CPUState *cs, struct TranslationBlock *tb)
6af0bf9c 20198{
9c489ea6 20199 CPUMIPSState *env = cs->env_ptr;
278d0702 20200 DisasContext ctx;
6cd79443 20201 target_ulong page_start;
2e70f6ef 20202 int max_insns;
c9602061 20203 int insn_bytes;
339cd2a8 20204 int is_slot;
6af0bf9c 20205
eeb3bba8
EC
20206 ctx.base.tb = tb;
20207 ctx.base.pc_first = tb->pc;
20208 ctx.base.pc_next = tb->pc;
20209 ctx.base.is_jmp = DISAS_NEXT;
20210 ctx.base.singlestep_enabled = cs->singlestep_enabled;
20211 ctx.base.num_insns = 0;
20212
20213 page_start = ctx.base.pc_first & TARGET_PAGE_MASK;
4ad40f36 20214 ctx.saved_pc = -1;
d75c135e 20215 ctx.insn_flags = env->insn_flags;
5ab5c041 20216 ctx.CP0_Config1 = env->CP0_Config1;
c20d594e 20217 ctx.btarget = 0;
e98c0d17 20218 ctx.kscrexist = (env->CP0_Config4 >> CP0C4_KScrExist) & 0xff;
7207c7f9 20219 ctx.rxi = (env->CP0_Config3 >> CP0C3_RXI) & 1;
9456c2fb 20220 ctx.ie = (env->CP0_Config4 >> CP0C4_IE) & 3;
aea14095
LA
20221 ctx.bi = (env->CP0_Config3 >> CP0C3_BI) & 1;
20222 ctx.bp = (env->CP0_Config3 >> CP0C3_BP) & 1;
5204ea79
LA
20223 ctx.PAMask = env->PAMask;
20224 ctx.mvh = (env->CP0_Config5 >> CP0C5_MVH) & 1;
76964147 20225 ctx.eva = (env->CP0_Config5 >> CP0C5_EVA) & 1;
cec56a73 20226 ctx.sc = (env->CP0_Config3 >> CP0C3_SC) & 1;
5204ea79 20227 ctx.CP0_LLAddr_shift = env->CP0_LLAddr_shift;
c870e3f5 20228 ctx.cmgcr = (env->CP0_Config3 >> CP0C3_CMGCR) & 1;
4ad40f36 20229 /* Restore delay slot state from the tb context. */
eeb3bba8 20230 ctx.hflags = (uint32_t)ctx.base.tb->flags; /* FIXME: maybe use 64 bits? */
66991d11 20231 ctx.ulri = (env->CP0_Config3 >> CP0C3_ULRI) & 1;
e29c9628
YK
20232 ctx.ps = ((env->active_fpu.fcr0 >> FCR0_PS) & 1) ||
20233 (env->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F));
01bc435b 20234 ctx.vp = (env->CP0_Config5 >> CP0C5_VP) & 1;
f6d4dd81 20235 ctx.mrp = (env->CP0_Config5 >> CP0C5_MRP) & 1;
87552089 20236 ctx.nan2008 = (env->active_fpu.fcr31 >> FCR31_NAN2008) & 1;
6be77480 20237 ctx.abs2008 = (env->active_fpu.fcr31 >> FCR31_ABS2008) & 1;
fd4a04eb 20238 restore_cpu_state(env, &ctx);
932e71cd 20239#ifdef CONFIG_USER_ONLY
0eaef5aa 20240 ctx.mem_idx = MIPS_HFLAG_UM;
932e71cd 20241#else
b0fc6003 20242 ctx.mem_idx = hflags_mmu_index(ctx.hflags);
932e71cd 20243#endif
be3a8c53
YK
20244 ctx.default_tcg_memop_mask = (ctx.insn_flags & ISA_MIPS32R6) ?
20245 MO_UNALN : MO_ALIGN;
c5a49c63 20246 max_insns = tb_cflags(tb) & CF_COUNT_MASK;
190ce7fb 20247 if (max_insns == 0) {
2e70f6ef 20248 max_insns = CF_COUNT_MASK;
190ce7fb
RH
20249 }
20250 if (max_insns > TCG_MAX_INSNS) {
20251 max_insns = TCG_MAX_INSNS;
20252 }
20253
d12d51d5 20254 LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb, ctx.mem_idx, ctx.hflags);
cd42d5b2 20255 gen_tb_start(tb);
eeb3bba8
EC
20256 while (ctx.base.is_jmp == DISAS_NEXT) {
20257 tcg_gen_insn_start(ctx.base.pc_next, ctx.hflags & MIPS_HFLAG_BMASK,
20258 ctx.btarget);
20259 ctx.base.num_insns++;
667b8e29 20260
eeb3bba8 20261 if (unlikely(cpu_breakpoint_test(cs, ctx.base.pc_next, BP_ANY))) {
b933066a 20262 save_cpu_state(&ctx, 1);
eeb3bba8 20263 ctx.base.is_jmp = DISAS_NORETURN;
b933066a 20264 gen_helper_raise_exception_debug(cpu_env);
522a0d4e
RH
20265 /* The address covered by the breakpoint must be included in
20266 [tb->pc, tb->pc + tb->size) in order to for it to be
20267 properly cleared -- thus we increment the PC here so that
20268 the logic setting tb->size below does the right thing. */
eeb3bba8 20269 ctx.base.pc_next += 4;
b933066a
RH
20270 goto done_generating;
20271 }
20272
eeb3bba8 20273 if (ctx.base.num_insns == max_insns && (tb_cflags(tb) & CF_LAST_IO)) {
2e70f6ef 20274 gen_io_start();
667b8e29 20275 }
c9602061 20276
339cd2a8 20277 is_slot = ctx.hflags & MIPS_HFLAG_BMASK;
364d4831 20278 if (!(ctx.hflags & MIPS_HFLAG_M16)) {
eeb3bba8 20279 ctx.opcode = cpu_ldl_code(env, ctx.base.pc_next);
c9602061 20280 insn_bytes = 4;
240ce26a 20281 decode_opc(env, &ctx);
d75c135e 20282 } else if (ctx.insn_flags & ASE_MICROMIPS) {
eeb3bba8 20283 ctx.opcode = cpu_lduw_code(env, ctx.base.pc_next);
240ce26a 20284 insn_bytes = decode_micromips_opc(env, &ctx);
d75c135e 20285 } else if (ctx.insn_flags & ASE_MIPS16) {
eeb3bba8 20286 ctx.opcode = cpu_lduw_code(env, ctx.base.pc_next);
240ce26a 20287 insn_bytes = decode_mips16_opc(env, &ctx);
c9602061 20288 } else {
9c708c7f 20289 generate_exception_end(&ctx, EXCP_RI);
c9602061
NF
20290 break;
20291 }
31837be3 20292
b231c103 20293 if (ctx.hflags & MIPS_HFLAG_BMASK) {
339cd2a8
LA
20294 if (!(ctx.hflags & (MIPS_HFLAG_BDS16 | MIPS_HFLAG_BDS32 |
20295 MIPS_HFLAG_FBNSLOT))) {
20296 /* force to generate branch as there is neither delay nor
20297 forbidden slot */
20298 is_slot = 1;
b231c103 20299 }
65935f07
YK
20300 if ((ctx.hflags & MIPS_HFLAG_M16) &&
20301 (ctx.hflags & MIPS_HFLAG_FBNSLOT)) {
20302 /* Force to generate branch as microMIPS R6 doesn't restrict
20303 branches in the forbidden slot. */
20304 is_slot = 1;
20305 }
b231c103 20306 }
339cd2a8 20307 if (is_slot) {
31837be3 20308 gen_branch(&ctx, insn_bytes);
c9602061 20309 }
eeb3bba8 20310 ctx.base.pc_next += insn_bytes;
c9602061 20311
7b270ef2
NF
20312 /* Execute a branch and its delay slot as a single instruction.
20313 This is what GDB expects and is consistent with what the
20314 hardware does (e.g. if a delay slot instruction faults, the
20315 reported PC is the PC of the branch). */
eeb3bba8
EC
20316 if (ctx.base.singlestep_enabled &&
20317 (ctx.hflags & MIPS_HFLAG_BMASK) == 0) {
4ad40f36 20318 break;
ed2803da 20319 }
4ad40f36 20320
eeb3bba8 20321 if (ctx.base.pc_next - page_start >= TARGET_PAGE_SIZE) {
6af0bf9c 20322 break;
fe237291 20323 }
4ad40f36 20324
fe700adb 20325 if (tcg_op_buf_full()) {
faf7aaa9 20326 break;
efd7f486 20327 }
faf7aaa9 20328
eeb3bba8 20329 if (ctx.base.num_insns >= max_insns) {
2e70f6ef 20330 break;
eeb3bba8 20331 }
1b530a6d
AJ
20332
20333 if (singlestep)
20334 break;
6af0bf9c 20335 }
c5a49c63 20336 if (tb_cflags(tb) & CF_LAST_IO) {
2e70f6ef 20337 gen_io_end();
ed2803da 20338 }
eeb3bba8
EC
20339 if (ctx.base.singlestep_enabled && ctx.base.is_jmp != DISAS_NORETURN) {
20340 save_cpu_state(&ctx, ctx.base.is_jmp != DISAS_EXIT);
9c708c7f 20341 gen_helper_raise_exception_debug(cpu_env);
16c00cb2 20342 } else {
eeb3bba8 20343 switch (ctx.base.is_jmp) {
b28425ba 20344 case DISAS_STOP:
eeb3bba8 20345 gen_save_pc(ctx.base.pc_next);
cd314a7d 20346 tcg_gen_lookup_and_goto_ptr();
df1561e2 20347 break;
b28425ba 20348 case DISAS_NEXT:
278d0702 20349 save_cpu_state(&ctx, 0);
eeb3bba8 20350 gen_goto_tb(&ctx, 0, ctx.base.pc_next);
16c00cb2 20351 break;
b28425ba 20352 case DISAS_EXIT:
57fec1fe 20353 tcg_gen_exit_tb(0);
16c00cb2 20354 break;
b28425ba 20355 case DISAS_NORETURN:
5a5012ec
TS
20356 default:
20357 break;
6958549d 20358 }
6af0bf9c 20359 }
4ad40f36 20360done_generating:
eeb3bba8 20361 gen_tb_end(tb, ctx.base.num_insns);
0a7df5da 20362
eeb3bba8
EC
20363 tb->size = ctx.base.pc_next - ctx.base.pc_first;
20364 tb->icount = ctx.base.num_insns;
4e5e1215 20365
6af0bf9c 20366#ifdef DEBUG_DISAS
d12d51d5 20367 LOG_DISAS("\n");
4910e6e4 20368 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)
eeb3bba8 20369 && qemu_log_in_addr_range(ctx.base.pc_first)) {
1ee73216 20370 qemu_log_lock();
eeb3bba8
EC
20371 qemu_log("IN: %s\n", lookup_symbol(ctx.base.pc_first));
20372 log_target_disas(cs, ctx.base.pc_first,
20373 ctx.base.pc_next - ctx.base.pc_first);
93fcfe39 20374 qemu_log("\n");
1ee73216 20375 qemu_log_unlock();
6af0bf9c
FB
20376 }
20377#endif
6af0bf9c
FB
20378}
20379
7db13fae 20380static void fpu_dump_state(CPUMIPSState *env, FILE *f, fprintf_function fpu_fprintf,
8706c382 20381 int flags)
6ea83fed
FB
20382{
20383 int i;
5e755519 20384 int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
5a5012ec 20385
2a5612e6
SW
20386#define printfpr(fp) \
20387 do { \
20388 if (is_fpu64) \
20389 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
20390 " fd:%13g fs:%13g psu: %13g\n", \
20391 (fp)->w[FP_ENDIAN_IDX], (fp)->d, \
20392 (double)(fp)->fd, \
20393 (double)(fp)->fs[FP_ENDIAN_IDX], \
20394 (double)(fp)->fs[!FP_ENDIAN_IDX]); \
20395 else { \
20396 fpr_t tmp; \
20397 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
20398 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
20399 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
20400 " fd:%13g fs:%13g psu:%13g\n", \
20401 tmp.w[FP_ENDIAN_IDX], tmp.d, \
20402 (double)tmp.fd, \
20403 (double)tmp.fs[FP_ENDIAN_IDX], \
20404 (double)tmp.fs[!FP_ENDIAN_IDX]); \
20405 } \
6ea83fed
FB
20406 } while(0)
20407
5a5012ec 20408
9a78eead
SW
20409 fpu_fprintf(f, "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%02x\n",
20410 env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64,
f01be154 20411 get_float_exception_flags(&env->active_fpu.fp_status));
5a5012ec
TS
20412 for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
20413 fpu_fprintf(f, "%3s: ", fregnames[i]);
f01be154 20414 printfpr(&env->active_fpu.fpr[i]);
6ea83fed
FB
20415 }
20416
20417#undef printfpr
20418}
20419
878096ee
AF
20420void mips_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
20421 int flags)
6af0bf9c 20422{
878096ee
AF
20423 MIPSCPU *cpu = MIPS_CPU(cs);
20424 CPUMIPSState *env = &cpu->env;
6af0bf9c 20425 int i;
3b46e624 20426
a7200c9f
SW
20427 cpu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
20428 " LO=0x" TARGET_FMT_lx " ds %04x "
20429 TARGET_FMT_lx " " TARGET_FMT_ld "\n",
3d5be870
TS
20430 env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
20431 env->hflags, env->btarget, env->bcond);
6af0bf9c
FB
20432 for (i = 0; i < 32; i++) {
20433 if ((i & 3) == 0)
20434 cpu_fprintf(f, "GPR%02d:", i);
b5dc7732 20435 cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
6af0bf9c
FB
20436 if ((i & 3) == 3)
20437 cpu_fprintf(f, "\n");
20438 }
568b600d 20439
3594c774 20440 cpu_fprintf(f, "CP0 Status 0x%08x Cause 0x%08x EPC 0x" TARGET_FMT_lx "\n",
5e755519 20441 env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
284b731a
LA
20442 cpu_fprintf(f, " Config0 0x%08x Config1 0x%08x LLAddr 0x%016"
20443 PRIx64 "\n",
5499b6ff 20444 env->CP0_Config0, env->CP0_Config1, env->lladdr);
27e1fb13
MR
20445 cpu_fprintf(f, " Config2 0x%08x Config3 0x%08x\n",
20446 env->CP0_Config2, env->CP0_Config3);
20447 cpu_fprintf(f, " Config4 0x%08x Config5 0x%08x\n",
20448 env->CP0_Config4, env->CP0_Config5);
5e755519 20449 if (env->hflags & MIPS_HFLAG_FPU)
7a387fff 20450 fpu_dump_state(env, f, cpu_fprintf, flags);
6af0bf9c
FB
20451}
20452
78ce64f4 20453void mips_tcg_init(void)
39454628 20454{
f01be154 20455 int i;
39454628 20456
f764718d 20457 cpu_gpr[0] = NULL;
bb928dbe 20458 for (i = 1; i < 32; i++)
e1ccc054 20459 cpu_gpr[i] = tcg_global_mem_new(cpu_env,
7db13fae 20460 offsetof(CPUMIPSState, active_tc.gpr[i]),
4b2eb8d2 20461 regnames[i]);
d73ee8a2 20462
863f264d
YK
20463 for (i = 0; i < 32; i++) {
20464 int off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[0]);
20465 msa_wr_d[i * 2] =
e1ccc054 20466 tcg_global_mem_new_i64(cpu_env, off, msaregnames[i * 2]);
cb269f27
YK
20467 /* The scalar floating-point unit (FPU) registers are mapped on
20468 * the MSA vector registers. */
20469 fpu_f64[i] = msa_wr_d[i * 2];
863f264d
YK
20470 off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[1]);
20471 msa_wr_d[i * 2 + 1] =
e1ccc054 20472 tcg_global_mem_new_i64(cpu_env, off, msaregnames[i * 2 + 1]);
863f264d
YK
20473 }
20474
e1ccc054 20475 cpu_PC = tcg_global_mem_new(cpu_env,
7db13fae 20476 offsetof(CPUMIPSState, active_tc.PC), "PC");
4b2eb8d2 20477 for (i = 0; i < MIPS_DSP_ACC; i++) {
e1ccc054 20478 cpu_HI[i] = tcg_global_mem_new(cpu_env,
7db13fae 20479 offsetof(CPUMIPSState, active_tc.HI[i]),
4b2eb8d2 20480 regnames_HI[i]);
e1ccc054 20481 cpu_LO[i] = tcg_global_mem_new(cpu_env,
7db13fae 20482 offsetof(CPUMIPSState, active_tc.LO[i]),
4b2eb8d2 20483 regnames_LO[i]);
4b2eb8d2 20484 }
e1ccc054 20485 cpu_dspctrl = tcg_global_mem_new(cpu_env,
7db13fae 20486 offsetof(CPUMIPSState, active_tc.DSPControl),
4b2eb8d2 20487 "DSPControl");
e1ccc054 20488 bcond = tcg_global_mem_new(cpu_env,
7db13fae 20489 offsetof(CPUMIPSState, bcond), "bcond");
e1ccc054 20490 btarget = tcg_global_mem_new(cpu_env,
7db13fae 20491 offsetof(CPUMIPSState, btarget), "btarget");
e1ccc054 20492 hflags = tcg_global_mem_new_i32(cpu_env,
7db13fae 20493 offsetof(CPUMIPSState, hflags), "hflags");
41db4607 20494
e1ccc054 20495 fpu_fcr0 = tcg_global_mem_new_i32(cpu_env,
7db13fae 20496 offsetof(CPUMIPSState, active_fpu.fcr0),
a7812ae4 20497 "fcr0");
e1ccc054 20498 fpu_fcr31 = tcg_global_mem_new_i32(cpu_env,
7db13fae 20499 offsetof(CPUMIPSState, active_fpu.fcr31),
a7812ae4 20500 "fcr31");
39454628
TS
20501}
20502
aaed909a
FB
20503#include "translate_init.c"
20504
27e38392
PMD
20505void cpu_mips_realize_env(CPUMIPSState *env)
20506{
20507 env->exception_base = (int32_t)0xBFC00000;
20508
20509#ifndef CONFIG_USER_ONLY
20510 mmu_init(env, env->cpu_model);
20511#endif
20512 fpu_init(env, env->cpu_model);
20513 mvp_init(env, env->cpu_model);
20514}
20515
a7519f2b 20516bool cpu_supports_cps_smp(const char *cpu_type)
bff384a4 20517{
a7519f2b
IM
20518 const MIPSCPUClass *mcc = MIPS_CPU_CLASS(object_class_by_name(cpu_type));
20519 return (mcc->cpu_def->CP0_Config3 & (1 << CP0C3_CMGCR)) != 0;
bff384a4
LA
20520}
20521
a7519f2b 20522bool cpu_supports_isa(const char *cpu_type, unsigned int isa)
bed9e5ce 20523{
a7519f2b
IM
20524 const MIPSCPUClass *mcc = MIPS_CPU_CLASS(object_class_by_name(cpu_type));
20525 return (mcc->cpu_def->insn_flags & isa) != 0;
bed9e5ce
PB
20526}
20527
89777fd1
LA
20528void cpu_set_exception_base(int vp_index, target_ulong address)
20529{
20530 MIPSCPU *vp = MIPS_CPU(qemu_get_cpu(vp_index));
20531 vp->env.exception_base = address;
20532}
20533
1bba0dc9 20534void cpu_state_reset(CPUMIPSState *env)
6ae81775 20535{
55e5c285
AF
20536 MIPSCPU *cpu = mips_env_get_cpu(env);
20537 CPUState *cs = CPU(cpu);
6ae81775 20538
51cc2e78
BS
20539 /* Reset registers to their default values */
20540 env->CP0_PRid = env->cpu_model->CP0_PRid;
20541 env->CP0_Config0 = env->cpu_model->CP0_Config0;
20542#ifdef TARGET_WORDS_BIGENDIAN
20543 env->CP0_Config0 |= (1 << CP0C0_BE);
20544#endif
20545 env->CP0_Config1 = env->cpu_model->CP0_Config1;
20546 env->CP0_Config2 = env->cpu_model->CP0_Config2;
20547 env->CP0_Config3 = env->cpu_model->CP0_Config3;
b4160af1
PJ
20548 env->CP0_Config4 = env->cpu_model->CP0_Config4;
20549 env->CP0_Config4_rw_bitmask = env->cpu_model->CP0_Config4_rw_bitmask;
b4dd99a3
PJ
20550 env->CP0_Config5 = env->cpu_model->CP0_Config5;
20551 env->CP0_Config5_rw_bitmask = env->cpu_model->CP0_Config5_rw_bitmask;
51cc2e78
BS
20552 env->CP0_Config6 = env->cpu_model->CP0_Config6;
20553 env->CP0_Config7 = env->cpu_model->CP0_Config7;
2a6e32dd
AJ
20554 env->CP0_LLAddr_rw_bitmask = env->cpu_model->CP0_LLAddr_rw_bitmask
20555 << env->cpu_model->CP0_LLAddr_shift;
20556 env->CP0_LLAddr_shift = env->cpu_model->CP0_LLAddr_shift;
51cc2e78
BS
20557 env->SYNCI_Step = env->cpu_model->SYNCI_Step;
20558 env->CCRes = env->cpu_model->CCRes;
20559 env->CP0_Status_rw_bitmask = env->cpu_model->CP0_Status_rw_bitmask;
20560 env->CP0_TCStatus_rw_bitmask = env->cpu_model->CP0_TCStatus_rw_bitmask;
20561 env->CP0_SRSCtl = env->cpu_model->CP0_SRSCtl;
20562 env->current_tc = 0;
20563 env->SEGBITS = env->cpu_model->SEGBITS;
20564 env->SEGMask = (target_ulong)((1ULL << env->cpu_model->SEGBITS) - 1);
20565#if defined(TARGET_MIPS64)
20566 if (env->cpu_model->insn_flags & ISA_MIPS3) {
20567 env->SEGMask |= 3ULL << 62;
20568 }
20569#endif
20570 env->PABITS = env->cpu_model->PABITS;
51cc2e78
BS
20571 env->CP0_SRSConf0_rw_bitmask = env->cpu_model->CP0_SRSConf0_rw_bitmask;
20572 env->CP0_SRSConf0 = env->cpu_model->CP0_SRSConf0;
20573 env->CP0_SRSConf1_rw_bitmask = env->cpu_model->CP0_SRSConf1_rw_bitmask;
20574 env->CP0_SRSConf1 = env->cpu_model->CP0_SRSConf1;
20575 env->CP0_SRSConf2_rw_bitmask = env->cpu_model->CP0_SRSConf2_rw_bitmask;
20576 env->CP0_SRSConf2 = env->cpu_model->CP0_SRSConf2;
20577 env->CP0_SRSConf3_rw_bitmask = env->cpu_model->CP0_SRSConf3_rw_bitmask;
20578 env->CP0_SRSConf3 = env->cpu_model->CP0_SRSConf3;
20579 env->CP0_SRSConf4_rw_bitmask = env->cpu_model->CP0_SRSConf4_rw_bitmask;
20580 env->CP0_SRSConf4 = env->cpu_model->CP0_SRSConf4;
7207c7f9
LA
20581 env->CP0_PageGrain_rw_bitmask = env->cpu_model->CP0_PageGrain_rw_bitmask;
20582 env->CP0_PageGrain = env->cpu_model->CP0_PageGrain;
74dbf824 20583 env->CP0_EBaseWG_rw_bitmask = env->cpu_model->CP0_EBaseWG_rw_bitmask;
f1cb0951 20584 env->active_fpu.fcr0 = env->cpu_model->CP1_fcr0;
599bc5e8 20585 env->active_fpu.fcr31_rw_bitmask = env->cpu_model->CP1_fcr31_rw_bitmask;
ba5c79f2 20586 env->active_fpu.fcr31 = env->cpu_model->CP1_fcr31;
863f264d 20587 env->msair = env->cpu_model->MSAIR;
51cc2e78
BS
20588 env->insn_flags = env->cpu_model->insn_flags;
20589
0eaef5aa 20590#if defined(CONFIG_USER_ONLY)
03e6e501 20591 env->CP0_Status = (MIPS_HFLAG_UM << CP0St_KSU);
68473f15
RH
20592# ifdef TARGET_MIPS64
20593 /* Enable 64-bit register mode. */
20594 env->CP0_Status |= (1 << CP0St_PX);
20595# endif
20596# ifdef TARGET_ABI_MIPSN64
20597 /* Enable 64-bit address mode. */
20598 env->CP0_Status |= (1 << CP0St_UX);
20599# endif
94159135
MI
20600 /* Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
20601 hardware registers. */
20602 env->CP0_HWREna |= 0x0000000F;
91a75935 20603 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
03e6e501 20604 env->CP0_Status |= (1 << CP0St_CU1);
91a75935 20605 }
6f0af304
PJ
20606 if (env->CP0_Config3 & (1 << CP0C3_DSPP)) {
20607 env->CP0_Status |= (1 << CP0St_MX);
853c3240 20608 }
4d66261f
PJ
20609# if defined(TARGET_MIPS64)
20610 /* For MIPS64, init FR bit to 1 if FPU unit is there and bit is writable. */
20611 if ((env->CP0_Config1 & (1 << CP0C1_FP)) &&
20612 (env->CP0_Status_rw_bitmask & (1 << CP0St_FR))) {
68473f15
RH
20613 env->CP0_Status |= (1 << CP0St_FR);
20614 }
4d66261f 20615# endif
932e71cd
AJ
20616#else
20617 if (env->hflags & MIPS_HFLAG_BMASK) {
20618 /* If the exception was raised from a delay slot,
20619 come back to the jump. */
c3577479
MR
20620 env->CP0_ErrorEPC = (env->active_tc.PC
20621 - (env->hflags & MIPS_HFLAG_B16 ? 2 : 4));
aa328add 20622 } else {
932e71cd
AJ
20623 env->CP0_ErrorEPC = env->active_tc.PC;
20624 }
89777fd1 20625 env->active_tc.PC = env->exception_base;
51cc2e78
BS
20626 env->CP0_Random = env->tlb->nb_tlb - 1;
20627 env->tlb->tlb_in_use = env->tlb->nb_tlb;
932e71cd 20628 env->CP0_Wired = 0;
01bc435b 20629 env->CP0_GlobalNumber = (cs->cpu_index & 0xFF) << CP0GN_VPId;
0a2672b7 20630 env->CP0_EBase = (cs->cpu_index & 0x3FF);
d3d93c6c 20631 if (mips_um_ksegs_enabled()) {
0a2672b7
JH
20632 env->CP0_EBase |= 0x40000000;
20633 } else {
74dbf824 20634 env->CP0_EBase |= (int32_t)0x80000000;
0a2672b7 20635 }
c870e3f5
YK
20636 if (env->CP0_Config3 & (1 << CP0C3_CMGCR)) {
20637 env->CP0_CMGCRBase = 0x1fbf8000 >> 4;
20638 }
a0c80608
PB
20639 env->CP0_EntryHi_ASID_mask = (env->CP0_Config4 & (1 << CP0C4_AE)) ?
20640 0x3ff : 0xff;
932e71cd
AJ
20641 env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
20642 /* vectored interrupts not implemented, timer on int 7,
20643 no performance counters. */
20644 env->CP0_IntCtl = 0xe0000000;
20645 {
20646 int i;
20647
20648 for (i = 0; i < 7; i++) {
20649 env->CP0_WatchLo[i] = 0;
20650 env->CP0_WatchHi[i] = 0x80000000;
fd88b6ab 20651 }
932e71cd
AJ
20652 env->CP0_WatchLo[7] = 0;
20653 env->CP0_WatchHi[7] = 0;
fd88b6ab 20654 }
932e71cd
AJ
20655 /* Count register increments in debug mode, EJTAG version 1 */
20656 env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
9e56e756 20657
4b69c7e2
JH
20658 cpu_mips_store_count(env, 1);
20659
9e56e756
EI
20660 if (env->CP0_Config3 & (1 << CP0C3_MT)) {
20661 int i;
20662
20663 /* Only TC0 on VPE 0 starts as active. */
20664 for (i = 0; i < ARRAY_SIZE(env->tcs); i++) {
55e5c285 20665 env->tcs[i].CP0_TCBind = cs->cpu_index << CP0TCBd_CurVPE;
9e56e756
EI
20666 env->tcs[i].CP0_TCHalt = 1;
20667 }
20668 env->active_tc.CP0_TCHalt = 1;
259186a7 20669 cs->halted = 1;
9e56e756 20670
55e5c285 20671 if (cs->cpu_index == 0) {
9e56e756
EI
20672 /* VPE0 starts up enabled. */
20673 env->mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
20674 env->CP0_VPEConf0 |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
20675
20676 /* TC0 starts up unhalted. */
259186a7 20677 cs->halted = 0;
9e56e756
EI
20678 env->active_tc.CP0_TCHalt = 0;
20679 env->tcs[0].CP0_TCHalt = 0;
20680 /* With thread 0 active. */
20681 env->active_tc.CP0_TCStatus = (1 << CP0TCSt_A);
20682 env->tcs[0].CP0_TCStatus = (1 << CP0TCSt_A);
20683 }
20684 }
cec56a73
JH
20685
20686 /*
20687 * Configure default legacy segmentation control. We use this regardless of
20688 * whether segmentation control is presented to the guest.
20689 */
20690 /* KSeg3 (seg0 0xE0000000..0xFFFFFFFF) */
20691 env->CP0_SegCtl0 = (CP0SC_AM_MK << CP0SC_AM);
20692 /* KSeg2 (seg1 0xC0000000..0xDFFFFFFF) */
20693 env->CP0_SegCtl0 |= ((CP0SC_AM_MSK << CP0SC_AM)) << 16;
20694 /* KSeg1 (seg2 0xA0000000..0x9FFFFFFF) */
20695 env->CP0_SegCtl1 = (0 << CP0SC_PA) | (CP0SC_AM_UK << CP0SC_AM) |
20696 (2 << CP0SC_C);
20697 /* KSeg0 (seg3 0x80000000..0x9FFFFFFF) */
20698 env->CP0_SegCtl1 |= ((0 << CP0SC_PA) | (CP0SC_AM_UK << CP0SC_AM) |
20699 (3 << CP0SC_C)) << 16;
20700 /* USeg (seg4 0x40000000..0x7FFFFFFF) */
20701 env->CP0_SegCtl2 = (2 << CP0SC_PA) | (CP0SC_AM_MUSK << CP0SC_AM) |
20702 (1 << CP0SC_EU) | (2 << CP0SC_C);
20703 /* USeg (seg5 0x00000000..0x3FFFFFFF) */
20704 env->CP0_SegCtl2 |= ((0 << CP0SC_PA) | (CP0SC_AM_MUSK << CP0SC_AM) |
20705 (1 << CP0SC_EU) | (2 << CP0SC_C)) << 16;
20706 /* XKPhys (note, SegCtl2.XR = 0, so XAM won't be used) */
20707 env->CP0_SegCtl1 |= (CP0SC_AM_UK << CP0SC1_XAM);
51cc2e78 20708#endif
ddc584bd
LA
20709 if ((env->insn_flags & ISA_MIPS32R6) &&
20710 (env->active_fpu.fcr0 & (1 << FCR0_F64))) {
20711 /* Status.FR = 0 mode in 64-bit FPU not allowed in R6 */
20712 env->CP0_Status |= (1 << CP0St_FR);
20713 }
20714
863f264d
YK
20715 /* MSA */
20716 if (env->CP0_Config3 & (1 << CP0C3_MSAP)) {
20717 msa_reset(env);
20718 }
20719
03e6e501 20720 compute_hflags(env);
599bc5e8 20721 restore_fp_status(env);
e117f526 20722 restore_pamask(env);
27103424 20723 cs->exception_index = EXCP_NONE;
3b3c1694
LA
20724
20725 if (semihosting_get_argc()) {
20726 /* UHI interface can be used to obtain argc and argv */
20727 env->active_tc.gpr[4] = -1;
20728 }
6af0bf9c 20729}
d2856f1a 20730
bad729e2
RH
20731void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb,
20732 target_ulong *data)
d2856f1a 20733{
bad729e2 20734 env->active_tc.PC = data[0];
d2856f1a 20735 env->hflags &= ~MIPS_HFLAG_BMASK;
bad729e2 20736 env->hflags |= data[1];
4636401d
AJ
20737 switch (env->hflags & MIPS_HFLAG_BMASK_BASE) {
20738 case MIPS_HFLAG_BR:
20739 break;
20740 case MIPS_HFLAG_BC:
20741 case MIPS_HFLAG_BL:
20742 case MIPS_HFLAG_B:
bad729e2 20743 env->btarget = data[2];
4636401d
AJ
20744 break;
20745 }
d2856f1a 20746}