]> git.proxmox.com Git - mirror_qemu.git/blame - target/mips/translate.c
target/mips: Avoid case statements formulated by ranges - part 2
[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,
c38a1d52
AR
905 OPC_C0_1 = (0x11 << 21) | OPC_CP0,
906 OPC_C0_2 = (0x12 << 21) | OPC_CP0,
907 OPC_C0_3 = (0x13 << 21) | OPC_CP0,
908 OPC_C0_4 = (0x14 << 21) | OPC_CP0,
909 OPC_C0_5 = (0x15 << 21) | OPC_CP0,
910 OPC_C0_6 = (0x16 << 21) | OPC_CP0,
911 OPC_C0_7 = (0x17 << 21) | OPC_CP0,
912 OPC_C0_8 = (0x18 << 21) | OPC_CP0,
913 OPC_C0_9 = (0x19 << 21) | OPC_CP0,
914 OPC_C0_A = (0x1A << 21) | OPC_CP0,
915 OPC_C0_B = (0x1B << 21) | OPC_CP0,
916 OPC_C0_C = (0x1C << 21) | OPC_CP0,
917 OPC_C0_D = (0x1D << 21) | OPC_CP0,
918 OPC_C0_E = (0x1E << 21) | OPC_CP0,
919 OPC_C0_F = (0x1F << 21) | OPC_CP0,
6ea83fed 920};
7a387fff
TS
921
922/* MFMC0 opcodes */
b48cfdff 923#define MASK_MFMC0(op) MASK_CP0(op) | (op & 0xFFFF)
7a387fff
TS
924
925enum {
ead9360e
TS
926 OPC_DMT = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
927 OPC_EMT = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
928 OPC_DVPE = 0x01 | (0 << 5) | OPC_MFMC0,
929 OPC_EVPE = 0x01 | (1 << 5) | OPC_MFMC0,
7a387fff
TS
930 OPC_DI = (0 << 5) | (0x0C << 11) | OPC_MFMC0,
931 OPC_EI = (1 << 5) | (0x0C << 11) | OPC_MFMC0,
01bc435b
YK
932 OPC_DVP = 0x04 | (0 << 3) | (1 << 5) | (0 << 11) | OPC_MFMC0,
933 OPC_EVP = 0x04 | (0 << 3) | (0 << 5) | (0 << 11) | OPC_MFMC0,
7a387fff
TS
934};
935
936/* Coprocessor 0 (with rs == C0) */
937#define MASK_C0(op) MASK_CP0(op) | (op & 0x3F)
938
939enum {
940 OPC_TLBR = 0x01 | OPC_C0,
941 OPC_TLBWI = 0x02 | OPC_C0,
9456c2fb
LA
942 OPC_TLBINV = 0x03 | OPC_C0,
943 OPC_TLBINVF = 0x04 | OPC_C0,
7a387fff
TS
944 OPC_TLBWR = 0x06 | OPC_C0,
945 OPC_TLBP = 0x08 | OPC_C0,
946 OPC_RFE = 0x10 | OPC_C0,
947 OPC_ERET = 0x18 | OPC_C0,
948 OPC_DERET = 0x1F | OPC_C0,
949 OPC_WAIT = 0x20 | OPC_C0,
950};
951
952/* Coprocessor 1 (rs field) */
953#define MASK_CP1(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
954
bf4120ad
NF
955/* Values for the fmt field in FP instructions */
956enum {
957 /* 0 - 15 are reserved */
e459440a
AJ
958 FMT_S = 16, /* single fp */
959 FMT_D = 17, /* double fp */
960 FMT_E = 18, /* extended fp */
961 FMT_Q = 19, /* quad fp */
962 FMT_W = 20, /* 32-bit fixed */
963 FMT_L = 21, /* 64-bit fixed */
964 FMT_PS = 22, /* paired single fp */
bf4120ad
NF
965 /* 23 - 31 are reserved */
966};
967
7a387fff
TS
968enum {
969 OPC_MFC1 = (0x00 << 21) | OPC_CP1,
970 OPC_DMFC1 = (0x01 << 21) | OPC_CP1,
971 OPC_CFC1 = (0x02 << 21) | OPC_CP1,
5a5012ec 972 OPC_MFHC1 = (0x03 << 21) | OPC_CP1,
7a387fff
TS
973 OPC_MTC1 = (0x04 << 21) | OPC_CP1,
974 OPC_DMTC1 = (0x05 << 21) | OPC_CP1,
975 OPC_CTC1 = (0x06 << 21) | OPC_CP1,
5a5012ec 976 OPC_MTHC1 = (0x07 << 21) | OPC_CP1,
7a387fff 977 OPC_BC1 = (0x08 << 21) | OPC_CP1, /* bc */
5a5012ec
TS
978 OPC_BC1ANY2 = (0x09 << 21) | OPC_CP1,
979 OPC_BC1ANY4 = (0x0A << 21) | OPC_CP1,
239dfebe
YK
980 OPC_BZ_V = (0x0B << 21) | OPC_CP1,
981 OPC_BNZ_V = (0x0F << 21) | OPC_CP1,
e459440a
AJ
982 OPC_S_FMT = (FMT_S << 21) | OPC_CP1,
983 OPC_D_FMT = (FMT_D << 21) | OPC_CP1,
984 OPC_E_FMT = (FMT_E << 21) | OPC_CP1,
985 OPC_Q_FMT = (FMT_Q << 21) | OPC_CP1,
986 OPC_W_FMT = (FMT_W << 21) | OPC_CP1,
987 OPC_L_FMT = (FMT_L << 21) | OPC_CP1,
988 OPC_PS_FMT = (FMT_PS << 21) | OPC_CP1,
31837be3
YK
989 OPC_BC1EQZ = (0x09 << 21) | OPC_CP1,
990 OPC_BC1NEZ = (0x0D << 21) | OPC_CP1,
239dfebe
YK
991 OPC_BZ_B = (0x18 << 21) | OPC_CP1,
992 OPC_BZ_H = (0x19 << 21) | OPC_CP1,
993 OPC_BZ_W = (0x1A << 21) | OPC_CP1,
994 OPC_BZ_D = (0x1B << 21) | OPC_CP1,
995 OPC_BNZ_B = (0x1C << 21) | OPC_CP1,
996 OPC_BNZ_H = (0x1D << 21) | OPC_CP1,
997 OPC_BNZ_W = (0x1E << 21) | OPC_CP1,
998 OPC_BNZ_D = (0x1F << 21) | OPC_CP1,
7a387fff
TS
999};
1000
5a5012ec
TS
1001#define MASK_CP1_FUNC(op) MASK_CP1(op) | (op & 0x3F)
1002#define MASK_BC1(op) MASK_CP1(op) | (op & (0x3 << 16))
1003
7a387fff
TS
1004enum {
1005 OPC_BC1F = (0x00 << 16) | OPC_BC1,
1006 OPC_BC1T = (0x01 << 16) | OPC_BC1,
1007 OPC_BC1FL = (0x02 << 16) | OPC_BC1,
1008 OPC_BC1TL = (0x03 << 16) | OPC_BC1,
1009};
1010
5a5012ec
TS
1011enum {
1012 OPC_BC1FANY2 = (0x00 << 16) | OPC_BC1ANY2,
1013 OPC_BC1TANY2 = (0x01 << 16) | OPC_BC1ANY2,
1014};
1015
1016enum {
1017 OPC_BC1FANY4 = (0x00 << 16) | OPC_BC1ANY4,
1018 OPC_BC1TANY4 = (0x01 << 16) | OPC_BC1ANY4,
1019};
7a387fff
TS
1020
1021#define MASK_CP2(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
e0c84da7
TS
1022
1023enum {
1024 OPC_MFC2 = (0x00 << 21) | OPC_CP2,
1025 OPC_DMFC2 = (0x01 << 21) | OPC_CP2,
1026 OPC_CFC2 = (0x02 << 21) | OPC_CP2,
1027 OPC_MFHC2 = (0x03 << 21) | OPC_CP2,
1028 OPC_MTC2 = (0x04 << 21) | OPC_CP2,
1029 OPC_DMTC2 = (0x05 << 21) | OPC_CP2,
1030 OPC_CTC2 = (0x06 << 21) | OPC_CP2,
1031 OPC_MTHC2 = (0x07 << 21) | OPC_CP2,
1032 OPC_BC2 = (0x08 << 21) | OPC_CP2,
31837be3
YK
1033 OPC_BC2EQZ = (0x09 << 21) | OPC_CP2,
1034 OPC_BC2NEZ = (0x0D << 21) | OPC_CP2,
e0c84da7
TS
1035};
1036
bd277fa1
RH
1037#define MASK_LMI(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)) | (op & 0x1F))
1038
1039enum {
1040 OPC_PADDSH = (24 << 21) | (0x00) | OPC_CP2,
1041 OPC_PADDUSH = (25 << 21) | (0x00) | OPC_CP2,
1042 OPC_PADDH = (26 << 21) | (0x00) | OPC_CP2,
1043 OPC_PADDW = (27 << 21) | (0x00) | OPC_CP2,
1044 OPC_PADDSB = (28 << 21) | (0x00) | OPC_CP2,
1045 OPC_PADDUSB = (29 << 21) | (0x00) | OPC_CP2,
1046 OPC_PADDB = (30 << 21) | (0x00) | OPC_CP2,
1047 OPC_PADDD = (31 << 21) | (0x00) | OPC_CP2,
1048
1049 OPC_PSUBSH = (24 << 21) | (0x01) | OPC_CP2,
1050 OPC_PSUBUSH = (25 << 21) | (0x01) | OPC_CP2,
1051 OPC_PSUBH = (26 << 21) | (0x01) | OPC_CP2,
1052 OPC_PSUBW = (27 << 21) | (0x01) | OPC_CP2,
1053 OPC_PSUBSB = (28 << 21) | (0x01) | OPC_CP2,
1054 OPC_PSUBUSB = (29 << 21) | (0x01) | OPC_CP2,
1055 OPC_PSUBB = (30 << 21) | (0x01) | OPC_CP2,
1056 OPC_PSUBD = (31 << 21) | (0x01) | OPC_CP2,
1057
1058 OPC_PSHUFH = (24 << 21) | (0x02) | OPC_CP2,
1059 OPC_PACKSSWH = (25 << 21) | (0x02) | OPC_CP2,
1060 OPC_PACKSSHB = (26 << 21) | (0x02) | OPC_CP2,
1061 OPC_PACKUSHB = (27 << 21) | (0x02) | OPC_CP2,
1062 OPC_XOR_CP2 = (28 << 21) | (0x02) | OPC_CP2,
1063 OPC_NOR_CP2 = (29 << 21) | (0x02) | OPC_CP2,
1064 OPC_AND_CP2 = (30 << 21) | (0x02) | OPC_CP2,
1065 OPC_PANDN = (31 << 21) | (0x02) | OPC_CP2,
1066
1067 OPC_PUNPCKLHW = (24 << 21) | (0x03) | OPC_CP2,
1068 OPC_PUNPCKHHW = (25 << 21) | (0x03) | OPC_CP2,
1069 OPC_PUNPCKLBH = (26 << 21) | (0x03) | OPC_CP2,
1070 OPC_PUNPCKHBH = (27 << 21) | (0x03) | OPC_CP2,
1071 OPC_PINSRH_0 = (28 << 21) | (0x03) | OPC_CP2,
1072 OPC_PINSRH_1 = (29 << 21) | (0x03) | OPC_CP2,
1073 OPC_PINSRH_2 = (30 << 21) | (0x03) | OPC_CP2,
1074 OPC_PINSRH_3 = (31 << 21) | (0x03) | OPC_CP2,
1075
1076 OPC_PAVGH = (24 << 21) | (0x08) | OPC_CP2,
1077 OPC_PAVGB = (25 << 21) | (0x08) | OPC_CP2,
1078 OPC_PMAXSH = (26 << 21) | (0x08) | OPC_CP2,
1079 OPC_PMINSH = (27 << 21) | (0x08) | OPC_CP2,
1080 OPC_PMAXUB = (28 << 21) | (0x08) | OPC_CP2,
1081 OPC_PMINUB = (29 << 21) | (0x08) | OPC_CP2,
1082
1083 OPC_PCMPEQW = (24 << 21) | (0x09) | OPC_CP2,
1084 OPC_PCMPGTW = (25 << 21) | (0x09) | OPC_CP2,
1085 OPC_PCMPEQH = (26 << 21) | (0x09) | OPC_CP2,
1086 OPC_PCMPGTH = (27 << 21) | (0x09) | OPC_CP2,
1087 OPC_PCMPEQB = (28 << 21) | (0x09) | OPC_CP2,
1088 OPC_PCMPGTB = (29 << 21) | (0x09) | OPC_CP2,
1089
1090 OPC_PSLLW = (24 << 21) | (0x0A) | OPC_CP2,
1091 OPC_PSLLH = (25 << 21) | (0x0A) | OPC_CP2,
1092 OPC_PMULLH = (26 << 21) | (0x0A) | OPC_CP2,
1093 OPC_PMULHH = (27 << 21) | (0x0A) | OPC_CP2,
1094 OPC_PMULUW = (28 << 21) | (0x0A) | OPC_CP2,
1095 OPC_PMULHUH = (29 << 21) | (0x0A) | OPC_CP2,
1096
1097 OPC_PSRLW = (24 << 21) | (0x0B) | OPC_CP2,
1098 OPC_PSRLH = (25 << 21) | (0x0B) | OPC_CP2,
1099 OPC_PSRAW = (26 << 21) | (0x0B) | OPC_CP2,
1100 OPC_PSRAH = (27 << 21) | (0x0B) | OPC_CP2,
1101 OPC_PUNPCKLWD = (28 << 21) | (0x0B) | OPC_CP2,
1102 OPC_PUNPCKHWD = (29 << 21) | (0x0B) | OPC_CP2,
1103
1104 OPC_ADDU_CP2 = (24 << 21) | (0x0C) | OPC_CP2,
1105 OPC_OR_CP2 = (25 << 21) | (0x0C) | OPC_CP2,
1106 OPC_ADD_CP2 = (26 << 21) | (0x0C) | OPC_CP2,
1107 OPC_DADD_CP2 = (27 << 21) | (0x0C) | OPC_CP2,
1108 OPC_SEQU_CP2 = (28 << 21) | (0x0C) | OPC_CP2,
1109 OPC_SEQ_CP2 = (29 << 21) | (0x0C) | OPC_CP2,
1110
1111 OPC_SUBU_CP2 = (24 << 21) | (0x0D) | OPC_CP2,
1112 OPC_PASUBUB = (25 << 21) | (0x0D) | OPC_CP2,
1113 OPC_SUB_CP2 = (26 << 21) | (0x0D) | OPC_CP2,
1114 OPC_DSUB_CP2 = (27 << 21) | (0x0D) | OPC_CP2,
1115 OPC_SLTU_CP2 = (28 << 21) | (0x0D) | OPC_CP2,
1116 OPC_SLT_CP2 = (29 << 21) | (0x0D) | OPC_CP2,
1117
1118 OPC_SLL_CP2 = (24 << 21) | (0x0E) | OPC_CP2,
1119 OPC_DSLL_CP2 = (25 << 21) | (0x0E) | OPC_CP2,
1120 OPC_PEXTRH = (26 << 21) | (0x0E) | OPC_CP2,
1121 OPC_PMADDHW = (27 << 21) | (0x0E) | OPC_CP2,
1122 OPC_SLEU_CP2 = (28 << 21) | (0x0E) | OPC_CP2,
1123 OPC_SLE_CP2 = (29 << 21) | (0x0E) | OPC_CP2,
1124
1125 OPC_SRL_CP2 = (24 << 21) | (0x0F) | OPC_CP2,
1126 OPC_DSRL_CP2 = (25 << 21) | (0x0F) | OPC_CP2,
1127 OPC_SRA_CP2 = (26 << 21) | (0x0F) | OPC_CP2,
1128 OPC_DSRA_CP2 = (27 << 21) | (0x0F) | OPC_CP2,
1129 OPC_BIADD = (28 << 21) | (0x0F) | OPC_CP2,
1130 OPC_PMOVMSKB = (29 << 21) | (0x0F) | OPC_CP2,
1131};
1132
1133
e0c84da7
TS
1134#define MASK_CP3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
1135
1136enum {
1137 OPC_LWXC1 = 0x00 | OPC_CP3,
1138 OPC_LDXC1 = 0x01 | OPC_CP3,
1139 OPC_LUXC1 = 0x05 | OPC_CP3,
1140 OPC_SWXC1 = 0x08 | OPC_CP3,
1141 OPC_SDXC1 = 0x09 | OPC_CP3,
1142 OPC_SUXC1 = 0x0D | OPC_CP3,
1143 OPC_PREFX = 0x0F | OPC_CP3,
1144 OPC_ALNV_PS = 0x1E | OPC_CP3,
1145 OPC_MADD_S = 0x20 | OPC_CP3,
1146 OPC_MADD_D = 0x21 | OPC_CP3,
1147 OPC_MADD_PS = 0x26 | OPC_CP3,
1148 OPC_MSUB_S = 0x28 | OPC_CP3,
1149 OPC_MSUB_D = 0x29 | OPC_CP3,
1150 OPC_MSUB_PS = 0x2E | OPC_CP3,
1151 OPC_NMADD_S = 0x30 | OPC_CP3,
fbcc6828 1152 OPC_NMADD_D = 0x31 | OPC_CP3,
e0c84da7
TS
1153 OPC_NMADD_PS= 0x36 | OPC_CP3,
1154 OPC_NMSUB_S = 0x38 | OPC_CP3,
1155 OPC_NMSUB_D = 0x39 | OPC_CP3,
1156 OPC_NMSUB_PS= 0x3E | OPC_CP3,
1157};
1158
239dfebe
YK
1159/* MSA Opcodes */
1160#define MASK_MSA_MINOR(op) (MASK_OP_MAJOR(op) | (op & 0x3F))
1161enum {
1162 OPC_MSA_I8_00 = 0x00 | OPC_MSA,
1163 OPC_MSA_I8_01 = 0x01 | OPC_MSA,
1164 OPC_MSA_I8_02 = 0x02 | OPC_MSA,
1165 OPC_MSA_I5_06 = 0x06 | OPC_MSA,
1166 OPC_MSA_I5_07 = 0x07 | OPC_MSA,
1167 OPC_MSA_BIT_09 = 0x09 | OPC_MSA,
1168 OPC_MSA_BIT_0A = 0x0A | OPC_MSA,
1169 OPC_MSA_3R_0D = 0x0D | OPC_MSA,
1170 OPC_MSA_3R_0E = 0x0E | OPC_MSA,
1171 OPC_MSA_3R_0F = 0x0F | OPC_MSA,
1172 OPC_MSA_3R_10 = 0x10 | OPC_MSA,
1173 OPC_MSA_3R_11 = 0x11 | OPC_MSA,
1174 OPC_MSA_3R_12 = 0x12 | OPC_MSA,
1175 OPC_MSA_3R_13 = 0x13 | OPC_MSA,
1176 OPC_MSA_3R_14 = 0x14 | OPC_MSA,
1177 OPC_MSA_3R_15 = 0x15 | OPC_MSA,
1178 OPC_MSA_ELM = 0x19 | OPC_MSA,
1179 OPC_MSA_3RF_1A = 0x1A | OPC_MSA,
1180 OPC_MSA_3RF_1B = 0x1B | OPC_MSA,
1181 OPC_MSA_3RF_1C = 0x1C | OPC_MSA,
1182 OPC_MSA_VEC = 0x1E | OPC_MSA,
1183
1184 /* MI10 instruction */
1185 OPC_LD_B = (0x20) | OPC_MSA,
1186 OPC_LD_H = (0x21) | OPC_MSA,
1187 OPC_LD_W = (0x22) | OPC_MSA,
1188 OPC_LD_D = (0x23) | OPC_MSA,
1189 OPC_ST_B = (0x24) | OPC_MSA,
1190 OPC_ST_H = (0x25) | OPC_MSA,
1191 OPC_ST_W = (0x26) | OPC_MSA,
1192 OPC_ST_D = (0x27) | OPC_MSA,
1193};
1194
1195enum {
1196 /* I5 instruction df(bits 22..21) = _b, _h, _w, _d */
1197 OPC_ADDVI_df = (0x0 << 23) | OPC_MSA_I5_06,
1198 OPC_CEQI_df = (0x0 << 23) | OPC_MSA_I5_07,
1199 OPC_SUBVI_df = (0x1 << 23) | OPC_MSA_I5_06,
1200 OPC_MAXI_S_df = (0x2 << 23) | OPC_MSA_I5_06,
1201 OPC_CLTI_S_df = (0x2 << 23) | OPC_MSA_I5_07,
1202 OPC_MAXI_U_df = (0x3 << 23) | OPC_MSA_I5_06,
1203 OPC_CLTI_U_df = (0x3 << 23) | OPC_MSA_I5_07,
1204 OPC_MINI_S_df = (0x4 << 23) | OPC_MSA_I5_06,
1205 OPC_CLEI_S_df = (0x4 << 23) | OPC_MSA_I5_07,
1206 OPC_MINI_U_df = (0x5 << 23) | OPC_MSA_I5_06,
1207 OPC_CLEI_U_df = (0x5 << 23) | OPC_MSA_I5_07,
1208 OPC_LDI_df = (0x6 << 23) | OPC_MSA_I5_07,
1209
1210 /* I8 instruction */
1211 OPC_ANDI_B = (0x0 << 24) | OPC_MSA_I8_00,
1212 OPC_BMNZI_B = (0x0 << 24) | OPC_MSA_I8_01,
1213 OPC_SHF_B = (0x0 << 24) | OPC_MSA_I8_02,
1214 OPC_ORI_B = (0x1 << 24) | OPC_MSA_I8_00,
1215 OPC_BMZI_B = (0x1 << 24) | OPC_MSA_I8_01,
1216 OPC_SHF_H = (0x1 << 24) | OPC_MSA_I8_02,
1217 OPC_NORI_B = (0x2 << 24) | OPC_MSA_I8_00,
1218 OPC_BSELI_B = (0x2 << 24) | OPC_MSA_I8_01,
1219 OPC_SHF_W = (0x2 << 24) | OPC_MSA_I8_02,
1220 OPC_XORI_B = (0x3 << 24) | OPC_MSA_I8_00,
1221
1222 /* VEC/2R/2RF instruction */
1223 OPC_AND_V = (0x00 << 21) | OPC_MSA_VEC,
1224 OPC_OR_V = (0x01 << 21) | OPC_MSA_VEC,
1225 OPC_NOR_V = (0x02 << 21) | OPC_MSA_VEC,
1226 OPC_XOR_V = (0x03 << 21) | OPC_MSA_VEC,
1227 OPC_BMNZ_V = (0x04 << 21) | OPC_MSA_VEC,
1228 OPC_BMZ_V = (0x05 << 21) | OPC_MSA_VEC,
1229 OPC_BSEL_V = (0x06 << 21) | OPC_MSA_VEC,
1230
1231 OPC_MSA_2R = (0x18 << 21) | OPC_MSA_VEC,
1232 OPC_MSA_2RF = (0x19 << 21) | OPC_MSA_VEC,
1233
1234 /* 2R instruction df(bits 17..16) = _b, _h, _w, _d */
1235 OPC_FILL_df = (0x00 << 18) | OPC_MSA_2R,
1236 OPC_PCNT_df = (0x01 << 18) | OPC_MSA_2R,
1237 OPC_NLOC_df = (0x02 << 18) | OPC_MSA_2R,
1238 OPC_NLZC_df = (0x03 << 18) | OPC_MSA_2R,
1239
1240 /* 2RF instruction df(bit 16) = _w, _d */
1241 OPC_FCLASS_df = (0x00 << 17) | OPC_MSA_2RF,
1242 OPC_FTRUNC_S_df = (0x01 << 17) | OPC_MSA_2RF,
1243 OPC_FTRUNC_U_df = (0x02 << 17) | OPC_MSA_2RF,
1244 OPC_FSQRT_df = (0x03 << 17) | OPC_MSA_2RF,
1245 OPC_FRSQRT_df = (0x04 << 17) | OPC_MSA_2RF,
1246 OPC_FRCP_df = (0x05 << 17) | OPC_MSA_2RF,
1247 OPC_FRINT_df = (0x06 << 17) | OPC_MSA_2RF,
1248 OPC_FLOG2_df = (0x07 << 17) | OPC_MSA_2RF,
1249 OPC_FEXUPL_df = (0x08 << 17) | OPC_MSA_2RF,
1250 OPC_FEXUPR_df = (0x09 << 17) | OPC_MSA_2RF,
1251 OPC_FFQL_df = (0x0A << 17) | OPC_MSA_2RF,
1252 OPC_FFQR_df = (0x0B << 17) | OPC_MSA_2RF,
1253 OPC_FTINT_S_df = (0x0C << 17) | OPC_MSA_2RF,
1254 OPC_FTINT_U_df = (0x0D << 17) | OPC_MSA_2RF,
1255 OPC_FFINT_S_df = (0x0E << 17) | OPC_MSA_2RF,
1256 OPC_FFINT_U_df = (0x0F << 17) | OPC_MSA_2RF,
1257
1258 /* 3R instruction df(bits 22..21) = _b, _h, _w, d */
1259 OPC_SLL_df = (0x0 << 23) | OPC_MSA_3R_0D,
1260 OPC_ADDV_df = (0x0 << 23) | OPC_MSA_3R_0E,
1261 OPC_CEQ_df = (0x0 << 23) | OPC_MSA_3R_0F,
1262 OPC_ADD_A_df = (0x0 << 23) | OPC_MSA_3R_10,
1263 OPC_SUBS_S_df = (0x0 << 23) | OPC_MSA_3R_11,
1264 OPC_MULV_df = (0x0 << 23) | OPC_MSA_3R_12,
1265 OPC_DOTP_S_df = (0x0 << 23) | OPC_MSA_3R_13,
1266 OPC_SLD_df = (0x0 << 23) | OPC_MSA_3R_14,
1267 OPC_VSHF_df = (0x0 << 23) | OPC_MSA_3R_15,
1268 OPC_SRA_df = (0x1 << 23) | OPC_MSA_3R_0D,
1269 OPC_SUBV_df = (0x1 << 23) | OPC_MSA_3R_0E,
1270 OPC_ADDS_A_df = (0x1 << 23) | OPC_MSA_3R_10,
1271 OPC_SUBS_U_df = (0x1 << 23) | OPC_MSA_3R_11,
1272 OPC_MADDV_df = (0x1 << 23) | OPC_MSA_3R_12,
1273 OPC_DOTP_U_df = (0x1 << 23) | OPC_MSA_3R_13,
1274 OPC_SPLAT_df = (0x1 << 23) | OPC_MSA_3R_14,
1275 OPC_SRAR_df = (0x1 << 23) | OPC_MSA_3R_15,
1276 OPC_SRL_df = (0x2 << 23) | OPC_MSA_3R_0D,
1277 OPC_MAX_S_df = (0x2 << 23) | OPC_MSA_3R_0E,
1278 OPC_CLT_S_df = (0x2 << 23) | OPC_MSA_3R_0F,
1279 OPC_ADDS_S_df = (0x2 << 23) | OPC_MSA_3R_10,
1280 OPC_SUBSUS_U_df = (0x2 << 23) | OPC_MSA_3R_11,
1281 OPC_MSUBV_df = (0x2 << 23) | OPC_MSA_3R_12,
1282 OPC_DPADD_S_df = (0x2 << 23) | OPC_MSA_3R_13,
1283 OPC_PCKEV_df = (0x2 << 23) | OPC_MSA_3R_14,
1284 OPC_SRLR_df = (0x2 << 23) | OPC_MSA_3R_15,
1285 OPC_BCLR_df = (0x3 << 23) | OPC_MSA_3R_0D,
1286 OPC_MAX_U_df = (0x3 << 23) | OPC_MSA_3R_0E,
1287 OPC_CLT_U_df = (0x3 << 23) | OPC_MSA_3R_0F,
1288 OPC_ADDS_U_df = (0x3 << 23) | OPC_MSA_3R_10,
1289 OPC_SUBSUU_S_df = (0x3 << 23) | OPC_MSA_3R_11,
1290 OPC_DPADD_U_df = (0x3 << 23) | OPC_MSA_3R_13,
1291 OPC_PCKOD_df = (0x3 << 23) | OPC_MSA_3R_14,
1292 OPC_BSET_df = (0x4 << 23) | OPC_MSA_3R_0D,
1293 OPC_MIN_S_df = (0x4 << 23) | OPC_MSA_3R_0E,
1294 OPC_CLE_S_df = (0x4 << 23) | OPC_MSA_3R_0F,
1295 OPC_AVE_S_df = (0x4 << 23) | OPC_MSA_3R_10,
1296 OPC_ASUB_S_df = (0x4 << 23) | OPC_MSA_3R_11,
1297 OPC_DIV_S_df = (0x4 << 23) | OPC_MSA_3R_12,
1298 OPC_DPSUB_S_df = (0x4 << 23) | OPC_MSA_3R_13,
1299 OPC_ILVL_df = (0x4 << 23) | OPC_MSA_3R_14,
1300 OPC_HADD_S_df = (0x4 << 23) | OPC_MSA_3R_15,
1301 OPC_BNEG_df = (0x5 << 23) | OPC_MSA_3R_0D,
1302 OPC_MIN_U_df = (0x5 << 23) | OPC_MSA_3R_0E,
1303 OPC_CLE_U_df = (0x5 << 23) | OPC_MSA_3R_0F,
1304 OPC_AVE_U_df = (0x5 << 23) | OPC_MSA_3R_10,
1305 OPC_ASUB_U_df = (0x5 << 23) | OPC_MSA_3R_11,
1306 OPC_DIV_U_df = (0x5 << 23) | OPC_MSA_3R_12,
1307 OPC_DPSUB_U_df = (0x5 << 23) | OPC_MSA_3R_13,
1308 OPC_ILVR_df = (0x5 << 23) | OPC_MSA_3R_14,
1309 OPC_HADD_U_df = (0x5 << 23) | OPC_MSA_3R_15,
1310 OPC_BINSL_df = (0x6 << 23) | OPC_MSA_3R_0D,
1311 OPC_MAX_A_df = (0x6 << 23) | OPC_MSA_3R_0E,
1312 OPC_AVER_S_df = (0x6 << 23) | OPC_MSA_3R_10,
1313 OPC_MOD_S_df = (0x6 << 23) | OPC_MSA_3R_12,
1314 OPC_ILVEV_df = (0x6 << 23) | OPC_MSA_3R_14,
1315 OPC_HSUB_S_df = (0x6 << 23) | OPC_MSA_3R_15,
1316 OPC_BINSR_df = (0x7 << 23) | OPC_MSA_3R_0D,
1317 OPC_MIN_A_df = (0x7 << 23) | OPC_MSA_3R_0E,
1318 OPC_AVER_U_df = (0x7 << 23) | OPC_MSA_3R_10,
1319 OPC_MOD_U_df = (0x7 << 23) | OPC_MSA_3R_12,
1320 OPC_ILVOD_df = (0x7 << 23) | OPC_MSA_3R_14,
1321 OPC_HSUB_U_df = (0x7 << 23) | OPC_MSA_3R_15,
1322
1323 /* ELM instructions df(bits 21..16) = _b, _h, _w, _d */
1324 OPC_SLDI_df = (0x0 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1325 OPC_CTCMSA = (0x0 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1326 OPC_SPLATI_df = (0x1 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1327 OPC_CFCMSA = (0x1 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1328 OPC_COPY_S_df = (0x2 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1329 OPC_MOVE_V = (0x2 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1330 OPC_COPY_U_df = (0x3 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1331 OPC_INSERT_df = (0x4 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1332 OPC_INSVE_df = (0x5 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1333
1334 /* 3RF instruction _df(bit 21) = _w, _d */
1335 OPC_FCAF_df = (0x0 << 22) | OPC_MSA_3RF_1A,
1336 OPC_FADD_df = (0x0 << 22) | OPC_MSA_3RF_1B,
1337 OPC_FCUN_df = (0x1 << 22) | OPC_MSA_3RF_1A,
1338 OPC_FSUB_df = (0x1 << 22) | OPC_MSA_3RF_1B,
1339 OPC_FCOR_df = (0x1 << 22) | OPC_MSA_3RF_1C,
1340 OPC_FCEQ_df = (0x2 << 22) | OPC_MSA_3RF_1A,
1341 OPC_FMUL_df = (0x2 << 22) | OPC_MSA_3RF_1B,
1342 OPC_FCUNE_df = (0x2 << 22) | OPC_MSA_3RF_1C,
1343 OPC_FCUEQ_df = (0x3 << 22) | OPC_MSA_3RF_1A,
1344 OPC_FDIV_df = (0x3 << 22) | OPC_MSA_3RF_1B,
1345 OPC_FCNE_df = (0x3 << 22) | OPC_MSA_3RF_1C,
1346 OPC_FCLT_df = (0x4 << 22) | OPC_MSA_3RF_1A,
1347 OPC_FMADD_df = (0x4 << 22) | OPC_MSA_3RF_1B,
1348 OPC_MUL_Q_df = (0x4 << 22) | OPC_MSA_3RF_1C,
1349 OPC_FCULT_df = (0x5 << 22) | OPC_MSA_3RF_1A,
1350 OPC_FMSUB_df = (0x5 << 22) | OPC_MSA_3RF_1B,
1351 OPC_MADD_Q_df = (0x5 << 22) | OPC_MSA_3RF_1C,
1352 OPC_FCLE_df = (0x6 << 22) | OPC_MSA_3RF_1A,
1353 OPC_MSUB_Q_df = (0x6 << 22) | OPC_MSA_3RF_1C,
1354 OPC_FCULE_df = (0x7 << 22) | OPC_MSA_3RF_1A,
1355 OPC_FEXP2_df = (0x7 << 22) | OPC_MSA_3RF_1B,
1356 OPC_FSAF_df = (0x8 << 22) | OPC_MSA_3RF_1A,
1357 OPC_FEXDO_df = (0x8 << 22) | OPC_MSA_3RF_1B,
1358 OPC_FSUN_df = (0x9 << 22) | OPC_MSA_3RF_1A,
1359 OPC_FSOR_df = (0x9 << 22) | OPC_MSA_3RF_1C,
1360 OPC_FSEQ_df = (0xA << 22) | OPC_MSA_3RF_1A,
1361 OPC_FTQ_df = (0xA << 22) | OPC_MSA_3RF_1B,
1362 OPC_FSUNE_df = (0xA << 22) | OPC_MSA_3RF_1C,
1363 OPC_FSUEQ_df = (0xB << 22) | OPC_MSA_3RF_1A,
1364 OPC_FSNE_df = (0xB << 22) | OPC_MSA_3RF_1C,
1365 OPC_FSLT_df = (0xC << 22) | OPC_MSA_3RF_1A,
1366 OPC_FMIN_df = (0xC << 22) | OPC_MSA_3RF_1B,
1367 OPC_MULR_Q_df = (0xC << 22) | OPC_MSA_3RF_1C,
1368 OPC_FSULT_df = (0xD << 22) | OPC_MSA_3RF_1A,
1369 OPC_FMIN_A_df = (0xD << 22) | OPC_MSA_3RF_1B,
1370 OPC_MADDR_Q_df = (0xD << 22) | OPC_MSA_3RF_1C,
1371 OPC_FSLE_df = (0xE << 22) | OPC_MSA_3RF_1A,
1372 OPC_FMAX_df = (0xE << 22) | OPC_MSA_3RF_1B,
1373 OPC_MSUBR_Q_df = (0xE << 22) | OPC_MSA_3RF_1C,
1374 OPC_FSULE_df = (0xF << 22) | OPC_MSA_3RF_1A,
1375 OPC_FMAX_A_df = (0xF << 22) | OPC_MSA_3RF_1B,
1376
1377 /* BIT instruction df(bits 22..16) = _B _H _W _D */
1378 OPC_SLLI_df = (0x0 << 23) | OPC_MSA_BIT_09,
1379 OPC_SAT_S_df = (0x0 << 23) | OPC_MSA_BIT_0A,
1380 OPC_SRAI_df = (0x1 << 23) | OPC_MSA_BIT_09,
1381 OPC_SAT_U_df = (0x1 << 23) | OPC_MSA_BIT_0A,
1382 OPC_SRLI_df = (0x2 << 23) | OPC_MSA_BIT_09,
1383 OPC_SRARI_df = (0x2 << 23) | OPC_MSA_BIT_0A,
1384 OPC_BCLRI_df = (0x3 << 23) | OPC_MSA_BIT_09,
1385 OPC_SRLRI_df = (0x3 << 23) | OPC_MSA_BIT_0A,
1386 OPC_BSETI_df = (0x4 << 23) | OPC_MSA_BIT_09,
1387 OPC_BNEGI_df = (0x5 << 23) | OPC_MSA_BIT_09,
1388 OPC_BINSLI_df = (0x6 << 23) | OPC_MSA_BIT_09,
1389 OPC_BINSRI_df = (0x7 << 23) | OPC_MSA_BIT_09,
1390};
1391
39454628 1392/* global register indices */
a7812ae4 1393static TCGv cpu_gpr[32], cpu_PC;
340fff72 1394static TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC];
41db4607
AJ
1395static TCGv cpu_dspctrl, btarget, bcond;
1396static TCGv_i32 hflags;
a7812ae4 1397static TCGv_i32 fpu_fcr0, fpu_fcr31;
d73ee8a2 1398static TCGv_i64 fpu_f64[32];
863f264d 1399static TCGv_i64 msa_wr_d[64];
aa0bf00b 1400
022c62cb 1401#include "exec/gen-icount.h"
2e70f6ef 1402
895c2d04 1403#define gen_helper_0e0i(name, arg) do { \
a7812ae4 1404 TCGv_i32 helper_tmp = tcg_const_i32(arg); \
895c2d04 1405 gen_helper_##name(cpu_env, helper_tmp); \
a7812ae4
PB
1406 tcg_temp_free_i32(helper_tmp); \
1407 } while(0)
be24bb4f 1408
895c2d04 1409#define gen_helper_0e1i(name, arg1, arg2) do { \
a7812ae4 1410 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
895c2d04 1411 gen_helper_##name(cpu_env, arg1, helper_tmp); \
a7812ae4
PB
1412 tcg_temp_free_i32(helper_tmp); \
1413 } while(0)
be24bb4f 1414
895c2d04
BS
1415#define gen_helper_1e0i(name, ret, arg1) do { \
1416 TCGv_i32 helper_tmp = tcg_const_i32(arg1); \
1417 gen_helper_##name(ret, cpu_env, helper_tmp); \
1418 tcg_temp_free_i32(helper_tmp); \
1419 } while(0)
1420
1421#define gen_helper_1e1i(name, ret, arg1, arg2) do { \
1422 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
1423 gen_helper_##name(ret, cpu_env, arg1, helper_tmp); \
1424 tcg_temp_free_i32(helper_tmp); \
1425 } while(0)
1426
1427#define gen_helper_0e2i(name, arg1, arg2, arg3) do { \
1428 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
1429 gen_helper_##name(cpu_env, arg1, arg2, helper_tmp); \
1430 tcg_temp_free_i32(helper_tmp); \
1431 } while(0)
1432
1433#define gen_helper_1e2i(name, ret, arg1, arg2, arg3) do { \
a7812ae4 1434 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
895c2d04 1435 gen_helper_##name(ret, cpu_env, arg1, arg2, helper_tmp); \
a7812ae4
PB
1436 tcg_temp_free_i32(helper_tmp); \
1437 } while(0)
be24bb4f 1438
895c2d04 1439#define gen_helper_0e3i(name, arg1, arg2, arg3, arg4) do { \
a7812ae4 1440 TCGv_i32 helper_tmp = tcg_const_i32(arg4); \
895c2d04 1441 gen_helper_##name(cpu_env, arg1, arg2, arg3, helper_tmp); \
a7812ae4
PB
1442 tcg_temp_free_i32(helper_tmp); \
1443 } while(0)
c239529e 1444
8e9ade68 1445typedef struct DisasContext {
eeb3bba8
EC
1446 DisasContextBase base;
1447 target_ulong saved_pc;
18f440ed 1448 target_ulong page_start;
8e9ade68 1449 uint32_t opcode;
d75c135e 1450 int insn_flags;
5ab5c041 1451 int32_t CP0_Config1;
8e9ade68
TS
1452 /* Routine used to access memory */
1453 int mem_idx;
be3a8c53 1454 TCGMemOp default_tcg_memop_mask;
8e9ade68 1455 uint32_t hflags, saved_hflags;
8e9ade68 1456 target_ulong btarget;
d279279e 1457 bool ulri;
e98c0d17 1458 int kscrexist;
7207c7f9 1459 bool rxi;
9456c2fb 1460 int ie;
aea14095
LA
1461 bool bi;
1462 bool bp;
5204ea79
LA
1463 uint64_t PAMask;
1464 bool mvh;
76964147 1465 bool eva;
cec56a73 1466 bool sc;
5204ea79 1467 int CP0_LLAddr_shift;
e29c9628 1468 bool ps;
01bc435b 1469 bool vp;
c870e3f5 1470 bool cmgcr;
f6d4dd81 1471 bool mrp;
87552089 1472 bool nan2008;
6be77480 1473 bool abs2008;
8e9ade68
TS
1474} DisasContext;
1475
b28425ba
EC
1476#define DISAS_STOP DISAS_TARGET_0
1477#define DISAS_EXIT DISAS_TARGET_1
8e9ade68 1478
d73ee8a2
RH
1479static const char * const regnames[] = {
1480 "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
1481 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
1482 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
1483 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
1484};
6af0bf9c 1485
d73ee8a2
RH
1486static const char * const regnames_HI[] = {
1487 "HI0", "HI1", "HI2", "HI3",
1488};
4b2eb8d2 1489
d73ee8a2
RH
1490static const char * const regnames_LO[] = {
1491 "LO0", "LO1", "LO2", "LO3",
1492};
4b2eb8d2 1493
d73ee8a2
RH
1494static const char * const fregnames[] = {
1495 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
1496 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
1497 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
1498 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
1499};
958fb4a9 1500
863f264d
YK
1501static const char * const msaregnames[] = {
1502 "w0.d0", "w0.d1", "w1.d0", "w1.d1",
1503 "w2.d0", "w2.d1", "w3.d0", "w3.d1",
1504 "w4.d0", "w4.d1", "w5.d0", "w5.d1",
1505 "w6.d0", "w6.d1", "w7.d0", "w7.d1",
1506 "w8.d0", "w8.d1", "w9.d0", "w9.d1",
1507 "w10.d0", "w10.d1", "w11.d0", "w11.d1",
1508 "w12.d0", "w12.d1", "w13.d0", "w13.d1",
1509 "w14.d0", "w14.d1", "w15.d0", "w15.d1",
1510 "w16.d0", "w16.d1", "w17.d0", "w17.d1",
1511 "w18.d0", "w18.d1", "w19.d0", "w19.d1",
1512 "w20.d0", "w20.d1", "w21.d0", "w21.d1",
1513 "w22.d0", "w22.d1", "w23.d0", "w23.d1",
1514 "w24.d0", "w24.d1", "w25.d0", "w25.d1",
1515 "w26.d0", "w26.d1", "w27.d0", "w27.d1",
1516 "w28.d0", "w28.d1", "w29.d0", "w29.d1",
1517 "w30.d0", "w30.d1", "w31.d0", "w31.d1",
1518};
1519
9d68ac14 1520#define LOG_DISAS(...) \
fb7729e2
RH
1521 do { \
1522 if (MIPS_DEBUG_DISAS) { \
9d68ac14 1523 qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__); \
fb7729e2
RH
1524 } \
1525 } while (0)
1526
9d68ac14 1527#define MIPS_INVAL(op) \
fb7729e2
RH
1528 do { \
1529 if (MIPS_DEBUG_DISAS) { \
9d68ac14
AJ
1530 qemu_log_mask(CPU_LOG_TB_IN_ASM, \
1531 TARGET_FMT_lx ": %08x Invalid %s %03x %03x %03x\n", \
eeb3bba8
EC
1532 ctx->base.pc_next, ctx->opcode, op, \
1533 ctx->opcode >> 26, ctx->opcode & 0x3F, \
1534 ((ctx->opcode >> 16) & 0x1F)); \
fb7729e2
RH
1535 } \
1536 } while (0)
958fb4a9 1537
8e9ade68
TS
1538/* General purpose registers moves. */
1539static inline void gen_load_gpr (TCGv t, int reg)
aaa9128a 1540{
8e9ade68
TS
1541 if (reg == 0)
1542 tcg_gen_movi_tl(t, 0);
1543 else
4b2eb8d2 1544 tcg_gen_mov_tl(t, cpu_gpr[reg]);
aaa9128a
TS
1545}
1546
8e9ade68 1547static inline void gen_store_gpr (TCGv t, int reg)
aaa9128a 1548{
8e9ade68 1549 if (reg != 0)
4b2eb8d2 1550 tcg_gen_mov_tl(cpu_gpr[reg], t);
aaa9128a
TS
1551}
1552
8e9ade68 1553/* Moves to/from shadow registers. */
be24bb4f 1554static inline void gen_load_srsgpr (int from, int to)
aaa9128a 1555{
d9bea114 1556 TCGv t0 = tcg_temp_new();
be24bb4f
TS
1557
1558 if (from == 0)
d9bea114 1559 tcg_gen_movi_tl(t0, 0);
8e9ade68 1560 else {
d9bea114 1561 TCGv_i32 t2 = tcg_temp_new_i32();
a7812ae4 1562 TCGv_ptr addr = tcg_temp_new_ptr();
aaa9128a 1563
7db13fae 1564 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
d9bea114
AJ
1565 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1566 tcg_gen_andi_i32(t2, t2, 0xf);
1567 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1568 tcg_gen_ext_i32_ptr(addr, t2);
a7812ae4 1569 tcg_gen_add_ptr(addr, cpu_env, addr);
aaa9128a 1570
d9bea114 1571 tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from);
a7812ae4 1572 tcg_temp_free_ptr(addr);
d9bea114 1573 tcg_temp_free_i32(t2);
8e9ade68 1574 }
d9bea114
AJ
1575 gen_store_gpr(t0, to);
1576 tcg_temp_free(t0);
aaa9128a
TS
1577}
1578
be24bb4f 1579static inline void gen_store_srsgpr (int from, int to)
aaa9128a 1580{
be24bb4f 1581 if (to != 0) {
d9bea114
AJ
1582 TCGv t0 = tcg_temp_new();
1583 TCGv_i32 t2 = tcg_temp_new_i32();
a7812ae4 1584 TCGv_ptr addr = tcg_temp_new_ptr();
be24bb4f 1585
d9bea114 1586 gen_load_gpr(t0, from);
7db13fae 1587 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
d9bea114
AJ
1588 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1589 tcg_gen_andi_i32(t2, t2, 0xf);
1590 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1591 tcg_gen_ext_i32_ptr(addr, t2);
a7812ae4 1592 tcg_gen_add_ptr(addr, cpu_env, addr);
be24bb4f 1593
d9bea114 1594 tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to);
a7812ae4 1595 tcg_temp_free_ptr(addr);
d9bea114
AJ
1596 tcg_temp_free_i32(t2);
1597 tcg_temp_free(t0);
8e9ade68 1598 }
aaa9128a
TS
1599}
1600
eab9944c
LA
1601/* Tests */
1602static inline void gen_save_pc(target_ulong pc)
1603{
1604 tcg_gen_movi_tl(cpu_PC, pc);
1605}
1606
1607static inline void save_cpu_state(DisasContext *ctx, int do_save_pc)
1608{
1609 LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
eeb3bba8
EC
1610 if (do_save_pc && ctx->base.pc_next != ctx->saved_pc) {
1611 gen_save_pc(ctx->base.pc_next);
1612 ctx->saved_pc = ctx->base.pc_next;
eab9944c
LA
1613 }
1614 if (ctx->hflags != ctx->saved_hflags) {
1615 tcg_gen_movi_i32(hflags, ctx->hflags);
1616 ctx->saved_hflags = ctx->hflags;
1617 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
1618 case MIPS_HFLAG_BR:
1619 break;
1620 case MIPS_HFLAG_BC:
1621 case MIPS_HFLAG_BL:
1622 case MIPS_HFLAG_B:
1623 tcg_gen_movi_tl(btarget, ctx->btarget);
1624 break;
1625 }
1626 }
1627}
1628
1629static inline void restore_cpu_state(CPUMIPSState *env, DisasContext *ctx)
1630{
1631 ctx->saved_hflags = ctx->hflags;
1632 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
1633 case MIPS_HFLAG_BR:
1634 break;
1635 case MIPS_HFLAG_BC:
1636 case MIPS_HFLAG_BL:
1637 case MIPS_HFLAG_B:
1638 ctx->btarget = env->btarget;
1639 break;
1640 }
1641}
1642
1643static inline void generate_exception_err(DisasContext *ctx, int excp, int err)
1644{
1645 TCGv_i32 texcp = tcg_const_i32(excp);
1646 TCGv_i32 terr = tcg_const_i32(err);
1647 save_cpu_state(ctx, 1);
1648 gen_helper_raise_exception_err(cpu_env, texcp, terr);
1649 tcg_temp_free_i32(terr);
1650 tcg_temp_free_i32(texcp);
eeb3bba8 1651 ctx->base.is_jmp = DISAS_NORETURN;
eab9944c
LA
1652}
1653
1654static inline void generate_exception(DisasContext *ctx, int excp)
1655{
eab9944c
LA
1656 gen_helper_0e0i(raise_exception, excp);
1657}
1658
9c708c7f
PD
1659static inline void generate_exception_end(DisasContext *ctx, int excp)
1660{
1661 generate_exception_err(ctx, excp, 0);
1662}
1663
aaa9128a 1664/* Floating point register moves. */
7c979afd 1665static void gen_load_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
aa0bf00b 1666{
7c979afd
LA
1667 if (ctx->hflags & MIPS_HFLAG_FRE) {
1668 generate_exception(ctx, EXCP_RI);
1669 }
ecc7b3aa 1670 tcg_gen_extrl_i64_i32(t, fpu_f64[reg]);
6ea83fed
FB
1671}
1672
7c979afd 1673static void gen_store_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
aa0bf00b 1674{
7c979afd
LA
1675 TCGv_i64 t64;
1676 if (ctx->hflags & MIPS_HFLAG_FRE) {
1677 generate_exception(ctx, EXCP_RI);
1678 }
1679 t64 = tcg_temp_new_i64();
d73ee8a2
RH
1680 tcg_gen_extu_i32_i64(t64, t);
1681 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 0, 32);
1682 tcg_temp_free_i64(t64);
6d066274
AJ
1683}
1684
7f6613ce 1685static void gen_load_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
6d066274 1686{
7f6613ce 1687 if (ctx->hflags & MIPS_HFLAG_F64) {
71f303cd 1688 tcg_gen_extrh_i64_i32(t, fpu_f64[reg]);
7f6613ce 1689 } else {
7c979afd 1690 gen_load_fpr32(ctx, t, reg | 1);
7f6613ce 1691 }
6d066274
AJ
1692}
1693
7f6613ce 1694static void gen_store_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
6d066274 1695{
7f6613ce
PJ
1696 if (ctx->hflags & MIPS_HFLAG_F64) {
1697 TCGv_i64 t64 = tcg_temp_new_i64();
1698 tcg_gen_extu_i32_i64(t64, t);
1699 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 32, 32);
1700 tcg_temp_free_i64(t64);
1701 } else {
7c979afd 1702 gen_store_fpr32(ctx, t, reg | 1);
7f6613ce 1703 }
aa0bf00b 1704}
6ea83fed 1705
d73ee8a2 1706static void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
aa0bf00b 1707{
f364515c 1708 if (ctx->hflags & MIPS_HFLAG_F64) {
d73ee8a2 1709 tcg_gen_mov_i64(t, fpu_f64[reg]);
f364515c 1710 } else {
d73ee8a2 1711 tcg_gen_concat32_i64(t, fpu_f64[reg & ~1], fpu_f64[reg | 1]);
aa0bf00b
TS
1712 }
1713}
6ea83fed 1714
d73ee8a2 1715static void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
aa0bf00b 1716{
f364515c 1717 if (ctx->hflags & MIPS_HFLAG_F64) {
d73ee8a2 1718 tcg_gen_mov_i64(fpu_f64[reg], t);
f364515c 1719 } else {
d73ee8a2
RH
1720 TCGv_i64 t0;
1721 tcg_gen_deposit_i64(fpu_f64[reg & ~1], fpu_f64[reg & ~1], t, 0, 32);
1722 t0 = tcg_temp_new_i64();
6d066274 1723 tcg_gen_shri_i64(t0, t, 32);
d73ee8a2 1724 tcg_gen_deposit_i64(fpu_f64[reg | 1], fpu_f64[reg | 1], t0, 0, 32);
6d066274 1725 tcg_temp_free_i64(t0);
aa0bf00b
TS
1726 }
1727}
6ea83fed 1728
d94536f4 1729static inline int get_fp_bit (int cc)
a16336e4 1730{
d94536f4
AJ
1731 if (cc)
1732 return 24 + cc;
1733 else
1734 return 23;
a16336e4
TS
1735}
1736
48d38ca5 1737/* Addresses computation */
941694d0 1738static inline void gen_op_addr_add (DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1)
4ad40f36 1739{
941694d0 1740 tcg_gen_add_tl(ret, arg0, arg1);
48d38ca5
TS
1741
1742#if defined(TARGET_MIPS64)
01f72885 1743 if (ctx->hflags & MIPS_HFLAG_AWRAP) {
941694d0 1744 tcg_gen_ext32s_i64(ret, ret);
48d38ca5
TS
1745 }
1746#endif
4ad40f36
FB
1747}
1748
31837be3
YK
1749/* Addresses computation (translation time) */
1750static target_long addr_add(DisasContext *ctx, target_long base,
1751 target_long offset)
1752{
1753 target_long sum = base + offset;
1754
1755#if defined(TARGET_MIPS64)
1756 if (ctx->hflags & MIPS_HFLAG_AWRAP) {
1757 sum = (int32_t)sum;
1758 }
1759#endif
1760 return sum;
1761}
1762
71f303cd 1763/* Sign-extract the low 32-bits to a target_long. */
1f1b4c00
YK
1764static inline void gen_move_low32(TCGv ret, TCGv_i64 arg)
1765{
1766#if defined(TARGET_MIPS64)
71f303cd
RH
1767 tcg_gen_ext32s_i64(ret, arg);
1768#else
1769 tcg_gen_extrl_i64_i32(ret, arg);
1770#endif
1771}
1772
1773/* Sign-extract the high 32-bits to a target_long. */
1774static inline void gen_move_high32(TCGv ret, TCGv_i64 arg)
1775{
1776#if defined(TARGET_MIPS64)
1777 tcg_gen_sari_i64(ret, arg, 32);
1f1b4c00 1778#else
71f303cd 1779 tcg_gen_extrh_i64_i32(ret, arg);
1f1b4c00
YK
1780#endif
1781}
1782
356265ae 1783static inline void check_cp0_enabled(DisasContext *ctx)
387a8fe5 1784{
fe253235 1785 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
c2c65dab 1786 generate_exception_err(ctx, EXCP_CpU, 0);
387a8fe5
TS
1787}
1788
356265ae 1789static inline void check_cp1_enabled(DisasContext *ctx)
5e755519 1790{
fe253235 1791 if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
5e755519
TS
1792 generate_exception_err(ctx, EXCP_CpU, 1);
1793}
1794
b8aa4598
TS
1795/* Verify that the processor is running with COP1X instructions enabled.
1796 This is associated with the nabla symbol in the MIPS32 and MIPS64
1797 opcode tables. */
1798
356265ae 1799static inline void check_cop1x(DisasContext *ctx)
b8aa4598
TS
1800{
1801 if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
9c708c7f 1802 generate_exception_end(ctx, EXCP_RI);
b8aa4598
TS
1803}
1804
1805/* Verify that the processor is running with 64-bit floating-point
1806 operations enabled. */
1807
356265ae 1808static inline void check_cp1_64bitmode(DisasContext *ctx)
5e755519 1809{
b8aa4598 1810 if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
9c708c7f 1811 generate_exception_end(ctx, EXCP_RI);
5e755519
TS
1812}
1813
1814/*
1815 * Verify if floating point register is valid; an operation is not defined
1816 * if bit 0 of any register specification is set and the FR bit in the
1817 * Status register equals zero, since the register numbers specify an
1818 * even-odd pair of adjacent coprocessor general registers. When the FR bit
1819 * in the Status register equals one, both even and odd register numbers
1820 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
1821 *
1822 * Multiple 64 bit wide registers can be checked by calling
1823 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
1824 */
356265ae 1825static inline void check_cp1_registers(DisasContext *ctx, int regs)
5e755519 1826{
fe253235 1827 if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)))
9c708c7f 1828 generate_exception_end(ctx, EXCP_RI);
5e755519
TS
1829}
1830
853c3240
JL
1831/* Verify that the processor is running with DSP instructions enabled.
1832 This is enabled by CP0 Status register MX(24) bit.
1833 */
1834
1835static inline void check_dsp(DisasContext *ctx)
1836{
1837 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP))) {
ad153f15 1838 if (ctx->insn_flags & ASE_DSP) {
9c708c7f 1839 generate_exception_end(ctx, EXCP_DSPDIS);
ad153f15 1840 } else {
9c708c7f 1841 generate_exception_end(ctx, EXCP_RI);
ad153f15 1842 }
853c3240
JL
1843 }
1844}
1845
1846static inline void check_dspr2(DisasContext *ctx)
1847{
1848 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSPR2))) {
ad153f15 1849 if (ctx->insn_flags & ASE_DSP) {
9c708c7f 1850 generate_exception_end(ctx, EXCP_DSPDIS);
ad153f15 1851 } else {
9c708c7f 1852 generate_exception_end(ctx, EXCP_RI);
ad153f15 1853 }
853c3240
JL
1854 }
1855}
1856
3a95e3a7 1857/* This code generates a "reserved instruction" exception if the
e189e748 1858 CPU does not support the instruction set corresponding to flags. */
d75c135e 1859static inline void check_insn(DisasContext *ctx, int flags)
3a95e3a7 1860{
d75c135e 1861 if (unlikely(!(ctx->insn_flags & flags))) {
9c708c7f 1862 generate_exception_end(ctx, EXCP_RI);
d75c135e 1863 }
3a95e3a7
TS
1864}
1865
fecd2646
LA
1866/* This code generates a "reserved instruction" exception if the
1867 CPU has corresponding flag set which indicates that the instruction
1868 has been removed. */
1869static inline void check_insn_opc_removed(DisasContext *ctx, int flags)
1870{
1871 if (unlikely(ctx->insn_flags & flags)) {
9c708c7f 1872 generate_exception_end(ctx, EXCP_RI);
fecd2646
LA
1873 }
1874}
1875
e29c9628
YK
1876/* This code generates a "reserved instruction" exception if the
1877 CPU does not support 64-bit paired-single (PS) floating point data type */
1878static inline void check_ps(DisasContext *ctx)
1879{
1880 if (unlikely(!ctx->ps)) {
1881 generate_exception(ctx, EXCP_RI);
1882 }
1883 check_cp1_64bitmode(ctx);
1884}
1885
c7986fd6 1886#ifdef TARGET_MIPS64
e189e748
TS
1887/* This code generates a "reserved instruction" exception if 64-bit
1888 instructions are not enabled. */
356265ae 1889static inline void check_mips_64(DisasContext *ctx)
e189e748 1890{
fe253235 1891 if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
9c708c7f 1892 generate_exception_end(ctx, EXCP_RI);
e189e748 1893}
c7986fd6 1894#endif
e189e748 1895
5204ea79
LA
1896#ifndef CONFIG_USER_ONLY
1897static inline void check_mvh(DisasContext *ctx)
1898{
1899 if (unlikely(!ctx->mvh)) {
1900 generate_exception(ctx, EXCP_RI);
1901 }
1902}
1903#endif
1904
8153667c
NF
1905/* Define small wrappers for gen_load_fpr* so that we have a uniform
1906 calling interface for 32 and 64-bit FPRs. No sense in changing
1907 all callers for gen_load_fpr32 when we need the CTX parameter for
1908 this one use. */
7c979afd 1909#define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(ctx, x, y)
8153667c
NF
1910#define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
1911#define FOP_CONDS(type, abs, fmt, ifmt, bits) \
1912static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \
1913 int ft, int fs, int cc) \
1914{ \
1915 TCGv_i##bits fp0 = tcg_temp_new_i##bits (); \
1916 TCGv_i##bits fp1 = tcg_temp_new_i##bits (); \
1917 switch (ifmt) { \
1918 case FMT_PS: \
e29c9628 1919 check_ps(ctx); \
8153667c
NF
1920 break; \
1921 case FMT_D: \
1922 if (abs) { \
1923 check_cop1x(ctx); \
1924 } \
1925 check_cp1_registers(ctx, fs | ft); \
1926 break; \
1927 case FMT_S: \
1928 if (abs) { \
1929 check_cop1x(ctx); \
1930 } \
1931 break; \
1932 } \
1933 gen_ldcmp_fpr##bits (ctx, fp0, fs); \
1934 gen_ldcmp_fpr##bits (ctx, fp1, ft); \
1935 switch (n) { \
895c2d04
BS
1936 case 0: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc); break;\
1937 case 1: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc); break;\
1938 case 2: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc); break;\
1939 case 3: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc); break;\
1940 case 4: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc); break;\
1941 case 5: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc); break;\
1942 case 6: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc); break;\
1943 case 7: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc); break;\
1944 case 8: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc); break;\
1945 case 9: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); break;\
1946 case 10: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc); break;\
1947 case 11: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc); break;\
1948 case 12: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc); break;\
1949 case 13: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc); break;\
1950 case 14: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc); break;\
1951 case 15: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc); break;\
8153667c
NF
1952 default: abort(); \
1953 } \
1954 tcg_temp_free_i##bits (fp0); \
1955 tcg_temp_free_i##bits (fp1); \
1956}
1957
1958FOP_CONDS(, 0, d, FMT_D, 64)
1959FOP_CONDS(abs, 1, d, FMT_D, 64)
1960FOP_CONDS(, 0, s, FMT_S, 32)
1961FOP_CONDS(abs, 1, s, FMT_S, 32)
1962FOP_CONDS(, 0, ps, FMT_PS, 64)
1963FOP_CONDS(abs, 1, ps, FMT_PS, 64)
1964#undef FOP_CONDS
3f493883
YK
1965
1966#define FOP_CONDNS(fmt, ifmt, bits, STORE) \
1967static inline void gen_r6_cmp_ ## fmt(DisasContext * ctx, int n, \
1968 int ft, int fs, int fd) \
1969{ \
1970 TCGv_i ## bits fp0 = tcg_temp_new_i ## bits(); \
1971 TCGv_i ## bits fp1 = tcg_temp_new_i ## bits(); \
00fb4a11 1972 if (ifmt == FMT_D) { \
3f493883 1973 check_cp1_registers(ctx, fs | ft | fd); \
3f493883
YK
1974 } \
1975 gen_ldcmp_fpr ## bits(ctx, fp0, fs); \
1976 gen_ldcmp_fpr ## bits(ctx, fp1, ft); \
1977 switch (n) { \
1978 case 0: \
1979 gen_helper_r6_cmp_ ## fmt ## _af(fp0, cpu_env, fp0, fp1); \
1980 break; \
1981 case 1: \
1982 gen_helper_r6_cmp_ ## fmt ## _un(fp0, cpu_env, fp0, fp1); \
1983 break; \
1984 case 2: \
1985 gen_helper_r6_cmp_ ## fmt ## _eq(fp0, cpu_env, fp0, fp1); \
1986 break; \
1987 case 3: \
1988 gen_helper_r6_cmp_ ## fmt ## _ueq(fp0, cpu_env, fp0, fp1); \
1989 break; \
1990 case 4: \
1991 gen_helper_r6_cmp_ ## fmt ## _lt(fp0, cpu_env, fp0, fp1); \
1992 break; \
1993 case 5: \
1994 gen_helper_r6_cmp_ ## fmt ## _ult(fp0, cpu_env, fp0, fp1); \
1995 break; \
1996 case 6: \
1997 gen_helper_r6_cmp_ ## fmt ## _le(fp0, cpu_env, fp0, fp1); \
1998 break; \
1999 case 7: \
2000 gen_helper_r6_cmp_ ## fmt ## _ule(fp0, cpu_env, fp0, fp1); \
2001 break; \
2002 case 8: \
2003 gen_helper_r6_cmp_ ## fmt ## _saf(fp0, cpu_env, fp0, fp1); \
2004 break; \
2005 case 9: \
2006 gen_helper_r6_cmp_ ## fmt ## _sun(fp0, cpu_env, fp0, fp1); \
2007 break; \
2008 case 10: \
2009 gen_helper_r6_cmp_ ## fmt ## _seq(fp0, cpu_env, fp0, fp1); \
2010 break; \
2011 case 11: \
2012 gen_helper_r6_cmp_ ## fmt ## _sueq(fp0, cpu_env, fp0, fp1); \
2013 break; \
2014 case 12: \
2015 gen_helper_r6_cmp_ ## fmt ## _slt(fp0, cpu_env, fp0, fp1); \
2016 break; \
2017 case 13: \
2018 gen_helper_r6_cmp_ ## fmt ## _sult(fp0, cpu_env, fp0, fp1); \
2019 break; \
2020 case 14: \
2021 gen_helper_r6_cmp_ ## fmt ## _sle(fp0, cpu_env, fp0, fp1); \
2022 break; \
2023 case 15: \
2024 gen_helper_r6_cmp_ ## fmt ## _sule(fp0, cpu_env, fp0, fp1); \
2025 break; \
2026 case 17: \
2027 gen_helper_r6_cmp_ ## fmt ## _or(fp0, cpu_env, fp0, fp1); \
2028 break; \
2029 case 18: \
2030 gen_helper_r6_cmp_ ## fmt ## _une(fp0, cpu_env, fp0, fp1); \
2031 break; \
2032 case 19: \
2033 gen_helper_r6_cmp_ ## fmt ## _ne(fp0, cpu_env, fp0, fp1); \
2034 break; \
2035 case 25: \
2036 gen_helper_r6_cmp_ ## fmt ## _sor(fp0, cpu_env, fp0, fp1); \
2037 break; \
2038 case 26: \
2039 gen_helper_r6_cmp_ ## fmt ## _sune(fp0, cpu_env, fp0, fp1); \
2040 break; \
2041 case 27: \
2042 gen_helper_r6_cmp_ ## fmt ## _sne(fp0, cpu_env, fp0, fp1); \
2043 break; \
2044 default: \
2045 abort(); \
2046 } \
2047 STORE; \
2048 tcg_temp_free_i ## bits (fp0); \
2049 tcg_temp_free_i ## bits (fp1); \
2050}
2051
2052FOP_CONDNS(d, FMT_D, 64, gen_store_fpr64(ctx, fp0, fd))
7c979afd 2053FOP_CONDNS(s, FMT_S, 32, gen_store_fpr32(ctx, fp0, fd))
3f493883 2054#undef FOP_CONDNS
8153667c
NF
2055#undef gen_ldcmp_fpr32
2056#undef gen_ldcmp_fpr64
2057
958fb4a9 2058/* load/store instructions. */
e7139c44 2059#ifdef CONFIG_USER_ONLY
d9bea114 2060#define OP_LD_ATOMIC(insn,fname) \
dd4096cd
JH
2061static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx, \
2062 DisasContext *ctx) \
d9bea114
AJ
2063{ \
2064 TCGv t0 = tcg_temp_new(); \
2065 tcg_gen_mov_tl(t0, arg1); \
2066 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
7db13fae
AF
2067 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
2068 tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval)); \
d9bea114 2069 tcg_temp_free(t0); \
aaa9128a 2070}
e7139c44
AJ
2071#else
2072#define OP_LD_ATOMIC(insn,fname) \
dd4096cd
JH
2073static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx, \
2074 DisasContext *ctx) \
e7139c44 2075{ \
dd4096cd 2076 gen_helper_1e1i(insn, ret, arg1, mem_idx); \
e7139c44
AJ
2077}
2078#endif
aaa9128a
TS
2079OP_LD_ATOMIC(ll,ld32s);
2080#if defined(TARGET_MIPS64)
2081OP_LD_ATOMIC(lld,ld64);
2082#endif
2083#undef OP_LD_ATOMIC
2084
590bc601
PB
2085#ifdef CONFIG_USER_ONLY
2086#define OP_ST_ATOMIC(insn,fname,ldname,almask) \
dd4096cd
JH
2087static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, int mem_idx, \
2088 DisasContext *ctx) \
590bc601
PB
2089{ \
2090 TCGv t0 = tcg_temp_new(); \
42a268c2
RH
2091 TCGLabel *l1 = gen_new_label(); \
2092 TCGLabel *l2 = gen_new_label(); \
590bc601
PB
2093 \
2094 tcg_gen_andi_tl(t0, arg2, almask); \
2095 tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1); \
7db13fae 2096 tcg_gen_st_tl(arg2, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr)); \
590bc601
PB
2097 generate_exception(ctx, EXCP_AdES); \
2098 gen_set_label(l1); \
7db13fae 2099 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
590bc601
PB
2100 tcg_gen_brcond_tl(TCG_COND_NE, arg2, t0, l2); \
2101 tcg_gen_movi_tl(t0, rt | ((almask << 3) & 0x20)); \
7db13fae
AF
2102 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, llreg)); \
2103 tcg_gen_st_tl(arg1, cpu_env, offsetof(CPUMIPSState, llnewval)); \
9c708c7f 2104 generate_exception_end(ctx, EXCP_SC); \
590bc601
PB
2105 gen_set_label(l2); \
2106 tcg_gen_movi_tl(t0, 0); \
2107 gen_store_gpr(t0, rt); \
2108 tcg_temp_free(t0); \
2109}
2110#else
2111#define OP_ST_ATOMIC(insn,fname,ldname,almask) \
dd4096cd
JH
2112static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, int mem_idx, \
2113 DisasContext *ctx) \
590bc601
PB
2114{ \
2115 TCGv t0 = tcg_temp_new(); \
dd4096cd 2116 gen_helper_1e2i(insn, t0, arg1, arg2, mem_idx); \
590bc601 2117 gen_store_gpr(t0, rt); \
590bc601
PB
2118 tcg_temp_free(t0); \
2119}
2120#endif
590bc601 2121OP_ST_ATOMIC(sc,st32,ld32s,0x3);
aaa9128a 2122#if defined(TARGET_MIPS64)
590bc601 2123OP_ST_ATOMIC(scd,st64,ld64,0x7);
aaa9128a
TS
2124#endif
2125#undef OP_ST_ATOMIC
2126
662d7485 2127static void gen_base_offset_addr (DisasContext *ctx, TCGv addr,
72e1f16f 2128 int base, int offset)
662d7485
NF
2129{
2130 if (base == 0) {
2131 tcg_gen_movi_tl(addr, offset);
2132 } else if (offset == 0) {
2133 gen_load_gpr(addr, base);
2134 } else {
2135 tcg_gen_movi_tl(addr, offset);
2136 gen_op_addr_add(ctx, addr, cpu_gpr[base], addr);
2137 }
2138}
2139
364d4831
NF
2140static target_ulong pc_relative_pc (DisasContext *ctx)
2141{
eeb3bba8 2142 target_ulong pc = ctx->base.pc_next;
364d4831
NF
2143
2144 if (ctx->hflags & MIPS_HFLAG_BMASK) {
2145 int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
2146
2147 pc -= branch_bytes;
2148 }
2149
2150 pc &= ~(target_ulong)3;
2151 return pc;
2152}
2153
5c13fdfd 2154/* Load */
d75c135e 2155static void gen_ld(DisasContext *ctx, uint32_t opc,
72e1f16f 2156 int rt, int base, int offset)
6af0bf9c 2157{
fc40787a 2158 TCGv t0, t1, t2;
dd4096cd 2159 int mem_idx = ctx->mem_idx;
afa88c3a 2160
d75c135e 2161 if (rt == 0 && ctx->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)) {
afa88c3a
AJ
2162 /* Loongson CPU uses a load to zero register for prefetch.
2163 We emulate it as a NOP. On other CPU we must perform the
2164 actual memory access. */
afa88c3a
AJ
2165 return;
2166 }
6af0bf9c 2167
afa88c3a 2168 t0 = tcg_temp_new();
662d7485 2169 gen_base_offset_addr(ctx, t0, base, offset);
afa88c3a 2170
6af0bf9c 2171 switch (opc) {
d26bc211 2172#if defined(TARGET_MIPS64)
6e473128 2173 case OPC_LWU:
dd4096cd 2174 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL |
be3a8c53 2175 ctx->default_tcg_memop_mask);
78723684 2176 gen_store_gpr(t0, rt);
6e473128 2177 break;
6af0bf9c 2178 case OPC_LD:
dd4096cd 2179 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ |
be3a8c53 2180 ctx->default_tcg_memop_mask);
78723684 2181 gen_store_gpr(t0, rt);
6af0bf9c 2182 break;
7a387fff 2183 case OPC_LLD:
bf7910c6 2184 case R6_OPC_LLD:
dd4096cd 2185 op_ld_lld(t0, t0, mem_idx, ctx);
78723684 2186 gen_store_gpr(t0, rt);
7a387fff 2187 break;
6af0bf9c 2188 case OPC_LDL:
3cee3050 2189 t1 = tcg_temp_new();
908680c6
AJ
2190 /* Do a byte access to possibly trigger a page
2191 fault with the unaligned address. */
dd4096cd 2192 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
fc40787a
AJ
2193 tcg_gen_andi_tl(t1, t0, 7);
2194#ifndef TARGET_WORDS_BIGENDIAN
2195 tcg_gen_xori_tl(t1, t1, 7);
2196#endif
2197 tcg_gen_shli_tl(t1, t1, 3);
2198 tcg_gen_andi_tl(t0, t0, ~7);
dd4096cd 2199 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
fc40787a 2200 tcg_gen_shl_tl(t0, t0, t1);
eb02cc3f
AJ
2201 t2 = tcg_const_tl(-1);
2202 tcg_gen_shl_tl(t2, t2, t1);
78723684 2203 gen_load_gpr(t1, rt);
eb02cc3f 2204 tcg_gen_andc_tl(t1, t1, t2);
fc40787a
AJ
2205 tcg_temp_free(t2);
2206 tcg_gen_or_tl(t0, t0, t1);
3cee3050 2207 tcg_temp_free(t1);
fc40787a 2208 gen_store_gpr(t0, rt);
6af0bf9c 2209 break;
6af0bf9c 2210 case OPC_LDR:
3cee3050 2211 t1 = tcg_temp_new();
908680c6
AJ
2212 /* Do a byte access to possibly trigger a page
2213 fault with the unaligned address. */
dd4096cd 2214 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
fc40787a
AJ
2215 tcg_gen_andi_tl(t1, t0, 7);
2216#ifdef TARGET_WORDS_BIGENDIAN
2217 tcg_gen_xori_tl(t1, t1, 7);
2218#endif
2219 tcg_gen_shli_tl(t1, t1, 3);
2220 tcg_gen_andi_tl(t0, t0, ~7);
dd4096cd 2221 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
fc40787a
AJ
2222 tcg_gen_shr_tl(t0, t0, t1);
2223 tcg_gen_xori_tl(t1, t1, 63);
2224 t2 = tcg_const_tl(0xfffffffffffffffeull);
2225 tcg_gen_shl_tl(t2, t2, t1);
78723684 2226 gen_load_gpr(t1, rt);
fc40787a
AJ
2227 tcg_gen_and_tl(t1, t1, t2);
2228 tcg_temp_free(t2);
2229 tcg_gen_or_tl(t0, t0, t1);
3cee3050 2230 tcg_temp_free(t1);
fc40787a 2231 gen_store_gpr(t0, rt);
6af0bf9c 2232 break;
364d4831 2233 case OPC_LDPC:
3cee3050 2234 t1 = tcg_const_tl(pc_relative_pc(ctx));
364d4831 2235 gen_op_addr_add(ctx, t0, t0, t1);
3cee3050 2236 tcg_temp_free(t1);
dd4096cd 2237 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
364d4831
NF
2238 gen_store_gpr(t0, rt);
2239 break;
6af0bf9c 2240#endif
364d4831 2241 case OPC_LWPC:
3cee3050 2242 t1 = tcg_const_tl(pc_relative_pc(ctx));
364d4831 2243 gen_op_addr_add(ctx, t0, t0, t1);
3cee3050 2244 tcg_temp_free(t1);
dd4096cd 2245 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESL);
364d4831
NF
2246 gen_store_gpr(t0, rt);
2247 break;
76964147
JH
2248 case OPC_LWE:
2249 mem_idx = MIPS_HFLAG_UM;
2250 /* fall through */
6af0bf9c 2251 case OPC_LW:
dd4096cd 2252 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESL |
be3a8c53 2253 ctx->default_tcg_memop_mask);
78723684 2254 gen_store_gpr(t0, rt);
6af0bf9c 2255 break;
76964147
JH
2256 case OPC_LHE:
2257 mem_idx = MIPS_HFLAG_UM;
2258 /* fall through */
6af0bf9c 2259 case OPC_LH:
dd4096cd 2260 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESW |
be3a8c53 2261 ctx->default_tcg_memop_mask);
78723684 2262 gen_store_gpr(t0, rt);
6af0bf9c 2263 break;
76964147
JH
2264 case OPC_LHUE:
2265 mem_idx = MIPS_HFLAG_UM;
2266 /* fall through */
6af0bf9c 2267 case OPC_LHU:
dd4096cd 2268 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUW |
be3a8c53 2269 ctx->default_tcg_memop_mask);
78723684 2270 gen_store_gpr(t0, rt);
6af0bf9c 2271 break;
76964147
JH
2272 case OPC_LBE:
2273 mem_idx = MIPS_HFLAG_UM;
2274 /* fall through */
6af0bf9c 2275 case OPC_LB:
dd4096cd 2276 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_SB);
78723684 2277 gen_store_gpr(t0, rt);
6af0bf9c 2278 break;
76964147
JH
2279 case OPC_LBUE:
2280 mem_idx = MIPS_HFLAG_UM;
2281 /* fall through */
6af0bf9c 2282 case OPC_LBU:
dd4096cd 2283 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_UB);
78723684 2284 gen_store_gpr(t0, rt);
6af0bf9c 2285 break;
76964147
JH
2286 case OPC_LWLE:
2287 mem_idx = MIPS_HFLAG_UM;
2288 /* fall through */
6af0bf9c 2289 case OPC_LWL:
3cee3050 2290 t1 = tcg_temp_new();
908680c6
AJ
2291 /* Do a byte access to possibly trigger a page
2292 fault with the unaligned address. */
dd4096cd 2293 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
fc40787a
AJ
2294 tcg_gen_andi_tl(t1, t0, 3);
2295#ifndef TARGET_WORDS_BIGENDIAN
2296 tcg_gen_xori_tl(t1, t1, 3);
2297#endif
2298 tcg_gen_shli_tl(t1, t1, 3);
2299 tcg_gen_andi_tl(t0, t0, ~3);
dd4096cd 2300 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL);
fc40787a 2301 tcg_gen_shl_tl(t0, t0, t1);
eb02cc3f
AJ
2302 t2 = tcg_const_tl(-1);
2303 tcg_gen_shl_tl(t2, t2, t1);
6958549d 2304 gen_load_gpr(t1, rt);
eb02cc3f 2305 tcg_gen_andc_tl(t1, t1, t2);
fc40787a
AJ
2306 tcg_temp_free(t2);
2307 tcg_gen_or_tl(t0, t0, t1);
3cee3050 2308 tcg_temp_free(t1);
fc40787a
AJ
2309 tcg_gen_ext32s_tl(t0, t0);
2310 gen_store_gpr(t0, rt);
6af0bf9c 2311 break;
76964147
JH
2312 case OPC_LWRE:
2313 mem_idx = MIPS_HFLAG_UM;
2314 /* fall through */
6af0bf9c 2315 case OPC_LWR:
3cee3050 2316 t1 = tcg_temp_new();
908680c6
AJ
2317 /* Do a byte access to possibly trigger a page
2318 fault with the unaligned address. */
dd4096cd 2319 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
fc40787a
AJ
2320 tcg_gen_andi_tl(t1, t0, 3);
2321#ifdef TARGET_WORDS_BIGENDIAN
2322 tcg_gen_xori_tl(t1, t1, 3);
2323#endif
2324 tcg_gen_shli_tl(t1, t1, 3);
2325 tcg_gen_andi_tl(t0, t0, ~3);
dd4096cd 2326 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL);
fc40787a
AJ
2327 tcg_gen_shr_tl(t0, t0, t1);
2328 tcg_gen_xori_tl(t1, t1, 31);
2329 t2 = tcg_const_tl(0xfffffffeull);
2330 tcg_gen_shl_tl(t2, t2, t1);
6958549d 2331 gen_load_gpr(t1, rt);
fc40787a
AJ
2332 tcg_gen_and_tl(t1, t1, t2);
2333 tcg_temp_free(t2);
2334 tcg_gen_or_tl(t0, t0, t1);
3cee3050 2335 tcg_temp_free(t1);
c728154b 2336 tcg_gen_ext32s_tl(t0, t0);
fc40787a 2337 gen_store_gpr(t0, rt);
6af0bf9c 2338 break;
76964147
JH
2339 case OPC_LLE:
2340 mem_idx = MIPS_HFLAG_UM;
2341 /* fall through */
6af0bf9c 2342 case OPC_LL:
4368b29a 2343 case R6_OPC_LL:
dd4096cd 2344 op_ld_ll(t0, t0, mem_idx, ctx);
78723684 2345 gen_store_gpr(t0, rt);
6af0bf9c 2346 break;
d66c7132 2347 }
d66c7132 2348 tcg_temp_free(t0);
d66c7132
AJ
2349}
2350
5c13fdfd
AJ
2351/* Store */
2352static void gen_st (DisasContext *ctx, uint32_t opc, int rt,
72e1f16f 2353 int base, int offset)
5c13fdfd 2354{
5c13fdfd
AJ
2355 TCGv t0 = tcg_temp_new();
2356 TCGv t1 = tcg_temp_new();
dd4096cd 2357 int mem_idx = ctx->mem_idx;
5c13fdfd
AJ
2358
2359 gen_base_offset_addr(ctx, t0, base, offset);
2360 gen_load_gpr(t1, rt);
2361 switch (opc) {
2362#if defined(TARGET_MIPS64)
2363 case OPC_SD:
dd4096cd 2364 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEQ |
be3a8c53 2365 ctx->default_tcg_memop_mask);
5c13fdfd
AJ
2366 break;
2367 case OPC_SDL:
dd4096cd 2368 gen_helper_0e2i(sdl, t1, t0, mem_idx);
5c13fdfd
AJ
2369 break;
2370 case OPC_SDR:
dd4096cd 2371 gen_helper_0e2i(sdr, t1, t0, mem_idx);
5c13fdfd
AJ
2372 break;
2373#endif
76964147
JH
2374 case OPC_SWE:
2375 mem_idx = MIPS_HFLAG_UM;
2376 /* fall through */
5c13fdfd 2377 case OPC_SW:
dd4096cd 2378 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUL |
be3a8c53 2379 ctx->default_tcg_memop_mask);
5c13fdfd 2380 break;
76964147
JH
2381 case OPC_SHE:
2382 mem_idx = MIPS_HFLAG_UM;
2383 /* fall through */
5c13fdfd 2384 case OPC_SH:
dd4096cd 2385 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUW |
be3a8c53 2386 ctx->default_tcg_memop_mask);
5c13fdfd 2387 break;
76964147
JH
2388 case OPC_SBE:
2389 mem_idx = MIPS_HFLAG_UM;
2390 /* fall through */
5c13fdfd 2391 case OPC_SB:
dd4096cd 2392 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_8);
5c13fdfd 2393 break;
76964147
JH
2394 case OPC_SWLE:
2395 mem_idx = MIPS_HFLAG_UM;
2396 /* fall through */
5c13fdfd 2397 case OPC_SWL:
dd4096cd 2398 gen_helper_0e2i(swl, t1, t0, mem_idx);
5c13fdfd 2399 break;
76964147
JH
2400 case OPC_SWRE:
2401 mem_idx = MIPS_HFLAG_UM;
2402 /* fall through */
5c13fdfd 2403 case OPC_SWR:
dd4096cd 2404 gen_helper_0e2i(swr, t1, t0, mem_idx);
5c13fdfd
AJ
2405 break;
2406 }
5c13fdfd
AJ
2407 tcg_temp_free(t0);
2408 tcg_temp_free(t1);
2409}
2410
2411
d66c7132
AJ
2412/* Store conditional */
2413static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt,
2414 int base, int16_t offset)
2415{
d66c7132 2416 TCGv t0, t1;
dd4096cd 2417 int mem_idx = ctx->mem_idx;
d66c7132 2418
2d2826b9 2419#ifdef CONFIG_USER_ONLY
d66c7132 2420 t0 = tcg_temp_local_new();
d66c7132 2421 t1 = tcg_temp_local_new();
2d2826b9
AJ
2422#else
2423 t0 = tcg_temp_new();
2424 t1 = tcg_temp_new();
2425#endif
2426 gen_base_offset_addr(ctx, t0, base, offset);
d66c7132
AJ
2427 gen_load_gpr(t1, rt);
2428 switch (opc) {
2429#if defined(TARGET_MIPS64)
2430 case OPC_SCD:
bf7910c6 2431 case R6_OPC_SCD:
dd4096cd 2432 op_st_scd(t1, t0, rt, mem_idx, ctx);
d66c7132
AJ
2433 break;
2434#endif
76964147
JH
2435 case OPC_SCE:
2436 mem_idx = MIPS_HFLAG_UM;
2437 /* fall through */
6af0bf9c 2438 case OPC_SC:
4368b29a 2439 case R6_OPC_SC:
dd4096cd 2440 op_st_sc(t1, t0, rt, mem_idx, ctx);
6af0bf9c 2441 break;
6af0bf9c 2442 }
78723684 2443 tcg_temp_free(t1);
d66c7132 2444 tcg_temp_free(t0);
6af0bf9c
FB
2445}
2446
6ea83fed 2447/* Load and store */
7a387fff 2448static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
b52d3bfa 2449 TCGv t0)
6ea83fed 2450{
6ea83fed 2451 /* Don't do NOP if destination is zero: we must perform the actual
ead9360e 2452 memory access. */
6ea83fed
FB
2453 switch (opc) {
2454 case OPC_LWC1:
b6d96bed 2455 {
a7812ae4 2456 TCGv_i32 fp0 = tcg_temp_new_i32();
be3a8c53
YK
2457 tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, MO_TESL |
2458 ctx->default_tcg_memop_mask);
7c979afd 2459 gen_store_fpr32(ctx, fp0, ft);
a7812ae4 2460 tcg_temp_free_i32(fp0);
b6d96bed 2461 }
6ea83fed
FB
2462 break;
2463 case OPC_SWC1:
b6d96bed 2464 {
a7812ae4 2465 TCGv_i32 fp0 = tcg_temp_new_i32();
7c979afd 2466 gen_load_fpr32(ctx, fp0, ft);
be3a8c53
YK
2467 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL |
2468 ctx->default_tcg_memop_mask);
a7812ae4 2469 tcg_temp_free_i32(fp0);
b6d96bed 2470 }
6ea83fed
FB
2471 break;
2472 case OPC_LDC1:
b6d96bed 2473 {
a7812ae4 2474 TCGv_i64 fp0 = tcg_temp_new_i64();
be3a8c53
YK
2475 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ |
2476 ctx->default_tcg_memop_mask);
b6d96bed 2477 gen_store_fpr64(ctx, fp0, ft);
a7812ae4 2478 tcg_temp_free_i64(fp0);
b6d96bed 2479 }
6ea83fed
FB
2480 break;
2481 case OPC_SDC1:
b6d96bed 2482 {
a7812ae4 2483 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 2484 gen_load_fpr64(ctx, fp0, ft);
be3a8c53
YK
2485 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ |
2486 ctx->default_tcg_memop_mask);
a7812ae4 2487 tcg_temp_free_i64(fp0);
b6d96bed 2488 }
6ea83fed
FB
2489 break;
2490 default:
9d68ac14 2491 MIPS_INVAL("flt_ldst");
9c708c7f 2492 generate_exception_end(ctx, EXCP_RI);
b52d3bfa 2493 break;
6ea83fed 2494 }
6ea83fed 2495}
6ea83fed 2496
5ab5c041
AJ
2497static void gen_cop1_ldst(DisasContext *ctx, uint32_t op, int rt,
2498 int rs, int16_t imm)
26ebe468 2499{
b52d3bfa
YK
2500 TCGv t0 = tcg_temp_new();
2501
5ab5c041 2502 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
26ebe468 2503 check_cp1_enabled(ctx);
d9224450
MR
2504 switch (op) {
2505 case OPC_LDC1:
2506 case OPC_SDC1:
2507 check_insn(ctx, ISA_MIPS2);
2508 /* Fallthrough */
2509 default:
b52d3bfa
YK
2510 gen_base_offset_addr(ctx, t0, rs, imm);
2511 gen_flt_ldst(ctx, op, rt, t0);
d9224450 2512 }
26ebe468
NF
2513 } else {
2514 generate_exception_err(ctx, EXCP_CpU, 1);
2515 }
b52d3bfa 2516 tcg_temp_free(t0);
26ebe468
NF
2517}
2518
6af0bf9c 2519/* Arithmetic with immediate operand */
d75c135e 2520static void gen_arith_imm(DisasContext *ctx, uint32_t opc,
72e1f16f 2521 int rt, int rs, int imm)
6af0bf9c 2522{
324d9e32 2523 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
6af0bf9c 2524
7a387fff 2525 if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
ead9360e
TS
2526 /* If no destination, treat it as a NOP.
2527 For addi, we must generate the overflow exception when needed. */
324d9e32 2528 return;
6af0bf9c
FB
2529 }
2530 switch (opc) {
2531 case OPC_ADDI:
48d38ca5 2532 {
324d9e32
AJ
2533 TCGv t0 = tcg_temp_local_new();
2534 TCGv t1 = tcg_temp_new();
2535 TCGv t2 = tcg_temp_new();
42a268c2 2536 TCGLabel *l1 = gen_new_label();
48d38ca5 2537
324d9e32
AJ
2538 gen_load_gpr(t1, rs);
2539 tcg_gen_addi_tl(t0, t1, uimm);
2540 tcg_gen_ext32s_tl(t0, t0);
48d38ca5 2541
324d9e32
AJ
2542 tcg_gen_xori_tl(t1, t1, ~uimm);
2543 tcg_gen_xori_tl(t2, t0, uimm);
2544 tcg_gen_and_tl(t1, t1, t2);
2545 tcg_temp_free(t2);
2546 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2547 tcg_temp_free(t1);
48d38ca5
TS
2548 /* operands of same sign, result different sign */
2549 generate_exception(ctx, EXCP_OVERFLOW);
2550 gen_set_label(l1);
78723684 2551 tcg_gen_ext32s_tl(t0, t0);
324d9e32
AJ
2552 gen_store_gpr(t0, rt);
2553 tcg_temp_free(t0);
48d38ca5 2554 }
6af0bf9c
FB
2555 break;
2556 case OPC_ADDIU:
324d9e32
AJ
2557 if (rs != 0) {
2558 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2559 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
2560 } else {
2561 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2562 }
6af0bf9c 2563 break;
d26bc211 2564#if defined(TARGET_MIPS64)
7a387fff 2565 case OPC_DADDI:
48d38ca5 2566 {
324d9e32
AJ
2567 TCGv t0 = tcg_temp_local_new();
2568 TCGv t1 = tcg_temp_new();
2569 TCGv t2 = tcg_temp_new();
42a268c2 2570 TCGLabel *l1 = gen_new_label();
48d38ca5 2571
324d9e32
AJ
2572 gen_load_gpr(t1, rs);
2573 tcg_gen_addi_tl(t0, t1, uimm);
48d38ca5 2574
324d9e32
AJ
2575 tcg_gen_xori_tl(t1, t1, ~uimm);
2576 tcg_gen_xori_tl(t2, t0, uimm);
2577 tcg_gen_and_tl(t1, t1, t2);
2578 tcg_temp_free(t2);
2579 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2580 tcg_temp_free(t1);
48d38ca5
TS
2581 /* operands of same sign, result different sign */
2582 generate_exception(ctx, EXCP_OVERFLOW);
2583 gen_set_label(l1);
324d9e32
AJ
2584 gen_store_gpr(t0, rt);
2585 tcg_temp_free(t0);
48d38ca5 2586 }
7a387fff
TS
2587 break;
2588 case OPC_DADDIU:
324d9e32
AJ
2589 if (rs != 0) {
2590 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2591 } else {
2592 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2593 }
7a387fff
TS
2594 break;
2595#endif
324d9e32 2596 }
324d9e32
AJ
2597}
2598
2599/* Logic with immediate operand */
d75c135e 2600static void gen_logic_imm(DisasContext *ctx, uint32_t opc,
9fa77488 2601 int rt, int rs, int16_t imm)
324d9e32
AJ
2602{
2603 target_ulong uimm;
324d9e32
AJ
2604
2605 if (rt == 0) {
2606 /* If no destination, treat it as a NOP. */
324d9e32
AJ
2607 return;
2608 }
2609 uimm = (uint16_t)imm;
2610 switch (opc) {
6af0bf9c 2611 case OPC_ANDI:
324d9e32
AJ
2612 if (likely(rs != 0))
2613 tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2614 else
2615 tcg_gen_movi_tl(cpu_gpr[rt], 0);
6af0bf9c
FB
2616 break;
2617 case OPC_ORI:
324d9e32
AJ
2618 if (rs != 0)
2619 tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2620 else
2621 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
6af0bf9c
FB
2622 break;
2623 case OPC_XORI:
324d9e32
AJ
2624 if (likely(rs != 0))
2625 tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2626 else
2627 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
6af0bf9c
FB
2628 break;
2629 case OPC_LUI:
d4ea6acd
LA
2630 if (rs != 0 && (ctx->insn_flags & ISA_MIPS32R6)) {
2631 /* OPC_AUI */
2632 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm << 16);
2633 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
d4ea6acd
LA
2634 } else {
2635 tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
d4ea6acd 2636 }
7c2c3ea3
EJ
2637 break;
2638
2639 default:
6af0bf9c 2640 break;
324d9e32 2641 }
324d9e32
AJ
2642}
2643
2644/* Set on less than with immediate operand */
d75c135e 2645static void gen_slt_imm(DisasContext *ctx, uint32_t opc,
9fa77488 2646 int rt, int rs, int16_t imm)
324d9e32
AJ
2647{
2648 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
324d9e32
AJ
2649 TCGv t0;
2650
2651 if (rt == 0) {
2652 /* If no destination, treat it as a NOP. */
324d9e32
AJ
2653 return;
2654 }
2655 t0 = tcg_temp_new();
2656 gen_load_gpr(t0, rs);
2657 switch (opc) {
2658 case OPC_SLTI:
e68dd28f 2659 tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
324d9e32
AJ
2660 break;
2661 case OPC_SLTIU:
e68dd28f 2662 tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
324d9e32
AJ
2663 break;
2664 }
324d9e32
AJ
2665 tcg_temp_free(t0);
2666}
2667
2668/* Shifts with immediate operand */
d75c135e 2669static void gen_shift_imm(DisasContext *ctx, uint32_t opc,
324d9e32
AJ
2670 int rt, int rs, int16_t imm)
2671{
2672 target_ulong uimm = ((uint16_t)imm) & 0x1f;
324d9e32
AJ
2673 TCGv t0;
2674
2675 if (rt == 0) {
2676 /* If no destination, treat it as a NOP. */
324d9e32
AJ
2677 return;
2678 }
2679
2680 t0 = tcg_temp_new();
2681 gen_load_gpr(t0, rs);
2682 switch (opc) {
6af0bf9c 2683 case OPC_SLL:
78723684 2684 tcg_gen_shli_tl(t0, t0, uimm);
324d9e32 2685 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
6af0bf9c
FB
2686 break;
2687 case OPC_SRA:
324d9e32 2688 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
6af0bf9c
FB
2689 break;
2690 case OPC_SRL:
ea63e2c3
NF
2691 if (uimm != 0) {
2692 tcg_gen_ext32u_tl(t0, t0);
2693 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2694 } else {
2695 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
5a63bcb2 2696 }
ea63e2c3
NF
2697 break;
2698 case OPC_ROTR:
2699 if (uimm != 0) {
2700 TCGv_i32 t1 = tcg_temp_new_i32();
2701
2702 tcg_gen_trunc_tl_i32(t1, t0);
2703 tcg_gen_rotri_i32(t1, t1, uimm);
2704 tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
2705 tcg_temp_free_i32(t1);
3399e30f
NF
2706 } else {
2707 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
ea63e2c3 2708 }
7a387fff 2709 break;
d26bc211 2710#if defined(TARGET_MIPS64)
7a387fff 2711 case OPC_DSLL:
324d9e32 2712 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
7a387fff
TS
2713 break;
2714 case OPC_DSRA:
324d9e32 2715 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
7a387fff
TS
2716 break;
2717 case OPC_DSRL:
ea63e2c3 2718 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
ea63e2c3
NF
2719 break;
2720 case OPC_DROTR:
2721 if (uimm != 0) {
2722 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
3399e30f
NF
2723 } else {
2724 tcg_gen_mov_tl(cpu_gpr[rt], t0);
5a63bcb2 2725 }
7a387fff
TS
2726 break;
2727 case OPC_DSLL32:
324d9e32 2728 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
7a387fff
TS
2729 break;
2730 case OPC_DSRA32:
324d9e32 2731 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
7a387fff
TS
2732 break;
2733 case OPC_DSRL32:
ea63e2c3 2734 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
ea63e2c3
NF
2735 break;
2736 case OPC_DROTR32:
2737 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
6af0bf9c 2738 break;
7a387fff 2739#endif
6af0bf9c 2740 }
78723684 2741 tcg_temp_free(t0);
6af0bf9c
FB
2742}
2743
2744/* Arithmetic */
d75c135e
AJ
2745static void gen_arith(DisasContext *ctx, uint32_t opc,
2746 int rd, int rs, int rt)
6af0bf9c 2747{
7a387fff
TS
2748 if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
2749 && opc != OPC_DADD && opc != OPC_DSUB) {
ead9360e
TS
2750 /* If no destination, treat it as a NOP.
2751 For add & sub, we must generate the overflow exception when needed. */
460f00c4 2752 return;
185f0762 2753 }
460f00c4 2754
6af0bf9c
FB
2755 switch (opc) {
2756 case OPC_ADD:
48d38ca5 2757 {
460f00c4
AJ
2758 TCGv t0 = tcg_temp_local_new();
2759 TCGv t1 = tcg_temp_new();
2760 TCGv t2 = tcg_temp_new();
42a268c2 2761 TCGLabel *l1 = gen_new_label();
48d38ca5 2762
460f00c4
AJ
2763 gen_load_gpr(t1, rs);
2764 gen_load_gpr(t2, rt);
2765 tcg_gen_add_tl(t0, t1, t2);
2766 tcg_gen_ext32s_tl(t0, t0);
2767 tcg_gen_xor_tl(t1, t1, t2);
460f00c4 2768 tcg_gen_xor_tl(t2, t0, t2);
deb4203d 2769 tcg_gen_andc_tl(t1, t2, t1);
460f00c4
AJ
2770 tcg_temp_free(t2);
2771 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2772 tcg_temp_free(t1);
48d38ca5
TS
2773 /* operands of same sign, result different sign */
2774 generate_exception(ctx, EXCP_OVERFLOW);
2775 gen_set_label(l1);
460f00c4
AJ
2776 gen_store_gpr(t0, rd);
2777 tcg_temp_free(t0);
48d38ca5 2778 }
6af0bf9c
FB
2779 break;
2780 case OPC_ADDU:
460f00c4
AJ
2781 if (rs != 0 && rt != 0) {
2782 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2783 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2784 } else if (rs == 0 && rt != 0) {
2785 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2786 } else if (rs != 0 && rt == 0) {
2787 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2788 } else {
2789 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2790 }
6af0bf9c
FB
2791 break;
2792 case OPC_SUB:
48d38ca5 2793 {
460f00c4
AJ
2794 TCGv t0 = tcg_temp_local_new();
2795 TCGv t1 = tcg_temp_new();
2796 TCGv t2 = tcg_temp_new();
42a268c2 2797 TCGLabel *l1 = gen_new_label();
48d38ca5 2798
460f00c4
AJ
2799 gen_load_gpr(t1, rs);
2800 gen_load_gpr(t2, rt);
2801 tcg_gen_sub_tl(t0, t1, t2);
2802 tcg_gen_ext32s_tl(t0, t0);
2803 tcg_gen_xor_tl(t2, t1, t2);
2804 tcg_gen_xor_tl(t1, t0, t1);
2805 tcg_gen_and_tl(t1, t1, t2);
2806 tcg_temp_free(t2);
2807 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2808 tcg_temp_free(t1);
31e3104f 2809 /* operands of different sign, first operand and result different sign */
48d38ca5
TS
2810 generate_exception(ctx, EXCP_OVERFLOW);
2811 gen_set_label(l1);
460f00c4
AJ
2812 gen_store_gpr(t0, rd);
2813 tcg_temp_free(t0);
48d38ca5 2814 }
6af0bf9c
FB
2815 break;
2816 case OPC_SUBU:
460f00c4
AJ
2817 if (rs != 0 && rt != 0) {
2818 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2819 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2820 } else if (rs == 0 && rt != 0) {
2821 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
6bb72b18 2822 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
460f00c4
AJ
2823 } else if (rs != 0 && rt == 0) {
2824 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2825 } else {
2826 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2827 }
6af0bf9c 2828 break;
d26bc211 2829#if defined(TARGET_MIPS64)
7a387fff 2830 case OPC_DADD:
48d38ca5 2831 {
460f00c4
AJ
2832 TCGv t0 = tcg_temp_local_new();
2833 TCGv t1 = tcg_temp_new();
2834 TCGv t2 = tcg_temp_new();
42a268c2 2835 TCGLabel *l1 = gen_new_label();
48d38ca5 2836
460f00c4
AJ
2837 gen_load_gpr(t1, rs);
2838 gen_load_gpr(t2, rt);
2839 tcg_gen_add_tl(t0, t1, t2);
2840 tcg_gen_xor_tl(t1, t1, t2);
460f00c4 2841 tcg_gen_xor_tl(t2, t0, t2);
deb4203d 2842 tcg_gen_andc_tl(t1, t2, t1);
460f00c4
AJ
2843 tcg_temp_free(t2);
2844 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2845 tcg_temp_free(t1);
48d38ca5
TS
2846 /* operands of same sign, result different sign */
2847 generate_exception(ctx, EXCP_OVERFLOW);
2848 gen_set_label(l1);
460f00c4
AJ
2849 gen_store_gpr(t0, rd);
2850 tcg_temp_free(t0);
48d38ca5 2851 }
7a387fff
TS
2852 break;
2853 case OPC_DADDU:
460f00c4
AJ
2854 if (rs != 0 && rt != 0) {
2855 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2856 } else if (rs == 0 && rt != 0) {
2857 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2858 } else if (rs != 0 && rt == 0) {
2859 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2860 } else {
2861 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2862 }
7a387fff
TS
2863 break;
2864 case OPC_DSUB:
48d38ca5 2865 {
460f00c4
AJ
2866 TCGv t0 = tcg_temp_local_new();
2867 TCGv t1 = tcg_temp_new();
2868 TCGv t2 = tcg_temp_new();
42a268c2 2869 TCGLabel *l1 = gen_new_label();
48d38ca5 2870
460f00c4
AJ
2871 gen_load_gpr(t1, rs);
2872 gen_load_gpr(t2, rt);
2873 tcg_gen_sub_tl(t0, t1, t2);
2874 tcg_gen_xor_tl(t2, t1, t2);
2875 tcg_gen_xor_tl(t1, t0, t1);
2876 tcg_gen_and_tl(t1, t1, t2);
2877 tcg_temp_free(t2);
2878 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2879 tcg_temp_free(t1);
31e3104f 2880 /* operands of different sign, first operand and result different sign */
48d38ca5
TS
2881 generate_exception(ctx, EXCP_OVERFLOW);
2882 gen_set_label(l1);
460f00c4
AJ
2883 gen_store_gpr(t0, rd);
2884 tcg_temp_free(t0);
48d38ca5 2885 }
7a387fff
TS
2886 break;
2887 case OPC_DSUBU:
460f00c4
AJ
2888 if (rs != 0 && rt != 0) {
2889 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2890 } else if (rs == 0 && rt != 0) {
2891 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2892 } else if (rs != 0 && rt == 0) {
2893 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2894 } else {
2895 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2896 }
7a387fff
TS
2897 break;
2898#endif
460f00c4
AJ
2899 case OPC_MUL:
2900 if (likely(rs != 0 && rt != 0)) {
2901 tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2902 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2903 } else {
2904 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2905 }
6af0bf9c 2906 break;
460f00c4 2907 }
460f00c4
AJ
2908}
2909
2910/* Conditional move */
d75c135e 2911static void gen_cond_move(DisasContext *ctx, uint32_t opc,
9fa77488 2912 int rd, int rs, int rt)
460f00c4 2913{
acf12465 2914 TCGv t0, t1, t2;
460f00c4
AJ
2915
2916 if (rd == 0) {
acf12465 2917 /* If no destination, treat it as a NOP. */
460f00c4
AJ
2918 return;
2919 }
2920
acf12465
AJ
2921 t0 = tcg_temp_new();
2922 gen_load_gpr(t0, rt);
2923 t1 = tcg_const_tl(0);
2924 t2 = tcg_temp_new();
2925 gen_load_gpr(t2, rs);
460f00c4
AJ
2926 switch (opc) {
2927 case OPC_MOVN:
acf12465 2928 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
6af0bf9c 2929 break;
460f00c4 2930 case OPC_MOVZ:
acf12465 2931 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
460f00c4 2932 break;
b691d9d2
LA
2933 case OPC_SELNEZ:
2934 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, t1);
b691d9d2
LA
2935 break;
2936 case OPC_SELEQZ:
2937 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, t1);
b691d9d2 2938 break;
460f00c4 2939 }
acf12465
AJ
2940 tcg_temp_free(t2);
2941 tcg_temp_free(t1);
2942 tcg_temp_free(t0);
460f00c4
AJ
2943}
2944
2945/* Logic */
d75c135e 2946static void gen_logic(DisasContext *ctx, uint32_t opc,
9fa77488 2947 int rd, int rs, int rt)
460f00c4 2948{
460f00c4
AJ
2949 if (rd == 0) {
2950 /* If no destination, treat it as a NOP. */
460f00c4
AJ
2951 return;
2952 }
2953
2954 switch (opc) {
6af0bf9c 2955 case OPC_AND:
460f00c4
AJ
2956 if (likely(rs != 0 && rt != 0)) {
2957 tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2958 } else {
2959 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2960 }
6af0bf9c
FB
2961 break;
2962 case OPC_NOR:
460f00c4
AJ
2963 if (rs != 0 && rt != 0) {
2964 tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2965 } else if (rs == 0 && rt != 0) {
2966 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
2967 } else if (rs != 0 && rt == 0) {
2968 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
2969 } else {
2970 tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
2971 }
6af0bf9c
FB
2972 break;
2973 case OPC_OR:
460f00c4
AJ
2974 if (likely(rs != 0 && rt != 0)) {
2975 tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2976 } else if (rs == 0 && rt != 0) {
2977 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2978 } else if (rs != 0 && rt == 0) {
2979 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2980 } else {
2981 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2982 }
6af0bf9c
FB
2983 break;
2984 case OPC_XOR:
460f00c4
AJ
2985 if (likely(rs != 0 && rt != 0)) {
2986 tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2987 } else if (rs == 0 && rt != 0) {
2988 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2989 } else if (rs != 0 && rt == 0) {
2990 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2991 } else {
2992 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2993 }
6af0bf9c 2994 break;
460f00c4 2995 }
460f00c4
AJ
2996}
2997
2998/* Set on lower than */
d75c135e 2999static void gen_slt(DisasContext *ctx, uint32_t opc,
9fa77488 3000 int rd, int rs, int rt)
460f00c4 3001{
460f00c4
AJ
3002 TCGv t0, t1;
3003
3004 if (rd == 0) {
3005 /* If no destination, treat it as a NOP. */
460f00c4
AJ
3006 return;
3007 }
3008
3009 t0 = tcg_temp_new();
3010 t1 = tcg_temp_new();
3011 gen_load_gpr(t0, rs);
3012 gen_load_gpr(t1, rt);
3013 switch (opc) {
3014 case OPC_SLT:
e68dd28f 3015 tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
6af0bf9c 3016 break;
460f00c4 3017 case OPC_SLTU:
e68dd28f 3018 tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
460f00c4
AJ
3019 break;
3020 }
460f00c4
AJ
3021 tcg_temp_free(t0);
3022 tcg_temp_free(t1);
3023}
20c4c97c 3024
460f00c4 3025/* Shifts */
d75c135e
AJ
3026static void gen_shift(DisasContext *ctx, uint32_t opc,
3027 int rd, int rs, int rt)
460f00c4 3028{
460f00c4 3029 TCGv t0, t1;
20c4c97c 3030
460f00c4
AJ
3031 if (rd == 0) {
3032 /* If no destination, treat it as a NOP.
3033 For add & sub, we must generate the overflow exception when needed. */
460f00c4
AJ
3034 return;
3035 }
3036
3037 t0 = tcg_temp_new();
3038 t1 = tcg_temp_new();
3039 gen_load_gpr(t0, rs);
3040 gen_load_gpr(t1, rt);
3041 switch (opc) {
6af0bf9c 3042 case OPC_SLLV:
78723684
TS
3043 tcg_gen_andi_tl(t0, t0, 0x1f);
3044 tcg_gen_shl_tl(t0, t1, t0);
460f00c4 3045 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
6af0bf9c
FB
3046 break;
3047 case OPC_SRAV:
78723684 3048 tcg_gen_andi_tl(t0, t0, 0x1f);
460f00c4 3049 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
6af0bf9c
FB
3050 break;
3051 case OPC_SRLV:
ea63e2c3
NF
3052 tcg_gen_ext32u_tl(t1, t1);
3053 tcg_gen_andi_tl(t0, t0, 0x1f);
3054 tcg_gen_shr_tl(t0, t1, t0);
3055 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
ea63e2c3
NF
3056 break;
3057 case OPC_ROTRV:
3058 {
3059 TCGv_i32 t2 = tcg_temp_new_i32();
3060 TCGv_i32 t3 = tcg_temp_new_i32();
3061
3062 tcg_gen_trunc_tl_i32(t2, t0);
3063 tcg_gen_trunc_tl_i32(t3, t1);
3064 tcg_gen_andi_i32(t2, t2, 0x1f);
3065 tcg_gen_rotr_i32(t2, t3, t2);
3066 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3067 tcg_temp_free_i32(t2);
3068 tcg_temp_free_i32(t3);
5a63bcb2 3069 }
7a387fff 3070 break;
d26bc211 3071#if defined(TARGET_MIPS64)
7a387fff 3072 case OPC_DSLLV:
78723684 3073 tcg_gen_andi_tl(t0, t0, 0x3f);
460f00c4 3074 tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
7a387fff
TS
3075 break;
3076 case OPC_DSRAV:
78723684 3077 tcg_gen_andi_tl(t0, t0, 0x3f);
460f00c4 3078 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
7a387fff
TS
3079 break;
3080 case OPC_DSRLV:
ea63e2c3
NF
3081 tcg_gen_andi_tl(t0, t0, 0x3f);
3082 tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
ea63e2c3
NF
3083 break;
3084 case OPC_DROTRV:
3085 tcg_gen_andi_tl(t0, t0, 0x3f);
3086 tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
6af0bf9c 3087 break;
7a387fff 3088#endif
6af0bf9c 3089 }
78723684
TS
3090 tcg_temp_free(t0);
3091 tcg_temp_free(t1);
6af0bf9c
FB
3092}
3093
3094/* Arithmetic on HI/LO registers */
26135ead 3095static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg)
6af0bf9c 3096{
6af0bf9c 3097 if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
ead9360e 3098 /* Treat as NOP. */
a1f6684d 3099 return;
6af0bf9c 3100 }
4133498f 3101
4133498f
JL
3102 if (acc != 0) {
3103 check_dsp(ctx);
3104 }
3105
6af0bf9c
FB
3106 switch (opc) {
3107 case OPC_MFHI:
4133498f
JL
3108#if defined(TARGET_MIPS64)
3109 if (acc != 0) {
3110 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]);
3111 } else
3112#endif
3113 {
3114 tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]);
3115 }
6af0bf9c
FB
3116 break;
3117 case OPC_MFLO:
4133498f
JL
3118#if defined(TARGET_MIPS64)
3119 if (acc != 0) {
3120 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]);
3121 } else
3122#endif
3123 {
3124 tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]);
3125 }
6af0bf9c
FB
3126 break;
3127 case OPC_MTHI:
4133498f
JL
3128 if (reg != 0) {
3129#if defined(TARGET_MIPS64)
3130 if (acc != 0) {
3131 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_gpr[reg]);
3132 } else
3133#endif
3134 {
3135 tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]);
3136 }
3137 } else {
3138 tcg_gen_movi_tl(cpu_HI[acc], 0);
3139 }
6af0bf9c
FB
3140 break;
3141 case OPC_MTLO:
4133498f
JL
3142 if (reg != 0) {
3143#if defined(TARGET_MIPS64)
3144 if (acc != 0) {
3145 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_gpr[reg]);
3146 } else
3147#endif
3148 {
3149 tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]);
3150 }
3151 } else {
3152 tcg_gen_movi_tl(cpu_LO[acc], 0);
3153 }
6af0bf9c 3154 break;
6af0bf9c 3155 }
6af0bf9c
FB
3156}
3157
d4ea6acd
LA
3158static inline void gen_r6_ld(target_long addr, int reg, int memidx,
3159 TCGMemOp memop)
3160{
3161 TCGv t0 = tcg_const_tl(addr);
3162 tcg_gen_qemu_ld_tl(t0, t0, memidx, memop);
3163 gen_store_gpr(t0, reg);
3164 tcg_temp_free(t0);
3165}
3166
ab39ee45
YK
3167static inline void gen_pcrel(DisasContext *ctx, int opc, target_ulong pc,
3168 int rs)
d4ea6acd
LA
3169{
3170 target_long offset;
3171 target_long addr;
3172
ab39ee45 3173 switch (MASK_OPC_PCREL_TOP2BITS(opc)) {
d4ea6acd
LA
3174 case OPC_ADDIUPC:
3175 if (rs != 0) {
3176 offset = sextract32(ctx->opcode << 2, 0, 21);
ab39ee45 3177 addr = addr_add(ctx, pc, offset);
d4ea6acd
LA
3178 tcg_gen_movi_tl(cpu_gpr[rs], addr);
3179 }
3180 break;
3181 case R6_OPC_LWPC:
3182 offset = sextract32(ctx->opcode << 2, 0, 21);
ab39ee45 3183 addr = addr_add(ctx, pc, offset);
d4ea6acd
LA
3184 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TESL);
3185 break;
3186#if defined(TARGET_MIPS64)
3187 case OPC_LWUPC:
3188 check_mips_64(ctx);
3189 offset = sextract32(ctx->opcode << 2, 0, 21);
ab39ee45 3190 addr = addr_add(ctx, pc, offset);
d4ea6acd
LA
3191 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEUL);
3192 break;
3193#endif
3194 default:
ab39ee45 3195 switch (MASK_OPC_PCREL_TOP5BITS(opc)) {
d4ea6acd
LA
3196 case OPC_AUIPC:
3197 if (rs != 0) {
ab39ee45
YK
3198 offset = sextract32(ctx->opcode, 0, 16) << 16;
3199 addr = addr_add(ctx, pc, offset);
d4ea6acd
LA
3200 tcg_gen_movi_tl(cpu_gpr[rs], addr);
3201 }
3202 break;
3203 case OPC_ALUIPC:
3204 if (rs != 0) {
ab39ee45
YK
3205 offset = sextract32(ctx->opcode, 0, 16) << 16;
3206 addr = ~0xFFFF & addr_add(ctx, pc, offset);
d4ea6acd
LA
3207 tcg_gen_movi_tl(cpu_gpr[rs], addr);
3208 }
3209 break;
3210#if defined(TARGET_MIPS64)
3211 case R6_OPC_LDPC: /* bits 16 and 17 are part of immediate */
3212 case R6_OPC_LDPC + (1 << 16):
3213 case R6_OPC_LDPC + (2 << 16):
3214 case R6_OPC_LDPC + (3 << 16):
3215 check_mips_64(ctx);
3216 offset = sextract32(ctx->opcode << 3, 0, 21);
ab39ee45 3217 addr = addr_add(ctx, (pc & ~0x7), offset);
d4ea6acd
LA
3218 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEQ);
3219 break;
3220#endif
3221 default:
3222 MIPS_INVAL("OPC_PCREL");
9c708c7f 3223 generate_exception_end(ctx, EXCP_RI);
d4ea6acd
LA
3224 break;
3225 }
3226 break;
3227 }
3228}
3229
b42ee5e1
LA
3230static void gen_r6_muldiv(DisasContext *ctx, int opc, int rd, int rs, int rt)
3231{
b42ee5e1
LA
3232 TCGv t0, t1;
3233
3234 if (rd == 0) {
3235 /* Treat as NOP. */
b42ee5e1
LA
3236 return;
3237 }
3238
3239 t0 = tcg_temp_new();
3240 t1 = tcg_temp_new();
3241
3242 gen_load_gpr(t0, rs);
3243 gen_load_gpr(t1, rt);
3244
3245 switch (opc) {
3246 case R6_OPC_DIV:
3247 {
3248 TCGv t2 = tcg_temp_new();
3249 TCGv t3 = tcg_temp_new();
3250 tcg_gen_ext32s_tl(t0, t0);
3251 tcg_gen_ext32s_tl(t1, t1);
3252 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3253 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3254 tcg_gen_and_tl(t2, t2, t3);
3255 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3256 tcg_gen_or_tl(t2, t2, t3);
3257 tcg_gen_movi_tl(t3, 0);
3258 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3259 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3260 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3261 tcg_temp_free(t3);
3262 tcg_temp_free(t2);
3263 }
b42ee5e1
LA
3264 break;
3265 case R6_OPC_MOD:
3266 {
3267 TCGv t2 = tcg_temp_new();
3268 TCGv t3 = tcg_temp_new();
3269 tcg_gen_ext32s_tl(t0, t0);
3270 tcg_gen_ext32s_tl(t1, t1);
3271 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3272 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3273 tcg_gen_and_tl(t2, t2, t3);
3274 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3275 tcg_gen_or_tl(t2, t2, t3);
3276 tcg_gen_movi_tl(t3, 0);
3277 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3278 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3279 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3280 tcg_temp_free(t3);
3281 tcg_temp_free(t2);
3282 }
b42ee5e1
LA
3283 break;
3284 case R6_OPC_DIVU:
3285 {
3286 TCGv t2 = tcg_const_tl(0);
3287 TCGv t3 = tcg_const_tl(1);
3288 tcg_gen_ext32u_tl(t0, t0);
3289 tcg_gen_ext32u_tl(t1, t1);
3290 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3291 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3292 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3293 tcg_temp_free(t3);
3294 tcg_temp_free(t2);
3295 }
b42ee5e1
LA
3296 break;
3297 case R6_OPC_MODU:
3298 {
3299 TCGv t2 = tcg_const_tl(0);
3300 TCGv t3 = tcg_const_tl(1);
3301 tcg_gen_ext32u_tl(t0, t0);
3302 tcg_gen_ext32u_tl(t1, t1);
3303 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3304 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3305 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3306 tcg_temp_free(t3);
3307 tcg_temp_free(t2);
3308 }
b42ee5e1
LA
3309 break;
3310 case R6_OPC_MUL:
3311 {
3312 TCGv_i32 t2 = tcg_temp_new_i32();
3313 TCGv_i32 t3 = tcg_temp_new_i32();
3314 tcg_gen_trunc_tl_i32(t2, t0);
3315 tcg_gen_trunc_tl_i32(t3, t1);
3316 tcg_gen_mul_i32(t2, t2, t3);
3317 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3318 tcg_temp_free_i32(t2);
3319 tcg_temp_free_i32(t3);
3320 }
b42ee5e1
LA
3321 break;
3322 case R6_OPC_MUH:
3323 {
3324 TCGv_i32 t2 = tcg_temp_new_i32();
3325 TCGv_i32 t3 = tcg_temp_new_i32();
3326 tcg_gen_trunc_tl_i32(t2, t0);
3327 tcg_gen_trunc_tl_i32(t3, t1);
3328 tcg_gen_muls2_i32(t2, t3, t2, t3);
3329 tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
3330 tcg_temp_free_i32(t2);
3331 tcg_temp_free_i32(t3);
3332 }
b42ee5e1
LA
3333 break;
3334 case R6_OPC_MULU:
3335 {
3336 TCGv_i32 t2 = tcg_temp_new_i32();
3337 TCGv_i32 t3 = tcg_temp_new_i32();
3338 tcg_gen_trunc_tl_i32(t2, t0);
3339 tcg_gen_trunc_tl_i32(t3, t1);
3340 tcg_gen_mul_i32(t2, t2, t3);
3341 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3342 tcg_temp_free_i32(t2);
3343 tcg_temp_free_i32(t3);
3344 }
b42ee5e1
LA
3345 break;
3346 case R6_OPC_MUHU:
3347 {
3348 TCGv_i32 t2 = tcg_temp_new_i32();
3349 TCGv_i32 t3 = tcg_temp_new_i32();
3350 tcg_gen_trunc_tl_i32(t2, t0);
3351 tcg_gen_trunc_tl_i32(t3, t1);
3352 tcg_gen_mulu2_i32(t2, t3, t2, t3);
3353 tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
3354 tcg_temp_free_i32(t2);
3355 tcg_temp_free_i32(t3);
3356 }
b42ee5e1
LA
3357 break;
3358#if defined(TARGET_MIPS64)
3359 case R6_OPC_DDIV:
3360 {
3361 TCGv t2 = tcg_temp_new();
3362 TCGv t3 = tcg_temp_new();
3363 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3364 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3365 tcg_gen_and_tl(t2, t2, t3);
3366 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3367 tcg_gen_or_tl(t2, t2, t3);
3368 tcg_gen_movi_tl(t3, 0);
3369 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3370 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3371 tcg_temp_free(t3);
3372 tcg_temp_free(t2);
3373 }
b42ee5e1
LA
3374 break;
3375 case R6_OPC_DMOD:
3376 {
3377 TCGv t2 = tcg_temp_new();
3378 TCGv t3 = tcg_temp_new();
3379 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3380 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3381 tcg_gen_and_tl(t2, t2, t3);
3382 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3383 tcg_gen_or_tl(t2, t2, t3);
3384 tcg_gen_movi_tl(t3, 0);
3385 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3386 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3387 tcg_temp_free(t3);
3388 tcg_temp_free(t2);
3389 }
b42ee5e1
LA
3390 break;
3391 case R6_OPC_DDIVU:
3392 {
3393 TCGv t2 = tcg_const_tl(0);
3394 TCGv t3 = tcg_const_tl(1);
3395 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3396 tcg_gen_divu_i64(cpu_gpr[rd], t0, t1);
3397 tcg_temp_free(t3);
3398 tcg_temp_free(t2);
3399 }
b42ee5e1
LA
3400 break;
3401 case R6_OPC_DMODU:
3402 {
3403 TCGv t2 = tcg_const_tl(0);
3404 TCGv t3 = tcg_const_tl(1);
3405 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3406 tcg_gen_remu_i64(cpu_gpr[rd], t0, t1);
3407 tcg_temp_free(t3);
3408 tcg_temp_free(t2);
3409 }
b42ee5e1
LA
3410 break;
3411 case R6_OPC_DMUL:
3412 tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
b42ee5e1
LA
3413 break;
3414 case R6_OPC_DMUH:
3415 {
3416 TCGv t2 = tcg_temp_new();
3417 tcg_gen_muls2_i64(t2, cpu_gpr[rd], t0, t1);
3418 tcg_temp_free(t2);
3419 }
b42ee5e1
LA
3420 break;
3421 case R6_OPC_DMULU:
3422 tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
b42ee5e1
LA
3423 break;
3424 case R6_OPC_DMUHU:
3425 {
3426 TCGv t2 = tcg_temp_new();
3427 tcg_gen_mulu2_i64(t2, cpu_gpr[rd], t0, t1);
3428 tcg_temp_free(t2);
3429 }
b42ee5e1
LA
3430 break;
3431#endif
3432 default:
9d68ac14 3433 MIPS_INVAL("r6 mul/div");
9c708c7f 3434 generate_exception_end(ctx, EXCP_RI);
b42ee5e1
LA
3435 goto out;
3436 }
b42ee5e1
LA
3437 out:
3438 tcg_temp_free(t0);
3439 tcg_temp_free(t1);
3440}
3441
26135ead
RS
3442static void gen_muldiv(DisasContext *ctx, uint32_t opc,
3443 int acc, int rs, int rt)
6af0bf9c 3444{
d45f89f4
AJ
3445 TCGv t0, t1;
3446
51127181
AJ
3447 t0 = tcg_temp_new();
3448 t1 = tcg_temp_new();
6af0bf9c 3449
78723684
TS
3450 gen_load_gpr(t0, rs);
3451 gen_load_gpr(t1, rt);
51127181 3452
26135ead
RS
3453 if (acc != 0) {
3454 check_dsp(ctx);
3455 }
3456
6af0bf9c
FB
3457 switch (opc) {
3458 case OPC_DIV:
48d38ca5 3459 {
51127181
AJ
3460 TCGv t2 = tcg_temp_new();
3461 TCGv t3 = tcg_temp_new();
d45f89f4
AJ
3462 tcg_gen_ext32s_tl(t0, t0);
3463 tcg_gen_ext32s_tl(t1, t1);
51127181
AJ
3464 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3465 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3466 tcg_gen_and_tl(t2, t2, t3);
3467 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3468 tcg_gen_or_tl(t2, t2, t3);
3469 tcg_gen_movi_tl(t3, 0);
3470 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
26135ead
RS
3471 tcg_gen_div_tl(cpu_LO[acc], t0, t1);
3472 tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
3473 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
3474 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
51127181
AJ
3475 tcg_temp_free(t3);
3476 tcg_temp_free(t2);
48d38ca5 3477 }
6af0bf9c
FB
3478 break;
3479 case OPC_DIVU:
48d38ca5 3480 {
51127181
AJ
3481 TCGv t2 = tcg_const_tl(0);
3482 TCGv t3 = tcg_const_tl(1);
0c0ed03b
AJ
3483 tcg_gen_ext32u_tl(t0, t0);
3484 tcg_gen_ext32u_tl(t1, t1);
51127181 3485 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
26135ead
RS
3486 tcg_gen_divu_tl(cpu_LO[acc], t0, t1);
3487 tcg_gen_remu_tl(cpu_HI[acc], t0, t1);
3488 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
3489 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
51127181
AJ
3490 tcg_temp_free(t3);
3491 tcg_temp_free(t2);
48d38ca5 3492 }
6af0bf9c
FB
3493 break;
3494 case OPC_MULT:
214c465f 3495 {
ce1dd5d1
RH
3496 TCGv_i32 t2 = tcg_temp_new_i32();
3497 TCGv_i32 t3 = tcg_temp_new_i32();
ce1dd5d1
RH
3498 tcg_gen_trunc_tl_i32(t2, t0);
3499 tcg_gen_trunc_tl_i32(t3, t1);
3500 tcg_gen_muls2_i32(t2, t3, t2, t3);
3501 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
3502 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
3503 tcg_temp_free_i32(t2);
3504 tcg_temp_free_i32(t3);
214c465f 3505 }
6af0bf9c
FB
3506 break;
3507 case OPC_MULTU:
214c465f 3508 {
ce1dd5d1
RH
3509 TCGv_i32 t2 = tcg_temp_new_i32();
3510 TCGv_i32 t3 = tcg_temp_new_i32();
ce1dd5d1
RH
3511 tcg_gen_trunc_tl_i32(t2, t0);
3512 tcg_gen_trunc_tl_i32(t3, t1);
3513 tcg_gen_mulu2_i32(t2, t3, t2, t3);
3514 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
3515 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
3516 tcg_temp_free_i32(t2);
3517 tcg_temp_free_i32(t3);
214c465f 3518 }
6af0bf9c 3519 break;
d26bc211 3520#if defined(TARGET_MIPS64)
7a387fff 3521 case OPC_DDIV:
48d38ca5 3522 {
51127181
AJ
3523 TCGv t2 = tcg_temp_new();
3524 TCGv t3 = tcg_temp_new();
3525 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3526 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3527 tcg_gen_and_tl(t2, t2, t3);
3528 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3529 tcg_gen_or_tl(t2, t2, t3);
3530 tcg_gen_movi_tl(t3, 0);
3531 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
26135ead
RS
3532 tcg_gen_div_tl(cpu_LO[acc], t0, t1);
3533 tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
51127181
AJ
3534 tcg_temp_free(t3);
3535 tcg_temp_free(t2);
48d38ca5 3536 }
7a387fff
TS
3537 break;
3538 case OPC_DDIVU:
48d38ca5 3539 {
51127181
AJ
3540 TCGv t2 = tcg_const_tl(0);
3541 TCGv t3 = tcg_const_tl(1);
3542 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
26135ead
RS
3543 tcg_gen_divu_i64(cpu_LO[acc], t0, t1);
3544 tcg_gen_remu_i64(cpu_HI[acc], t0, t1);
51127181
AJ
3545 tcg_temp_free(t3);
3546 tcg_temp_free(t2);
48d38ca5 3547 }
7a387fff
TS
3548 break;
3549 case OPC_DMULT:
26135ead 3550 tcg_gen_muls2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
7a387fff
TS
3551 break;
3552 case OPC_DMULTU:
26135ead 3553 tcg_gen_mulu2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
7a387fff
TS
3554 break;
3555#endif
6af0bf9c 3556 case OPC_MADD:
214c465f 3557 {
d45f89f4
AJ
3558 TCGv_i64 t2 = tcg_temp_new_i64();
3559 TCGv_i64 t3 = tcg_temp_new_i64();
3560
3561 tcg_gen_ext_tl_i64(t2, t0);
3562 tcg_gen_ext_tl_i64(t3, t1);
3563 tcg_gen_mul_i64(t2, t2, t3);
4133498f 3564 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
d45f89f4
AJ
3565 tcg_gen_add_i64(t2, t2, t3);
3566 tcg_temp_free_i64(t3);
71f303cd
RH
3567 gen_move_low32(cpu_LO[acc], t2);
3568 gen_move_high32(cpu_HI[acc], t2);
d45f89f4 3569 tcg_temp_free_i64(t2);
214c465f 3570 }
6af0bf9c
FB
3571 break;
3572 case OPC_MADDU:
4133498f 3573 {
d45f89f4
AJ
3574 TCGv_i64 t2 = tcg_temp_new_i64();
3575 TCGv_i64 t3 = tcg_temp_new_i64();
214c465f 3576
78723684
TS
3577 tcg_gen_ext32u_tl(t0, t0);
3578 tcg_gen_ext32u_tl(t1, t1);
d45f89f4
AJ
3579 tcg_gen_extu_tl_i64(t2, t0);
3580 tcg_gen_extu_tl_i64(t3, t1);
3581 tcg_gen_mul_i64(t2, t2, t3);
4133498f 3582 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
d45f89f4
AJ
3583 tcg_gen_add_i64(t2, t2, t3);
3584 tcg_temp_free_i64(t3);
71f303cd
RH
3585 gen_move_low32(cpu_LO[acc], t2);
3586 gen_move_high32(cpu_HI[acc], t2);
d45f89f4 3587 tcg_temp_free_i64(t2);
214c465f 3588 }
6af0bf9c
FB
3589 break;
3590 case OPC_MSUB:
214c465f 3591 {
d45f89f4
AJ
3592 TCGv_i64 t2 = tcg_temp_new_i64();
3593 TCGv_i64 t3 = tcg_temp_new_i64();
3594
3595 tcg_gen_ext_tl_i64(t2, t0);
3596 tcg_gen_ext_tl_i64(t3, t1);
3597 tcg_gen_mul_i64(t2, t2, t3);
4133498f 3598 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
98070ce0 3599 tcg_gen_sub_i64(t2, t3, t2);
d45f89f4 3600 tcg_temp_free_i64(t3);
71f303cd
RH
3601 gen_move_low32(cpu_LO[acc], t2);
3602 gen_move_high32(cpu_HI[acc], t2);
d45f89f4 3603 tcg_temp_free_i64(t2);
214c465f 3604 }
6af0bf9c
FB
3605 break;
3606 case OPC_MSUBU:
214c465f 3607 {
d45f89f4
AJ
3608 TCGv_i64 t2 = tcg_temp_new_i64();
3609 TCGv_i64 t3 = tcg_temp_new_i64();
214c465f 3610
78723684
TS
3611 tcg_gen_ext32u_tl(t0, t0);
3612 tcg_gen_ext32u_tl(t1, t1);
d45f89f4
AJ
3613 tcg_gen_extu_tl_i64(t2, t0);
3614 tcg_gen_extu_tl_i64(t3, t1);
3615 tcg_gen_mul_i64(t2, t2, t3);
4133498f 3616 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
98070ce0 3617 tcg_gen_sub_i64(t2, t3, t2);
d45f89f4 3618 tcg_temp_free_i64(t3);
71f303cd
RH
3619 gen_move_low32(cpu_LO[acc], t2);
3620 gen_move_high32(cpu_HI[acc], t2);
d45f89f4 3621 tcg_temp_free_i64(t2);
214c465f 3622 }
6af0bf9c
FB
3623 break;
3624 default:
9d68ac14 3625 MIPS_INVAL("mul/div");
9c708c7f 3626 generate_exception_end(ctx, EXCP_RI);
78723684 3627 goto out;
6af0bf9c 3628 }
78723684
TS
3629 out:
3630 tcg_temp_free(t0);
3631 tcg_temp_free(t1);
6af0bf9c
FB
3632}
3633
e9c71dd1
TS
3634static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
3635 int rd, int rs, int rt)
3636{
f157bfe1
AJ
3637 TCGv t0 = tcg_temp_new();
3638 TCGv t1 = tcg_temp_new();
e9c71dd1 3639
6c5c1e20
TS
3640 gen_load_gpr(t0, rs);
3641 gen_load_gpr(t1, rt);
e9c71dd1
TS
3642
3643 switch (opc) {
3644 case OPC_VR54XX_MULS:
895c2d04 3645 gen_helper_muls(t0, cpu_env, t0, t1);
6958549d 3646 break;
e9c71dd1 3647 case OPC_VR54XX_MULSU:
895c2d04 3648 gen_helper_mulsu(t0, cpu_env, t0, t1);
6958549d 3649 break;
e9c71dd1 3650 case OPC_VR54XX_MACC:
895c2d04 3651 gen_helper_macc(t0, cpu_env, t0, t1);
6958549d 3652 break;
e9c71dd1 3653 case OPC_VR54XX_MACCU:
895c2d04 3654 gen_helper_maccu(t0, cpu_env, t0, t1);
6958549d 3655 break;
e9c71dd1 3656 case OPC_VR54XX_MSAC:
895c2d04 3657 gen_helper_msac(t0, cpu_env, t0, t1);
6958549d 3658 break;
e9c71dd1 3659 case OPC_VR54XX_MSACU:
895c2d04 3660 gen_helper_msacu(t0, cpu_env, t0, t1);
6958549d 3661 break;
e9c71dd1 3662 case OPC_VR54XX_MULHI:
895c2d04 3663 gen_helper_mulhi(t0, cpu_env, t0, t1);
6958549d 3664 break;
e9c71dd1 3665 case OPC_VR54XX_MULHIU:
895c2d04 3666 gen_helper_mulhiu(t0, cpu_env, t0, t1);
6958549d 3667 break;
e9c71dd1 3668 case OPC_VR54XX_MULSHI:
895c2d04 3669 gen_helper_mulshi(t0, cpu_env, t0, t1);
6958549d 3670 break;
e9c71dd1 3671 case OPC_VR54XX_MULSHIU:
895c2d04 3672 gen_helper_mulshiu(t0, cpu_env, t0, t1);
6958549d 3673 break;
e9c71dd1 3674 case OPC_VR54XX_MACCHI:
895c2d04 3675 gen_helper_macchi(t0, cpu_env, t0, t1);
6958549d 3676 break;
e9c71dd1 3677 case OPC_VR54XX_MACCHIU:
895c2d04 3678 gen_helper_macchiu(t0, cpu_env, t0, t1);
6958549d 3679 break;
e9c71dd1 3680 case OPC_VR54XX_MSACHI:
895c2d04 3681 gen_helper_msachi(t0, cpu_env, t0, t1);
6958549d 3682 break;
e9c71dd1 3683 case OPC_VR54XX_MSACHIU:
895c2d04 3684 gen_helper_msachiu(t0, cpu_env, t0, t1);
6958549d 3685 break;
e9c71dd1
TS
3686 default:
3687 MIPS_INVAL("mul vr54xx");
9c708c7f 3688 generate_exception_end(ctx, EXCP_RI);
6c5c1e20 3689 goto out;
e9c71dd1 3690 }
6c5c1e20 3691 gen_store_gpr(t0, rd);
6c5c1e20
TS
3692
3693 out:
3694 tcg_temp_free(t0);
3695 tcg_temp_free(t1);
e9c71dd1
TS
3696}
3697
7a387fff 3698static void gen_cl (DisasContext *ctx, uint32_t opc,
6af0bf9c
FB
3699 int rd, int rs)
3700{
20e1fb52 3701 TCGv t0;
6c5c1e20 3702
6af0bf9c 3703 if (rd == 0) {
ead9360e 3704 /* Treat as NOP. */
20e1fb52 3705 return;
6af0bf9c 3706 }
1a0196c5 3707 t0 = cpu_gpr[rd];
6c5c1e20 3708 gen_load_gpr(t0, rs);
1a0196c5 3709
6af0bf9c
FB
3710 switch (opc) {
3711 case OPC_CLO:
4267d3e6 3712 case R6_OPC_CLO:
1a0196c5
RH
3713#if defined(TARGET_MIPS64)
3714 case OPC_DCLO:
3715 case R6_OPC_DCLO:
3716#endif
3717 tcg_gen_not_tl(t0, t0);
6af0bf9c 3718 break;
1a0196c5
RH
3719 }
3720
3721 switch (opc) {
3722 case OPC_CLO:
3723 case R6_OPC_CLO:
6af0bf9c 3724 case OPC_CLZ:
4267d3e6 3725 case R6_OPC_CLZ:
1a0196c5
RH
3726 tcg_gen_ext32u_tl(t0, t0);
3727 tcg_gen_clzi_tl(t0, t0, TARGET_LONG_BITS);
3728 tcg_gen_subi_tl(t0, t0, TARGET_LONG_BITS - 32);
6af0bf9c 3729 break;
d26bc211 3730#if defined(TARGET_MIPS64)
7a387fff 3731 case OPC_DCLO:
4267d3e6 3732 case R6_OPC_DCLO:
7a387fff 3733 case OPC_DCLZ:
4267d3e6 3734 case R6_OPC_DCLZ:
1a0196c5 3735 tcg_gen_clzi_i64(t0, t0, 64);
7a387fff
TS
3736 break;
3737#endif
6af0bf9c 3738 }
6af0bf9c
FB
3739}
3740
161f85e6 3741/* Godson integer instructions */
bd277fa1
RH
3742static void gen_loongson_integer(DisasContext *ctx, uint32_t opc,
3743 int rd, int rs, int rt)
161f85e6 3744{
161f85e6
AJ
3745 TCGv t0, t1;
3746
3747 if (rd == 0) {
3748 /* Treat as NOP. */
161f85e6
AJ
3749 return;
3750 }
3751
3752 switch (opc) {
3753 case OPC_MULT_G_2E:
3754 case OPC_MULT_G_2F:
3755 case OPC_MULTU_G_2E:
3756 case OPC_MULTU_G_2F:
3757#if defined(TARGET_MIPS64)
3758 case OPC_DMULT_G_2E:
3759 case OPC_DMULT_G_2F:
3760 case OPC_DMULTU_G_2E:
3761 case OPC_DMULTU_G_2F:
3762#endif
3763 t0 = tcg_temp_new();
3764 t1 = tcg_temp_new();
3765 break;
3766 default:
3767 t0 = tcg_temp_local_new();
3768 t1 = tcg_temp_local_new();
3769 break;
3770 }
3771
3772 gen_load_gpr(t0, rs);
3773 gen_load_gpr(t1, rt);
3774
3775 switch (opc) {
3776 case OPC_MULT_G_2E:
3777 case OPC_MULT_G_2F:
3778 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3779 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
161f85e6
AJ
3780 break;
3781 case OPC_MULTU_G_2E:
3782 case OPC_MULTU_G_2F:
3783 tcg_gen_ext32u_tl(t0, t0);
3784 tcg_gen_ext32u_tl(t1, t1);
3785 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3786 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
161f85e6
AJ
3787 break;
3788 case OPC_DIV_G_2E:
3789 case OPC_DIV_G_2F:
3790 {
42a268c2
RH
3791 TCGLabel *l1 = gen_new_label();
3792 TCGLabel *l2 = gen_new_label();
3793 TCGLabel *l3 = gen_new_label();
161f85e6
AJ
3794 tcg_gen_ext32s_tl(t0, t0);
3795 tcg_gen_ext32s_tl(t1, t1);
3796 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3797 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3798 tcg_gen_br(l3);
3799 gen_set_label(l1);
3800 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3801 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3802 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3803 tcg_gen_br(l3);
3804 gen_set_label(l2);
3805 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3806 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3807 gen_set_label(l3);
3808 }
161f85e6
AJ
3809 break;
3810 case OPC_DIVU_G_2E:
3811 case OPC_DIVU_G_2F:
3812 {
42a268c2
RH
3813 TCGLabel *l1 = gen_new_label();
3814 TCGLabel *l2 = gen_new_label();
161f85e6
AJ
3815 tcg_gen_ext32u_tl(t0, t0);
3816 tcg_gen_ext32u_tl(t1, t1);
3817 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3818 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3819 tcg_gen_br(l2);
3820 gen_set_label(l1);
3821 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3822 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3823 gen_set_label(l2);
3824 }
161f85e6
AJ
3825 break;
3826 case OPC_MOD_G_2E:
3827 case OPC_MOD_G_2F:
3828 {
42a268c2
RH
3829 TCGLabel *l1 = gen_new_label();
3830 TCGLabel *l2 = gen_new_label();
3831 TCGLabel *l3 = gen_new_label();
161f85e6
AJ
3832 tcg_gen_ext32u_tl(t0, t0);
3833 tcg_gen_ext32u_tl(t1, t1);
3834 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3835 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3836 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3837 gen_set_label(l1);
3838 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3839 tcg_gen_br(l3);
3840 gen_set_label(l2);
3841 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3842 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3843 gen_set_label(l3);
3844 }
161f85e6
AJ
3845 break;
3846 case OPC_MODU_G_2E:
3847 case OPC_MODU_G_2F:
3848 {
42a268c2
RH
3849 TCGLabel *l1 = gen_new_label();
3850 TCGLabel *l2 = gen_new_label();
161f85e6
AJ
3851 tcg_gen_ext32u_tl(t0, t0);
3852 tcg_gen_ext32u_tl(t1, t1);
3853 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3854 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3855 tcg_gen_br(l2);
3856 gen_set_label(l1);
3857 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3858 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3859 gen_set_label(l2);
3860 }
161f85e6
AJ
3861 break;
3862#if defined(TARGET_MIPS64)
3863 case OPC_DMULT_G_2E:
3864 case OPC_DMULT_G_2F:
3865 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
161f85e6
AJ
3866 break;
3867 case OPC_DMULTU_G_2E:
3868 case OPC_DMULTU_G_2F:
3869 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
161f85e6
AJ
3870 break;
3871 case OPC_DDIV_G_2E:
3872 case OPC_DDIV_G_2F:
3873 {
42a268c2
RH
3874 TCGLabel *l1 = gen_new_label();
3875 TCGLabel *l2 = gen_new_label();
3876 TCGLabel *l3 = gen_new_label();
161f85e6
AJ
3877 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3878 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3879 tcg_gen_br(l3);
3880 gen_set_label(l1);
3881 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3882 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3883 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3884 tcg_gen_br(l3);
3885 gen_set_label(l2);
3886 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3887 gen_set_label(l3);
3888 }
161f85e6
AJ
3889 break;
3890 case OPC_DDIVU_G_2E:
3891 case OPC_DDIVU_G_2F:
3892 {
42a268c2
RH
3893 TCGLabel *l1 = gen_new_label();
3894 TCGLabel *l2 = gen_new_label();
161f85e6
AJ
3895 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3896 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3897 tcg_gen_br(l2);
3898 gen_set_label(l1);
3899 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3900 gen_set_label(l2);
3901 }
161f85e6
AJ
3902 break;
3903 case OPC_DMOD_G_2E:
3904 case OPC_DMOD_G_2F:
3905 {
42a268c2
RH
3906 TCGLabel *l1 = gen_new_label();
3907 TCGLabel *l2 = gen_new_label();
3908 TCGLabel *l3 = gen_new_label();
161f85e6
AJ
3909 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3910 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3911 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3912 gen_set_label(l1);
3913 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3914 tcg_gen_br(l3);
3915 gen_set_label(l2);
3916 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3917 gen_set_label(l3);
3918 }
161f85e6
AJ
3919 break;
3920 case OPC_DMODU_G_2E:
3921 case OPC_DMODU_G_2F:
3922 {
42a268c2
RH
3923 TCGLabel *l1 = gen_new_label();
3924 TCGLabel *l2 = gen_new_label();
161f85e6
AJ
3925 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3926 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3927 tcg_gen_br(l2);
3928 gen_set_label(l1);
3929 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3930 gen_set_label(l2);
3931 }
161f85e6
AJ
3932 break;
3933#endif
3934 }
3935
161f85e6
AJ
3936 tcg_temp_free(t0);
3937 tcg_temp_free(t1);
3938}
3939
bd277fa1
RH
3940/* Loongson multimedia instructions */
3941static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt)
3942{
bd277fa1
RH
3943 uint32_t opc, shift_max;
3944 TCGv_i64 t0, t1;
3945
3946 opc = MASK_LMI(ctx->opcode);
3947 switch (opc) {
3948 case OPC_ADD_CP2:
3949 case OPC_SUB_CP2:
3950 case OPC_DADD_CP2:
3951 case OPC_DSUB_CP2:
3952 t0 = tcg_temp_local_new_i64();
3953 t1 = tcg_temp_local_new_i64();
3954 break;
3955 default:
3956 t0 = tcg_temp_new_i64();
3957 t1 = tcg_temp_new_i64();
3958 break;
3959 }
3960
b5a587b6 3961 check_cp1_enabled(ctx);
bd277fa1
RH
3962 gen_load_fpr64(ctx, t0, rs);
3963 gen_load_fpr64(ctx, t1, rt);
3964
3965#define LMI_HELPER(UP, LO) \
9d68ac14 3966 case OPC_##UP: gen_helper_##LO(t0, t0, t1); break
bd277fa1 3967#define LMI_HELPER_1(UP, LO) \
9d68ac14 3968 case OPC_##UP: gen_helper_##LO(t0, t0); break
bd277fa1 3969#define LMI_DIRECT(UP, LO, OP) \
9d68ac14 3970 case OPC_##UP: tcg_gen_##OP##_i64(t0, t0, t1); break
bd277fa1
RH
3971
3972 switch (opc) {
3973 LMI_HELPER(PADDSH, paddsh);
3974 LMI_HELPER(PADDUSH, paddush);
3975 LMI_HELPER(PADDH, paddh);
3976 LMI_HELPER(PADDW, paddw);
3977 LMI_HELPER(PADDSB, paddsb);
3978 LMI_HELPER(PADDUSB, paddusb);
3979 LMI_HELPER(PADDB, paddb);
3980
3981 LMI_HELPER(PSUBSH, psubsh);
3982 LMI_HELPER(PSUBUSH, psubush);
3983 LMI_HELPER(PSUBH, psubh);
3984 LMI_HELPER(PSUBW, psubw);
3985 LMI_HELPER(PSUBSB, psubsb);
3986 LMI_HELPER(PSUBUSB, psubusb);
3987 LMI_HELPER(PSUBB, psubb);
3988
3989 LMI_HELPER(PSHUFH, pshufh);
3990 LMI_HELPER(PACKSSWH, packsswh);
3991 LMI_HELPER(PACKSSHB, packsshb);
3992 LMI_HELPER(PACKUSHB, packushb);
3993
3994 LMI_HELPER(PUNPCKLHW, punpcklhw);
3995 LMI_HELPER(PUNPCKHHW, punpckhhw);
3996 LMI_HELPER(PUNPCKLBH, punpcklbh);
3997 LMI_HELPER(PUNPCKHBH, punpckhbh);
3998 LMI_HELPER(PUNPCKLWD, punpcklwd);
3999 LMI_HELPER(PUNPCKHWD, punpckhwd);
4000
4001 LMI_HELPER(PAVGH, pavgh);
4002 LMI_HELPER(PAVGB, pavgb);
4003 LMI_HELPER(PMAXSH, pmaxsh);
4004 LMI_HELPER(PMINSH, pminsh);
4005 LMI_HELPER(PMAXUB, pmaxub);
4006 LMI_HELPER(PMINUB, pminub);
4007
4008 LMI_HELPER(PCMPEQW, pcmpeqw);
4009 LMI_HELPER(PCMPGTW, pcmpgtw);
4010 LMI_HELPER(PCMPEQH, pcmpeqh);
4011 LMI_HELPER(PCMPGTH, pcmpgth);
4012 LMI_HELPER(PCMPEQB, pcmpeqb);
4013 LMI_HELPER(PCMPGTB, pcmpgtb);
4014
4015 LMI_HELPER(PSLLW, psllw);
4016 LMI_HELPER(PSLLH, psllh);
4017 LMI_HELPER(PSRLW, psrlw);
4018 LMI_HELPER(PSRLH, psrlh);
4019 LMI_HELPER(PSRAW, psraw);
4020 LMI_HELPER(PSRAH, psrah);
4021
4022 LMI_HELPER(PMULLH, pmullh);
4023 LMI_HELPER(PMULHH, pmulhh);
4024 LMI_HELPER(PMULHUH, pmulhuh);
4025 LMI_HELPER(PMADDHW, pmaddhw);
4026
4027 LMI_HELPER(PASUBUB, pasubub);
4028 LMI_HELPER_1(BIADD, biadd);
4029 LMI_HELPER_1(PMOVMSKB, pmovmskb);
4030
4031 LMI_DIRECT(PADDD, paddd, add);
4032 LMI_DIRECT(PSUBD, psubd, sub);
4033 LMI_DIRECT(XOR_CP2, xor, xor);
4034 LMI_DIRECT(NOR_CP2, nor, nor);
4035 LMI_DIRECT(AND_CP2, and, and);
bb7cab5f 4036 LMI_DIRECT(OR_CP2, or, or);
bd277fa1 4037
9099a36b
H
4038 case OPC_PANDN:
4039 tcg_gen_andc_i64(t0, t1, t0);
4040 break;
4041
bd277fa1
RH
4042 case OPC_PINSRH_0:
4043 tcg_gen_deposit_i64(t0, t0, t1, 0, 16);
bd277fa1
RH
4044 break;
4045 case OPC_PINSRH_1:
4046 tcg_gen_deposit_i64(t0, t0, t1, 16, 16);
bd277fa1
RH
4047 break;
4048 case OPC_PINSRH_2:
4049 tcg_gen_deposit_i64(t0, t0, t1, 32, 16);
bd277fa1
RH
4050 break;
4051 case OPC_PINSRH_3:
4052 tcg_gen_deposit_i64(t0, t0, t1, 48, 16);
bd277fa1
RH
4053 break;
4054
4055 case OPC_PEXTRH:
4056 tcg_gen_andi_i64(t1, t1, 3);
4057 tcg_gen_shli_i64(t1, t1, 4);
4058 tcg_gen_shr_i64(t0, t0, t1);
4059 tcg_gen_ext16u_i64(t0, t0);
bd277fa1
RH
4060 break;
4061
4062 case OPC_ADDU_CP2:
4063 tcg_gen_add_i64(t0, t0, t1);
4064 tcg_gen_ext32s_i64(t0, t0);
bd277fa1
RH
4065 break;
4066 case OPC_SUBU_CP2:
4067 tcg_gen_sub_i64(t0, t0, t1);
4068 tcg_gen_ext32s_i64(t0, t0);
bd277fa1
RH
4069 break;
4070
4071 case OPC_SLL_CP2:
bd277fa1
RH
4072 shift_max = 32;
4073 goto do_shift;
4074 case OPC_SRL_CP2:
bd277fa1
RH
4075 shift_max = 32;
4076 goto do_shift;
4077 case OPC_SRA_CP2:
bd277fa1
RH
4078 shift_max = 32;
4079 goto do_shift;
4080 case OPC_DSLL_CP2:
bd277fa1
RH
4081 shift_max = 64;
4082 goto do_shift;
4083 case OPC_DSRL_CP2:
bd277fa1
RH
4084 shift_max = 64;
4085 goto do_shift;
4086 case OPC_DSRA_CP2:
bd277fa1
RH
4087 shift_max = 64;
4088 goto do_shift;
4089 do_shift:
4090 /* Make sure shift count isn't TCG undefined behaviour. */
4091 tcg_gen_andi_i64(t1, t1, shift_max - 1);
4092
4093 switch (opc) {
4094 case OPC_SLL_CP2:
4095 case OPC_DSLL_CP2:
4096 tcg_gen_shl_i64(t0, t0, t1);
4097 break;
4098 case OPC_SRA_CP2:
4099 case OPC_DSRA_CP2:
4100 /* Since SRA is UndefinedResult without sign-extended inputs,
4101 we can treat SRA and DSRA the same. */
4102 tcg_gen_sar_i64(t0, t0, t1);
4103 break;
4104 case OPC_SRL_CP2:
4105 /* We want to shift in zeros for SRL; zero-extend first. */
4106 tcg_gen_ext32u_i64(t0, t0);
4107 /* FALLTHRU */
4108 case OPC_DSRL_CP2:
4109 tcg_gen_shr_i64(t0, t0, t1);
4110 break;
4111 }
4112
4113 if (shift_max == 32) {
4114 tcg_gen_ext32s_i64(t0, t0);
4115 }
4116
4117 /* Shifts larger than MAX produce zero. */
4118 tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max);
4119 tcg_gen_neg_i64(t1, t1);
4120 tcg_gen_and_i64(t0, t0, t1);
4121 break;
4122
4123 case OPC_ADD_CP2:
4124 case OPC_DADD_CP2:
4125 {
4126 TCGv_i64 t2 = tcg_temp_new_i64();
42a268c2 4127 TCGLabel *lab = gen_new_label();
bd277fa1
RH
4128
4129 tcg_gen_mov_i64(t2, t0);
4130 tcg_gen_add_i64(t0, t1, t2);
4131 if (opc == OPC_ADD_CP2) {
4132 tcg_gen_ext32s_i64(t0, t0);
4133 }
4134 tcg_gen_xor_i64(t1, t1, t2);
4135 tcg_gen_xor_i64(t2, t2, t0);
4136 tcg_gen_andc_i64(t1, t2, t1);
4137 tcg_temp_free_i64(t2);
4138 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
4139 generate_exception(ctx, EXCP_OVERFLOW);
4140 gen_set_label(lab);
bd277fa1
RH
4141 break;
4142 }
4143
4144 case OPC_SUB_CP2:
4145 case OPC_DSUB_CP2:
4146 {
4147 TCGv_i64 t2 = tcg_temp_new_i64();
42a268c2 4148 TCGLabel *lab = gen_new_label();
bd277fa1
RH
4149
4150 tcg_gen_mov_i64(t2, t0);
4151 tcg_gen_sub_i64(t0, t1, t2);
4152 if (opc == OPC_SUB_CP2) {
4153 tcg_gen_ext32s_i64(t0, t0);
4154 }
4155 tcg_gen_xor_i64(t1, t1, t2);
4156 tcg_gen_xor_i64(t2, t2, t0);
4157 tcg_gen_and_i64(t1, t1, t2);
4158 tcg_temp_free_i64(t2);
4159 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
4160 generate_exception(ctx, EXCP_OVERFLOW);
4161 gen_set_label(lab);
bd277fa1
RH
4162 break;
4163 }
4164
4165 case OPC_PMULUW:
4166 tcg_gen_ext32u_i64(t0, t0);
4167 tcg_gen_ext32u_i64(t1, t1);
4168 tcg_gen_mul_i64(t0, t0, t1);
bd277fa1
RH
4169 break;
4170
4171 case OPC_SEQU_CP2:
4172 case OPC_SEQ_CP2:
4173 case OPC_SLTU_CP2:
4174 case OPC_SLT_CP2:
4175 case OPC_SLEU_CP2:
4176 case OPC_SLE_CP2:
4177 /* ??? Document is unclear: Set FCC[CC]. Does that mean the
4178 FD field is the CC field? */
4179 default:
9d68ac14 4180 MIPS_INVAL("loongson_cp2");
9c708c7f 4181 generate_exception_end(ctx, EXCP_RI);
bd277fa1
RH
4182 return;
4183 }
4184
4185#undef LMI_HELPER
4186#undef LMI_DIRECT
4187
4188 gen_store_fpr64(ctx, t0, rd);
4189
bd277fa1
RH
4190 tcg_temp_free_i64(t0);
4191 tcg_temp_free_i64(t1);
4192}
4193
6af0bf9c 4194/* Traps */
7a387fff 4195static void gen_trap (DisasContext *ctx, uint32_t opc,
6af0bf9c
FB
4196 int rs, int rt, int16_t imm)
4197{
4198 int cond;
cdc0faa6 4199 TCGv t0 = tcg_temp_new();
1ba74fb8 4200 TCGv t1 = tcg_temp_new();
6af0bf9c
FB
4201
4202 cond = 0;
4203 /* Load needed operands */
4204 switch (opc) {
4205 case OPC_TEQ:
4206 case OPC_TGE:
4207 case OPC_TGEU:
4208 case OPC_TLT:
4209 case OPC_TLTU:
4210 case OPC_TNE:
4211 /* Compare two registers */
4212 if (rs != rt) {
be24bb4f
TS
4213 gen_load_gpr(t0, rs);
4214 gen_load_gpr(t1, rt);
6af0bf9c
FB
4215 cond = 1;
4216 }
179e32bb 4217 break;
6af0bf9c
FB
4218 case OPC_TEQI:
4219 case OPC_TGEI:
4220 case OPC_TGEIU:
4221 case OPC_TLTI:
4222 case OPC_TLTIU:
4223 case OPC_TNEI:
4224 /* Compare register to immediate */
4225 if (rs != 0 || imm != 0) {
be24bb4f
TS
4226 gen_load_gpr(t0, rs);
4227 tcg_gen_movi_tl(t1, (int32_t)imm);
6af0bf9c
FB
4228 cond = 1;
4229 }
4230 break;
4231 }
4232 if (cond == 0) {
4233 switch (opc) {
4234 case OPC_TEQ: /* rs == rs */
4235 case OPC_TEQI: /* r0 == 0 */
4236 case OPC_TGE: /* rs >= rs */
4237 case OPC_TGEI: /* r0 >= 0 */
4238 case OPC_TGEU: /* rs >= rs unsigned */
4239 case OPC_TGEIU: /* r0 >= 0 unsigned */
4240 /* Always trap */
9c708c7f 4241 generate_exception_end(ctx, EXCP_TRAP);
6af0bf9c
FB
4242 break;
4243 case OPC_TLT: /* rs < rs */
4244 case OPC_TLTI: /* r0 < 0 */
4245 case OPC_TLTU: /* rs < rs unsigned */
4246 case OPC_TLTIU: /* r0 < 0 unsigned */
4247 case OPC_TNE: /* rs != rs */
4248 case OPC_TNEI: /* r0 != 0 */
ead9360e 4249 /* Never trap: treat as NOP. */
cdc0faa6 4250 break;
6af0bf9c
FB
4251 }
4252 } else {
42a268c2 4253 TCGLabel *l1 = gen_new_label();
cdc0faa6 4254
6af0bf9c
FB
4255 switch (opc) {
4256 case OPC_TEQ:
4257 case OPC_TEQI:
cdc0faa6 4258 tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
6af0bf9c
FB
4259 break;
4260 case OPC_TGE:
4261 case OPC_TGEI:
cdc0faa6 4262 tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
6af0bf9c
FB
4263 break;
4264 case OPC_TGEU:
4265 case OPC_TGEIU:
cdc0faa6 4266 tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
6af0bf9c
FB
4267 break;
4268 case OPC_TLT:
4269 case OPC_TLTI:
cdc0faa6 4270 tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
6af0bf9c
FB
4271 break;
4272 case OPC_TLTU:
4273 case OPC_TLTIU:
cdc0faa6 4274 tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
6af0bf9c
FB
4275 break;
4276 case OPC_TNE:
4277 case OPC_TNEI:
cdc0faa6 4278 tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
6af0bf9c 4279 break;
6af0bf9c 4280 }
cdc0faa6 4281 generate_exception(ctx, EXCP_TRAP);
08ba7963
TS
4282 gen_set_label(l1);
4283 }
be24bb4f
TS
4284 tcg_temp_free(t0);
4285 tcg_temp_free(t1);
6af0bf9c
FB
4286}
4287
90aa39a1
SF
4288static inline bool use_goto_tb(DisasContext *ctx, target_ulong dest)
4289{
eeb3bba8 4290 if (unlikely(ctx->base.singlestep_enabled)) {
90aa39a1
SF
4291 return false;
4292 }
4293
4294#ifndef CONFIG_USER_ONLY
eeb3bba8 4295 return (ctx->base.tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
90aa39a1
SF
4296#else
4297 return true;
4298#endif
4299}
4300
356265ae 4301static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
c53be334 4302{
90aa39a1 4303 if (use_goto_tb(ctx, dest)) {
57fec1fe 4304 tcg_gen_goto_tb(n);
9b9e4393 4305 gen_save_pc(dest);
07ea28b4 4306 tcg_gen_exit_tb(ctx->base.tb, n);
6e256c93 4307 } else {
9b9e4393 4308 gen_save_pc(dest);
eeb3bba8 4309 if (ctx->base.singlestep_enabled) {
7b270ef2 4310 save_cpu_state(ctx, 0);
9c708c7f 4311 gen_helper_raise_exception_debug(cpu_env);
7b270ef2 4312 }
7f11636d 4313 tcg_gen_lookup_and_goto_ptr();
6e256c93 4314 }
c53be334
FB
4315}
4316
6af0bf9c 4317/* Branches (before delay slot) */
7a387fff 4318static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
7dca4ad0 4319 int insn_bytes,
b231c103
YK
4320 int rs, int rt, int32_t offset,
4321 int delayslot_size)
6af0bf9c 4322{
d077b6f7 4323 target_ulong btgt = -1;
3ad4bb2d 4324 int blink = 0;
2fdbad25 4325 int bcond_compute = 0;
1ba74fb8
AJ
4326 TCGv t0 = tcg_temp_new();
4327 TCGv t1 = tcg_temp_new();
3ad4bb2d
TS
4328
4329 if (ctx->hflags & MIPS_HFLAG_BMASK) {
923617a3 4330#ifdef MIPS_DEBUG_DISAS
339cd2a8 4331 LOG_DISAS("Branch in delay / forbidden slot at PC 0x"
eeb3bba8 4332 TARGET_FMT_lx "\n", ctx->base.pc_next);
923617a3 4333#endif
9c708c7f 4334 generate_exception_end(ctx, EXCP_RI);
6c5c1e20 4335 goto out;
3ad4bb2d 4336 }
6af0bf9c 4337
6af0bf9c
FB
4338 /* Load needed operands */
4339 switch (opc) {
4340 case OPC_BEQ:
4341 case OPC_BEQL:
4342 case OPC_BNE:
4343 case OPC_BNEL:
4344 /* Compare two registers */
4345 if (rs != rt) {
6c5c1e20
TS
4346 gen_load_gpr(t0, rs);
4347 gen_load_gpr(t1, rt);
2fdbad25 4348 bcond_compute = 1;
6af0bf9c 4349 }
eeb3bba8 4350 btgt = ctx->base.pc_next + insn_bytes + offset;
6af0bf9c
FB
4351 break;
4352 case OPC_BGEZ:
4353 case OPC_BGEZAL:
4354 case OPC_BGEZALL:
4355 case OPC_BGEZL:
4356 case OPC_BGTZ:
4357 case OPC_BGTZL:
4358 case OPC_BLEZ:
4359 case OPC_BLEZL:
4360 case OPC_BLTZ:
4361 case OPC_BLTZAL:
4362 case OPC_BLTZALL:
4363 case OPC_BLTZL:
4364 /* Compare to zero */
4365 if (rs != 0) {
6c5c1e20 4366 gen_load_gpr(t0, rs);
2fdbad25 4367 bcond_compute = 1;
6af0bf9c 4368 }
eeb3bba8 4369 btgt = ctx->base.pc_next + insn_bytes + offset;
6af0bf9c 4370 break;
e45a93e2
JL
4371 case OPC_BPOSGE32:
4372#if defined(TARGET_MIPS64)
4373 case OPC_BPOSGE64:
4374 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x7F);
4375#else
4376 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
4377#endif
4378 bcond_compute = 1;
eeb3bba8 4379 btgt = ctx->base.pc_next + insn_bytes + offset;
e45a93e2 4380 break;
6af0bf9c
FB
4381 case OPC_J:
4382 case OPC_JAL:
364d4831 4383 case OPC_JALX:
6af0bf9c 4384 /* Jump to immediate */
eeb3bba8
EC
4385 btgt = ((ctx->base.pc_next + insn_bytes) & (int32_t)0xF0000000) |
4386 (uint32_t)offset;
6af0bf9c
FB
4387 break;
4388 case OPC_JR:
4389 case OPC_JALR:
4390 /* Jump to register */
7a387fff
TS
4391 if (offset != 0 && offset != 16) {
4392 /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
cbeb0857 4393 others are reserved. */
923617a3 4394 MIPS_INVAL("jump hint");
9c708c7f 4395 generate_exception_end(ctx, EXCP_RI);
6c5c1e20 4396 goto out;
6af0bf9c 4397 }
d077b6f7 4398 gen_load_gpr(btarget, rs);
6af0bf9c
FB
4399 break;
4400 default:
4401 MIPS_INVAL("branch/jump");
9c708c7f 4402 generate_exception_end(ctx, EXCP_RI);
6c5c1e20 4403 goto out;
6af0bf9c 4404 }
2fdbad25 4405 if (bcond_compute == 0) {
6af0bf9c
FB
4406 /* No condition to be computed */
4407 switch (opc) {
4408 case OPC_BEQ: /* rx == rx */
4409 case OPC_BEQL: /* rx == rx likely */
4410 case OPC_BGEZ: /* 0 >= 0 */
4411 case OPC_BGEZL: /* 0 >= 0 likely */
4412 case OPC_BLEZ: /* 0 <= 0 */
4413 case OPC_BLEZL: /* 0 <= 0 likely */
4414 /* Always take */
4ad40f36 4415 ctx->hflags |= MIPS_HFLAG_B;
6af0bf9c
FB
4416 break;
4417 case OPC_BGEZAL: /* 0 >= 0 */
4418 case OPC_BGEZALL: /* 0 >= 0 likely */
4419 /* Always take and link */
4420 blink = 31;
4ad40f36 4421 ctx->hflags |= MIPS_HFLAG_B;
6af0bf9c
FB
4422 break;
4423 case OPC_BNE: /* rx != rx */
4424 case OPC_BGTZ: /* 0 > 0 */
4425 case OPC_BLTZ: /* 0 < 0 */
ead9360e 4426 /* Treat as NOP. */
6c5c1e20 4427 goto out;
eeef26cd 4428 case OPC_BLTZAL: /* 0 < 0 */
3c824109
NF
4429 /* Handle as an unconditional branch to get correct delay
4430 slot checking. */
4431 blink = 31;
eeb3bba8 4432 btgt = ctx->base.pc_next + insn_bytes + delayslot_size;
3c824109 4433 ctx->hflags |= MIPS_HFLAG_B;
3c824109 4434 break;
eeef26cd 4435 case OPC_BLTZALL: /* 0 < 0 likely */
eeb3bba8 4436 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 8);
9898128f 4437 /* Skip the instruction in the delay slot */
eeb3bba8 4438 ctx->base.pc_next += 4;
6c5c1e20 4439 goto out;
6af0bf9c
FB
4440 case OPC_BNEL: /* rx != rx likely */
4441 case OPC_BGTZL: /* 0 > 0 likely */
6af0bf9c
FB
4442 case OPC_BLTZL: /* 0 < 0 likely */
4443 /* Skip the instruction in the delay slot */
eeb3bba8 4444 ctx->base.pc_next += 4;
6c5c1e20 4445 goto out;
6af0bf9c 4446 case OPC_J:
4ad40f36 4447 ctx->hflags |= MIPS_HFLAG_B;
6af0bf9c 4448 break;
364d4831
NF
4449 case OPC_JALX:
4450 ctx->hflags |= MIPS_HFLAG_BX;
4451 /* Fallthrough */
6af0bf9c
FB
4452 case OPC_JAL:
4453 blink = 31;
4ad40f36 4454 ctx->hflags |= MIPS_HFLAG_B;
6af0bf9c
FB
4455 break;
4456 case OPC_JR:
4ad40f36 4457 ctx->hflags |= MIPS_HFLAG_BR;
6af0bf9c
FB
4458 break;
4459 case OPC_JALR:
4460 blink = rt;
4ad40f36 4461 ctx->hflags |= MIPS_HFLAG_BR;
6af0bf9c
FB
4462 break;
4463 default:
4464 MIPS_INVAL("branch/jump");
9c708c7f 4465 generate_exception_end(ctx, EXCP_RI);
6c5c1e20 4466 goto out;
6af0bf9c
FB
4467 }
4468 } else {
4469 switch (opc) {
4470 case OPC_BEQ:
e68dd28f 4471 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
6af0bf9c
FB
4472 goto not_likely;
4473 case OPC_BEQL:
e68dd28f 4474 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
6af0bf9c
FB
4475 goto likely;
4476 case OPC_BNE:
e68dd28f 4477 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
6af0bf9c
FB
4478 goto not_likely;
4479 case OPC_BNEL:
e68dd28f 4480 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
6af0bf9c
FB
4481 goto likely;
4482 case OPC_BGEZ:
e68dd28f 4483 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6af0bf9c
FB
4484 goto not_likely;
4485 case OPC_BGEZL:
e68dd28f 4486 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6af0bf9c
FB
4487 goto likely;
4488 case OPC_BGEZAL:
e68dd28f 4489 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6af0bf9c
FB
4490 blink = 31;
4491 goto not_likely;
4492 case OPC_BGEZALL:
e68dd28f 4493 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6af0bf9c 4494 blink = 31;
6af0bf9c
FB
4495 goto likely;
4496 case OPC_BGTZ:
e68dd28f 4497 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
6af0bf9c
FB
4498 goto not_likely;
4499 case OPC_BGTZL:
e68dd28f 4500 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
6af0bf9c
FB
4501 goto likely;
4502 case OPC_BLEZ:
e68dd28f 4503 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
6af0bf9c
FB
4504 goto not_likely;
4505 case OPC_BLEZL:
e68dd28f 4506 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
6af0bf9c
FB
4507 goto likely;
4508 case OPC_BLTZ:
e68dd28f 4509 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6af0bf9c
FB
4510 goto not_likely;
4511 case OPC_BLTZL:
e68dd28f 4512 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6af0bf9c 4513 goto likely;
e45a93e2
JL
4514 case OPC_BPOSGE32:
4515 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
e45a93e2
JL
4516 goto not_likely;
4517#if defined(TARGET_MIPS64)
4518 case OPC_BPOSGE64:
4519 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 64);
e45a93e2
JL
4520 goto not_likely;
4521#endif
6af0bf9c 4522 case OPC_BLTZAL:
e68dd28f 4523 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6af0bf9c 4524 blink = 31;
6af0bf9c 4525 not_likely:
4ad40f36 4526 ctx->hflags |= MIPS_HFLAG_BC;
6af0bf9c
FB
4527 break;
4528 case OPC_BLTZALL:
e68dd28f 4529 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6af0bf9c 4530 blink = 31;
6af0bf9c 4531 likely:
4ad40f36 4532 ctx->hflags |= MIPS_HFLAG_BL;
6af0bf9c 4533 break;
c53f4a62
TS
4534 default:
4535 MIPS_INVAL("conditional branch/jump");
9c708c7f 4536 generate_exception_end(ctx, EXCP_RI);
6c5c1e20 4537 goto out;
6af0bf9c 4538 }
6af0bf9c 4539 }
9b9e4393 4540
d077b6f7 4541 ctx->btarget = btgt;
b231c103
YK
4542
4543 switch (delayslot_size) {
4544 case 2:
4545 ctx->hflags |= MIPS_HFLAG_BDS16;
4546 break;
4547 case 4:
4548 ctx->hflags |= MIPS_HFLAG_BDS32;
4549 break;
4550 }
4551
6af0bf9c 4552 if (blink > 0) {
b231c103 4553 int post_delay = insn_bytes + delayslot_size;
364d4831
NF
4554 int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
4555
eeb3bba8
EC
4556 tcg_gen_movi_tl(cpu_gpr[blink],
4557 ctx->base.pc_next + post_delay + lowbit);
6af0bf9c 4558 }
6c5c1e20
TS
4559
4560 out:
364d4831
NF
4561 if (insn_bytes == 2)
4562 ctx->hflags |= MIPS_HFLAG_B16;
6c5c1e20
TS
4563 tcg_temp_free(t0);
4564 tcg_temp_free(t1);
6af0bf9c
FB
4565}
4566
7a387fff
TS
4567/* special3 bitfield operations */
4568static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
356265ae 4569 int rs, int lsb, int msb)
7a387fff 4570{
a7812ae4
PB
4571 TCGv t0 = tcg_temp_new();
4572 TCGv t1 = tcg_temp_new();
6c5c1e20
TS
4573
4574 gen_load_gpr(t1, rs);
7a387fff
TS
4575 switch (opc) {
4576 case OPC_EXT:
b7f26e52 4577 if (lsb + msb > 31) {
7a387fff 4578 goto fail;
b7f26e52 4579 }
505ad7c2 4580 if (msb != 31) {
6eebb7a4 4581 tcg_gen_extract_tl(t0, t1, lsb, msb + 1);
505ad7c2 4582 } else {
6eebb7a4
RH
4583 /* The two checks together imply that lsb == 0,
4584 so this is a simple sign-extension. */
4585 tcg_gen_ext32s_tl(t0, t1);
505ad7c2 4586 }
7a387fff 4587 break;
c6d6dd7c 4588#if defined(TARGET_MIPS64)
7a387fff 4589 case OPC_DEXTU:
b7f26e52
RH
4590 lsb += 32;
4591 goto do_dext;
4592 case OPC_DEXTM:
4593 msb += 32;
4594 goto do_dext;
7a387fff 4595 case OPC_DEXT:
b7f26e52
RH
4596 do_dext:
4597 if (lsb + msb > 63) {
4598 goto fail;
4599 }
6eebb7a4 4600 tcg_gen_extract_tl(t0, t1, lsb, msb + 1);
7a387fff 4601 break;
c6d6dd7c 4602#endif
7a387fff 4603 case OPC_INS:
b7f26e52 4604 if (lsb > msb) {
7a387fff 4605 goto fail;
b7f26e52 4606 }
6c5c1e20 4607 gen_load_gpr(t0, rt);
e0d002f1 4608 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
505ad7c2 4609 tcg_gen_ext32s_tl(t0, t0);
7a387fff 4610 break;
c6d6dd7c 4611#if defined(TARGET_MIPS64)
7a387fff 4612 case OPC_DINSU:
b7f26e52
RH
4613 lsb += 32;
4614 /* FALLTHRU */
4615 case OPC_DINSM:
4616 msb += 32;
4617 /* FALLTHRU */
7a387fff 4618 case OPC_DINS:
b7f26e52
RH
4619 if (lsb > msb) {
4620 goto fail;
4621 }
6c5c1e20 4622 gen_load_gpr(t0, rt);
e0d002f1 4623 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
7a387fff 4624 break;
c6d6dd7c 4625#endif
7a387fff
TS
4626 default:
4627fail:
4628 MIPS_INVAL("bitops");
9c708c7f 4629 generate_exception_end(ctx, EXCP_RI);
6c5c1e20
TS
4630 tcg_temp_free(t0);
4631 tcg_temp_free(t1);
7a387fff
TS
4632 return;
4633 }
6c5c1e20
TS
4634 gen_store_gpr(t0, rt);
4635 tcg_temp_free(t0);
4636 tcg_temp_free(t1);
7a387fff
TS
4637}
4638
49bcf33c
AJ
4639static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
4640{
3a55fa47 4641 TCGv t0;
49bcf33c 4642
3a55fa47
AJ
4643 if (rd == 0) {
4644 /* If no destination, treat it as a NOP. */
3a55fa47
AJ
4645 return;
4646 }
4647
4648 t0 = tcg_temp_new();
4649 gen_load_gpr(t0, rt);
49bcf33c
AJ
4650 switch (op2) {
4651 case OPC_WSBH:
3a55fa47
AJ
4652 {
4653 TCGv t1 = tcg_temp_new();
06a57e5c 4654 TCGv t2 = tcg_const_tl(0x00FF00FF);
3a55fa47
AJ
4655
4656 tcg_gen_shri_tl(t1, t0, 8);
06a57e5c
AJ
4657 tcg_gen_and_tl(t1, t1, t2);
4658 tcg_gen_and_tl(t0, t0, t2);
3a55fa47 4659 tcg_gen_shli_tl(t0, t0, 8);
3a55fa47 4660 tcg_gen_or_tl(t0, t0, t1);
06a57e5c 4661 tcg_temp_free(t2);
3a55fa47
AJ
4662 tcg_temp_free(t1);
4663 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
4664 }
49bcf33c
AJ
4665 break;
4666 case OPC_SEB:
3a55fa47 4667 tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
49bcf33c
AJ
4668 break;
4669 case OPC_SEH:
3a55fa47 4670 tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
49bcf33c
AJ
4671 break;
4672#if defined(TARGET_MIPS64)
4673 case OPC_DSBH:
3a55fa47
AJ
4674 {
4675 TCGv t1 = tcg_temp_new();
06a57e5c 4676 TCGv t2 = tcg_const_tl(0x00FF00FF00FF00FFULL);
3a55fa47
AJ
4677
4678 tcg_gen_shri_tl(t1, t0, 8);
06a57e5c
AJ
4679 tcg_gen_and_tl(t1, t1, t2);
4680 tcg_gen_and_tl(t0, t0, t2);
3a55fa47 4681 tcg_gen_shli_tl(t0, t0, 8);
3a55fa47 4682 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
06a57e5c 4683 tcg_temp_free(t2);
3a55fa47
AJ
4684 tcg_temp_free(t1);
4685 }
49bcf33c
AJ
4686 break;
4687 case OPC_DSHD:
3a55fa47
AJ
4688 {
4689 TCGv t1 = tcg_temp_new();
06a57e5c 4690 TCGv t2 = tcg_const_tl(0x0000FFFF0000FFFFULL);
3a55fa47
AJ
4691
4692 tcg_gen_shri_tl(t1, t0, 16);
06a57e5c
AJ
4693 tcg_gen_and_tl(t1, t1, t2);
4694 tcg_gen_and_tl(t0, t0, t2);
3a55fa47 4695 tcg_gen_shli_tl(t0, t0, 16);
3a55fa47
AJ
4696 tcg_gen_or_tl(t0, t0, t1);
4697 tcg_gen_shri_tl(t1, t0, 32);
4698 tcg_gen_shli_tl(t0, t0, 32);
4699 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
06a57e5c 4700 tcg_temp_free(t2);
3a55fa47
AJ
4701 tcg_temp_free(t1);
4702 }
49bcf33c
AJ
4703 break;
4704#endif
4705 default:
4706 MIPS_INVAL("bsfhl");
9c708c7f 4707 generate_exception_end(ctx, EXCP_RI);
49bcf33c 4708 tcg_temp_free(t0);
49bcf33c
AJ
4709 return;
4710 }
49bcf33c 4711 tcg_temp_free(t0);
49bcf33c
AJ
4712}
4713
1f1b4c00
YK
4714static void gen_lsa(DisasContext *ctx, int opc, int rd, int rs, int rt,
4715 int imm2)
4716{
4717 TCGv t0;
4718 TCGv t1;
4719 if (rd == 0) {
4720 /* Treat as NOP. */
4721 return;
4722 }
4723 t0 = tcg_temp_new();
4724 t1 = tcg_temp_new();
4725 gen_load_gpr(t0, rs);
4726 gen_load_gpr(t1, rt);
4727 tcg_gen_shli_tl(t0, t0, imm2 + 1);
4728 tcg_gen_add_tl(cpu_gpr[rd], t0, t1);
4729 if (opc == OPC_LSA) {
4730 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4731 }
4732
4733 tcg_temp_free(t1);
4734 tcg_temp_free(t0);
4735
4736 return;
4737}
4738
4739static void gen_align(DisasContext *ctx, int opc, int rd, int rs, int rt,
4740 int bp)
284b731a 4741{
1f1b4c00
YK
4742 TCGv t0;
4743 if (rd == 0) {
4744 /* Treat as NOP. */
4745 return;
4746 }
4747 t0 = tcg_temp_new();
4748 gen_load_gpr(t0, rt);
4749 if (bp == 0) {
51243852
MD
4750 switch (opc) {
4751 case OPC_ALIGN:
4752 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
4753 break;
4754#if defined(TARGET_MIPS64)
4755 case OPC_DALIGN:
4756 tcg_gen_mov_tl(cpu_gpr[rd], t0);
4757 break;
4758#endif
4759 }
1f1b4c00
YK
4760 } else {
4761 TCGv t1 = tcg_temp_new();
4762 gen_load_gpr(t1, rs);
4763 switch (opc) {
4764 case OPC_ALIGN:
4765 {
4766 TCGv_i64 t2 = tcg_temp_new_i64();
4767 tcg_gen_concat_tl_i64(t2, t1, t0);
4768 tcg_gen_shri_i64(t2, t2, 8 * (4 - bp));
4769 gen_move_low32(cpu_gpr[rd], t2);
4770 tcg_temp_free_i64(t2);
4771 }
4772 break;
284b731a 4773#if defined(TARGET_MIPS64)
1f1b4c00
YK
4774 case OPC_DALIGN:
4775 tcg_gen_shli_tl(t0, t0, 8 * bp);
4776 tcg_gen_shri_tl(t1, t1, 8 * (8 - bp));
4777 tcg_gen_or_tl(cpu_gpr[rd], t1, t0);
4778 break;
284b731a 4779#endif
1f1b4c00
YK
4780 }
4781 tcg_temp_free(t1);
4782 }
4783
4784 tcg_temp_free(t0);
4785}
4786
4787static void gen_bitswap(DisasContext *ctx, int opc, int rd, int rt)
4788{
4789 TCGv t0;
4790 if (rd == 0) {
4791 /* Treat as NOP. */
4792 return;
4793 }
4794 t0 = tcg_temp_new();
4795 gen_load_gpr(t0, rt);
4796 switch (opc) {
4797 case OPC_BITSWAP:
4798 gen_helper_bitswap(cpu_gpr[rd], t0);
4799 break;
4800#if defined(TARGET_MIPS64)
4801 case OPC_DBITSWAP:
4802 gen_helper_dbitswap(cpu_gpr[rd], t0);
4803 break;
4804#endif
4805 }
4806 tcg_temp_free(t0);
284b731a
LA
4807}
4808
1f1b4c00
YK
4809#ifndef CONFIG_USER_ONLY
4810/* CP0 (MMU and control) */
5204ea79
LA
4811static inline void gen_mthc0_entrylo(TCGv arg, target_ulong off)
4812{
4813 TCGv_i64 t0 = tcg_temp_new_i64();
4814 TCGv_i64 t1 = tcg_temp_new_i64();
4815
4816 tcg_gen_ext_tl_i64(t0, arg);
4817 tcg_gen_ld_i64(t1, cpu_env, off);
4818#if defined(TARGET_MIPS64)
4819 tcg_gen_deposit_i64(t1, t1, t0, 30, 32);
4820#else
4821 tcg_gen_concat32_i64(t1, t1, t0);
4822#endif
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_mthc0_store64(TCGv arg, target_ulong off)
4829{
4830 TCGv_i64 t0 = tcg_temp_new_i64();
4831 TCGv_i64 t1 = tcg_temp_new_i64();
4832
4833 tcg_gen_ext_tl_i64(t0, arg);
4834 tcg_gen_ld_i64(t1, cpu_env, off);
4835 tcg_gen_concat32_i64(t1, t1, t0);
4836 tcg_gen_st_i64(t1, cpu_env, off);
4837 tcg_temp_free_i64(t1);
4838 tcg_temp_free_i64(t0);
4839}
4840
4841static inline void gen_mfhc0_entrylo(TCGv arg, target_ulong off)
4842{
4843 TCGv_i64 t0 = tcg_temp_new_i64();
4844
4845 tcg_gen_ld_i64(t0, cpu_env, off);
4846#if defined(TARGET_MIPS64)
4847 tcg_gen_shri_i64(t0, t0, 30);
4848#else
4849 tcg_gen_shri_i64(t0, t0, 32);
4850#endif
4851 gen_move_low32(arg, t0);
4852 tcg_temp_free_i64(t0);
4853}
4854
4855static inline void gen_mfhc0_load64(TCGv arg, target_ulong off, int shift)
4856{
4857 TCGv_i64 t0 = tcg_temp_new_i64();
4858
4859 tcg_gen_ld_i64(t0, cpu_env, off);
4860 tcg_gen_shri_i64(t0, t0, 32 + shift);
4861 gen_move_low32(arg, t0);
4862 tcg_temp_free_i64(t0);
4863}
4864
d9bea114 4865static inline void gen_mfc0_load32 (TCGv arg, target_ulong off)
4f57689a 4866{
d9bea114 4867 TCGv_i32 t0 = tcg_temp_new_i32();
4f57689a 4868
d9bea114
AJ
4869 tcg_gen_ld_i32(t0, cpu_env, off);
4870 tcg_gen_ext_i32_tl(arg, t0);
4871 tcg_temp_free_i32(t0);
4f57689a
TS
4872}
4873
d9bea114 4874static inline void gen_mfc0_load64 (TCGv arg, target_ulong off)
4f57689a 4875{
d9bea114
AJ
4876 tcg_gen_ld_tl(arg, cpu_env, off);
4877 tcg_gen_ext32s_tl(arg, arg);
4f57689a
TS
4878}
4879
d9bea114 4880static inline void gen_mtc0_store32 (TCGv arg, target_ulong off)
f1aa6320 4881{
d9bea114 4882 TCGv_i32 t0 = tcg_temp_new_i32();
f1aa6320 4883
d9bea114
AJ
4884 tcg_gen_trunc_tl_i32(t0, arg);
4885 tcg_gen_st_i32(t0, cpu_env, off);
4886 tcg_temp_free_i32(t0);
f1aa6320
TS
4887}
4888
c98d3d79
YK
4889#define CP0_CHECK(c) \
4890 do { \
4891 if (!(c)) { \
4892 goto cp0_unimplemented; \
4893 } \
4894 } while (0)
4895
5204ea79
LA
4896static void gen_mfhc0(DisasContext *ctx, TCGv arg, int reg, int sel)
4897{
4898 const char *rn = "invalid";
4899
c98d3d79 4900 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
5204ea79
LA
4901
4902 switch (reg) {
4903 case 2:
4904 switch (sel) {
4905 case 0:
4906 gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
4907 rn = "EntryLo0";
4908 break;
4909 default:
c98d3d79 4910 goto cp0_unimplemented;
5204ea79
LA
4911 }
4912 break;
4913 case 3:
4914 switch (sel) {
4915 case 0:
4916 gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
4917 rn = "EntryLo1";
4918 break;
4919 default:
c98d3d79 4920 goto cp0_unimplemented;
5204ea79
LA
4921 }
4922 break;
4923 case 17:
4924 switch (sel) {
4925 case 0:
4926 gen_mfhc0_load64(arg, offsetof(CPUMIPSState, lladdr),
4927 ctx->CP0_LLAddr_shift);
4928 rn = "LLAddr";
4929 break;
f6d4dd81
YK
4930 case 1:
4931 CP0_CHECK(ctx->mrp);
4932 gen_helper_mfhc0_maar(arg, cpu_env);
4933 rn = "MAAR";
4934 break;
5204ea79 4935 default:
c98d3d79 4936 goto cp0_unimplemented;
5204ea79
LA
4937 }
4938 break;
4939 case 28:
4940 switch (sel) {
4941 case 0:
4942 case 2:
4943 case 4:
4944 case 6:
4945 gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_TagLo), 0);
4946 rn = "TagLo";
4947 break;
4948 default:
c98d3d79 4949 goto cp0_unimplemented;
5204ea79
LA
4950 }
4951 break;
4952 default:
c98d3d79 4953 goto cp0_unimplemented;
5204ea79 4954 }
b44a7fb1 4955 trace_mips_translate_c0("mfhc0", rn, reg, sel);
5204ea79
LA
4956 return;
4957
c98d3d79 4958cp0_unimplemented:
965447ee 4959 qemu_log_mask(LOG_UNIMP, "mfhc0 %s (reg %d sel %d)\n", rn, reg, sel);
5204ea79
LA
4960 tcg_gen_movi_tl(arg, 0);
4961}
4962
4963static void gen_mthc0(DisasContext *ctx, TCGv arg, int reg, int sel)
4964{
4965 const char *rn = "invalid";
4966 uint64_t mask = ctx->PAMask >> 36;
4967
c98d3d79 4968 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
5204ea79
LA
4969
4970 switch (reg) {
4971 case 2:
4972 switch (sel) {
4973 case 0:
4974 tcg_gen_andi_tl(arg, arg, mask);
4975 gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
4976 rn = "EntryLo0";
4977 break;
4978 default:
c98d3d79 4979 goto cp0_unimplemented;
5204ea79
LA
4980 }
4981 break;
4982 case 3:
4983 switch (sel) {
4984 case 0:
4985 tcg_gen_andi_tl(arg, arg, mask);
4986 gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
4987 rn = "EntryLo1";
4988 break;
4989 default:
c98d3d79 4990 goto cp0_unimplemented;
5204ea79
LA
4991 }
4992 break;
4993 case 17:
4994 switch (sel) {
4995 case 0:
4996 /* LLAddr is read-only (the only exception is bit 0 if LLB is
4997 supported); the CP0_LLAddr_rw_bitmask does not seem to be
4998 relevant for modern MIPS cores supporting MTHC0, therefore
4999 treating MTHC0 to LLAddr as NOP. */
5000 rn = "LLAddr";
5001 break;
f6d4dd81
YK
5002 case 1:
5003 CP0_CHECK(ctx->mrp);
5004 gen_helper_mthc0_maar(cpu_env, arg);
5005 rn = "MAAR";
5006 break;
5204ea79 5007 default:
c98d3d79 5008 goto cp0_unimplemented;
5204ea79
LA
5009 }
5010 break;
5011 case 28:
5012 switch (sel) {
5013 case 0:
5014 case 2:
5015 case 4:
5016 case 6:
5017 tcg_gen_andi_tl(arg, arg, mask);
5018 gen_mthc0_store64(arg, offsetof(CPUMIPSState, CP0_TagLo));
5019 rn = "TagLo";
5020 break;
5021 default:
c98d3d79 5022 goto cp0_unimplemented;
5204ea79
LA
5023 }
5024 break;
5025 default:
c98d3d79 5026 goto cp0_unimplemented;
5204ea79 5027 }
b44a7fb1 5028 trace_mips_translate_c0("mthc0", rn, reg, sel);
5204ea79 5029
c98d3d79 5030cp0_unimplemented:
965447ee 5031 qemu_log_mask(LOG_UNIMP, "mthc0 %s (reg %d sel %d)\n", rn, reg, sel);
5204ea79
LA
5032}
5033
e98c0d17
LA
5034static inline void gen_mfc0_unimplemented(DisasContext *ctx, TCGv arg)
5035{
5036 if (ctx->insn_flags & ISA_MIPS32R6) {
5037 tcg_gen_movi_tl(arg, 0);
5038 } else {
5039 tcg_gen_movi_tl(arg, ~0);
5040 }
5041}
5042
d75c135e 5043static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
873eb012 5044{
7a387fff 5045 const char *rn = "invalid";
873eb012 5046
e189e748 5047 if (sel != 0)
d75c135e 5048 check_insn(ctx, ISA_MIPS32);
e189e748 5049
873eb012
TS
5050 switch (reg) {
5051 case 0:
7a387fff
TS
5052 switch (sel) {
5053 case 0:
7db13fae 5054 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
7a387fff
TS
5055 rn = "Index";
5056 break;
5057 case 1:
f31b035a 5058 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5059 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
7a387fff 5060 rn = "MVPControl";
ead9360e 5061 break;
7a387fff 5062 case 2:
f31b035a 5063 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5064 gen_helper_mfc0_mvpconf0(arg, cpu_env);
7a387fff 5065 rn = "MVPConf0";
ead9360e 5066 break;
7a387fff 5067 case 3:
f31b035a 5068 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5069 gen_helper_mfc0_mvpconf1(arg, cpu_env);
7a387fff 5070 rn = "MVPConf1";
ead9360e 5071 break;
01bc435b
YK
5072 case 4:
5073 CP0_CHECK(ctx->vp);
5074 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl));
5075 rn = "VPControl";
5076 break;
7a387fff 5077 default:
f31b035a 5078 goto cp0_unimplemented;
7a387fff 5079 }
873eb012
TS
5080 break;
5081 case 1:
7a387fff
TS
5082 switch (sel) {
5083 case 0:
f31b035a 5084 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
895c2d04 5085 gen_helper_mfc0_random(arg, cpu_env);
7a387fff 5086 rn = "Random";
2423f660 5087 break;
7a387fff 5088 case 1:
f31b035a 5089 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 5090 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
7a387fff 5091 rn = "VPEControl";
ead9360e 5092 break;
7a387fff 5093 case 2:
f31b035a 5094 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 5095 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
7a387fff 5096 rn = "VPEConf0";
ead9360e 5097 break;
7a387fff 5098 case 3:
f31b035a 5099 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 5100 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
7a387fff 5101 rn = "VPEConf1";
ead9360e 5102 break;
7a387fff 5103 case 4:
f31b035a 5104 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 5105 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask));
7a387fff 5106 rn = "YQMask";
ead9360e 5107 break;
7a387fff 5108 case 5:
f31b035a 5109 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 5110 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
7a387fff 5111 rn = "VPESchedule";
ead9360e 5112 break;
7a387fff 5113 case 6:
f31b035a 5114 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 5115 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
7a387fff 5116 rn = "VPEScheFBack";
ead9360e 5117 break;
7a387fff 5118 case 7:
f31b035a 5119 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 5120 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
7a387fff 5121 rn = "VPEOpt";
ead9360e 5122 break;
7a387fff 5123 default:
f31b035a 5124 goto cp0_unimplemented;
7a387fff 5125 }
873eb012
TS
5126 break;
5127 case 2:
7a387fff
TS
5128 switch (sel) {
5129 case 0:
284b731a
LA
5130 {
5131 TCGv_i64 tmp = tcg_temp_new_i64();
5132 tcg_gen_ld_i64(tmp, cpu_env,
5133 offsetof(CPUMIPSState, CP0_EntryLo0));
7207c7f9 5134#if defined(TARGET_MIPS64)
284b731a
LA
5135 if (ctx->rxi) {
5136 /* Move RI/XI fields to bits 31:30 */
5137 tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
5138 tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
5139 }
7207c7f9 5140#endif
284b731a
LA
5141 gen_move_low32(arg, tmp);
5142 tcg_temp_free_i64(tmp);
5143 }
2423f660
TS
5144 rn = "EntryLo0";
5145 break;
7a387fff 5146 case 1:
f31b035a 5147 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5148 gen_helper_mfc0_tcstatus(arg, cpu_env);
2423f660 5149 rn = "TCStatus";
ead9360e 5150 break;
7a387fff 5151 case 2:
f31b035a 5152 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5153 gen_helper_mfc0_tcbind(arg, cpu_env);
2423f660 5154 rn = "TCBind";
ead9360e 5155 break;
7a387fff 5156 case 3:
f31b035a 5157 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5158 gen_helper_mfc0_tcrestart(arg, cpu_env);
2423f660 5159 rn = "TCRestart";
ead9360e 5160 break;
7a387fff 5161 case 4:
f31b035a 5162 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5163 gen_helper_mfc0_tchalt(arg, cpu_env);
2423f660 5164 rn = "TCHalt";
ead9360e 5165 break;
7a387fff 5166 case 5:
f31b035a 5167 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5168 gen_helper_mfc0_tccontext(arg, cpu_env);
2423f660 5169 rn = "TCContext";
ead9360e 5170 break;
7a387fff 5171 case 6:
f31b035a 5172 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5173 gen_helper_mfc0_tcschedule(arg, cpu_env);
2423f660 5174 rn = "TCSchedule";
ead9360e 5175 break;
7a387fff 5176 case 7:
f31b035a 5177 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5178 gen_helper_mfc0_tcschefback(arg, cpu_env);
2423f660 5179 rn = "TCScheFBack";
ead9360e 5180 break;
7a387fff 5181 default:
f31b035a 5182 goto cp0_unimplemented;
7a387fff 5183 }
873eb012
TS
5184 break;
5185 case 3:
7a387fff
TS
5186 switch (sel) {
5187 case 0:
284b731a
LA
5188 {
5189 TCGv_i64 tmp = tcg_temp_new_i64();
5190 tcg_gen_ld_i64(tmp, cpu_env,
5191 offsetof(CPUMIPSState, CP0_EntryLo1));
7207c7f9 5192#if defined(TARGET_MIPS64)
284b731a
LA
5193 if (ctx->rxi) {
5194 /* Move RI/XI fields to bits 31:30 */
5195 tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
5196 tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
5197 }
7207c7f9 5198#endif
284b731a
LA
5199 gen_move_low32(arg, tmp);
5200 tcg_temp_free_i64(tmp);
5201 }
2423f660
TS
5202 rn = "EntryLo1";
5203 break;
01bc435b
YK
5204 case 1:
5205 CP0_CHECK(ctx->vp);
5206 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber));
5207 rn = "GlobalNumber";
5208 break;
7a387fff 5209 default:
f31b035a 5210 goto cp0_unimplemented;
1579a72e 5211 }
873eb012
TS
5212 break;
5213 case 4:
7a387fff
TS
5214 switch (sel) {
5215 case 0:
7db13fae 5216 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
d9bea114 5217 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
5218 rn = "Context";
5219 break;
7a387fff 5220 case 1:
d9bea114 5221// gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
2423f660 5222 rn = "ContextConfig";
f31b035a 5223 goto cp0_unimplemented;
d279279e 5224 case 2:
f31b035a 5225 CP0_CHECK(ctx->ulri);
e40df9a8
JH
5226 tcg_gen_ld_tl(arg, cpu_env,
5227 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
5228 tcg_gen_ext32s_tl(arg, arg);
f31b035a 5229 rn = "UserLocal";
d279279e 5230 break;
7a387fff 5231 default:
f31b035a 5232 goto cp0_unimplemented;
1579a72e 5233 }
873eb012
TS
5234 break;
5235 case 5:
7a387fff
TS
5236 switch (sel) {
5237 case 0:
7db13fae 5238 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
2423f660
TS
5239 rn = "PageMask";
5240 break;
7a387fff 5241 case 1:
d75c135e 5242 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5243 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
2423f660
TS
5244 rn = "PageGrain";
5245 break;
cec56a73
JH
5246 case 2:
5247 CP0_CHECK(ctx->sc);
5248 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl0));
5249 tcg_gen_ext32s_tl(arg, arg);
5250 rn = "SegCtl0";
5251 break;
5252 case 3:
5253 CP0_CHECK(ctx->sc);
5254 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl1));
5255 tcg_gen_ext32s_tl(arg, arg);
5256 rn = "SegCtl1";
5257 break;
5258 case 4:
5259 CP0_CHECK(ctx->sc);
5260 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl2));
5261 tcg_gen_ext32s_tl(arg, arg);
5262 rn = "SegCtl2";
5263 break;
7a387fff 5264 default:
f31b035a 5265 goto cp0_unimplemented;
1579a72e 5266 }
873eb012
TS
5267 break;
5268 case 6:
7a387fff
TS
5269 switch (sel) {
5270 case 0:
7db13fae 5271 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
2423f660
TS
5272 rn = "Wired";
5273 break;
7a387fff 5274 case 1:
d75c135e 5275 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5276 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
2423f660 5277 rn = "SRSConf0";
ead9360e 5278 break;
7a387fff 5279 case 2:
d75c135e 5280 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5281 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
2423f660 5282 rn = "SRSConf1";
ead9360e 5283 break;
7a387fff 5284 case 3:
d75c135e 5285 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5286 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
2423f660 5287 rn = "SRSConf2";
ead9360e 5288 break;
7a387fff 5289 case 4:
d75c135e 5290 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5291 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
2423f660 5292 rn = "SRSConf3";
ead9360e 5293 break;
7a387fff 5294 case 5:
d75c135e 5295 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5296 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
2423f660 5297 rn = "SRSConf4";
ead9360e 5298 break;
7a387fff 5299 default:
f31b035a 5300 goto cp0_unimplemented;
1579a72e 5301 }
873eb012 5302 break;
8c0fdd85 5303 case 7:
7a387fff
TS
5304 switch (sel) {
5305 case 0:
d75c135e 5306 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5307 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
2423f660
TS
5308 rn = "HWREna";
5309 break;
7a387fff 5310 default:
f31b035a 5311 goto cp0_unimplemented;
1579a72e 5312 }
8c0fdd85 5313 break;
873eb012 5314 case 8:
7a387fff
TS
5315 switch (sel) {
5316 case 0:
7db13fae 5317 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
d9bea114 5318 tcg_gen_ext32s_tl(arg, arg);
f0b3f3ae 5319 rn = "BadVAddr";
2423f660 5320 break;
aea14095 5321 case 1:
f31b035a
LA
5322 CP0_CHECK(ctx->bi);
5323 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
5324 rn = "BadInstr";
aea14095
LA
5325 break;
5326 case 2:
f31b035a
LA
5327 CP0_CHECK(ctx->bp);
5328 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
5329 rn = "BadInstrP";
aea14095 5330 break;
7a387fff 5331 default:
f31b035a 5332 goto cp0_unimplemented;
aea14095 5333 }
873eb012
TS
5334 break;
5335 case 9:
7a387fff
TS
5336 switch (sel) {
5337 case 0:
2e70f6ef 5338 /* Mark as an IO operation because we read the time. */
eeb3bba8 5339 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
2e70f6ef 5340 gen_io_start();
bd79255d 5341 }
895c2d04 5342 gen_helper_mfc0_count(arg, cpu_env);
eeb3bba8 5343 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
2e70f6ef 5344 gen_io_end();
2e70f6ef 5345 }
55807224 5346 /* Break the TB to be able to take timer interrupts immediately
b28425ba
EC
5347 after reading count. DISAS_STOP isn't sufficient, we need to
5348 ensure we break completely out of translated code. */
eeb3bba8
EC
5349 gen_save_pc(ctx->base.pc_next + 4);
5350 ctx->base.is_jmp = DISAS_EXIT;
2423f660
TS
5351 rn = "Count";
5352 break;
5353 /* 6,7 are implementation dependent */
7a387fff 5354 default:
f31b035a 5355 goto cp0_unimplemented;
2423f660 5356 }
873eb012
TS
5357 break;
5358 case 10:
7a387fff
TS
5359 switch (sel) {
5360 case 0:
7db13fae 5361 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
d9bea114 5362 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
5363 rn = "EntryHi";
5364 break;
7a387fff 5365 default:
f31b035a 5366 goto cp0_unimplemented;
1579a72e 5367 }
873eb012
TS
5368 break;
5369 case 11:
7a387fff
TS
5370 switch (sel) {
5371 case 0:
7db13fae 5372 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
2423f660
TS
5373 rn = "Compare";
5374 break;
5375 /* 6,7 are implementation dependent */
7a387fff 5376 default:
f31b035a 5377 goto cp0_unimplemented;
2423f660 5378 }
873eb012
TS
5379 break;
5380 case 12:
7a387fff
TS
5381 switch (sel) {
5382 case 0:
7db13fae 5383 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
2423f660
TS
5384 rn = "Status";
5385 break;
7a387fff 5386 case 1:
d75c135e 5387 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5388 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
2423f660
TS
5389 rn = "IntCtl";
5390 break;
7a387fff 5391 case 2:
d75c135e 5392 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5393 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
2423f660
TS
5394 rn = "SRSCtl";
5395 break;
7a387fff 5396 case 3:
d75c135e 5397 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5398 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
2423f660 5399 rn = "SRSMap";
fd88b6ab 5400 break;
7a387fff 5401 default:
f31b035a 5402 goto cp0_unimplemented;
7a387fff 5403 }
873eb012
TS
5404 break;
5405 case 13:
7a387fff
TS
5406 switch (sel) {
5407 case 0:
7db13fae 5408 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
2423f660
TS
5409 rn = "Cause";
5410 break;
7a387fff 5411 default:
f31b035a 5412 goto cp0_unimplemented;
7a387fff 5413 }
873eb012
TS
5414 break;
5415 case 14:
7a387fff
TS
5416 switch (sel) {
5417 case 0:
7db13fae 5418 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
d9bea114 5419 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
5420 rn = "EPC";
5421 break;
7a387fff 5422 default:
f31b035a 5423 goto cp0_unimplemented;
1579a72e 5424 }
873eb012
TS
5425 break;
5426 case 15:
7a387fff
TS
5427 switch (sel) {
5428 case 0:
7db13fae 5429 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
2423f660
TS
5430 rn = "PRid";
5431 break;
7a387fff 5432 case 1:
d75c135e 5433 check_insn(ctx, ISA_MIPS32R2);
74dbf824
JH
5434 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EBase));
5435 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
5436 rn = "EBase";
5437 break;
c870e3f5
YK
5438 case 3:
5439 check_insn(ctx, ISA_MIPS32R2);
5440 CP0_CHECK(ctx->cmgcr);
5441 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase));
5442 tcg_gen_ext32s_tl(arg, arg);
5443 rn = "CMGCRBase";
5444 break;
7a387fff 5445 default:
f31b035a 5446 goto cp0_unimplemented;
7a387fff 5447 }
873eb012
TS
5448 break;
5449 case 16:
5450 switch (sel) {
5451 case 0:
7db13fae 5452 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
873eb012
TS
5453 rn = "Config";
5454 break;
5455 case 1:
7db13fae 5456 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
873eb012
TS
5457 rn = "Config1";
5458 break;
7a387fff 5459 case 2:
7db13fae 5460 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
7a387fff
TS
5461 rn = "Config2";
5462 break;
5463 case 3:
7db13fae 5464 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
7a387fff
TS
5465 rn = "Config3";
5466 break;
b4160af1
PJ
5467 case 4:
5468 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
5469 rn = "Config4";
5470 break;
b4dd99a3
PJ
5471 case 5:
5472 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
5473 rn = "Config5";
5474 break;
e397ee33
TS
5475 /* 6,7 are implementation dependent */
5476 case 6:
7db13fae 5477 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
e397ee33
TS
5478 rn = "Config6";
5479 break;
5480 case 7:
7db13fae 5481 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
e397ee33
TS
5482 rn = "Config7";
5483 break;
873eb012 5484 default:
f31b035a 5485 goto cp0_unimplemented;
873eb012
TS
5486 }
5487 break;
5488 case 17:
7a387fff
TS
5489 switch (sel) {
5490 case 0:
895c2d04 5491 gen_helper_mfc0_lladdr(arg, cpu_env);
2423f660
TS
5492 rn = "LLAddr";
5493 break;
f6d4dd81
YK
5494 case 1:
5495 CP0_CHECK(ctx->mrp);
5496 gen_helper_mfc0_maar(arg, cpu_env);
5497 rn = "MAAR";
5498 break;
5499 case 2:
5500 CP0_CHECK(ctx->mrp);
5501 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI));
5502 rn = "MAARI";
5503 break;
7a387fff 5504 default:
f31b035a 5505 goto cp0_unimplemented;
7a387fff 5506 }
873eb012
TS
5507 break;
5508 case 18:
7a387fff 5509 switch (sel) {
c2e19f3c
AM
5510 case 0:
5511 case 1:
5512 case 2:
5513 case 3:
5514 case 4:
5515 case 5:
5516 case 6:
5517 case 7:
895c2d04 5518 gen_helper_1e0i(mfc0_watchlo, arg, sel);
2423f660
TS
5519 rn = "WatchLo";
5520 break;
7a387fff 5521 default:
f31b035a 5522 goto cp0_unimplemented;
7a387fff 5523 }
873eb012
TS
5524 break;
5525 case 19:
7a387fff 5526 switch (sel) {
c2e19f3c
AM
5527 case 0:
5528 case 1:
5529 case 2:
5530 case 3:
5531 case 4:
5532 case 5:
5533 case 6:
5534 case 7:
895c2d04 5535 gen_helper_1e0i(mfc0_watchhi, arg, sel);
2423f660
TS
5536 rn = "WatchHi";
5537 break;
7a387fff 5538 default:
f31b035a 5539 goto cp0_unimplemented;
7a387fff 5540 }
873eb012 5541 break;
8c0fdd85 5542 case 20:
7a387fff
TS
5543 switch (sel) {
5544 case 0:
d26bc211 5545#if defined(TARGET_MIPS64)
d75c135e 5546 check_insn(ctx, ISA_MIPS3);
7db13fae 5547 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
d9bea114 5548 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
5549 rn = "XContext";
5550 break;
703eaf37 5551#endif
7a387fff 5552 default:
f31b035a 5553 goto cp0_unimplemented;
7a387fff 5554 }
8c0fdd85
TS
5555 break;
5556 case 21:
7a387fff 5557 /* Officially reserved, but sel 0 is used for R1x000 framemask */
f31b035a 5558 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
7a387fff
TS
5559 switch (sel) {
5560 case 0:
7db13fae 5561 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
2423f660
TS
5562 rn = "Framemask";
5563 break;
7a387fff 5564 default:
f31b035a 5565 goto cp0_unimplemented;
7a387fff 5566 }
8c0fdd85
TS
5567 break;
5568 case 22:
d9bea114 5569 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
5570 rn = "'Diagnostic"; /* implementation dependent */
5571 break;
873eb012 5572 case 23:
7a387fff
TS
5573 switch (sel) {
5574 case 0:
895c2d04 5575 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
2423f660
TS
5576 rn = "Debug";
5577 break;
7a387fff 5578 case 1:
d9bea114 5579// gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
2423f660 5580 rn = "TraceControl";
3570d7f6 5581 goto cp0_unimplemented;
7a387fff 5582 case 2:
d9bea114 5583// gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
2423f660 5584 rn = "TraceControl2";
3570d7f6 5585 goto cp0_unimplemented;
7a387fff 5586 case 3:
d9bea114 5587// gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
2423f660 5588 rn = "UserTraceData";
3570d7f6 5589 goto cp0_unimplemented;
7a387fff 5590 case 4:
d9bea114 5591// gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
2423f660 5592 rn = "TraceBPC";
3570d7f6 5593 goto cp0_unimplemented;
7a387fff 5594 default:
f31b035a 5595 goto cp0_unimplemented;
7a387fff 5596 }
873eb012
TS
5597 break;
5598 case 24:
7a387fff
TS
5599 switch (sel) {
5600 case 0:
f0b3f3ae 5601 /* EJTAG support */
7db13fae 5602 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
d9bea114 5603 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
5604 rn = "DEPC";
5605 break;
7a387fff 5606 default:
f31b035a 5607 goto cp0_unimplemented;
7a387fff 5608 }
873eb012 5609 break;
8c0fdd85 5610 case 25:
7a387fff
TS
5611 switch (sel) {
5612 case 0:
7db13fae 5613 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
2423f660 5614 rn = "Performance0";
7a387fff
TS
5615 break;
5616 case 1:
d9bea114 5617// gen_helper_mfc0_performance1(arg);
2423f660 5618 rn = "Performance1";
3570d7f6 5619 goto cp0_unimplemented;
7a387fff 5620 case 2:
d9bea114 5621// gen_helper_mfc0_performance2(arg);
2423f660 5622 rn = "Performance2";
3570d7f6 5623 goto cp0_unimplemented;
7a387fff 5624 case 3:
d9bea114 5625// gen_helper_mfc0_performance3(arg);
2423f660 5626 rn = "Performance3";
3570d7f6 5627 goto cp0_unimplemented;
7a387fff 5628 case 4:
d9bea114 5629// gen_helper_mfc0_performance4(arg);
2423f660 5630 rn = "Performance4";
3570d7f6 5631 goto cp0_unimplemented;
7a387fff 5632 case 5:
d9bea114 5633// gen_helper_mfc0_performance5(arg);
2423f660 5634 rn = "Performance5";
3570d7f6 5635 goto cp0_unimplemented;
7a387fff 5636 case 6:
d9bea114 5637// gen_helper_mfc0_performance6(arg);
2423f660 5638 rn = "Performance6";
3570d7f6 5639 goto cp0_unimplemented;
7a387fff 5640 case 7:
d9bea114 5641// gen_helper_mfc0_performance7(arg);
2423f660 5642 rn = "Performance7";
3570d7f6 5643 goto cp0_unimplemented;
7a387fff 5644 default:
f31b035a 5645 goto cp0_unimplemented;
7a387fff 5646 }
8c0fdd85
TS
5647 break;
5648 case 26:
0d74a222
LA
5649 switch (sel) {
5650 case 0:
5651 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl));
5652 rn = "ErrCtl";
5653 break;
5654 default:
5655 goto cp0_unimplemented;
5656 }
da80682b 5657 break;
8c0fdd85 5658 case 27:
7a387fff 5659 switch (sel) {
c2e19f3c
AM
5660 case 0:
5661 case 1:
5662 case 2:
5663 case 3:
d9bea114 5664 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
5665 rn = "CacheErr";
5666 break;
7a387fff 5667 default:
f31b035a 5668 goto cp0_unimplemented;
7a387fff 5669 }
8c0fdd85 5670 break;
873eb012
TS
5671 case 28:
5672 switch (sel) {
5673 case 0:
7a387fff
TS
5674 case 2:
5675 case 4:
5676 case 6:
284b731a
LA
5677 {
5678 TCGv_i64 tmp = tcg_temp_new_i64();
5679 tcg_gen_ld_i64(tmp, cpu_env, offsetof(CPUMIPSState, CP0_TagLo));
5680 gen_move_low32(arg, tmp);
5681 tcg_temp_free_i64(tmp);
5682 }
873eb012
TS
5683 rn = "TagLo";
5684 break;
5685 case 1:
7a387fff
TS
5686 case 3:
5687 case 5:
5688 case 7:
7db13fae 5689 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
873eb012
TS
5690 rn = "DataLo";
5691 break;
5692 default:
f31b035a 5693 goto cp0_unimplemented;
873eb012
TS
5694 }
5695 break;
8c0fdd85 5696 case 29:
7a387fff
TS
5697 switch (sel) {
5698 case 0:
5699 case 2:
5700 case 4:
5701 case 6:
7db13fae 5702 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
7a387fff
TS
5703 rn = "TagHi";
5704 break;
5705 case 1:
5706 case 3:
5707 case 5:
5708 case 7:
7db13fae 5709 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
7a387fff
TS
5710 rn = "DataHi";
5711 break;
5712 default:
f31b035a 5713 goto cp0_unimplemented;
7a387fff 5714 }
8c0fdd85 5715 break;
873eb012 5716 case 30:
7a387fff
TS
5717 switch (sel) {
5718 case 0:
7db13fae 5719 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
d9bea114 5720 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
5721 rn = "ErrorEPC";
5722 break;
7a387fff 5723 default:
f31b035a 5724 goto cp0_unimplemented;
7a387fff 5725 }
873eb012
TS
5726 break;
5727 case 31:
7a387fff
TS
5728 switch (sel) {
5729 case 0:
f0b3f3ae 5730 /* EJTAG support */
7db13fae 5731 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
5732 rn = "DESAVE";
5733 break;
c2e19f3c
AM
5734 case 2:
5735 case 3:
5736 case 4:
5737 case 5:
5738 case 6:
5739 case 7:
f31b035a
LA
5740 CP0_CHECK(ctx->kscrexist & (1 << sel));
5741 tcg_gen_ld_tl(arg, cpu_env,
5742 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
5743 tcg_gen_ext32s_tl(arg, arg);
5744 rn = "KScratch";
e98c0d17 5745 break;
7a387fff 5746 default:
f31b035a 5747 goto cp0_unimplemented;
7a387fff 5748 }
873eb012
TS
5749 break;
5750 default:
f31b035a 5751 goto cp0_unimplemented;
873eb012 5752 }
b44a7fb1 5753 trace_mips_translate_c0("mfc0", rn, reg, sel);
873eb012
TS
5754 return;
5755
f31b035a 5756cp0_unimplemented:
965447ee 5757 qemu_log_mask(LOG_UNIMP, "mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
f31b035a 5758 gen_mfc0_unimplemented(ctx, arg);
873eb012
TS
5759}
5760
d75c135e 5761static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
8c0fdd85 5762{
7a387fff
TS
5763 const char *rn = "invalid";
5764
e189e748 5765 if (sel != 0)
d75c135e 5766 check_insn(ctx, ISA_MIPS32);
e189e748 5767
eeb3bba8 5768 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
2e70f6ef 5769 gen_io_start();
bd79255d 5770 }
2e70f6ef 5771
8c0fdd85
TS
5772 switch (reg) {
5773 case 0:
7a387fff
TS
5774 switch (sel) {
5775 case 0:
895c2d04 5776 gen_helper_mtc0_index(cpu_env, arg);
7a387fff
TS
5777 rn = "Index";
5778 break;
5779 case 1:
f31b035a 5780 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5781 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
7a387fff 5782 rn = "MVPControl";
ead9360e 5783 break;
7a387fff 5784 case 2:
f31b035a 5785 CP0_CHECK(ctx->insn_flags & ASE_MT);
ead9360e 5786 /* ignored */
7a387fff 5787 rn = "MVPConf0";
ead9360e 5788 break;
7a387fff 5789 case 3:
f31b035a 5790 CP0_CHECK(ctx->insn_flags & ASE_MT);
ead9360e 5791 /* ignored */
7a387fff 5792 rn = "MVPConf1";
ead9360e 5793 break;
01bc435b
YK
5794 case 4:
5795 CP0_CHECK(ctx->vp);
5796 /* ignored */
5797 rn = "VPControl";
5798 break;
7a387fff 5799 default:
f31b035a 5800 goto cp0_unimplemented;
7a387fff 5801 }
8c0fdd85
TS
5802 break;
5803 case 1:
7a387fff
TS
5804 switch (sel) {
5805 case 0:
2423f660 5806 /* ignored */
7a387fff 5807 rn = "Random";
2423f660 5808 break;
7a387fff 5809 case 1:
f31b035a 5810 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5811 gen_helper_mtc0_vpecontrol(cpu_env, arg);
7a387fff 5812 rn = "VPEControl";
ead9360e 5813 break;
7a387fff 5814 case 2:
f31b035a 5815 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5816 gen_helper_mtc0_vpeconf0(cpu_env, arg);
7a387fff 5817 rn = "VPEConf0";
ead9360e 5818 break;
7a387fff 5819 case 3:
f31b035a 5820 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5821 gen_helper_mtc0_vpeconf1(cpu_env, arg);
7a387fff 5822 rn = "VPEConf1";
ead9360e 5823 break;
7a387fff 5824 case 4:
f31b035a 5825 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5826 gen_helper_mtc0_yqmask(cpu_env, arg);
7a387fff 5827 rn = "YQMask";
ead9360e 5828 break;
7a387fff 5829 case 5:
f31b035a 5830 CP0_CHECK(ctx->insn_flags & ASE_MT);
d54a299b
LA
5831 tcg_gen_st_tl(arg, cpu_env,
5832 offsetof(CPUMIPSState, CP0_VPESchedule));
7a387fff 5833 rn = "VPESchedule";
ead9360e 5834 break;
7a387fff 5835 case 6:
f31b035a 5836 CP0_CHECK(ctx->insn_flags & ASE_MT);
d54a299b
LA
5837 tcg_gen_st_tl(arg, cpu_env,
5838 offsetof(CPUMIPSState, CP0_VPEScheFBack));
7a387fff 5839 rn = "VPEScheFBack";
ead9360e 5840 break;
7a387fff 5841 case 7:
f31b035a 5842 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5843 gen_helper_mtc0_vpeopt(cpu_env, arg);
7a387fff 5844 rn = "VPEOpt";
ead9360e 5845 break;
7a387fff 5846 default:
f31b035a 5847 goto cp0_unimplemented;
7a387fff 5848 }
8c0fdd85
TS
5849 break;
5850 case 2:
7a387fff
TS
5851 switch (sel) {
5852 case 0:
895c2d04 5853 gen_helper_mtc0_entrylo0(cpu_env, arg);
2423f660
TS
5854 rn = "EntryLo0";
5855 break;
7a387fff 5856 case 1:
f31b035a 5857 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5858 gen_helper_mtc0_tcstatus(cpu_env, arg);
2423f660 5859 rn = "TCStatus";
ead9360e 5860 break;
7a387fff 5861 case 2:
f31b035a 5862 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5863 gen_helper_mtc0_tcbind(cpu_env, arg);
2423f660 5864 rn = "TCBind";
ead9360e 5865 break;
7a387fff 5866 case 3:
f31b035a 5867 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5868 gen_helper_mtc0_tcrestart(cpu_env, arg);
2423f660 5869 rn = "TCRestart";
ead9360e 5870 break;
7a387fff 5871 case 4:
f31b035a 5872 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5873 gen_helper_mtc0_tchalt(cpu_env, arg);
2423f660 5874 rn = "TCHalt";
ead9360e 5875 break;
7a387fff 5876 case 5:
f31b035a 5877 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5878 gen_helper_mtc0_tccontext(cpu_env, arg);
2423f660 5879 rn = "TCContext";
ead9360e 5880 break;
7a387fff 5881 case 6:
f31b035a 5882 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5883 gen_helper_mtc0_tcschedule(cpu_env, arg);
2423f660 5884 rn = "TCSchedule";
ead9360e 5885 break;
7a387fff 5886 case 7:
f31b035a 5887 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5888 gen_helper_mtc0_tcschefback(cpu_env, arg);
2423f660 5889 rn = "TCScheFBack";
ead9360e 5890 break;
7a387fff 5891 default:
f31b035a 5892 goto cp0_unimplemented;
7a387fff 5893 }
8c0fdd85
TS
5894 break;
5895 case 3:
7a387fff
TS
5896 switch (sel) {
5897 case 0:
895c2d04 5898 gen_helper_mtc0_entrylo1(cpu_env, arg);
2423f660
TS
5899 rn = "EntryLo1";
5900 break;
01bc435b
YK
5901 case 1:
5902 CP0_CHECK(ctx->vp);
5903 /* ignored */
5904 rn = "GlobalNumber";
5905 break;
7a387fff 5906 default:
f31b035a 5907 goto cp0_unimplemented;
876d4b07 5908 }
8c0fdd85
TS
5909 break;
5910 case 4:
7a387fff
TS
5911 switch (sel) {
5912 case 0:
895c2d04 5913 gen_helper_mtc0_context(cpu_env, arg);
2423f660
TS
5914 rn = "Context";
5915 break;
7a387fff 5916 case 1:
895c2d04 5917// gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
2423f660 5918 rn = "ContextConfig";
f31b035a 5919 goto cp0_unimplemented;
d279279e 5920 case 2:
f31b035a
LA
5921 CP0_CHECK(ctx->ulri);
5922 tcg_gen_st_tl(arg, cpu_env,
5923 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
5924 rn = "UserLocal";
d279279e 5925 break;
7a387fff 5926 default:
f31b035a 5927 goto cp0_unimplemented;
876d4b07 5928 }
8c0fdd85
TS
5929 break;
5930 case 5:
7a387fff
TS
5931 switch (sel) {
5932 case 0:
895c2d04 5933 gen_helper_mtc0_pagemask(cpu_env, arg);
2423f660
TS
5934 rn = "PageMask";
5935 break;
7a387fff 5936 case 1:
d75c135e 5937 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5938 gen_helper_mtc0_pagegrain(cpu_env, arg);
2423f660 5939 rn = "PageGrain";
eeb3bba8 5940 ctx->base.is_jmp = DISAS_STOP;
2423f660 5941 break;
cec56a73
JH
5942 case 2:
5943 CP0_CHECK(ctx->sc);
5944 gen_helper_mtc0_segctl0(cpu_env, arg);
5945 rn = "SegCtl0";
5946 break;
5947 case 3:
5948 CP0_CHECK(ctx->sc);
5949 gen_helper_mtc0_segctl1(cpu_env, arg);
5950 rn = "SegCtl1";
5951 break;
5952 case 4:
5953 CP0_CHECK(ctx->sc);
5954 gen_helper_mtc0_segctl2(cpu_env, arg);
5955 rn = "SegCtl2";
5956 break;
7a387fff 5957 default:
f31b035a 5958 goto cp0_unimplemented;
876d4b07 5959 }
8c0fdd85
TS
5960 break;
5961 case 6:
7a387fff
TS
5962 switch (sel) {
5963 case 0:
895c2d04 5964 gen_helper_mtc0_wired(cpu_env, arg);
2423f660
TS
5965 rn = "Wired";
5966 break;
7a387fff 5967 case 1:
d75c135e 5968 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5969 gen_helper_mtc0_srsconf0(cpu_env, arg);
2423f660 5970 rn = "SRSConf0";
ead9360e 5971 break;
7a387fff 5972 case 2:
d75c135e 5973 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5974 gen_helper_mtc0_srsconf1(cpu_env, arg);
2423f660 5975 rn = "SRSConf1";
ead9360e 5976 break;
7a387fff 5977 case 3:
d75c135e 5978 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5979 gen_helper_mtc0_srsconf2(cpu_env, arg);
2423f660 5980 rn = "SRSConf2";
ead9360e 5981 break;
7a387fff 5982 case 4:
d75c135e 5983 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5984 gen_helper_mtc0_srsconf3(cpu_env, arg);
2423f660 5985 rn = "SRSConf3";
ead9360e 5986 break;
7a387fff 5987 case 5:
d75c135e 5988 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5989 gen_helper_mtc0_srsconf4(cpu_env, arg);
2423f660 5990 rn = "SRSConf4";
ead9360e 5991 break;
7a387fff 5992 default:
f31b035a 5993 goto cp0_unimplemented;
876d4b07 5994 }
8c0fdd85
TS
5995 break;
5996 case 7:
7a387fff
TS
5997 switch (sel) {
5998 case 0:
d75c135e 5999 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6000 gen_helper_mtc0_hwrena(cpu_env, arg);
eeb3bba8 6001 ctx->base.is_jmp = DISAS_STOP;
2423f660
TS
6002 rn = "HWREna";
6003 break;
7a387fff 6004 default:
f31b035a 6005 goto cp0_unimplemented;
876d4b07 6006 }
8c0fdd85
TS
6007 break;
6008 case 8:
aea14095
LA
6009 switch (sel) {
6010 case 0:
6011 /* ignored */
6012 rn = "BadVAddr";
6013 break;
6014 case 1:
6015 /* ignored */
6016 rn = "BadInstr";
6017 break;
6018 case 2:
6019 /* ignored */
6020 rn = "BadInstrP";
6021 break;
6022 default:
f31b035a 6023 goto cp0_unimplemented;
aea14095 6024 }
8c0fdd85
TS
6025 break;
6026 case 9:
7a387fff
TS
6027 switch (sel) {
6028 case 0:
895c2d04 6029 gen_helper_mtc0_count(cpu_env, arg);
2423f660
TS
6030 rn = "Count";
6031 break;
876d4b07 6032 /* 6,7 are implementation dependent */
7a387fff 6033 default:
f31b035a 6034 goto cp0_unimplemented;
876d4b07 6035 }
8c0fdd85
TS
6036 break;
6037 case 10:
7a387fff
TS
6038 switch (sel) {
6039 case 0:
895c2d04 6040 gen_helper_mtc0_entryhi(cpu_env, arg);
2423f660
TS
6041 rn = "EntryHi";
6042 break;
7a387fff 6043 default:
f31b035a 6044 goto cp0_unimplemented;
876d4b07 6045 }
8c0fdd85
TS
6046 break;
6047 case 11:
7a387fff
TS
6048 switch (sel) {
6049 case 0:
895c2d04 6050 gen_helper_mtc0_compare(cpu_env, arg);
2423f660
TS
6051 rn = "Compare";
6052 break;
6053 /* 6,7 are implementation dependent */
7a387fff 6054 default:
f31b035a 6055 goto cp0_unimplemented;
876d4b07 6056 }
8c0fdd85
TS
6057 break;
6058 case 12:
7a387fff
TS
6059 switch (sel) {
6060 case 0:
867abc7e 6061 save_cpu_state(ctx, 1);
895c2d04 6062 gen_helper_mtc0_status(cpu_env, arg);
b28425ba 6063 /* DISAS_STOP isn't good enough here, hflags may have changed. */
eeb3bba8
EC
6064 gen_save_pc(ctx->base.pc_next + 4);
6065 ctx->base.is_jmp = DISAS_EXIT;
2423f660
TS
6066 rn = "Status";
6067 break;
7a387fff 6068 case 1:
d75c135e 6069 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6070 gen_helper_mtc0_intctl(cpu_env, arg);
8487327a 6071 /* Stop translation as we may have switched the execution mode */
eeb3bba8 6072 ctx->base.is_jmp = DISAS_STOP;
2423f660
TS
6073 rn = "IntCtl";
6074 break;
7a387fff 6075 case 2:
d75c135e 6076 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6077 gen_helper_mtc0_srsctl(cpu_env, arg);
8487327a 6078 /* Stop translation as we may have switched the execution mode */
eeb3bba8 6079 ctx->base.is_jmp = DISAS_STOP;
2423f660
TS
6080 rn = "SRSCtl";
6081 break;
7a387fff 6082 case 3:
d75c135e 6083 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6084 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
8487327a 6085 /* Stop translation as we may have switched the execution mode */
eeb3bba8 6086 ctx->base.is_jmp = DISAS_STOP;
2423f660 6087 rn = "SRSMap";
fd88b6ab 6088 break;
7a387fff 6089 default:
f31b035a 6090 goto cp0_unimplemented;
876d4b07 6091 }
8c0fdd85
TS
6092 break;
6093 case 13:
7a387fff
TS
6094 switch (sel) {
6095 case 0:
867abc7e 6096 save_cpu_state(ctx, 1);
895c2d04 6097 gen_helper_mtc0_cause(cpu_env, arg);
b28425ba
EC
6098 /* Stop translation as we may have triggered an interrupt.
6099 * DISAS_STOP isn't sufficient, we need to ensure we break out of
6100 * translated code to check for pending interrupts. */
eeb3bba8
EC
6101 gen_save_pc(ctx->base.pc_next + 4);
6102 ctx->base.is_jmp = DISAS_EXIT;
2423f660
TS
6103 rn = "Cause";
6104 break;
7a387fff 6105 default:
f31b035a 6106 goto cp0_unimplemented;
876d4b07 6107 }
8c0fdd85
TS
6108 break;
6109 case 14:
7a387fff
TS
6110 switch (sel) {
6111 case 0:
d54a299b 6112 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
2423f660
TS
6113 rn = "EPC";
6114 break;
7a387fff 6115 default:
f31b035a 6116 goto cp0_unimplemented;
876d4b07 6117 }
8c0fdd85
TS
6118 break;
6119 case 15:
7a387fff
TS
6120 switch (sel) {
6121 case 0:
2423f660
TS
6122 /* ignored */
6123 rn = "PRid";
6124 break;
7a387fff 6125 case 1:
d75c135e 6126 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6127 gen_helper_mtc0_ebase(cpu_env, arg);
2423f660
TS
6128 rn = "EBase";
6129 break;
7a387fff 6130 default:
f31b035a 6131 goto cp0_unimplemented;
1579a72e 6132 }
8c0fdd85
TS
6133 break;
6134 case 16:
6135 switch (sel) {
6136 case 0:
895c2d04 6137 gen_helper_mtc0_config0(cpu_env, arg);
7a387fff 6138 rn = "Config";
2423f660 6139 /* Stop translation as we may have switched the execution mode */
eeb3bba8 6140 ctx->base.is_jmp = DISAS_STOP;
7a387fff
TS
6141 break;
6142 case 1:
e397ee33 6143 /* ignored, read only */
7a387fff
TS
6144 rn = "Config1";
6145 break;
6146 case 2:
895c2d04 6147 gen_helper_mtc0_config2(cpu_env, arg);
7a387fff 6148 rn = "Config2";
2423f660 6149 /* Stop translation as we may have switched the execution mode */
eeb3bba8 6150 ctx->base.is_jmp = DISAS_STOP;
8c0fdd85 6151 break;
7a387fff 6152 case 3:
90f12d73 6153 gen_helper_mtc0_config3(cpu_env, arg);
7a387fff 6154 rn = "Config3";
90f12d73 6155 /* Stop translation as we may have switched the execution mode */
eeb3bba8 6156 ctx->base.is_jmp = DISAS_STOP;
7a387fff 6157 break;
b4160af1
PJ
6158 case 4:
6159 gen_helper_mtc0_config4(cpu_env, arg);
6160 rn = "Config4";
eeb3bba8 6161 ctx->base.is_jmp = DISAS_STOP;
b4160af1 6162 break;
b4dd99a3
PJ
6163 case 5:
6164 gen_helper_mtc0_config5(cpu_env, arg);
6165 rn = "Config5";
6166 /* Stop translation as we may have switched the execution mode */
eeb3bba8 6167 ctx->base.is_jmp = DISAS_STOP;
b4dd99a3 6168 break;
e397ee33
TS
6169 /* 6,7 are implementation dependent */
6170 case 6:
6171 /* ignored */
6172 rn = "Config6";
6173 break;
6174 case 7:
6175 /* ignored */
6176 rn = "Config7";
6177 break;
8c0fdd85
TS
6178 default:
6179 rn = "Invalid config selector";
f31b035a 6180 goto cp0_unimplemented;
8c0fdd85
TS
6181 }
6182 break;
6183 case 17:
7a387fff
TS
6184 switch (sel) {
6185 case 0:
895c2d04 6186 gen_helper_mtc0_lladdr(cpu_env, arg);
2423f660
TS
6187 rn = "LLAddr";
6188 break;
f6d4dd81
YK
6189 case 1:
6190 CP0_CHECK(ctx->mrp);
6191 gen_helper_mtc0_maar(cpu_env, arg);
6192 rn = "MAAR";
6193 break;
6194 case 2:
6195 CP0_CHECK(ctx->mrp);
6196 gen_helper_mtc0_maari(cpu_env, arg);
6197 rn = "MAARI";
6198 break;
7a387fff 6199 default:
f31b035a 6200 goto cp0_unimplemented;
7a387fff 6201 }
8c0fdd85
TS
6202 break;
6203 case 18:
7a387fff 6204 switch (sel) {
c2e19f3c
AM
6205 case 0:
6206 case 1:
6207 case 2:
6208 case 3:
6209 case 4:
6210 case 5:
6211 case 6:
6212 case 7:
895c2d04 6213 gen_helper_0e1i(mtc0_watchlo, arg, sel);
2423f660
TS
6214 rn = "WatchLo";
6215 break;
7a387fff 6216 default:
f31b035a 6217 goto cp0_unimplemented;
7a387fff 6218 }
8c0fdd85
TS
6219 break;
6220 case 19:
7a387fff 6221 switch (sel) {
c2e19f3c
AM
6222 case 0:
6223 case 1:
6224 case 2:
6225 case 3:
6226 case 4:
6227 case 5:
6228 case 6:
6229 case 7:
895c2d04 6230 gen_helper_0e1i(mtc0_watchhi, arg, sel);
2423f660
TS
6231 rn = "WatchHi";
6232 break;
7a387fff 6233 default:
f31b035a 6234 goto cp0_unimplemented;
7a387fff 6235 }
8c0fdd85
TS
6236 break;
6237 case 20:
7a387fff
TS
6238 switch (sel) {
6239 case 0:
d26bc211 6240#if defined(TARGET_MIPS64)
d75c135e 6241 check_insn(ctx, ISA_MIPS3);
895c2d04 6242 gen_helper_mtc0_xcontext(cpu_env, arg);
2423f660
TS
6243 rn = "XContext";
6244 break;
703eaf37 6245#endif
7a387fff 6246 default:
f31b035a 6247 goto cp0_unimplemented;
7a387fff 6248 }
8c0fdd85
TS
6249 break;
6250 case 21:
7a387fff 6251 /* Officially reserved, but sel 0 is used for R1x000 framemask */
f31b035a 6252 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
7a387fff
TS
6253 switch (sel) {
6254 case 0:
895c2d04 6255 gen_helper_mtc0_framemask(cpu_env, arg);
2423f660
TS
6256 rn = "Framemask";
6257 break;
7a387fff 6258 default:
f31b035a 6259 goto cp0_unimplemented;
7a387fff
TS
6260 }
6261 break;
8c0fdd85 6262 case 22:
7a387fff
TS
6263 /* ignored */
6264 rn = "Diagnostic"; /* implementation dependent */
2423f660 6265 break;
8c0fdd85 6266 case 23:
7a387fff
TS
6267 switch (sel) {
6268 case 0:
895c2d04 6269 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
b28425ba 6270 /* DISAS_STOP isn't good enough here, hflags may have changed. */
eeb3bba8
EC
6271 gen_save_pc(ctx->base.pc_next + 4);
6272 ctx->base.is_jmp = DISAS_EXIT;
2423f660
TS
6273 rn = "Debug";
6274 break;
7a387fff 6275 case 1:
895c2d04 6276// gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
2423f660 6277 rn = "TraceControl";
8487327a 6278 /* Stop translation as we may have switched the execution mode */
eeb3bba8 6279 ctx->base.is_jmp = DISAS_STOP;
3570d7f6 6280 goto cp0_unimplemented;
7a387fff 6281 case 2:
895c2d04 6282// gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
2423f660 6283 rn = "TraceControl2";
8487327a 6284 /* Stop translation as we may have switched the execution mode */
eeb3bba8 6285 ctx->base.is_jmp = DISAS_STOP;
3570d7f6 6286 goto cp0_unimplemented;
7a387fff 6287 case 3:
8487327a 6288 /* Stop translation as we may have switched the execution mode */
eeb3bba8 6289 ctx->base.is_jmp = DISAS_STOP;
895c2d04 6290// gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
2423f660 6291 rn = "UserTraceData";
8487327a 6292 /* Stop translation as we may have switched the execution mode */
eeb3bba8 6293 ctx->base.is_jmp = DISAS_STOP;
3570d7f6 6294 goto cp0_unimplemented;
7a387fff 6295 case 4:
895c2d04 6296// gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
8487327a 6297 /* Stop translation as we may have switched the execution mode */
eeb3bba8 6298 ctx->base.is_jmp = DISAS_STOP;
2423f660 6299 rn = "TraceBPC";
3570d7f6 6300 goto cp0_unimplemented;
7a387fff 6301 default:
f31b035a 6302 goto cp0_unimplemented;
7a387fff 6303 }
8c0fdd85
TS
6304 break;
6305 case 24:
7a387fff
TS
6306 switch (sel) {
6307 case 0:
f1aa6320 6308 /* EJTAG support */
d54a299b 6309 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
2423f660
TS
6310 rn = "DEPC";
6311 break;
7a387fff 6312 default:
f31b035a 6313 goto cp0_unimplemented;
7a387fff 6314 }
8c0fdd85
TS
6315 break;
6316 case 25:
7a387fff
TS
6317 switch (sel) {
6318 case 0:
895c2d04 6319 gen_helper_mtc0_performance0(cpu_env, arg);
2423f660
TS
6320 rn = "Performance0";
6321 break;
7a387fff 6322 case 1:
d9bea114 6323// gen_helper_mtc0_performance1(arg);
2423f660 6324 rn = "Performance1";
3570d7f6 6325 goto cp0_unimplemented;
7a387fff 6326 case 2:
d9bea114 6327// gen_helper_mtc0_performance2(arg);
2423f660 6328 rn = "Performance2";
3570d7f6 6329 goto cp0_unimplemented;
7a387fff 6330 case 3:
d9bea114 6331// gen_helper_mtc0_performance3(arg);
2423f660 6332 rn = "Performance3";
3570d7f6 6333 goto cp0_unimplemented;
7a387fff 6334 case 4:
d9bea114 6335// gen_helper_mtc0_performance4(arg);
2423f660 6336 rn = "Performance4";
3570d7f6 6337 goto cp0_unimplemented;
7a387fff 6338 case 5:
d9bea114 6339// gen_helper_mtc0_performance5(arg);
2423f660 6340 rn = "Performance5";
3570d7f6 6341 goto cp0_unimplemented;
7a387fff 6342 case 6:
d9bea114 6343// gen_helper_mtc0_performance6(arg);
2423f660 6344 rn = "Performance6";
3570d7f6 6345 goto cp0_unimplemented;
7a387fff 6346 case 7:
d9bea114 6347// gen_helper_mtc0_performance7(arg);
2423f660 6348 rn = "Performance7";
3570d7f6 6349 goto cp0_unimplemented;
7a387fff 6350 default:
f31b035a 6351 goto cp0_unimplemented;
7a387fff 6352 }
8c0fdd85
TS
6353 break;
6354 case 26:
0d74a222
LA
6355 switch (sel) {
6356 case 0:
6357 gen_helper_mtc0_errctl(cpu_env, arg);
eeb3bba8 6358 ctx->base.is_jmp = DISAS_STOP;
0d74a222
LA
6359 rn = "ErrCtl";
6360 break;
6361 default:
6362 goto cp0_unimplemented;
6363 }
2423f660 6364 break;
8c0fdd85 6365 case 27:
7a387fff 6366 switch (sel) {
c2e19f3c
AM
6367 case 0:
6368 case 1:
6369 case 2:
6370 case 3:
2423f660
TS
6371 /* ignored */
6372 rn = "CacheErr";
6373 break;
7a387fff 6374 default:
f31b035a 6375 goto cp0_unimplemented;
7a387fff 6376 }
8c0fdd85
TS
6377 break;
6378 case 28:
6379 switch (sel) {
6380 case 0:
7a387fff
TS
6381 case 2:
6382 case 4:
6383 case 6:
895c2d04 6384 gen_helper_mtc0_taglo(cpu_env, arg);
8c0fdd85
TS
6385 rn = "TagLo";
6386 break;
7a387fff
TS
6387 case 1:
6388 case 3:
6389 case 5:
6390 case 7:
895c2d04 6391 gen_helper_mtc0_datalo(cpu_env, arg);
7a387fff
TS
6392 rn = "DataLo";
6393 break;
8c0fdd85 6394 default:
f31b035a 6395 goto cp0_unimplemented;
8c0fdd85
TS
6396 }
6397 break;
6398 case 29:
7a387fff
TS
6399 switch (sel) {
6400 case 0:
6401 case 2:
6402 case 4:
6403 case 6:
895c2d04 6404 gen_helper_mtc0_taghi(cpu_env, arg);
7a387fff
TS
6405 rn = "TagHi";
6406 break;
6407 case 1:
6408 case 3:
6409 case 5:
6410 case 7:
895c2d04 6411 gen_helper_mtc0_datahi(cpu_env, arg);
7a387fff
TS
6412 rn = "DataHi";
6413 break;
6414 default:
6415 rn = "invalid sel";
f31b035a 6416 goto cp0_unimplemented;
7a387fff 6417 }
8c0fdd85
TS
6418 break;
6419 case 30:
7a387fff
TS
6420 switch (sel) {
6421 case 0:
d54a299b 6422 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
2423f660
TS
6423 rn = "ErrorEPC";
6424 break;
7a387fff 6425 default:
f31b035a 6426 goto cp0_unimplemented;
7a387fff 6427 }
8c0fdd85
TS
6428 break;
6429 case 31:
7a387fff
TS
6430 switch (sel) {
6431 case 0:
f1aa6320 6432 /* EJTAG support */
7db13fae 6433 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
6434 rn = "DESAVE";
6435 break;
c2e19f3c
AM
6436 case 2:
6437 case 3:
6438 case 4:
6439 case 5:
6440 case 6:
6441 case 7:
f31b035a
LA
6442 CP0_CHECK(ctx->kscrexist & (1 << sel));
6443 tcg_gen_st_tl(arg, cpu_env,
6444 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
6445 rn = "KScratch";
e98c0d17 6446 break;
7a387fff 6447 default:
f31b035a 6448 goto cp0_unimplemented;
7a387fff 6449 }
8c0fdd85
TS
6450 break;
6451 default:
f31b035a 6452 goto cp0_unimplemented;
8c0fdd85 6453 }
b44a7fb1
PMD
6454 trace_mips_translate_c0("mtc0", rn, reg, sel);
6455
bf20dc07 6456 /* For simplicity assume that all writes can cause interrupts. */
eeb3bba8 6457 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
2e70f6ef 6458 gen_io_end();
b28425ba 6459 /* DISAS_STOP isn't sufficient, we need to ensure we break out of
b74cddcb 6460 * translated code to check for pending interrupts. */
eeb3bba8
EC
6461 gen_save_pc(ctx->base.pc_next + 4);
6462 ctx->base.is_jmp = DISAS_EXIT;
2e70f6ef 6463 }
8c0fdd85
TS
6464 return;
6465
f31b035a 6466cp0_unimplemented:
965447ee 6467 qemu_log_mask(LOG_UNIMP, "mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
8c0fdd85
TS
6468}
6469
d26bc211 6470#if defined(TARGET_MIPS64)
d75c135e 6471static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
9c2149c8
TS
6472{
6473 const char *rn = "invalid";
6474
e189e748 6475 if (sel != 0)
d75c135e 6476 check_insn(ctx, ISA_MIPS64);
e189e748 6477
9c2149c8
TS
6478 switch (reg) {
6479 case 0:
6480 switch (sel) {
6481 case 0:
7db13fae 6482 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
9c2149c8
TS
6483 rn = "Index";
6484 break;
6485 case 1:
f31b035a 6486 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6487 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
9c2149c8 6488 rn = "MVPControl";
ead9360e 6489 break;
9c2149c8 6490 case 2:
f31b035a 6491 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6492 gen_helper_mfc0_mvpconf0(arg, cpu_env);
9c2149c8 6493 rn = "MVPConf0";
ead9360e 6494 break;
9c2149c8 6495 case 3:
f31b035a 6496 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6497 gen_helper_mfc0_mvpconf1(arg, cpu_env);
9c2149c8 6498 rn = "MVPConf1";
ead9360e 6499 break;
01bc435b
YK
6500 case 4:
6501 CP0_CHECK(ctx->vp);
6502 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl));
6503 rn = "VPControl";
6504 break;
9c2149c8 6505 default:
f31b035a 6506 goto cp0_unimplemented;
9c2149c8
TS
6507 }
6508 break;
6509 case 1:
6510 switch (sel) {
6511 case 0:
f31b035a 6512 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
895c2d04 6513 gen_helper_mfc0_random(arg, cpu_env);
9c2149c8 6514 rn = "Random";
2423f660 6515 break;
9c2149c8 6516 case 1:
f31b035a 6517 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6518 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
9c2149c8 6519 rn = "VPEControl";
ead9360e 6520 break;
9c2149c8 6521 case 2:
f31b035a 6522 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6523 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
9c2149c8 6524 rn = "VPEConf0";
ead9360e 6525 break;
9c2149c8 6526 case 3:
f31b035a 6527 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6528 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
9c2149c8 6529 rn = "VPEConf1";
ead9360e 6530 break;
9c2149c8 6531 case 4:
f31b035a 6532 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6533 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_YQMask));
9c2149c8 6534 rn = "YQMask";
ead9360e 6535 break;
9c2149c8 6536 case 5:
f31b035a 6537 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6538 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
9c2149c8 6539 rn = "VPESchedule";
ead9360e 6540 break;
9c2149c8 6541 case 6:
f31b035a 6542 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6543 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
9c2149c8 6544 rn = "VPEScheFBack";
ead9360e 6545 break;
9c2149c8 6546 case 7:
f31b035a 6547 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6548 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
9c2149c8 6549 rn = "VPEOpt";
ead9360e 6550 break;
9c2149c8 6551 default:
f31b035a 6552 goto cp0_unimplemented;
9c2149c8
TS
6553 }
6554 break;
6555 case 2:
6556 switch (sel) {
6557 case 0:
7db13fae 6558 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
2423f660
TS
6559 rn = "EntryLo0";
6560 break;
9c2149c8 6561 case 1:
f31b035a 6562 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6563 gen_helper_mfc0_tcstatus(arg, cpu_env);
2423f660 6564 rn = "TCStatus";
ead9360e 6565 break;
9c2149c8 6566 case 2:
f31b035a 6567 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6568 gen_helper_mfc0_tcbind(arg, cpu_env);
2423f660 6569 rn = "TCBind";
ead9360e 6570 break;
9c2149c8 6571 case 3:
f31b035a 6572 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6573 gen_helper_dmfc0_tcrestart(arg, cpu_env);
2423f660 6574 rn = "TCRestart";
ead9360e 6575 break;
9c2149c8 6576 case 4:
f31b035a 6577 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6578 gen_helper_dmfc0_tchalt(arg, cpu_env);
2423f660 6579 rn = "TCHalt";
ead9360e 6580 break;
9c2149c8 6581 case 5:
f31b035a 6582 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6583 gen_helper_dmfc0_tccontext(arg, cpu_env);
2423f660 6584 rn = "TCContext";
ead9360e 6585 break;
9c2149c8 6586 case 6:
f31b035a 6587 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6588 gen_helper_dmfc0_tcschedule(arg, cpu_env);
2423f660 6589 rn = "TCSchedule";
ead9360e 6590 break;
9c2149c8 6591 case 7:
f31b035a 6592 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6593 gen_helper_dmfc0_tcschefback(arg, cpu_env);
2423f660 6594 rn = "TCScheFBack";
ead9360e 6595 break;
9c2149c8 6596 default:
f31b035a 6597 goto cp0_unimplemented;
9c2149c8
TS
6598 }
6599 break;
6600 case 3:
6601 switch (sel) {
6602 case 0:
7db13fae 6603 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
2423f660
TS
6604 rn = "EntryLo1";
6605 break;
01bc435b
YK
6606 case 1:
6607 CP0_CHECK(ctx->vp);
6608 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber));
6609 rn = "GlobalNumber";
6610 break;
9c2149c8 6611 default:
f31b035a 6612 goto cp0_unimplemented;
1579a72e 6613 }
9c2149c8
TS
6614 break;
6615 case 4:
6616 switch (sel) {
6617 case 0:
7db13fae 6618 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
2423f660
TS
6619 rn = "Context";
6620 break;
9c2149c8 6621 case 1:
d9bea114 6622// gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
2423f660 6623 rn = "ContextConfig";
f31b035a 6624 goto cp0_unimplemented;
d279279e 6625 case 2:
f31b035a
LA
6626 CP0_CHECK(ctx->ulri);
6627 tcg_gen_ld_tl(arg, cpu_env,
6628 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
6629 rn = "UserLocal";
d279279e 6630 break;
9c2149c8 6631 default:
f31b035a 6632 goto cp0_unimplemented;
876d4b07 6633 }
9c2149c8
TS
6634 break;
6635 case 5:
6636 switch (sel) {
6637 case 0:
7db13fae 6638 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
2423f660
TS
6639 rn = "PageMask";
6640 break;
9c2149c8 6641 case 1:
d75c135e 6642 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6643 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
2423f660
TS
6644 rn = "PageGrain";
6645 break;
cec56a73
JH
6646 case 2:
6647 CP0_CHECK(ctx->sc);
6648 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl0));
6649 rn = "SegCtl0";
6650 break;
6651 case 3:
6652 CP0_CHECK(ctx->sc);
6653 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl1));
6654 rn = "SegCtl1";
6655 break;
6656 case 4:
6657 CP0_CHECK(ctx->sc);
6658 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl2));
6659 rn = "SegCtl2";
6660 break;
9c2149c8 6661 default:
f31b035a 6662 goto cp0_unimplemented;
876d4b07 6663 }
9c2149c8
TS
6664 break;
6665 case 6:
6666 switch (sel) {
6667 case 0:
7db13fae 6668 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
2423f660
TS
6669 rn = "Wired";
6670 break;
9c2149c8 6671 case 1:
d75c135e 6672 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6673 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
2423f660 6674 rn = "SRSConf0";
ead9360e 6675 break;
9c2149c8 6676 case 2:
d75c135e 6677 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6678 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
2423f660 6679 rn = "SRSConf1";
ead9360e 6680 break;
9c2149c8 6681 case 3:
d75c135e 6682 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6683 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
2423f660 6684 rn = "SRSConf2";
ead9360e 6685 break;
9c2149c8 6686 case 4:
d75c135e 6687 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6688 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
2423f660 6689 rn = "SRSConf3";
ead9360e 6690 break;
9c2149c8 6691 case 5:
d75c135e 6692 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6693 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
2423f660 6694 rn = "SRSConf4";
ead9360e 6695 break;
9c2149c8 6696 default:
f31b035a 6697 goto cp0_unimplemented;
876d4b07 6698 }
9c2149c8
TS
6699 break;
6700 case 7:
6701 switch (sel) {
6702 case 0:
d75c135e 6703 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6704 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
2423f660
TS
6705 rn = "HWREna";
6706 break;
9c2149c8 6707 default:
f31b035a 6708 goto cp0_unimplemented;
876d4b07 6709 }
9c2149c8
TS
6710 break;
6711 case 8:
6712 switch (sel) {
6713 case 0:
7db13fae 6714 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
f0b3f3ae 6715 rn = "BadVAddr";
2423f660 6716 break;
aea14095 6717 case 1:
f31b035a
LA
6718 CP0_CHECK(ctx->bi);
6719 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
6720 rn = "BadInstr";
aea14095
LA
6721 break;
6722 case 2:
f31b035a
LA
6723 CP0_CHECK(ctx->bp);
6724 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
6725 rn = "BadInstrP";
aea14095 6726 break;
9c2149c8 6727 default:
f31b035a 6728 goto cp0_unimplemented;
876d4b07 6729 }
9c2149c8
TS
6730 break;
6731 case 9:
6732 switch (sel) {
6733 case 0:
2e70f6ef 6734 /* Mark as an IO operation because we read the time. */
eeb3bba8 6735 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
2e70f6ef 6736 gen_io_start();
bd79255d 6737 }
895c2d04 6738 gen_helper_mfc0_count(arg, cpu_env);
eeb3bba8 6739 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
2e70f6ef 6740 gen_io_end();
2e70f6ef 6741 }
55807224 6742 /* Break the TB to be able to take timer interrupts immediately
b28425ba
EC
6743 after reading count. DISAS_STOP isn't sufficient, we need to
6744 ensure we break completely out of translated code. */
eeb3bba8
EC
6745 gen_save_pc(ctx->base.pc_next + 4);
6746 ctx->base.is_jmp = DISAS_EXIT;
2423f660
TS
6747 rn = "Count";
6748 break;
6749 /* 6,7 are implementation dependent */
9c2149c8 6750 default:
f31b035a 6751 goto cp0_unimplemented;
876d4b07 6752 }
9c2149c8
TS
6753 break;
6754 case 10:
6755 switch (sel) {
6756 case 0:
7db13fae 6757 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
2423f660
TS
6758 rn = "EntryHi";
6759 break;
9c2149c8 6760 default:
f31b035a 6761 goto cp0_unimplemented;
876d4b07 6762 }
9c2149c8
TS
6763 break;
6764 case 11:
6765 switch (sel) {
6766 case 0:
7db13fae 6767 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
2423f660
TS
6768 rn = "Compare";
6769 break;
876d4b07 6770 /* 6,7 are implementation dependent */
9c2149c8 6771 default:
f31b035a 6772 goto cp0_unimplemented;
876d4b07 6773 }
9c2149c8
TS
6774 break;
6775 case 12:
6776 switch (sel) {
6777 case 0:
7db13fae 6778 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
2423f660
TS
6779 rn = "Status";
6780 break;
9c2149c8 6781 case 1:
d75c135e 6782 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6783 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
2423f660
TS
6784 rn = "IntCtl";
6785 break;
9c2149c8 6786 case 2:
d75c135e 6787 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6788 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
2423f660
TS
6789 rn = "SRSCtl";
6790 break;
9c2149c8 6791 case 3:
d75c135e 6792 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6793 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
2423f660
TS
6794 rn = "SRSMap";
6795 break;
9c2149c8 6796 default:
f31b035a 6797 goto cp0_unimplemented;
876d4b07 6798 }
9c2149c8
TS
6799 break;
6800 case 13:
6801 switch (sel) {
6802 case 0:
7db13fae 6803 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
2423f660
TS
6804 rn = "Cause";
6805 break;
9c2149c8 6806 default:
f31b035a 6807 goto cp0_unimplemented;
876d4b07 6808 }
9c2149c8
TS
6809 break;
6810 case 14:
6811 switch (sel) {
6812 case 0:
7db13fae 6813 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
2423f660
TS
6814 rn = "EPC";
6815 break;
9c2149c8 6816 default:
f31b035a 6817 goto cp0_unimplemented;
876d4b07 6818 }
9c2149c8
TS
6819 break;
6820 case 15:
6821 switch (sel) {
6822 case 0:
7db13fae 6823 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
2423f660
TS
6824 rn = "PRid";
6825 break;
9c2149c8 6826 case 1:
d75c135e 6827 check_insn(ctx, ISA_MIPS32R2);
74dbf824 6828 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EBase));
2423f660
TS
6829 rn = "EBase";
6830 break;
c870e3f5
YK
6831 case 3:
6832 check_insn(ctx, ISA_MIPS32R2);
6833 CP0_CHECK(ctx->cmgcr);
6834 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase));
6835 rn = "CMGCRBase";
6836 break;
9c2149c8 6837 default:
f31b035a 6838 goto cp0_unimplemented;
876d4b07 6839 }
9c2149c8
TS
6840 break;
6841 case 16:
6842 switch (sel) {
6843 case 0:
7db13fae 6844 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
9c2149c8
TS
6845 rn = "Config";
6846 break;
6847 case 1:
7db13fae 6848 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
9c2149c8
TS
6849 rn = "Config1";
6850 break;
6851 case 2:
7db13fae 6852 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
9c2149c8
TS
6853 rn = "Config2";
6854 break;
6855 case 3:
7db13fae 6856 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
9c2149c8
TS
6857 rn = "Config3";
6858 break;
faf1f68b
LA
6859 case 4:
6860 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
6861 rn = "Config4";
6862 break;
6863 case 5:
6864 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
6865 rn = "Config5";
6866 break;
9c2149c8 6867 /* 6,7 are implementation dependent */
f0b3f3ae 6868 case 6:
7db13fae 6869 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
f0b3f3ae
TS
6870 rn = "Config6";
6871 break;
6872 case 7:
7db13fae 6873 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
f0b3f3ae
TS
6874 rn = "Config7";
6875 break;
9c2149c8 6876 default:
f31b035a 6877 goto cp0_unimplemented;
9c2149c8
TS
6878 }
6879 break;
6880 case 17:
6881 switch (sel) {
6882 case 0:
895c2d04 6883 gen_helper_dmfc0_lladdr(arg, cpu_env);
2423f660
TS
6884 rn = "LLAddr";
6885 break;
f6d4dd81
YK
6886 case 1:
6887 CP0_CHECK(ctx->mrp);
6888 gen_helper_dmfc0_maar(arg, cpu_env);
6889 rn = "MAAR";
6890 break;
6891 case 2:
6892 CP0_CHECK(ctx->mrp);
6893 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI));
6894 rn = "MAARI";
6895 break;
9c2149c8 6896 default:
f31b035a 6897 goto cp0_unimplemented;
9c2149c8
TS
6898 }
6899 break;
6900 case 18:
6901 switch (sel) {
c2e19f3c
AM
6902 case 0:
6903 case 1:
6904 case 2:
6905 case 3:
6906 case 4:
6907 case 5:
6908 case 6:
6909 case 7:
895c2d04 6910 gen_helper_1e0i(dmfc0_watchlo, arg, sel);
2423f660
TS
6911 rn = "WatchLo";
6912 break;
9c2149c8 6913 default:
f31b035a 6914 goto cp0_unimplemented;
9c2149c8
TS
6915 }
6916 break;
6917 case 19:
6918 switch (sel) {
c2e19f3c
AM
6919 case 0:
6920 case 1:
6921 case 2:
6922 case 3:
6923 case 4:
6924 case 5:
6925 case 6:
6926 case 7:
895c2d04 6927 gen_helper_1e0i(mfc0_watchhi, arg, sel);
2423f660
TS
6928 rn = "WatchHi";
6929 break;
9c2149c8 6930 default:
f31b035a 6931 goto cp0_unimplemented;
9c2149c8
TS
6932 }
6933 break;
6934 case 20:
6935 switch (sel) {
6936 case 0:
d75c135e 6937 check_insn(ctx, ISA_MIPS3);
7db13fae 6938 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
2423f660
TS
6939 rn = "XContext";
6940 break;
9c2149c8 6941 default:
f31b035a 6942 goto cp0_unimplemented;
9c2149c8
TS
6943 }
6944 break;
6945 case 21:
6946 /* Officially reserved, but sel 0 is used for R1x000 framemask */
f31b035a 6947 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
9c2149c8
TS
6948 switch (sel) {
6949 case 0:
7db13fae 6950 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
2423f660
TS
6951 rn = "Framemask";
6952 break;
9c2149c8 6953 default:
f31b035a 6954 goto cp0_unimplemented;
9c2149c8
TS
6955 }
6956 break;
6957 case 22:
d9bea114 6958 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
6959 rn = "'Diagnostic"; /* implementation dependent */
6960 break;
9c2149c8
TS
6961 case 23:
6962 switch (sel) {
6963 case 0:
895c2d04 6964 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
2423f660
TS
6965 rn = "Debug";
6966 break;
9c2149c8 6967 case 1:
895c2d04 6968// gen_helper_dmfc0_tracecontrol(arg, cpu_env); /* PDtrace support */
2423f660 6969 rn = "TraceControl";
3570d7f6 6970 goto cp0_unimplemented;
9c2149c8 6971 case 2:
895c2d04 6972// gen_helper_dmfc0_tracecontrol2(arg, cpu_env); /* PDtrace support */
2423f660 6973 rn = "TraceControl2";
3570d7f6 6974 goto cp0_unimplemented;
9c2149c8 6975 case 3:
895c2d04 6976// gen_helper_dmfc0_usertracedata(arg, cpu_env); /* PDtrace support */
2423f660 6977 rn = "UserTraceData";
3570d7f6 6978 goto cp0_unimplemented;
9c2149c8 6979 case 4:
895c2d04 6980// gen_helper_dmfc0_tracebpc(arg, cpu_env); /* PDtrace support */
2423f660 6981 rn = "TraceBPC";
3570d7f6 6982 goto cp0_unimplemented;
9c2149c8 6983 default:
f31b035a 6984 goto cp0_unimplemented;
9c2149c8
TS
6985 }
6986 break;
6987 case 24:
6988 switch (sel) {
6989 case 0:
f0b3f3ae 6990 /* EJTAG support */
7db13fae 6991 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
2423f660
TS
6992 rn = "DEPC";
6993 break;
9c2149c8 6994 default:
f31b035a 6995 goto cp0_unimplemented;
9c2149c8
TS
6996 }
6997 break;
6998 case 25:
6999 switch (sel) {
7000 case 0:
7db13fae 7001 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
2423f660 7002 rn = "Performance0";
9c2149c8
TS
7003 break;
7004 case 1:
d9bea114 7005// gen_helper_dmfc0_performance1(arg);
2423f660 7006 rn = "Performance1";
3570d7f6 7007 goto cp0_unimplemented;
9c2149c8 7008 case 2:
d9bea114 7009// gen_helper_dmfc0_performance2(arg);
2423f660 7010 rn = "Performance2";
3570d7f6 7011 goto cp0_unimplemented;
9c2149c8 7012 case 3:
d9bea114 7013// gen_helper_dmfc0_performance3(arg);
2423f660 7014 rn = "Performance3";
3570d7f6 7015 goto cp0_unimplemented;
9c2149c8 7016 case 4:
d9bea114 7017// gen_helper_dmfc0_performance4(arg);
2423f660 7018 rn = "Performance4";
3570d7f6 7019 goto cp0_unimplemented;
9c2149c8 7020 case 5:
d9bea114 7021// gen_helper_dmfc0_performance5(arg);
2423f660 7022 rn = "Performance5";
3570d7f6 7023 goto cp0_unimplemented;
9c2149c8 7024 case 6:
d9bea114 7025// gen_helper_dmfc0_performance6(arg);
2423f660 7026 rn = "Performance6";
3570d7f6 7027 goto cp0_unimplemented;
9c2149c8 7028 case 7:
d9bea114 7029// gen_helper_dmfc0_performance7(arg);
2423f660 7030 rn = "Performance7";
3570d7f6 7031 goto cp0_unimplemented;
9c2149c8 7032 default:
f31b035a 7033 goto cp0_unimplemented;
9c2149c8
TS
7034 }
7035 break;
7036 case 26:
0d74a222
LA
7037 switch (sel) {
7038 case 0:
7039 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl));
7040 rn = "ErrCtl";
7041 break;
7042 default:
7043 goto cp0_unimplemented;
7044 }
da80682b 7045 break;
9c2149c8
TS
7046 case 27:
7047 switch (sel) {
7048 /* ignored */
c2e19f3c
AM
7049 case 0:
7050 case 1:
7051 case 2:
7052 case 3:
d9bea114 7053 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
7054 rn = "CacheErr";
7055 break;
9c2149c8 7056 default:
f31b035a 7057 goto cp0_unimplemented;
9c2149c8
TS
7058 }
7059 break;
7060 case 28:
7061 switch (sel) {
7062 case 0:
7063 case 2:
7064 case 4:
7065 case 6:
7db13fae 7066 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
9c2149c8
TS
7067 rn = "TagLo";
7068 break;
7069 case 1:
7070 case 3:
7071 case 5:
7072 case 7:
7db13fae 7073 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
9c2149c8
TS
7074 rn = "DataLo";
7075 break;
7076 default:
f31b035a 7077 goto cp0_unimplemented;
9c2149c8
TS
7078 }
7079 break;
7080 case 29:
7081 switch (sel) {
7082 case 0:
7083 case 2:
7084 case 4:
7085 case 6:
7db13fae 7086 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
9c2149c8
TS
7087 rn = "TagHi";
7088 break;
7089 case 1:
7090 case 3:
7091 case 5:
7092 case 7:
7db13fae 7093 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
9c2149c8
TS
7094 rn = "DataHi";
7095 break;
7096 default:
f31b035a 7097 goto cp0_unimplemented;
9c2149c8
TS
7098 }
7099 break;
7100 case 30:
7101 switch (sel) {
7102 case 0:
7db13fae 7103 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
2423f660
TS
7104 rn = "ErrorEPC";
7105 break;
9c2149c8 7106 default:
f31b035a 7107 goto cp0_unimplemented;
9c2149c8
TS
7108 }
7109 break;
7110 case 31:
7111 switch (sel) {
7112 case 0:
f0b3f3ae 7113 /* EJTAG support */
7db13fae 7114 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
7115 rn = "DESAVE";
7116 break;
c2e19f3c
AM
7117 case 2:
7118 case 3:
7119 case 4:
7120 case 5:
7121 case 6:
7122 case 7:
f31b035a
LA
7123 CP0_CHECK(ctx->kscrexist & (1 << sel));
7124 tcg_gen_ld_tl(arg, cpu_env,
7125 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
7126 rn = "KScratch";
e98c0d17 7127 break;
9c2149c8 7128 default:
f31b035a 7129 goto cp0_unimplemented;
9c2149c8
TS
7130 }
7131 break;
7132 default:
f31b035a 7133 goto cp0_unimplemented;
9c2149c8 7134 }
b44a7fb1 7135 trace_mips_translate_c0("dmfc0", rn, reg, sel);
9c2149c8
TS
7136 return;
7137
f31b035a 7138cp0_unimplemented:
965447ee 7139 qemu_log_mask(LOG_UNIMP, "dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
f31b035a 7140 gen_mfc0_unimplemented(ctx, arg);
9c2149c8
TS
7141}
7142
d75c135e 7143static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
9c2149c8
TS
7144{
7145 const char *rn = "invalid";
7146
e189e748 7147 if (sel != 0)
d75c135e 7148 check_insn(ctx, ISA_MIPS64);
e189e748 7149
eeb3bba8 7150 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
2e70f6ef 7151 gen_io_start();
bd79255d 7152 }
2e70f6ef 7153
9c2149c8
TS
7154 switch (reg) {
7155 case 0:
7156 switch (sel) {
7157 case 0:
895c2d04 7158 gen_helper_mtc0_index(cpu_env, arg);
9c2149c8
TS
7159 rn = "Index";
7160 break;
7161 case 1:
f31b035a 7162 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7163 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
9c2149c8 7164 rn = "MVPControl";
ead9360e 7165 break;
9c2149c8 7166 case 2:
f31b035a 7167 CP0_CHECK(ctx->insn_flags & ASE_MT);
ead9360e 7168 /* ignored */
9c2149c8 7169 rn = "MVPConf0";
ead9360e 7170 break;
9c2149c8 7171 case 3:
f31b035a 7172 CP0_CHECK(ctx->insn_flags & ASE_MT);
ead9360e 7173 /* ignored */
9c2149c8 7174 rn = "MVPConf1";
ead9360e 7175 break;
01bc435b
YK
7176 case 4:
7177 CP0_CHECK(ctx->vp);
7178 /* ignored */
7179 rn = "VPControl";
7180 break;
9c2149c8 7181 default:
f31b035a 7182 goto cp0_unimplemented;
9c2149c8
TS
7183 }
7184 break;
7185 case 1:
7186 switch (sel) {
7187 case 0:
2423f660 7188 /* ignored */
9c2149c8 7189 rn = "Random";
2423f660 7190 break;
9c2149c8 7191 case 1:
f31b035a 7192 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7193 gen_helper_mtc0_vpecontrol(cpu_env, arg);
9c2149c8 7194 rn = "VPEControl";
ead9360e 7195 break;
9c2149c8 7196 case 2:
f31b035a 7197 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7198 gen_helper_mtc0_vpeconf0(cpu_env, arg);
9c2149c8 7199 rn = "VPEConf0";
ead9360e 7200 break;
9c2149c8 7201 case 3:
f31b035a 7202 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7203 gen_helper_mtc0_vpeconf1(cpu_env, arg);
9c2149c8 7204 rn = "VPEConf1";
ead9360e 7205 break;
9c2149c8 7206 case 4:
f31b035a 7207 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7208 gen_helper_mtc0_yqmask(cpu_env, arg);
9c2149c8 7209 rn = "YQMask";
ead9360e 7210 break;
9c2149c8 7211 case 5:
f31b035a 7212 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 7213 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
9c2149c8 7214 rn = "VPESchedule";
ead9360e 7215 break;
9c2149c8 7216 case 6:
f31b035a 7217 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 7218 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
9c2149c8 7219 rn = "VPEScheFBack";
ead9360e 7220 break;
9c2149c8 7221 case 7:
f31b035a 7222 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7223 gen_helper_mtc0_vpeopt(cpu_env, arg);
9c2149c8 7224 rn = "VPEOpt";
ead9360e 7225 break;
9c2149c8 7226 default:
f31b035a 7227 goto cp0_unimplemented;
9c2149c8
TS
7228 }
7229 break;
7230 case 2:
7231 switch (sel) {
7232 case 0:
7207c7f9 7233 gen_helper_dmtc0_entrylo0(cpu_env, arg);
2423f660
TS
7234 rn = "EntryLo0";
7235 break;
9c2149c8 7236 case 1:
f31b035a 7237 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7238 gen_helper_mtc0_tcstatus(cpu_env, arg);
2423f660 7239 rn = "TCStatus";
ead9360e 7240 break;
9c2149c8 7241 case 2:
f31b035a 7242 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7243 gen_helper_mtc0_tcbind(cpu_env, arg);
2423f660 7244 rn = "TCBind";
ead9360e 7245 break;
9c2149c8 7246 case 3:
f31b035a 7247 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7248 gen_helper_mtc0_tcrestart(cpu_env, arg);
2423f660 7249 rn = "TCRestart";
ead9360e 7250 break;
9c2149c8 7251 case 4:
f31b035a 7252 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7253 gen_helper_mtc0_tchalt(cpu_env, arg);
2423f660 7254 rn = "TCHalt";
ead9360e 7255 break;
9c2149c8 7256 case 5:
f31b035a 7257 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7258 gen_helper_mtc0_tccontext(cpu_env, arg);
2423f660 7259 rn = "TCContext";
ead9360e 7260 break;
9c2149c8 7261 case 6:
f31b035a 7262 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7263 gen_helper_mtc0_tcschedule(cpu_env, arg);
2423f660 7264 rn = "TCSchedule";
ead9360e 7265 break;
9c2149c8 7266 case 7:
f31b035a 7267 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7268 gen_helper_mtc0_tcschefback(cpu_env, arg);
2423f660 7269 rn = "TCScheFBack";
ead9360e 7270 break;
9c2149c8 7271 default:
f31b035a 7272 goto cp0_unimplemented;
9c2149c8
TS
7273 }
7274 break;
7275 case 3:
7276 switch (sel) {
7277 case 0:
7207c7f9 7278 gen_helper_dmtc0_entrylo1(cpu_env, arg);
2423f660
TS
7279 rn = "EntryLo1";
7280 break;
01bc435b
YK
7281 case 1:
7282 CP0_CHECK(ctx->vp);
7283 /* ignored */
7284 rn = "GlobalNumber";
7285 break;
9c2149c8 7286 default:
f31b035a 7287 goto cp0_unimplemented;
876d4b07 7288 }
9c2149c8
TS
7289 break;
7290 case 4:
7291 switch (sel) {
7292 case 0:
895c2d04 7293 gen_helper_mtc0_context(cpu_env, arg);
2423f660
TS
7294 rn = "Context";
7295 break;
9c2149c8 7296 case 1:
895c2d04 7297// gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
2423f660 7298 rn = "ContextConfig";
f31b035a 7299 goto cp0_unimplemented;
d279279e 7300 case 2:
f31b035a
LA
7301 CP0_CHECK(ctx->ulri);
7302 tcg_gen_st_tl(arg, cpu_env,
7303 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
7304 rn = "UserLocal";
d279279e 7305 break;
9c2149c8 7306 default:
f31b035a 7307 goto cp0_unimplemented;
876d4b07 7308 }
9c2149c8
TS
7309 break;
7310 case 5:
7311 switch (sel) {
7312 case 0:
895c2d04 7313 gen_helper_mtc0_pagemask(cpu_env, arg);
2423f660
TS
7314 rn = "PageMask";
7315 break;
9c2149c8 7316 case 1:
d75c135e 7317 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7318 gen_helper_mtc0_pagegrain(cpu_env, arg);
2423f660
TS
7319 rn = "PageGrain";
7320 break;
cec56a73
JH
7321 case 2:
7322 CP0_CHECK(ctx->sc);
7323 gen_helper_mtc0_segctl0(cpu_env, arg);
7324 rn = "SegCtl0";
7325 break;
7326 case 3:
7327 CP0_CHECK(ctx->sc);
7328 gen_helper_mtc0_segctl1(cpu_env, arg);
7329 rn = "SegCtl1";
7330 break;
7331 case 4:
7332 CP0_CHECK(ctx->sc);
7333 gen_helper_mtc0_segctl2(cpu_env, arg);
7334 rn = "SegCtl2";
7335 break;
9c2149c8 7336 default:
f31b035a 7337 goto cp0_unimplemented;
876d4b07 7338 }
9c2149c8
TS
7339 break;
7340 case 6:
7341 switch (sel) {
7342 case 0:
895c2d04 7343 gen_helper_mtc0_wired(cpu_env, arg);
2423f660
TS
7344 rn = "Wired";
7345 break;
9c2149c8 7346 case 1:
d75c135e 7347 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7348 gen_helper_mtc0_srsconf0(cpu_env, arg);
2423f660 7349 rn = "SRSConf0";
ead9360e 7350 break;
9c2149c8 7351 case 2:
d75c135e 7352 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7353 gen_helper_mtc0_srsconf1(cpu_env, arg);
2423f660 7354 rn = "SRSConf1";
ead9360e 7355 break;
9c2149c8 7356 case 3:
d75c135e 7357 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7358 gen_helper_mtc0_srsconf2(cpu_env, arg);
2423f660 7359 rn = "SRSConf2";
ead9360e 7360 break;
9c2149c8 7361 case 4:
d75c135e 7362 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7363 gen_helper_mtc0_srsconf3(cpu_env, arg);
2423f660 7364 rn = "SRSConf3";
ead9360e 7365 break;
9c2149c8 7366 case 5:
d75c135e 7367 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7368 gen_helper_mtc0_srsconf4(cpu_env, arg);
2423f660 7369 rn = "SRSConf4";
ead9360e 7370 break;
9c2149c8 7371 default:
f31b035a 7372 goto cp0_unimplemented;
876d4b07 7373 }
9c2149c8
TS
7374 break;
7375 case 7:
7376 switch (sel) {
7377 case 0:
d75c135e 7378 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7379 gen_helper_mtc0_hwrena(cpu_env, arg);
eeb3bba8 7380 ctx->base.is_jmp = DISAS_STOP;
2423f660
TS
7381 rn = "HWREna";
7382 break;
9c2149c8 7383 default:
f31b035a 7384 goto cp0_unimplemented;
876d4b07 7385 }
9c2149c8
TS
7386 break;
7387 case 8:
aea14095
LA
7388 switch (sel) {
7389 case 0:
7390 /* ignored */
7391 rn = "BadVAddr";
7392 break;
7393 case 1:
7394 /* ignored */
7395 rn = "BadInstr";
7396 break;
7397 case 2:
7398 /* ignored */
7399 rn = "BadInstrP";
7400 break;
7401 default:
f31b035a 7402 goto cp0_unimplemented;
aea14095 7403 }
9c2149c8
TS
7404 break;
7405 case 9:
7406 switch (sel) {
7407 case 0:
895c2d04 7408 gen_helper_mtc0_count(cpu_env, arg);
2423f660
TS
7409 rn = "Count";
7410 break;
876d4b07 7411 /* 6,7 are implementation dependent */
9c2149c8 7412 default:
f31b035a 7413 goto cp0_unimplemented;
876d4b07
TS
7414 }
7415 /* Stop translation as we may have switched the execution mode */
eeb3bba8 7416 ctx->base.is_jmp = DISAS_STOP;
9c2149c8
TS
7417 break;
7418 case 10:
7419 switch (sel) {
7420 case 0:
895c2d04 7421 gen_helper_mtc0_entryhi(cpu_env, arg);
2423f660
TS
7422 rn = "EntryHi";
7423 break;
9c2149c8 7424 default:
f31b035a 7425 goto cp0_unimplemented;
876d4b07 7426 }
9c2149c8
TS
7427 break;
7428 case 11:
7429 switch (sel) {
7430 case 0:
895c2d04 7431 gen_helper_mtc0_compare(cpu_env, arg);
2423f660
TS
7432 rn = "Compare";
7433 break;
876d4b07 7434 /* 6,7 are implementation dependent */
9c2149c8 7435 default:
f31b035a 7436 goto cp0_unimplemented;
876d4b07 7437 }
de9a95f0 7438 /* Stop translation as we may have switched the execution mode */
eeb3bba8 7439 ctx->base.is_jmp = DISAS_STOP;
9c2149c8
TS
7440 break;
7441 case 12:
7442 switch (sel) {
7443 case 0:
867abc7e 7444 save_cpu_state(ctx, 1);
895c2d04 7445 gen_helper_mtc0_status(cpu_env, arg);
b28425ba 7446 /* DISAS_STOP isn't good enough here, hflags may have changed. */
eeb3bba8
EC
7447 gen_save_pc(ctx->base.pc_next + 4);
7448 ctx->base.is_jmp = DISAS_EXIT;
2423f660
TS
7449 rn = "Status";
7450 break;
9c2149c8 7451 case 1:
d75c135e 7452 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7453 gen_helper_mtc0_intctl(cpu_env, arg);
8487327a 7454 /* Stop translation as we may have switched the execution mode */
eeb3bba8 7455 ctx->base.is_jmp = DISAS_STOP;
2423f660
TS
7456 rn = "IntCtl";
7457 break;
9c2149c8 7458 case 2:
d75c135e 7459 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7460 gen_helper_mtc0_srsctl(cpu_env, arg);
8487327a 7461 /* Stop translation as we may have switched the execution mode */
eeb3bba8 7462 ctx->base.is_jmp = DISAS_STOP;
2423f660
TS
7463 rn = "SRSCtl";
7464 break;
9c2149c8 7465 case 3:
d75c135e 7466 check_insn(ctx, ISA_MIPS32R2);
7db13fae 7467 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
8487327a 7468 /* Stop translation as we may have switched the execution mode */
eeb3bba8 7469 ctx->base.is_jmp = DISAS_STOP;
2423f660
TS
7470 rn = "SRSMap";
7471 break;
7472 default:
f31b035a 7473 goto cp0_unimplemented;
876d4b07 7474 }
9c2149c8
TS
7475 break;
7476 case 13:
7477 switch (sel) {
7478 case 0:
867abc7e 7479 save_cpu_state(ctx, 1);
895c2d04 7480 gen_helper_mtc0_cause(cpu_env, arg);
b28425ba
EC
7481 /* Stop translation as we may have triggered an interrupt.
7482 * DISAS_STOP isn't sufficient, we need to ensure we break out of
7483 * translated code to check for pending interrupts. */
eeb3bba8
EC
7484 gen_save_pc(ctx->base.pc_next + 4);
7485 ctx->base.is_jmp = DISAS_EXIT;
2423f660
TS
7486 rn = "Cause";
7487 break;
9c2149c8 7488 default:
f31b035a 7489 goto cp0_unimplemented;
876d4b07 7490 }
9c2149c8
TS
7491 break;
7492 case 14:
7493 switch (sel) {
7494 case 0:
7db13fae 7495 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
2423f660
TS
7496 rn = "EPC";
7497 break;
9c2149c8 7498 default:
f31b035a 7499 goto cp0_unimplemented;
876d4b07 7500 }
9c2149c8
TS
7501 break;
7502 case 15:
7503 switch (sel) {
7504 case 0:
2423f660
TS
7505 /* ignored */
7506 rn = "PRid";
7507 break;
9c2149c8 7508 case 1:
d75c135e 7509 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7510 gen_helper_mtc0_ebase(cpu_env, arg);
2423f660
TS
7511 rn = "EBase";
7512 break;
9c2149c8 7513 default:
f31b035a 7514 goto cp0_unimplemented;
876d4b07 7515 }
9c2149c8
TS
7516 break;
7517 case 16:
7518 switch (sel) {
7519 case 0:
895c2d04 7520 gen_helper_mtc0_config0(cpu_env, arg);
9c2149c8 7521 rn = "Config";
2423f660 7522 /* Stop translation as we may have switched the execution mode */
eeb3bba8 7523 ctx->base.is_jmp = DISAS_STOP;
9c2149c8
TS
7524 break;
7525 case 1:
1fc7bf6e 7526 /* ignored, read only */
9c2149c8
TS
7527 rn = "Config1";
7528 break;
7529 case 2:
895c2d04 7530 gen_helper_mtc0_config2(cpu_env, arg);
9c2149c8 7531 rn = "Config2";
2423f660 7532 /* Stop translation as we may have switched the execution mode */
eeb3bba8 7533 ctx->base.is_jmp = DISAS_STOP;
9c2149c8
TS
7534 break;
7535 case 3:
90f12d73 7536 gen_helper_mtc0_config3(cpu_env, arg);
9c2149c8 7537 rn = "Config3";
90f12d73 7538 /* Stop translation as we may have switched the execution mode */
eeb3bba8 7539 ctx->base.is_jmp = DISAS_STOP;
9c2149c8 7540 break;
faf1f68b
LA
7541 case 4:
7542 /* currently ignored */
7543 rn = "Config4";
7544 break;
7545 case 5:
7546 gen_helper_mtc0_config5(cpu_env, arg);
7547 rn = "Config5";
7548 /* Stop translation as we may have switched the execution mode */
eeb3bba8 7549 ctx->base.is_jmp = DISAS_STOP;
faf1f68b 7550 break;
9c2149c8
TS
7551 /* 6,7 are implementation dependent */
7552 default:
7553 rn = "Invalid config selector";
f31b035a 7554 goto cp0_unimplemented;
9c2149c8 7555 }
9c2149c8
TS
7556 break;
7557 case 17:
7558 switch (sel) {
7559 case 0:
895c2d04 7560 gen_helper_mtc0_lladdr(cpu_env, arg);
2423f660
TS
7561 rn = "LLAddr";
7562 break;
f6d4dd81
YK
7563 case 1:
7564 CP0_CHECK(ctx->mrp);
7565 gen_helper_mtc0_maar(cpu_env, arg);
7566 rn = "MAAR";
7567 break;
7568 case 2:
7569 CP0_CHECK(ctx->mrp);
7570 gen_helper_mtc0_maari(cpu_env, arg);
7571 rn = "MAARI";
7572 break;
9c2149c8 7573 default:
f31b035a 7574 goto cp0_unimplemented;
9c2149c8
TS
7575 }
7576 break;
7577 case 18:
7578 switch (sel) {
c2e19f3c
AM
7579 case 0:
7580 case 1:
7581 case 2:
7582 case 3:
7583 case 4:
7584 case 5:
7585 case 6:
7586 case 7:
895c2d04 7587 gen_helper_0e1i(mtc0_watchlo, arg, sel);
2423f660
TS
7588 rn = "WatchLo";
7589 break;
9c2149c8 7590 default:
f31b035a 7591 goto cp0_unimplemented;
9c2149c8
TS
7592 }
7593 break;
7594 case 19:
7595 switch (sel) {
c2e19f3c
AM
7596 case 0:
7597 case 1:
7598 case 2:
7599 case 3:
7600 case 4:
7601 case 5:
7602 case 6:
7603 case 7:
895c2d04 7604 gen_helper_0e1i(mtc0_watchhi, arg, sel);
2423f660
TS
7605 rn = "WatchHi";
7606 break;
9c2149c8 7607 default:
f31b035a 7608 goto cp0_unimplemented;
9c2149c8
TS
7609 }
7610 break;
7611 case 20:
7612 switch (sel) {
7613 case 0:
d75c135e 7614 check_insn(ctx, ISA_MIPS3);
895c2d04 7615 gen_helper_mtc0_xcontext(cpu_env, arg);
2423f660
TS
7616 rn = "XContext";
7617 break;
9c2149c8 7618 default:
f31b035a 7619 goto cp0_unimplemented;
9c2149c8
TS
7620 }
7621 break;
7622 case 21:
7623 /* Officially reserved, but sel 0 is used for R1x000 framemask */
f31b035a 7624 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
9c2149c8
TS
7625 switch (sel) {
7626 case 0:
895c2d04 7627 gen_helper_mtc0_framemask(cpu_env, arg);
2423f660
TS
7628 rn = "Framemask";
7629 break;
9c2149c8 7630 default:
f31b035a 7631 goto cp0_unimplemented;
9c2149c8
TS
7632 }
7633 break;
7634 case 22:
7635 /* ignored */
7636 rn = "Diagnostic"; /* implementation dependent */
876d4b07 7637 break;
9c2149c8
TS
7638 case 23:
7639 switch (sel) {
7640 case 0:
895c2d04 7641 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
b28425ba 7642 /* DISAS_STOP isn't good enough here, hflags may have changed. */
eeb3bba8
EC
7643 gen_save_pc(ctx->base.pc_next + 4);
7644 ctx->base.is_jmp = DISAS_EXIT;
2423f660
TS
7645 rn = "Debug";
7646 break;
9c2149c8 7647 case 1:
895c2d04 7648// gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
8487327a 7649 /* Stop translation as we may have switched the execution mode */
eeb3bba8 7650 ctx->base.is_jmp = DISAS_STOP;
2423f660 7651 rn = "TraceControl";
3570d7f6 7652 goto cp0_unimplemented;
9c2149c8 7653 case 2:
895c2d04 7654// gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
8487327a 7655 /* Stop translation as we may have switched the execution mode */
eeb3bba8 7656 ctx->base.is_jmp = DISAS_STOP;
2423f660 7657 rn = "TraceControl2";
3570d7f6 7658 goto cp0_unimplemented;
9c2149c8 7659 case 3:
895c2d04 7660// gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
8487327a 7661 /* Stop translation as we may have switched the execution mode */
eeb3bba8 7662 ctx->base.is_jmp = DISAS_STOP;
2423f660 7663 rn = "UserTraceData";
3570d7f6 7664 goto cp0_unimplemented;
9c2149c8 7665 case 4:
895c2d04 7666// gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
8487327a 7667 /* Stop translation as we may have switched the execution mode */
eeb3bba8 7668 ctx->base.is_jmp = DISAS_STOP;
2423f660 7669 rn = "TraceBPC";
3570d7f6 7670 goto cp0_unimplemented;
9c2149c8 7671 default:
f31b035a 7672 goto cp0_unimplemented;
9c2149c8 7673 }
9c2149c8
TS
7674 break;
7675 case 24:
7676 switch (sel) {
7677 case 0:
f1aa6320 7678 /* EJTAG support */
7db13fae 7679 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
2423f660
TS
7680 rn = "DEPC";
7681 break;
9c2149c8 7682 default:
f31b035a 7683 goto cp0_unimplemented;
9c2149c8
TS
7684 }
7685 break;
7686 case 25:
7687 switch (sel) {
7688 case 0:
895c2d04 7689 gen_helper_mtc0_performance0(cpu_env, arg);
2423f660
TS
7690 rn = "Performance0";
7691 break;
9c2149c8 7692 case 1:
895c2d04 7693// gen_helper_mtc0_performance1(cpu_env, arg);
2423f660 7694 rn = "Performance1";
3570d7f6 7695 goto cp0_unimplemented;
9c2149c8 7696 case 2:
895c2d04 7697// gen_helper_mtc0_performance2(cpu_env, arg);
2423f660 7698 rn = "Performance2";
3570d7f6 7699 goto cp0_unimplemented;
9c2149c8 7700 case 3:
895c2d04 7701// gen_helper_mtc0_performance3(cpu_env, arg);
2423f660 7702 rn = "Performance3";
3570d7f6 7703 goto cp0_unimplemented;
9c2149c8 7704 case 4:
895c2d04 7705// gen_helper_mtc0_performance4(cpu_env, arg);
2423f660 7706 rn = "Performance4";
3570d7f6 7707 goto cp0_unimplemented;
9c2149c8 7708 case 5:
895c2d04 7709// gen_helper_mtc0_performance5(cpu_env, arg);
2423f660 7710 rn = "Performance5";
3570d7f6 7711 goto cp0_unimplemented;
9c2149c8 7712 case 6:
895c2d04 7713// gen_helper_mtc0_performance6(cpu_env, arg);
2423f660 7714 rn = "Performance6";
3570d7f6 7715 goto cp0_unimplemented;
9c2149c8 7716 case 7:
895c2d04 7717// gen_helper_mtc0_performance7(cpu_env, arg);
2423f660 7718 rn = "Performance7";
3570d7f6 7719 goto cp0_unimplemented;
9c2149c8 7720 default:
f31b035a 7721 goto cp0_unimplemented;
9c2149c8 7722 }
876d4b07 7723 break;
9c2149c8 7724 case 26:
0d74a222
LA
7725 switch (sel) {
7726 case 0:
7727 gen_helper_mtc0_errctl(cpu_env, arg);
eeb3bba8 7728 ctx->base.is_jmp = DISAS_STOP;
0d74a222
LA
7729 rn = "ErrCtl";
7730 break;
7731 default:
7732 goto cp0_unimplemented;
7733 }
876d4b07 7734 break;
9c2149c8
TS
7735 case 27:
7736 switch (sel) {
c2e19f3c
AM
7737 case 0:
7738 case 1:
7739 case 2:
7740 case 3:
2423f660
TS
7741 /* ignored */
7742 rn = "CacheErr";
7743 break;
9c2149c8 7744 default:
f31b035a 7745 goto cp0_unimplemented;
9c2149c8 7746 }
876d4b07 7747 break;
9c2149c8
TS
7748 case 28:
7749 switch (sel) {
7750 case 0:
7751 case 2:
7752 case 4:
7753 case 6:
895c2d04 7754 gen_helper_mtc0_taglo(cpu_env, arg);
9c2149c8
TS
7755 rn = "TagLo";
7756 break;
7757 case 1:
7758 case 3:
7759 case 5:
7760 case 7:
895c2d04 7761 gen_helper_mtc0_datalo(cpu_env, arg);
9c2149c8
TS
7762 rn = "DataLo";
7763 break;
7764 default:
f31b035a 7765 goto cp0_unimplemented;
9c2149c8
TS
7766 }
7767 break;
7768 case 29:
7769 switch (sel) {
7770 case 0:
7771 case 2:
7772 case 4:
7773 case 6:
895c2d04 7774 gen_helper_mtc0_taghi(cpu_env, arg);
9c2149c8
TS
7775 rn = "TagHi";
7776 break;
7777 case 1:
7778 case 3:
7779 case 5:
7780 case 7:
895c2d04 7781 gen_helper_mtc0_datahi(cpu_env, arg);
9c2149c8
TS
7782 rn = "DataHi";
7783 break;
7784 default:
7785 rn = "invalid sel";
f31b035a 7786 goto cp0_unimplemented;
9c2149c8 7787 }
876d4b07 7788 break;
9c2149c8
TS
7789 case 30:
7790 switch (sel) {
7791 case 0:
7db13fae 7792 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
2423f660
TS
7793 rn = "ErrorEPC";
7794 break;
9c2149c8 7795 default:
f31b035a 7796 goto cp0_unimplemented;
9c2149c8
TS
7797 }
7798 break;
7799 case 31:
7800 switch (sel) {
7801 case 0:
f1aa6320 7802 /* EJTAG support */
7db13fae 7803 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
7804 rn = "DESAVE";
7805 break;
c2e19f3c
AM
7806 case 2:
7807 case 3:
7808 case 4:
7809 case 5:
7810 case 6:
7811 case 7:
f31b035a
LA
7812 CP0_CHECK(ctx->kscrexist & (1 << sel));
7813 tcg_gen_st_tl(arg, cpu_env,
7814 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
7815 rn = "KScratch";
e98c0d17 7816 break;
9c2149c8 7817 default:
f31b035a 7818 goto cp0_unimplemented;
9c2149c8 7819 }
9c2149c8
TS
7820 break;
7821 default:
f31b035a 7822 goto cp0_unimplemented;
9c2149c8 7823 }
b44a7fb1
PMD
7824 trace_mips_translate_c0("dmtc0", rn, reg, sel);
7825
bf20dc07 7826 /* For simplicity assume that all writes can cause interrupts. */
eeb3bba8 7827 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
2e70f6ef 7828 gen_io_end();
b28425ba 7829 /* DISAS_STOP isn't sufficient, we need to ensure we break out of
b74cddcb 7830 * translated code to check for pending interrupts. */
eeb3bba8
EC
7831 gen_save_pc(ctx->base.pc_next + 4);
7832 ctx->base.is_jmp = DISAS_EXIT;
2e70f6ef 7833 }
9c2149c8
TS
7834 return;
7835
f31b035a 7836cp0_unimplemented:
965447ee 7837 qemu_log_mask(LOG_UNIMP, "dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
9c2149c8 7838}
d26bc211 7839#endif /* TARGET_MIPS64 */
9c2149c8 7840
7db13fae 7841static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
ead9360e
TS
7842 int u, int sel, int h)
7843{
7844 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
a7812ae4 7845 TCGv t0 = tcg_temp_local_new();
ead9360e
TS
7846
7847 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
b5dc7732
TS
7848 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
7849 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
1a3fd9c3 7850 tcg_gen_movi_tl(t0, -1);
ead9360e
TS
7851 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
7852 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
1a3fd9c3 7853 tcg_gen_movi_tl(t0, -1);
ead9360e
TS
7854 else if (u == 0) {
7855 switch (rt) {
5a25ce94
EI
7856 case 1:
7857 switch (sel) {
7858 case 1:
895c2d04 7859 gen_helper_mftc0_vpecontrol(t0, cpu_env);
5a25ce94
EI
7860 break;
7861 case 2:
895c2d04 7862 gen_helper_mftc0_vpeconf0(t0, cpu_env);
5a25ce94
EI
7863 break;
7864 default:
7865 goto die;
7866 break;
7867 }
7868 break;
ead9360e
TS
7869 case 2:
7870 switch (sel) {
7871 case 1:
895c2d04 7872 gen_helper_mftc0_tcstatus(t0, cpu_env);
ead9360e
TS
7873 break;
7874 case 2:
895c2d04 7875 gen_helper_mftc0_tcbind(t0, cpu_env);
ead9360e
TS
7876 break;
7877 case 3:
895c2d04 7878 gen_helper_mftc0_tcrestart(t0, cpu_env);
ead9360e
TS
7879 break;
7880 case 4:
895c2d04 7881 gen_helper_mftc0_tchalt(t0, cpu_env);
ead9360e
TS
7882 break;
7883 case 5:
895c2d04 7884 gen_helper_mftc0_tccontext(t0, cpu_env);
ead9360e
TS
7885 break;
7886 case 6:
895c2d04 7887 gen_helper_mftc0_tcschedule(t0, cpu_env);
ead9360e
TS
7888 break;
7889 case 7:
895c2d04 7890 gen_helper_mftc0_tcschefback(t0, cpu_env);
ead9360e
TS
7891 break;
7892 default:
d75c135e 7893 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
7894 break;
7895 }
7896 break;
7897 case 10:
7898 switch (sel) {
7899 case 0:
895c2d04 7900 gen_helper_mftc0_entryhi(t0, cpu_env);
ead9360e
TS
7901 break;
7902 default:
d75c135e 7903 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
7904 break;
7905 }
7906 case 12:
7907 switch (sel) {
7908 case 0:
895c2d04 7909 gen_helper_mftc0_status(t0, cpu_env);
ead9360e
TS
7910 break;
7911 default:
d75c135e 7912 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
7913 break;
7914 }
5a25ce94
EI
7915 case 13:
7916 switch (sel) {
7917 case 0:
895c2d04 7918 gen_helper_mftc0_cause(t0, cpu_env);
5a25ce94
EI
7919 break;
7920 default:
7921 goto die;
7922 break;
7923 }
7924 break;
7925 case 14:
7926 switch (sel) {
7927 case 0:
895c2d04 7928 gen_helper_mftc0_epc(t0, cpu_env);
5a25ce94
EI
7929 break;
7930 default:
7931 goto die;
7932 break;
7933 }
7934 break;
7935 case 15:
7936 switch (sel) {
7937 case 1:
895c2d04 7938 gen_helper_mftc0_ebase(t0, cpu_env);
5a25ce94
EI
7939 break;
7940 default:
7941 goto die;
7942 break;
7943 }
7944 break;
7945 case 16:
7946 switch (sel) {
c2e19f3c
AM
7947 case 0:
7948 case 1:
7949 case 2:
7950 case 3:
7951 case 4:
7952 case 5:
7953 case 6:
7954 case 7:
895c2d04 7955 gen_helper_mftc0_configx(t0, cpu_env, tcg_const_tl(sel));
5a25ce94
EI
7956 break;
7957 default:
7958 goto die;
7959 break;
7960 }
7961 break;
ead9360e
TS
7962 case 23:
7963 switch (sel) {
7964 case 0:
895c2d04 7965 gen_helper_mftc0_debug(t0, cpu_env);
ead9360e
TS
7966 break;
7967 default:
d75c135e 7968 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
7969 break;
7970 }
7971 break;
7972 default:
d75c135e 7973 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
7974 }
7975 } else switch (sel) {
7976 /* GPR registers. */
7977 case 0:
895c2d04 7978 gen_helper_1e0i(mftgpr, t0, rt);
ead9360e
TS
7979 break;
7980 /* Auxiliary CPU registers */
7981 case 1:
7982 switch (rt) {
7983 case 0:
895c2d04 7984 gen_helper_1e0i(mftlo, t0, 0);
ead9360e
TS
7985 break;
7986 case 1:
895c2d04 7987 gen_helper_1e0i(mfthi, t0, 0);
ead9360e
TS
7988 break;
7989 case 2:
895c2d04 7990 gen_helper_1e0i(mftacx, t0, 0);
ead9360e
TS
7991 break;
7992 case 4:
895c2d04 7993 gen_helper_1e0i(mftlo, t0, 1);
ead9360e
TS
7994 break;
7995 case 5:
895c2d04 7996 gen_helper_1e0i(mfthi, t0, 1);
ead9360e
TS
7997 break;
7998 case 6:
895c2d04 7999 gen_helper_1e0i(mftacx, t0, 1);
ead9360e
TS
8000 break;
8001 case 8:
895c2d04 8002 gen_helper_1e0i(mftlo, t0, 2);
ead9360e
TS
8003 break;
8004 case 9:
895c2d04 8005 gen_helper_1e0i(mfthi, t0, 2);
ead9360e
TS
8006 break;
8007 case 10:
895c2d04 8008 gen_helper_1e0i(mftacx, t0, 2);
ead9360e
TS
8009 break;
8010 case 12:
895c2d04 8011 gen_helper_1e0i(mftlo, t0, 3);
ead9360e
TS
8012 break;
8013 case 13:
895c2d04 8014 gen_helper_1e0i(mfthi, t0, 3);
ead9360e
TS
8015 break;
8016 case 14:
895c2d04 8017 gen_helper_1e0i(mftacx, t0, 3);
ead9360e
TS
8018 break;
8019 case 16:
895c2d04 8020 gen_helper_mftdsp(t0, cpu_env);
ead9360e
TS
8021 break;
8022 default:
8023 goto die;
8024 }
8025 break;
8026 /* Floating point (COP1). */
8027 case 2:
8028 /* XXX: For now we support only a single FPU context. */
8029 if (h == 0) {
a7812ae4 8030 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8031
7c979afd 8032 gen_load_fpr32(ctx, fp0, rt);
b6d96bed 8033 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 8034 tcg_temp_free_i32(fp0);
ead9360e 8035 } else {
a7812ae4 8036 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8037
7f6613ce 8038 gen_load_fpr32h(ctx, fp0, rt);
b6d96bed 8039 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 8040 tcg_temp_free_i32(fp0);
ead9360e
TS
8041 }
8042 break;
8043 case 3:
8044 /* XXX: For now we support only a single FPU context. */
895c2d04 8045 gen_helper_1e0i(cfc1, t0, rt);
ead9360e
TS
8046 break;
8047 /* COP2: Not implemented. */
8048 case 4:
8049 case 5:
8050 /* fall through */
8051 default:
8052 goto die;
8053 }
b44a7fb1 8054 trace_mips_translate_tr("mftr", rt, u, sel, h);
1a3fd9c3
TS
8055 gen_store_gpr(t0, rd);
8056 tcg_temp_free(t0);
ead9360e
TS
8057 return;
8058
8059die:
1a3fd9c3 8060 tcg_temp_free(t0);
d12d51d5 8061 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
9c708c7f 8062 generate_exception_end(ctx, EXCP_RI);
ead9360e
TS
8063}
8064
7db13fae 8065static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
ead9360e
TS
8066 int u, int sel, int h)
8067{
8068 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
a7812ae4 8069 TCGv t0 = tcg_temp_local_new();
ead9360e 8070
1a3fd9c3 8071 gen_load_gpr(t0, rt);
ead9360e 8072 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
b5dc7732
TS
8073 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
8074 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
ead9360e
TS
8075 /* NOP */ ;
8076 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
8077 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
8078 /* NOP */ ;
8079 else if (u == 0) {
8080 switch (rd) {
5a25ce94
EI
8081 case 1:
8082 switch (sel) {
8083 case 1:
895c2d04 8084 gen_helper_mttc0_vpecontrol(cpu_env, t0);
5a25ce94
EI
8085 break;
8086 case 2:
895c2d04 8087 gen_helper_mttc0_vpeconf0(cpu_env, t0);
5a25ce94
EI
8088 break;
8089 default:
8090 goto die;
8091 break;
8092 }
8093 break;
ead9360e
TS
8094 case 2:
8095 switch (sel) {
8096 case 1:
895c2d04 8097 gen_helper_mttc0_tcstatus(cpu_env, t0);
ead9360e
TS
8098 break;
8099 case 2:
895c2d04 8100 gen_helper_mttc0_tcbind(cpu_env, t0);
ead9360e
TS
8101 break;
8102 case 3:
895c2d04 8103 gen_helper_mttc0_tcrestart(cpu_env, t0);
ead9360e
TS
8104 break;
8105 case 4:
895c2d04 8106 gen_helper_mttc0_tchalt(cpu_env, t0);
ead9360e
TS
8107 break;
8108 case 5:
895c2d04 8109 gen_helper_mttc0_tccontext(cpu_env, t0);
ead9360e
TS
8110 break;
8111 case 6:
895c2d04 8112 gen_helper_mttc0_tcschedule(cpu_env, t0);
ead9360e
TS
8113 break;
8114 case 7:
895c2d04 8115 gen_helper_mttc0_tcschefback(cpu_env, t0);
ead9360e
TS
8116 break;
8117 default:
d75c135e 8118 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
8119 break;
8120 }
8121 break;
8122 case 10:
8123 switch (sel) {
8124 case 0:
895c2d04 8125 gen_helper_mttc0_entryhi(cpu_env, t0);
ead9360e
TS
8126 break;
8127 default:
d75c135e 8128 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
8129 break;
8130 }
8131 case 12:
8132 switch (sel) {
8133 case 0:
895c2d04 8134 gen_helper_mttc0_status(cpu_env, t0);
ead9360e
TS
8135 break;
8136 default:
d75c135e 8137 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
8138 break;
8139 }
5a25ce94
EI
8140 case 13:
8141 switch (sel) {
8142 case 0:
895c2d04 8143 gen_helper_mttc0_cause(cpu_env, t0);
5a25ce94
EI
8144 break;
8145 default:
8146 goto die;
8147 break;
8148 }
8149 break;
8150 case 15:
8151 switch (sel) {
8152 case 1:
895c2d04 8153 gen_helper_mttc0_ebase(cpu_env, t0);
5a25ce94
EI
8154 break;
8155 default:
8156 goto die;
8157 break;
8158 }
8159 break;
ead9360e
TS
8160 case 23:
8161 switch (sel) {
8162 case 0:
895c2d04 8163 gen_helper_mttc0_debug(cpu_env, t0);
ead9360e
TS
8164 break;
8165 default:
d75c135e 8166 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
8167 break;
8168 }
8169 break;
8170 default:
d75c135e 8171 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
8172 }
8173 } else switch (sel) {
8174 /* GPR registers. */
8175 case 0:
895c2d04 8176 gen_helper_0e1i(mttgpr, t0, rd);
ead9360e
TS
8177 break;
8178 /* Auxiliary CPU registers */
8179 case 1:
8180 switch (rd) {
8181 case 0:
895c2d04 8182 gen_helper_0e1i(mttlo, t0, 0);
ead9360e
TS
8183 break;
8184 case 1:
895c2d04 8185 gen_helper_0e1i(mtthi, t0, 0);
ead9360e
TS
8186 break;
8187 case 2:
895c2d04 8188 gen_helper_0e1i(mttacx, t0, 0);
ead9360e
TS
8189 break;
8190 case 4:
895c2d04 8191 gen_helper_0e1i(mttlo, t0, 1);
ead9360e
TS
8192 break;
8193 case 5:
895c2d04 8194 gen_helper_0e1i(mtthi, t0, 1);
ead9360e
TS
8195 break;
8196 case 6:
895c2d04 8197 gen_helper_0e1i(mttacx, t0, 1);
ead9360e
TS
8198 break;
8199 case 8:
895c2d04 8200 gen_helper_0e1i(mttlo, t0, 2);
ead9360e
TS
8201 break;
8202 case 9:
895c2d04 8203 gen_helper_0e1i(mtthi, t0, 2);
ead9360e
TS
8204 break;
8205 case 10:
895c2d04 8206 gen_helper_0e1i(mttacx, t0, 2);
ead9360e
TS
8207 break;
8208 case 12:
895c2d04 8209 gen_helper_0e1i(mttlo, t0, 3);
ead9360e
TS
8210 break;
8211 case 13:
895c2d04 8212 gen_helper_0e1i(mtthi, t0, 3);
ead9360e
TS
8213 break;
8214 case 14:
895c2d04 8215 gen_helper_0e1i(mttacx, t0, 3);
ead9360e
TS
8216 break;
8217 case 16:
895c2d04 8218 gen_helper_mttdsp(cpu_env, t0);
ead9360e
TS
8219 break;
8220 default:
8221 goto die;
8222 }
8223 break;
8224 /* Floating point (COP1). */
8225 case 2:
8226 /* XXX: For now we support only a single FPU context. */
8227 if (h == 0) {
a7812ae4 8228 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8229
8230 tcg_gen_trunc_tl_i32(fp0, t0);
7c979afd 8231 gen_store_fpr32(ctx, fp0, rd);
a7812ae4 8232 tcg_temp_free_i32(fp0);
ead9360e 8233 } else {
a7812ae4 8234 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8235
8236 tcg_gen_trunc_tl_i32(fp0, t0);
7f6613ce 8237 gen_store_fpr32h(ctx, fp0, rd);
a7812ae4 8238 tcg_temp_free_i32(fp0);
ead9360e
TS
8239 }
8240 break;
8241 case 3:
8242 /* XXX: For now we support only a single FPU context. */
736d120a
PJ
8243 {
8244 TCGv_i32 fs_tmp = tcg_const_i32(rd);
8245
8246 gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
8247 tcg_temp_free_i32(fs_tmp);
8248 }
4cf8a45f 8249 /* Stop translation as we may have changed hflags */
eeb3bba8 8250 ctx->base.is_jmp = DISAS_STOP;
ead9360e
TS
8251 break;
8252 /* COP2: Not implemented. */
8253 case 4:
8254 case 5:
8255 /* fall through */
8256 default:
8257 goto die;
8258 }
b44a7fb1 8259 trace_mips_translate_tr("mttr", rd, u, sel, h);
1a3fd9c3 8260 tcg_temp_free(t0);
ead9360e
TS
8261 return;
8262
8263die:
1a3fd9c3 8264 tcg_temp_free(t0);
d12d51d5 8265 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
9c708c7f 8266 generate_exception_end(ctx, EXCP_RI);
ead9360e
TS
8267}
8268
7db13fae 8269static void gen_cp0 (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
6af0bf9c 8270{
287c4b84 8271 const char *opn = "ldst";
6af0bf9c 8272
2e15497c 8273 check_cp0_enabled(ctx);
6af0bf9c
FB
8274 switch (opc) {
8275 case OPC_MFC0:
8276 if (rt == 0) {
ead9360e 8277 /* Treat as NOP. */
6af0bf9c
FB
8278 return;
8279 }
d75c135e 8280 gen_mfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
6af0bf9c
FB
8281 opn = "mfc0";
8282 break;
8283 case OPC_MTC0:
1a3fd9c3 8284 {
1fc7bf6e 8285 TCGv t0 = tcg_temp_new();
1a3fd9c3
TS
8286
8287 gen_load_gpr(t0, rt);
d75c135e 8288 gen_mtc0(ctx, t0, rd, ctx->opcode & 0x7);
1a3fd9c3
TS
8289 tcg_temp_free(t0);
8290 }
6af0bf9c
FB
8291 opn = "mtc0";
8292 break;
d26bc211 8293#if defined(TARGET_MIPS64)
9c2149c8 8294 case OPC_DMFC0:
d75c135e 8295 check_insn(ctx, ISA_MIPS3);
9c2149c8 8296 if (rt == 0) {
ead9360e 8297 /* Treat as NOP. */
9c2149c8
TS
8298 return;
8299 }
d75c135e 8300 gen_dmfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
9c2149c8
TS
8301 opn = "dmfc0";
8302 break;
8303 case OPC_DMTC0:
d75c135e 8304 check_insn(ctx, ISA_MIPS3);
1a3fd9c3 8305 {
1fc7bf6e 8306 TCGv t0 = tcg_temp_new();
1a3fd9c3
TS
8307
8308 gen_load_gpr(t0, rt);
d75c135e 8309 gen_dmtc0(ctx, t0, rd, ctx->opcode & 0x7);
1a3fd9c3
TS
8310 tcg_temp_free(t0);
8311 }
9c2149c8
TS
8312 opn = "dmtc0";
8313 break;
534ce69f 8314#endif
5204ea79
LA
8315 case OPC_MFHC0:
8316 check_mvh(ctx);
8317 if (rt == 0) {
8318 /* Treat as NOP. */
8319 return;
8320 }
8321 gen_mfhc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
8322 opn = "mfhc0";
8323 break;
8324 case OPC_MTHC0:
8325 check_mvh(ctx);
8326 {
8327 TCGv t0 = tcg_temp_new();
8328 gen_load_gpr(t0, rt);
8329 gen_mthc0(ctx, t0, rd, ctx->opcode & 0x7);
8330 tcg_temp_free(t0);
8331 }
8332 opn = "mthc0";
8333 break;
ead9360e 8334 case OPC_MFTR:
d75c135e 8335 check_insn(ctx, ASE_MT);
ead9360e
TS
8336 if (rd == 0) {
8337 /* Treat as NOP. */
8338 return;
8339 }
6c5c1e20 8340 gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
ead9360e 8341 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
ead9360e
TS
8342 opn = "mftr";
8343 break;
8344 case OPC_MTTR:
d75c135e 8345 check_insn(ctx, ASE_MT);
6c5c1e20 8346 gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
ead9360e
TS
8347 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
8348 opn = "mttr";
8349 break;
6af0bf9c 8350 case OPC_TLBWI:
6af0bf9c 8351 opn = "tlbwi";
c01fccd2 8352 if (!env->tlb->helper_tlbwi)
29929e34 8353 goto die;
895c2d04 8354 gen_helper_tlbwi(cpu_env);
6af0bf9c 8355 break;
9456c2fb
LA
8356 case OPC_TLBINV:
8357 opn = "tlbinv";
8358 if (ctx->ie >= 2) {
8359 if (!env->tlb->helper_tlbinv) {
8360 goto die;
8361 }
8362 gen_helper_tlbinv(cpu_env);
8363 } /* treat as nop if TLBINV not supported */
8364 break;
8365 case OPC_TLBINVF:
8366 opn = "tlbinvf";
8367 if (ctx->ie >= 2) {
8368 if (!env->tlb->helper_tlbinvf) {
8369 goto die;
8370 }
8371 gen_helper_tlbinvf(cpu_env);
8372 } /* treat as nop if TLBINV not supported */
8373 break;
6af0bf9c 8374 case OPC_TLBWR:
6af0bf9c 8375 opn = "tlbwr";
c01fccd2 8376 if (!env->tlb->helper_tlbwr)
29929e34 8377 goto die;
895c2d04 8378 gen_helper_tlbwr(cpu_env);
6af0bf9c
FB
8379 break;
8380 case OPC_TLBP:
6af0bf9c 8381 opn = "tlbp";
c01fccd2 8382 if (!env->tlb->helper_tlbp)
29929e34 8383 goto die;
895c2d04 8384 gen_helper_tlbp(cpu_env);
6af0bf9c
FB
8385 break;
8386 case OPC_TLBR:
6af0bf9c 8387 opn = "tlbr";
c01fccd2 8388 if (!env->tlb->helper_tlbr)
29929e34 8389 goto die;
895c2d04 8390 gen_helper_tlbr(cpu_env);
6af0bf9c 8391 break;
ce9782f4 8392 case OPC_ERET: /* OPC_ERETNC */
339cd2a8
LA
8393 if ((ctx->insn_flags & ISA_MIPS32R6) &&
8394 (ctx->hflags & MIPS_HFLAG_BMASK)) {
339cd2a8 8395 goto die;
ce9782f4
LA
8396 } else {
8397 int bit_shift = (ctx->hflags & MIPS_HFLAG_M16) ? 16 : 6;
8398 if (ctx->opcode & (1 << bit_shift)) {
8399 /* OPC_ERETNC */
8400 opn = "eretnc";
8401 check_insn(ctx, ISA_MIPS32R5);
8402 gen_helper_eretnc(cpu_env);
8403 } else {
8404 /* OPC_ERET */
8405 opn = "eret";
8406 check_insn(ctx, ISA_MIPS2);
8407 gen_helper_eret(cpu_env);
8408 }
eeb3bba8 8409 ctx->base.is_jmp = DISAS_EXIT;
339cd2a8 8410 }
6af0bf9c
FB
8411 break;
8412 case OPC_DERET:
8413 opn = "deret";
d75c135e 8414 check_insn(ctx, ISA_MIPS32);
339cd2a8
LA
8415 if ((ctx->insn_flags & ISA_MIPS32R6) &&
8416 (ctx->hflags & MIPS_HFLAG_BMASK)) {
339cd2a8
LA
8417 goto die;
8418 }
6af0bf9c 8419 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
923617a3 8420 MIPS_INVAL(opn);
9c708c7f 8421 generate_exception_end(ctx, EXCP_RI);
6af0bf9c 8422 } else {
895c2d04 8423 gen_helper_deret(cpu_env);
eeb3bba8 8424 ctx->base.is_jmp = DISAS_EXIT;
6af0bf9c
FB
8425 }
8426 break;
4ad40f36
FB
8427 case OPC_WAIT:
8428 opn = "wait";
d75c135e 8429 check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
339cd2a8
LA
8430 if ((ctx->insn_flags & ISA_MIPS32R6) &&
8431 (ctx->hflags & MIPS_HFLAG_BMASK)) {
339cd2a8
LA
8432 goto die;
8433 }
4ad40f36 8434 /* If we get an exception, we want to restart at next instruction */
eeb3bba8 8435 ctx->base.pc_next += 4;
4ad40f36 8436 save_cpu_state(ctx, 1);
eeb3bba8 8437 ctx->base.pc_next -= 4;
895c2d04 8438 gen_helper_wait(cpu_env);
eeb3bba8 8439 ctx->base.is_jmp = DISAS_NORETURN;
4ad40f36 8440 break;
6af0bf9c 8441 default:
29929e34 8442 die:
923617a3 8443 MIPS_INVAL(opn);
9c708c7f 8444 generate_exception_end(ctx, EXCP_RI);
6af0bf9c
FB
8445 return;
8446 }
2abf314d 8447 (void)opn; /* avoid a compiler warning */
6af0bf9c 8448}
f1aa6320 8449#endif /* !CONFIG_USER_ONLY */
6af0bf9c 8450
6ea83fed 8451/* CP1 Branches (before delay slot) */
d75c135e
AJ
8452static void gen_compute_branch1(DisasContext *ctx, uint32_t op,
8453 int32_t cc, int32_t offset)
6ea83fed
FB
8454{
8455 target_ulong btarget;
a7812ae4 8456 TCGv_i32 t0 = tcg_temp_new_i32();
6ea83fed 8457
339cd2a8 8458 if ((ctx->insn_flags & ISA_MIPS32R6) && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9c708c7f 8459 generate_exception_end(ctx, EXCP_RI);
339cd2a8
LA
8460 goto out;
8461 }
8462
e189e748 8463 if (cc != 0)
d75c135e 8464 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
e189e748 8465
eeb3bba8 8466 btarget = ctx->base.pc_next + 4 + offset;
6ea83fed 8467
7a387fff
TS
8468 switch (op) {
8469 case OPC_BC1F:
d94536f4
AJ
8470 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8471 tcg_gen_not_i32(t0, t0);
8472 tcg_gen_andi_i32(t0, t0, 1);
8473 tcg_gen_extu_i32_tl(bcond, t0);
6ea83fed 8474 goto not_likely;
7a387fff 8475 case OPC_BC1FL:
d94536f4
AJ
8476 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8477 tcg_gen_not_i32(t0, t0);
8478 tcg_gen_andi_i32(t0, t0, 1);
8479 tcg_gen_extu_i32_tl(bcond, t0);
6ea83fed 8480 goto likely;
7a387fff 8481 case OPC_BC1T:
d94536f4
AJ
8482 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8483 tcg_gen_andi_i32(t0, t0, 1);
8484 tcg_gen_extu_i32_tl(bcond, t0);
5a5012ec 8485 goto not_likely;
7a387fff 8486 case OPC_BC1TL:
d94536f4
AJ
8487 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8488 tcg_gen_andi_i32(t0, t0, 1);
8489 tcg_gen_extu_i32_tl(bcond, t0);
6ea83fed
FB
8490 likely:
8491 ctx->hflags |= MIPS_HFLAG_BL;
8492 break;
5a5012ec 8493 case OPC_BC1FANY2:
a16336e4 8494 {
d94536f4
AJ
8495 TCGv_i32 t1 = tcg_temp_new_i32();
8496 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8497 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
d7f66b52 8498 tcg_gen_nand_i32(t0, t0, t1);
d94536f4 8499 tcg_temp_free_i32(t1);
d94536f4
AJ
8500 tcg_gen_andi_i32(t0, t0, 1);
8501 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 8502 }
5a5012ec
TS
8503 goto not_likely;
8504 case OPC_BC1TANY2:
a16336e4 8505 {
d94536f4
AJ
8506 TCGv_i32 t1 = tcg_temp_new_i32();
8507 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8508 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
8509 tcg_gen_or_i32(t0, t0, t1);
8510 tcg_temp_free_i32(t1);
8511 tcg_gen_andi_i32(t0, t0, 1);
8512 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 8513 }
5a5012ec
TS
8514 goto not_likely;
8515 case OPC_BC1FANY4:
a16336e4 8516 {
d94536f4
AJ
8517 TCGv_i32 t1 = tcg_temp_new_i32();
8518 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8519 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
d7f66b52 8520 tcg_gen_and_i32(t0, t0, t1);
d94536f4 8521 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
d7f66b52 8522 tcg_gen_and_i32(t0, t0, t1);
d94536f4 8523 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
d7f66b52 8524 tcg_gen_nand_i32(t0, t0, t1);
d94536f4 8525 tcg_temp_free_i32(t1);
d94536f4
AJ
8526 tcg_gen_andi_i32(t0, t0, 1);
8527 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 8528 }
5a5012ec
TS
8529 goto not_likely;
8530 case OPC_BC1TANY4:
a16336e4 8531 {
d94536f4
AJ
8532 TCGv_i32 t1 = tcg_temp_new_i32();
8533 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8534 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
8535 tcg_gen_or_i32(t0, t0, t1);
8536 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
8537 tcg_gen_or_i32(t0, t0, t1);
8538 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
8539 tcg_gen_or_i32(t0, t0, t1);
8540 tcg_temp_free_i32(t1);
8541 tcg_gen_andi_i32(t0, t0, 1);
8542 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 8543 }
5a5012ec
TS
8544 not_likely:
8545 ctx->hflags |= MIPS_HFLAG_BC;
5a5012ec
TS
8546 break;
8547 default:
9d68ac14 8548 MIPS_INVAL("cp1 cond branch");
9c708c7f 8549 generate_exception_end(ctx, EXCP_RI);
6c5c1e20 8550 goto out;
6ea83fed 8551 }
6ea83fed 8552 ctx->btarget = btarget;
b231c103 8553 ctx->hflags |= MIPS_HFLAG_BDS32;
6c5c1e20 8554 out:
a7812ae4 8555 tcg_temp_free_i32(t0);
6ea83fed
FB
8556}
8557
31837be3
YK
8558/* R6 CP1 Branches */
8559static void gen_compute_branch1_r6(DisasContext *ctx, uint32_t op,
65935f07
YK
8560 int32_t ft, int32_t offset,
8561 int delayslot_size)
31837be3
YK
8562{
8563 target_ulong btarget;
31837be3
YK
8564 TCGv_i64 t0 = tcg_temp_new_i64();
8565
8566 if (ctx->hflags & MIPS_HFLAG_BMASK) {
8567#ifdef MIPS_DEBUG_DISAS
339cd2a8 8568 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
eeb3bba8 8569 "\n", ctx->base.pc_next);
31837be3 8570#endif
9c708c7f 8571 generate_exception_end(ctx, EXCP_RI);
31837be3
YK
8572 goto out;
8573 }
8574
8575 gen_load_fpr64(ctx, t0, ft);
8576 tcg_gen_andi_i64(t0, t0, 1);
8577
eeb3bba8 8578 btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
31837be3
YK
8579
8580 switch (op) {
8581 case OPC_BC1EQZ:
8582 tcg_gen_xori_i64(t0, t0, 1);
31837be3
YK
8583 ctx->hflags |= MIPS_HFLAG_BC;
8584 break;
8585 case OPC_BC1NEZ:
8586 /* t0 already set */
31837be3
YK
8587 ctx->hflags |= MIPS_HFLAG_BC;
8588 break;
8589 default:
9d68ac14 8590 MIPS_INVAL("cp1 cond branch");
9c708c7f 8591 generate_exception_end(ctx, EXCP_RI);
31837be3
YK
8592 goto out;
8593 }
8594
8595 tcg_gen_trunc_i64_tl(bcond, t0);
8596
31837be3 8597 ctx->btarget = btarget;
65935f07
YK
8598
8599 switch (delayslot_size) {
8600 case 2:
8601 ctx->hflags |= MIPS_HFLAG_BDS16;
8602 break;
8603 case 4:
8604 ctx->hflags |= MIPS_HFLAG_BDS32;
8605 break;
8606 }
31837be3
YK
8607
8608out:
8609 tcg_temp_free_i64(t0);
8610}
8611
6af0bf9c 8612/* Coprocessor 1 (FPU) */
5a5012ec 8613
5a5012ec
TS
8614#define FOP(func, fmt) (((fmt) << 21) | (func))
8615
bf4120ad
NF
8616enum fopcode {
8617 OPC_ADD_S = FOP(0, FMT_S),
8618 OPC_SUB_S = FOP(1, FMT_S),
8619 OPC_MUL_S = FOP(2, FMT_S),
8620 OPC_DIV_S = FOP(3, FMT_S),
8621 OPC_SQRT_S = FOP(4, FMT_S),
8622 OPC_ABS_S = FOP(5, FMT_S),
8623 OPC_MOV_S = FOP(6, FMT_S),
8624 OPC_NEG_S = FOP(7, FMT_S),
8625 OPC_ROUND_L_S = FOP(8, FMT_S),
8626 OPC_TRUNC_L_S = FOP(9, FMT_S),
8627 OPC_CEIL_L_S = FOP(10, FMT_S),
8628 OPC_FLOOR_L_S = FOP(11, FMT_S),
8629 OPC_ROUND_W_S = FOP(12, FMT_S),
8630 OPC_TRUNC_W_S = FOP(13, FMT_S),
8631 OPC_CEIL_W_S = FOP(14, FMT_S),
8632 OPC_FLOOR_W_S = FOP(15, FMT_S),
e7f16abb 8633 OPC_SEL_S = FOP(16, FMT_S),
bf4120ad
NF
8634 OPC_MOVCF_S = FOP(17, FMT_S),
8635 OPC_MOVZ_S = FOP(18, FMT_S),
8636 OPC_MOVN_S = FOP(19, FMT_S),
e7f16abb 8637 OPC_SELEQZ_S = FOP(20, FMT_S),
bf4120ad
NF
8638 OPC_RECIP_S = FOP(21, FMT_S),
8639 OPC_RSQRT_S = FOP(22, FMT_S),
e7f16abb
LA
8640 OPC_SELNEZ_S = FOP(23, FMT_S),
8641 OPC_MADDF_S = FOP(24, FMT_S),
8642 OPC_MSUBF_S = FOP(25, FMT_S),
8643 OPC_RINT_S = FOP(26, FMT_S),
8644 OPC_CLASS_S = FOP(27, FMT_S),
8645 OPC_MIN_S = FOP(28, FMT_S),
bf4120ad 8646 OPC_RECIP2_S = FOP(28, FMT_S),
e7f16abb 8647 OPC_MINA_S = FOP(29, FMT_S),
bf4120ad 8648 OPC_RECIP1_S = FOP(29, FMT_S),
e7f16abb 8649 OPC_MAX_S = FOP(30, FMT_S),
bf4120ad 8650 OPC_RSQRT1_S = FOP(30, FMT_S),
e7f16abb 8651 OPC_MAXA_S = FOP(31, FMT_S),
bf4120ad
NF
8652 OPC_RSQRT2_S = FOP(31, FMT_S),
8653 OPC_CVT_D_S = FOP(33, FMT_S),
8654 OPC_CVT_W_S = FOP(36, FMT_S),
8655 OPC_CVT_L_S = FOP(37, FMT_S),
8656 OPC_CVT_PS_S = FOP(38, FMT_S),
8657 OPC_CMP_F_S = FOP (48, FMT_S),
8658 OPC_CMP_UN_S = FOP (49, FMT_S),
8659 OPC_CMP_EQ_S = FOP (50, FMT_S),
8660 OPC_CMP_UEQ_S = FOP (51, FMT_S),
8661 OPC_CMP_OLT_S = FOP (52, FMT_S),
8662 OPC_CMP_ULT_S = FOP (53, FMT_S),
8663 OPC_CMP_OLE_S = FOP (54, FMT_S),
8664 OPC_CMP_ULE_S = FOP (55, FMT_S),
8665 OPC_CMP_SF_S = FOP (56, FMT_S),
8666 OPC_CMP_NGLE_S = FOP (57, FMT_S),
8667 OPC_CMP_SEQ_S = FOP (58, FMT_S),
8668 OPC_CMP_NGL_S = FOP (59, FMT_S),
8669 OPC_CMP_LT_S = FOP (60, FMT_S),
8670 OPC_CMP_NGE_S = FOP (61, FMT_S),
8671 OPC_CMP_LE_S = FOP (62, FMT_S),
8672 OPC_CMP_NGT_S = FOP (63, FMT_S),
8673
8674 OPC_ADD_D = FOP(0, FMT_D),
8675 OPC_SUB_D = FOP(1, FMT_D),
8676 OPC_MUL_D = FOP(2, FMT_D),
8677 OPC_DIV_D = FOP(3, FMT_D),
8678 OPC_SQRT_D = FOP(4, FMT_D),
8679 OPC_ABS_D = FOP(5, FMT_D),
8680 OPC_MOV_D = FOP(6, FMT_D),
8681 OPC_NEG_D = FOP(7, FMT_D),
8682 OPC_ROUND_L_D = FOP(8, FMT_D),
8683 OPC_TRUNC_L_D = FOP(9, FMT_D),
8684 OPC_CEIL_L_D = FOP(10, FMT_D),
8685 OPC_FLOOR_L_D = FOP(11, FMT_D),
8686 OPC_ROUND_W_D = FOP(12, FMT_D),
8687 OPC_TRUNC_W_D = FOP(13, FMT_D),
8688 OPC_CEIL_W_D = FOP(14, FMT_D),
8689 OPC_FLOOR_W_D = FOP(15, FMT_D),
e7f16abb 8690 OPC_SEL_D = FOP(16, FMT_D),
bf4120ad
NF
8691 OPC_MOVCF_D = FOP(17, FMT_D),
8692 OPC_MOVZ_D = FOP(18, FMT_D),
8693 OPC_MOVN_D = FOP(19, FMT_D),
e7f16abb 8694 OPC_SELEQZ_D = FOP(20, FMT_D),
bf4120ad
NF
8695 OPC_RECIP_D = FOP(21, FMT_D),
8696 OPC_RSQRT_D = FOP(22, FMT_D),
e7f16abb
LA
8697 OPC_SELNEZ_D = FOP(23, FMT_D),
8698 OPC_MADDF_D = FOP(24, FMT_D),
8699 OPC_MSUBF_D = FOP(25, FMT_D),
8700 OPC_RINT_D = FOP(26, FMT_D),
8701 OPC_CLASS_D = FOP(27, FMT_D),
8702 OPC_MIN_D = FOP(28, FMT_D),
bf4120ad 8703 OPC_RECIP2_D = FOP(28, FMT_D),
e7f16abb 8704 OPC_MINA_D = FOP(29, FMT_D),
bf4120ad 8705 OPC_RECIP1_D = FOP(29, FMT_D),
e7f16abb 8706 OPC_MAX_D = FOP(30, FMT_D),
bf4120ad 8707 OPC_RSQRT1_D = FOP(30, FMT_D),
e7f16abb 8708 OPC_MAXA_D = FOP(31, FMT_D),
bf4120ad
NF
8709 OPC_RSQRT2_D = FOP(31, FMT_D),
8710 OPC_CVT_S_D = FOP(32, FMT_D),
8711 OPC_CVT_W_D = FOP(36, FMT_D),
8712 OPC_CVT_L_D = FOP(37, FMT_D),
8713 OPC_CMP_F_D = FOP (48, FMT_D),
8714 OPC_CMP_UN_D = FOP (49, FMT_D),
8715 OPC_CMP_EQ_D = FOP (50, FMT_D),
8716 OPC_CMP_UEQ_D = FOP (51, FMT_D),
8717 OPC_CMP_OLT_D = FOP (52, FMT_D),
8718 OPC_CMP_ULT_D = FOP (53, FMT_D),
8719 OPC_CMP_OLE_D = FOP (54, FMT_D),
8720 OPC_CMP_ULE_D = FOP (55, FMT_D),
8721 OPC_CMP_SF_D = FOP (56, FMT_D),
8722 OPC_CMP_NGLE_D = FOP (57, FMT_D),
8723 OPC_CMP_SEQ_D = FOP (58, FMT_D),
8724 OPC_CMP_NGL_D = FOP (59, FMT_D),
8725 OPC_CMP_LT_D = FOP (60, FMT_D),
8726 OPC_CMP_NGE_D = FOP (61, FMT_D),
8727 OPC_CMP_LE_D = FOP (62, FMT_D),
8728 OPC_CMP_NGT_D = FOP (63, FMT_D),
8729
8730 OPC_CVT_S_W = FOP(32, FMT_W),
8731 OPC_CVT_D_W = FOP(33, FMT_W),
8732 OPC_CVT_S_L = FOP(32, FMT_L),
8733 OPC_CVT_D_L = FOP(33, FMT_L),
8734 OPC_CVT_PS_PW = FOP(38, FMT_W),
8735
8736 OPC_ADD_PS = FOP(0, FMT_PS),
8737 OPC_SUB_PS = FOP(1, FMT_PS),
8738 OPC_MUL_PS = FOP(2, FMT_PS),
8739 OPC_DIV_PS = FOP(3, FMT_PS),
8740 OPC_ABS_PS = FOP(5, FMT_PS),
8741 OPC_MOV_PS = FOP(6, FMT_PS),
8742 OPC_NEG_PS = FOP(7, FMT_PS),
8743 OPC_MOVCF_PS = FOP(17, FMT_PS),
8744 OPC_MOVZ_PS = FOP(18, FMT_PS),
8745 OPC_MOVN_PS = FOP(19, FMT_PS),
8746 OPC_ADDR_PS = FOP(24, FMT_PS),
8747 OPC_MULR_PS = FOP(26, FMT_PS),
8748 OPC_RECIP2_PS = FOP(28, FMT_PS),
8749 OPC_RECIP1_PS = FOP(29, FMT_PS),
8750 OPC_RSQRT1_PS = FOP(30, FMT_PS),
8751 OPC_RSQRT2_PS = FOP(31, FMT_PS),
8752
8753 OPC_CVT_S_PU = FOP(32, FMT_PS),
8754 OPC_CVT_PW_PS = FOP(36, FMT_PS),
8755 OPC_CVT_S_PL = FOP(40, FMT_PS),
8756 OPC_PLL_PS = FOP(44, FMT_PS),
8757 OPC_PLU_PS = FOP(45, FMT_PS),
8758 OPC_PUL_PS = FOP(46, FMT_PS),
8759 OPC_PUU_PS = FOP(47, FMT_PS),
8760 OPC_CMP_F_PS = FOP (48, FMT_PS),
8761 OPC_CMP_UN_PS = FOP (49, FMT_PS),
8762 OPC_CMP_EQ_PS = FOP (50, FMT_PS),
8763 OPC_CMP_UEQ_PS = FOP (51, FMT_PS),
8764 OPC_CMP_OLT_PS = FOP (52, FMT_PS),
8765 OPC_CMP_ULT_PS = FOP (53, FMT_PS),
8766 OPC_CMP_OLE_PS = FOP (54, FMT_PS),
8767 OPC_CMP_ULE_PS = FOP (55, FMT_PS),
8768 OPC_CMP_SF_PS = FOP (56, FMT_PS),
8769 OPC_CMP_NGLE_PS = FOP (57, FMT_PS),
8770 OPC_CMP_SEQ_PS = FOP (58, FMT_PS),
8771 OPC_CMP_NGL_PS = FOP (59, FMT_PS),
8772 OPC_CMP_LT_PS = FOP (60, FMT_PS),
8773 OPC_CMP_NGE_PS = FOP (61, FMT_PS),
8774 OPC_CMP_LE_PS = FOP (62, FMT_PS),
8775 OPC_CMP_NGT_PS = FOP (63, FMT_PS),
8776};
8777
3f493883
YK
8778enum r6_f_cmp_op {
8779 R6_OPC_CMP_AF_S = FOP(0, FMT_W),
8780 R6_OPC_CMP_UN_S = FOP(1, FMT_W),
8781 R6_OPC_CMP_EQ_S = FOP(2, FMT_W),
8782 R6_OPC_CMP_UEQ_S = FOP(3, FMT_W),
8783 R6_OPC_CMP_LT_S = FOP(4, FMT_W),
8784 R6_OPC_CMP_ULT_S = FOP(5, FMT_W),
8785 R6_OPC_CMP_LE_S = FOP(6, FMT_W),
8786 R6_OPC_CMP_ULE_S = FOP(7, FMT_W),
8787 R6_OPC_CMP_SAF_S = FOP(8, FMT_W),
8788 R6_OPC_CMP_SUN_S = FOP(9, FMT_W),
8789 R6_OPC_CMP_SEQ_S = FOP(10, FMT_W),
8790 R6_OPC_CMP_SEUQ_S = FOP(11, FMT_W),
8791 R6_OPC_CMP_SLT_S = FOP(12, FMT_W),
8792 R6_OPC_CMP_SULT_S = FOP(13, FMT_W),
8793 R6_OPC_CMP_SLE_S = FOP(14, FMT_W),
8794 R6_OPC_CMP_SULE_S = FOP(15, FMT_W),
8795 R6_OPC_CMP_OR_S = FOP(17, FMT_W),
8796 R6_OPC_CMP_UNE_S = FOP(18, FMT_W),
8797 R6_OPC_CMP_NE_S = FOP(19, FMT_W),
8798 R6_OPC_CMP_SOR_S = FOP(25, FMT_W),
8799 R6_OPC_CMP_SUNE_S = FOP(26, FMT_W),
8800 R6_OPC_CMP_SNE_S = FOP(27, FMT_W),
8801
8802 R6_OPC_CMP_AF_D = FOP(0, FMT_L),
8803 R6_OPC_CMP_UN_D = FOP(1, FMT_L),
8804 R6_OPC_CMP_EQ_D = FOP(2, FMT_L),
8805 R6_OPC_CMP_UEQ_D = FOP(3, FMT_L),
8806 R6_OPC_CMP_LT_D = FOP(4, FMT_L),
8807 R6_OPC_CMP_ULT_D = FOP(5, FMT_L),
8808 R6_OPC_CMP_LE_D = FOP(6, FMT_L),
8809 R6_OPC_CMP_ULE_D = FOP(7, FMT_L),
8810 R6_OPC_CMP_SAF_D = FOP(8, FMT_L),
8811 R6_OPC_CMP_SUN_D = FOP(9, FMT_L),
8812 R6_OPC_CMP_SEQ_D = FOP(10, FMT_L),
8813 R6_OPC_CMP_SEUQ_D = FOP(11, FMT_L),
8814 R6_OPC_CMP_SLT_D = FOP(12, FMT_L),
8815 R6_OPC_CMP_SULT_D = FOP(13, FMT_L),
8816 R6_OPC_CMP_SLE_D = FOP(14, FMT_L),
8817 R6_OPC_CMP_SULE_D = FOP(15, FMT_L),
8818 R6_OPC_CMP_OR_D = FOP(17, FMT_L),
8819 R6_OPC_CMP_UNE_D = FOP(18, FMT_L),
8820 R6_OPC_CMP_NE_D = FOP(19, FMT_L),
8821 R6_OPC_CMP_SOR_D = FOP(25, FMT_L),
8822 R6_OPC_CMP_SUNE_D = FOP(26, FMT_L),
8823 R6_OPC_CMP_SNE_D = FOP(27, FMT_L),
8824};
7a387fff 8825static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
6ea83fed 8826{
72c3a3ee 8827 TCGv t0 = tcg_temp_new();
6ea83fed
FB
8828
8829 switch (opc) {
8830 case OPC_MFC1:
b6d96bed 8831 {
a7812ae4 8832 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8833
7c979afd 8834 gen_load_fpr32(ctx, fp0, fs);
b6d96bed 8835 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 8836 tcg_temp_free_i32(fp0);
6958549d 8837 }
6c5c1e20 8838 gen_store_gpr(t0, rt);
6ea83fed
FB
8839 break;
8840 case OPC_MTC1:
6c5c1e20 8841 gen_load_gpr(t0, rt);
b6d96bed 8842 {
a7812ae4 8843 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8844
8845 tcg_gen_trunc_tl_i32(fp0, t0);
7c979afd 8846 gen_store_fpr32(ctx, fp0, fs);
a7812ae4 8847 tcg_temp_free_i32(fp0);
6958549d 8848 }
6ea83fed
FB
8849 break;
8850 case OPC_CFC1:
895c2d04 8851 gen_helper_1e0i(cfc1, t0, fs);
6c5c1e20 8852 gen_store_gpr(t0, rt);
6ea83fed
FB
8853 break;
8854 case OPC_CTC1:
6c5c1e20 8855 gen_load_gpr(t0, rt);
9c708c7f 8856 save_cpu_state(ctx, 0);
736d120a
PJ
8857 {
8858 TCGv_i32 fs_tmp = tcg_const_i32(fs);
8859
8860 gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
8861 tcg_temp_free_i32(fs_tmp);
8862 }
4cf8a45f 8863 /* Stop translation as we may have changed hflags */
eeb3bba8 8864 ctx->base.is_jmp = DISAS_STOP;
6ea83fed 8865 break;
72c3a3ee 8866#if defined(TARGET_MIPS64)
9c2149c8 8867 case OPC_DMFC1:
72c3a3ee 8868 gen_load_fpr64(ctx, t0, fs);
6c5c1e20 8869 gen_store_gpr(t0, rt);
5a5012ec 8870 break;
9c2149c8 8871 case OPC_DMTC1:
6c5c1e20 8872 gen_load_gpr(t0, rt);
72c3a3ee 8873 gen_store_fpr64(ctx, t0, fs);
5a5012ec 8874 break;
72c3a3ee 8875#endif
5a5012ec 8876 case OPC_MFHC1:
b6d96bed 8877 {
a7812ae4 8878 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8879
7f6613ce 8880 gen_load_fpr32h(ctx, fp0, fs);
b6d96bed 8881 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 8882 tcg_temp_free_i32(fp0);
6958549d 8883 }
6c5c1e20 8884 gen_store_gpr(t0, rt);
5a5012ec
TS
8885 break;
8886 case OPC_MTHC1:
6c5c1e20 8887 gen_load_gpr(t0, rt);
b6d96bed 8888 {
a7812ae4 8889 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8890
8891 tcg_gen_trunc_tl_i32(fp0, t0);
7f6613ce 8892 gen_store_fpr32h(ctx, fp0, fs);
a7812ae4 8893 tcg_temp_free_i32(fp0);
6958549d 8894 }
5a5012ec 8895 break;
6ea83fed 8896 default:
9d68ac14 8897 MIPS_INVAL("cp1 move");
9c708c7f 8898 generate_exception_end(ctx, EXCP_RI);
6c5c1e20 8899 goto out;
6ea83fed 8900 }
6c5c1e20
TS
8901
8902 out:
8903 tcg_temp_free(t0);
6ea83fed
FB
8904}
8905
5a5012ec
TS
8906static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
8907{
42a268c2 8908 TCGLabel *l1;
e214b9bb 8909 TCGCond cond;
af58f9ca
AJ
8910 TCGv_i32 t0;
8911
8912 if (rd == 0) {
8913 /* Treat as NOP. */
8914 return;
8915 }
6ea83fed 8916
e214b9bb 8917 if (tf)
e214b9bb 8918 cond = TCG_COND_EQ;
27848470
TS
8919 else
8920 cond = TCG_COND_NE;
8921
af58f9ca
AJ
8922 l1 = gen_new_label();
8923 t0 = tcg_temp_new_i32();
fa31af0e 8924 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
af58f9ca 8925 tcg_gen_brcondi_i32(cond, t0, 0, l1);
a4e8338d 8926 tcg_temp_free_i32(t0);
af58f9ca
AJ
8927 if (rs == 0) {
8928 tcg_gen_movi_tl(cpu_gpr[rd], 0);
8929 } else {
8930 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
8931 }
e214b9bb 8932 gen_set_label(l1);
5a5012ec
TS
8933}
8934
7c979afd
LA
8935static inline void gen_movcf_s(DisasContext *ctx, int fs, int fd, int cc,
8936 int tf)
a16336e4 8937{
a16336e4 8938 int cond;
cbc37b28 8939 TCGv_i32 t0 = tcg_temp_new_i32();
42a268c2 8940 TCGLabel *l1 = gen_new_label();
a16336e4 8941
a16336e4
TS
8942 if (tf)
8943 cond = TCG_COND_EQ;
8944 else
8945 cond = TCG_COND_NE;
8946
fa31af0e 8947 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
cbc37b28 8948 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7c979afd
LA
8949 gen_load_fpr32(ctx, t0, fs);
8950 gen_store_fpr32(ctx, t0, fd);
a16336e4 8951 gen_set_label(l1);
cbc37b28 8952 tcg_temp_free_i32(t0);
5a5012ec 8953}
a16336e4 8954
b6d96bed 8955static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
a16336e4 8956{
a16336e4 8957 int cond;
cbc37b28
AJ
8958 TCGv_i32 t0 = tcg_temp_new_i32();
8959 TCGv_i64 fp0;
42a268c2 8960 TCGLabel *l1 = gen_new_label();
a16336e4 8961
a16336e4
TS
8962 if (tf)
8963 cond = TCG_COND_EQ;
8964 else
8965 cond = TCG_COND_NE;
8966
fa31af0e 8967 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
cbc37b28 8968 tcg_gen_brcondi_i32(cond, t0, 0, l1);
a4e8338d 8969 tcg_temp_free_i32(t0);
11f94258 8970 fp0 = tcg_temp_new_i64();
9bf3eb2c 8971 gen_load_fpr64(ctx, fp0, fs);
9bf3eb2c 8972 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8973 tcg_temp_free_i64(fp0);
cbc37b28 8974 gen_set_label(l1);
a16336e4
TS
8975}
8976
7f6613ce
PJ
8977static inline void gen_movcf_ps(DisasContext *ctx, int fs, int fd,
8978 int cc, int tf)
a16336e4
TS
8979{
8980 int cond;
cbc37b28 8981 TCGv_i32 t0 = tcg_temp_new_i32();
42a268c2
RH
8982 TCGLabel *l1 = gen_new_label();
8983 TCGLabel *l2 = gen_new_label();
a16336e4
TS
8984
8985 if (tf)
8986 cond = TCG_COND_EQ;
8987 else
8988 cond = TCG_COND_NE;
8989
fa31af0e 8990 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
cbc37b28 8991 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7c979afd
LA
8992 gen_load_fpr32(ctx, t0, fs);
8993 gen_store_fpr32(ctx, t0, fd);
a16336e4 8994 gen_set_label(l1);
9bf3eb2c 8995
fa31af0e 8996 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc+1));
cbc37b28 8997 tcg_gen_brcondi_i32(cond, t0, 0, l2);
7f6613ce
PJ
8998 gen_load_fpr32h(ctx, t0, fs);
8999 gen_store_fpr32h(ctx, t0, fd);
52a0e9eb 9000 tcg_temp_free_i32(t0);
a16336e4 9001 gen_set_label(l2);
a16336e4
TS
9002}
9003
e7f16abb
LA
9004static void gen_sel_s(DisasContext *ctx, enum fopcode op1, int fd, int ft,
9005 int fs)
9006{
9007 TCGv_i32 t1 = tcg_const_i32(0);
9008 TCGv_i32 fp0 = tcg_temp_new_i32();
9009 TCGv_i32 fp1 = tcg_temp_new_i32();
9010 TCGv_i32 fp2 = tcg_temp_new_i32();
7c979afd
LA
9011 gen_load_fpr32(ctx, fp0, fd);
9012 gen_load_fpr32(ctx, fp1, ft);
9013 gen_load_fpr32(ctx, fp2, fs);
e7f16abb
LA
9014
9015 switch (op1) {
9016 case OPC_SEL_S:
9017 tcg_gen_andi_i32(fp0, fp0, 1);
9018 tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
9019 break;
9020 case OPC_SELEQZ_S:
9021 tcg_gen_andi_i32(fp1, fp1, 1);
9022 tcg_gen_movcond_i32(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
9023 break;
9024 case OPC_SELNEZ_S:
9025 tcg_gen_andi_i32(fp1, fp1, 1);
9026 tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
9027 break;
9028 default:
9029 MIPS_INVAL("gen_sel_s");
9c708c7f 9030 generate_exception_end(ctx, EXCP_RI);
e7f16abb
LA
9031 break;
9032 }
9033
7c979afd 9034 gen_store_fpr32(ctx, fp0, fd);
e7f16abb
LA
9035 tcg_temp_free_i32(fp2);
9036 tcg_temp_free_i32(fp1);
9037 tcg_temp_free_i32(fp0);
9038 tcg_temp_free_i32(t1);
9039}
9040
9041static void gen_sel_d(DisasContext *ctx, enum fopcode op1, int fd, int ft,
9042 int fs)
9043{
9044 TCGv_i64 t1 = tcg_const_i64(0);
9045 TCGv_i64 fp0 = tcg_temp_new_i64();
9046 TCGv_i64 fp1 = tcg_temp_new_i64();
9047 TCGv_i64 fp2 = tcg_temp_new_i64();
9048 gen_load_fpr64(ctx, fp0, fd);
9049 gen_load_fpr64(ctx, fp1, ft);
9050 gen_load_fpr64(ctx, fp2, fs);
9051
9052 switch (op1) {
9053 case OPC_SEL_D:
9054 tcg_gen_andi_i64(fp0, fp0, 1);
9055 tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
9056 break;
9057 case OPC_SELEQZ_D:
9058 tcg_gen_andi_i64(fp1, fp1, 1);
9059 tcg_gen_movcond_i64(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
9060 break;
9061 case OPC_SELNEZ_D:
9062 tcg_gen_andi_i64(fp1, fp1, 1);
9063 tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
9064 break;
9065 default:
9066 MIPS_INVAL("gen_sel_d");
9c708c7f 9067 generate_exception_end(ctx, EXCP_RI);
e7f16abb
LA
9068 break;
9069 }
9070
9071 gen_store_fpr64(ctx, fp0, fd);
9072 tcg_temp_free_i64(fp2);
9073 tcg_temp_free_i64(fp1);
9074 tcg_temp_free_i64(fp0);
9075 tcg_temp_free_i64(t1);
9076}
6ea83fed 9077
bf4120ad 9078static void gen_farith (DisasContext *ctx, enum fopcode op1,
5e755519 9079 int ft, int fs, int fd, int cc)
6ea83fed 9080{
7a387fff 9081 uint32_t func = ctx->opcode & 0x3f;
bf4120ad
NF
9082 switch (op1) {
9083 case OPC_ADD_S:
b6d96bed 9084 {
a7812ae4
PB
9085 TCGv_i32 fp0 = tcg_temp_new_i32();
9086 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 9087
7c979afd
LA
9088 gen_load_fpr32(ctx, fp0, fs);
9089 gen_load_fpr32(ctx, fp1, ft);
895c2d04 9090 gen_helper_float_add_s(fp0, cpu_env, fp0, fp1);
a7812ae4 9091 tcg_temp_free_i32(fp1);
7c979afd 9092 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9093 tcg_temp_free_i32(fp0);
b6d96bed 9094 }
5a5012ec 9095 break;
bf4120ad 9096 case OPC_SUB_S:
b6d96bed 9097 {
a7812ae4
PB
9098 TCGv_i32 fp0 = tcg_temp_new_i32();
9099 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 9100
7c979afd
LA
9101 gen_load_fpr32(ctx, fp0, fs);
9102 gen_load_fpr32(ctx, fp1, ft);
895c2d04 9103 gen_helper_float_sub_s(fp0, cpu_env, fp0, fp1);
a7812ae4 9104 tcg_temp_free_i32(fp1);
7c979afd 9105 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9106 tcg_temp_free_i32(fp0);
b6d96bed 9107 }
5a5012ec 9108 break;
bf4120ad 9109 case OPC_MUL_S:
b6d96bed 9110 {
a7812ae4
PB
9111 TCGv_i32 fp0 = tcg_temp_new_i32();
9112 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 9113
7c979afd
LA
9114 gen_load_fpr32(ctx, fp0, fs);
9115 gen_load_fpr32(ctx, fp1, ft);
895c2d04 9116 gen_helper_float_mul_s(fp0, cpu_env, fp0, fp1);
a7812ae4 9117 tcg_temp_free_i32(fp1);
7c979afd 9118 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9119 tcg_temp_free_i32(fp0);
b6d96bed 9120 }
5a5012ec 9121 break;
bf4120ad 9122 case OPC_DIV_S:
b6d96bed 9123 {
a7812ae4
PB
9124 TCGv_i32 fp0 = tcg_temp_new_i32();
9125 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 9126
7c979afd
LA
9127 gen_load_fpr32(ctx, fp0, fs);
9128 gen_load_fpr32(ctx, fp1, ft);
895c2d04 9129 gen_helper_float_div_s(fp0, cpu_env, fp0, fp1);
a7812ae4 9130 tcg_temp_free_i32(fp1);
7c979afd 9131 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9132 tcg_temp_free_i32(fp0);
b6d96bed 9133 }
5a5012ec 9134 break;
bf4120ad 9135 case OPC_SQRT_S:
b6d96bed 9136 {
a7812ae4 9137 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9138
7c979afd 9139 gen_load_fpr32(ctx, fp0, fs);
895c2d04 9140 gen_helper_float_sqrt_s(fp0, cpu_env, fp0);
7c979afd 9141 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9142 tcg_temp_free_i32(fp0);
b6d96bed 9143 }
5a5012ec 9144 break;
bf4120ad 9145 case OPC_ABS_S:
b6d96bed 9146 {
a7812ae4 9147 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9148
7c979afd 9149 gen_load_fpr32(ctx, fp0, fs);
6be77480
AM
9150 if (ctx->abs2008) {
9151 tcg_gen_andi_i32(fp0, fp0, 0x7fffffffUL);
9152 } else {
9153 gen_helper_float_abs_s(fp0, fp0);
9154 }
7c979afd 9155 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9156 tcg_temp_free_i32(fp0);
b6d96bed 9157 }
5a5012ec 9158 break;
bf4120ad 9159 case OPC_MOV_S:
b6d96bed 9160 {
a7812ae4 9161 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9162
7c979afd
LA
9163 gen_load_fpr32(ctx, fp0, fs);
9164 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9165 tcg_temp_free_i32(fp0);
b6d96bed 9166 }
5a5012ec 9167 break;
bf4120ad 9168 case OPC_NEG_S:
b6d96bed 9169 {
a7812ae4 9170 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9171
7c979afd 9172 gen_load_fpr32(ctx, fp0, fs);
6be77480
AM
9173 if (ctx->abs2008) {
9174 tcg_gen_xori_i32(fp0, fp0, 1UL << 31);
9175 } else {
9176 gen_helper_float_chs_s(fp0, fp0);
9177 }
7c979afd 9178 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9179 tcg_temp_free_i32(fp0);
b6d96bed 9180 }
5a5012ec 9181 break;
bf4120ad 9182 case OPC_ROUND_L_S:
5e755519 9183 check_cp1_64bitmode(ctx);
b6d96bed 9184 {
a7812ae4
PB
9185 TCGv_i32 fp32 = tcg_temp_new_i32();
9186 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 9187
7c979afd 9188 gen_load_fpr32(ctx, fp32, fs);
87552089
AM
9189 if (ctx->nan2008) {
9190 gen_helper_float_round_2008_l_s(fp64, cpu_env, fp32);
9191 } else {
9192 gen_helper_float_round_l_s(fp64, cpu_env, fp32);
9193 }
a7812ae4 9194 tcg_temp_free_i32(fp32);
b6d96bed 9195 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 9196 tcg_temp_free_i64(fp64);
b6d96bed 9197 }
5a5012ec 9198 break;
bf4120ad 9199 case OPC_TRUNC_L_S:
5e755519 9200 check_cp1_64bitmode(ctx);
b6d96bed 9201 {
a7812ae4
PB
9202 TCGv_i32 fp32 = tcg_temp_new_i32();
9203 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 9204
7c979afd 9205 gen_load_fpr32(ctx, fp32, fs);
87552089
AM
9206 if (ctx->nan2008) {
9207 gen_helper_float_trunc_2008_l_s(fp64, cpu_env, fp32);
9208 } else {
9209 gen_helper_float_trunc_l_s(fp64, cpu_env, fp32);
9210 }
a7812ae4 9211 tcg_temp_free_i32(fp32);
b6d96bed 9212 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 9213 tcg_temp_free_i64(fp64);
b6d96bed 9214 }
5a5012ec 9215 break;
bf4120ad 9216 case OPC_CEIL_L_S:
5e755519 9217 check_cp1_64bitmode(ctx);
b6d96bed 9218 {
a7812ae4
PB
9219 TCGv_i32 fp32 = tcg_temp_new_i32();
9220 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 9221
7c979afd 9222 gen_load_fpr32(ctx, fp32, fs);
87552089
AM
9223 if (ctx->nan2008) {
9224 gen_helper_float_ceil_2008_l_s(fp64, cpu_env, fp32);
9225 } else {
9226 gen_helper_float_ceil_l_s(fp64, cpu_env, fp32);
9227 }
a7812ae4 9228 tcg_temp_free_i32(fp32);
b6d96bed 9229 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 9230 tcg_temp_free_i64(fp64);
b6d96bed 9231 }
5a5012ec 9232 break;
bf4120ad 9233 case OPC_FLOOR_L_S:
5e755519 9234 check_cp1_64bitmode(ctx);
b6d96bed 9235 {
a7812ae4
PB
9236 TCGv_i32 fp32 = tcg_temp_new_i32();
9237 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 9238
7c979afd 9239 gen_load_fpr32(ctx, fp32, fs);
87552089
AM
9240 if (ctx->nan2008) {
9241 gen_helper_float_floor_2008_l_s(fp64, cpu_env, fp32);
9242 } else {
9243 gen_helper_float_floor_l_s(fp64, cpu_env, fp32);
9244 }
a7812ae4 9245 tcg_temp_free_i32(fp32);
b6d96bed 9246 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 9247 tcg_temp_free_i64(fp64);
b6d96bed 9248 }
5a5012ec 9249 break;
bf4120ad 9250 case OPC_ROUND_W_S:
b6d96bed 9251 {
a7812ae4 9252 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9253
7c979afd 9254 gen_load_fpr32(ctx, fp0, fs);
87552089
AM
9255 if (ctx->nan2008) {
9256 gen_helper_float_round_2008_w_s(fp0, cpu_env, fp0);
9257 } else {
9258 gen_helper_float_round_w_s(fp0, cpu_env, fp0);
9259 }
7c979afd 9260 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9261 tcg_temp_free_i32(fp0);
b6d96bed 9262 }
5a5012ec 9263 break;
bf4120ad 9264 case OPC_TRUNC_W_S:
b6d96bed 9265 {
a7812ae4 9266 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9267
7c979afd 9268 gen_load_fpr32(ctx, fp0, fs);
87552089
AM
9269 if (ctx->nan2008) {
9270 gen_helper_float_trunc_2008_w_s(fp0, cpu_env, fp0);
9271 } else {
9272 gen_helper_float_trunc_w_s(fp0, cpu_env, fp0);
9273 }
7c979afd 9274 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9275 tcg_temp_free_i32(fp0);
b6d96bed 9276 }
5a5012ec 9277 break;
bf4120ad 9278 case OPC_CEIL_W_S:
b6d96bed 9279 {
a7812ae4 9280 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9281
7c979afd 9282 gen_load_fpr32(ctx, fp0, fs);
87552089
AM
9283 if (ctx->nan2008) {
9284 gen_helper_float_ceil_2008_w_s(fp0, cpu_env, fp0);
9285 } else {
9286 gen_helper_float_ceil_w_s(fp0, cpu_env, fp0);
9287 }
7c979afd 9288 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9289 tcg_temp_free_i32(fp0);
b6d96bed 9290 }
5a5012ec 9291 break;
bf4120ad 9292 case OPC_FLOOR_W_S:
b6d96bed 9293 {
a7812ae4 9294 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9295
7c979afd 9296 gen_load_fpr32(ctx, fp0, fs);
87552089
AM
9297 if (ctx->nan2008) {
9298 gen_helper_float_floor_2008_w_s(fp0, cpu_env, fp0);
9299 } else {
9300 gen_helper_float_floor_w_s(fp0, cpu_env, fp0);
9301 }
7c979afd 9302 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9303 tcg_temp_free_i32(fp0);
b6d96bed 9304 }
5a5012ec 9305 break;
e7f16abb
LA
9306 case OPC_SEL_S:
9307 check_insn(ctx, ISA_MIPS32R6);
9308 gen_sel_s(ctx, op1, fd, ft, fs);
e7f16abb
LA
9309 break;
9310 case OPC_SELEQZ_S:
9311 check_insn(ctx, ISA_MIPS32R6);
9312 gen_sel_s(ctx, op1, fd, ft, fs);
e7f16abb
LA
9313 break;
9314 case OPC_SELNEZ_S:
9315 check_insn(ctx, ISA_MIPS32R6);
9316 gen_sel_s(ctx, op1, fd, ft, fs);
e7f16abb 9317 break;
bf4120ad 9318 case OPC_MOVCF_S:
fecd2646 9319 check_insn_opc_removed(ctx, ISA_MIPS32R6);
7c979afd 9320 gen_movcf_s(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
5a5012ec 9321 break;
bf4120ad 9322 case OPC_MOVZ_S:
fecd2646 9323 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a16336e4 9324 {
42a268c2 9325 TCGLabel *l1 = gen_new_label();
c9297f4d 9326 TCGv_i32 fp0;
a16336e4 9327
c9297f4d
AJ
9328 if (ft != 0) {
9329 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
9330 }
9331 fp0 = tcg_temp_new_i32();
7c979afd
LA
9332 gen_load_fpr32(ctx, fp0, fs);
9333 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9334 tcg_temp_free_i32(fp0);
a16336e4
TS
9335 gen_set_label(l1);
9336 }
5a5012ec 9337 break;
bf4120ad 9338 case OPC_MOVN_S:
fecd2646 9339 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a16336e4 9340 {
42a268c2 9341 TCGLabel *l1 = gen_new_label();
c9297f4d
AJ
9342 TCGv_i32 fp0;
9343
9344 if (ft != 0) {
9345 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
9346 fp0 = tcg_temp_new_i32();
7c979afd
LA
9347 gen_load_fpr32(ctx, fp0, fs);
9348 gen_store_fpr32(ctx, fp0, fd);
c9297f4d
AJ
9349 tcg_temp_free_i32(fp0);
9350 gen_set_label(l1);
9351 }
a16336e4 9352 }
5a5012ec 9353 break;
bf4120ad 9354 case OPC_RECIP_S:
b6d96bed 9355 {
a7812ae4 9356 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9357
7c979afd 9358 gen_load_fpr32(ctx, fp0, fs);
895c2d04 9359 gen_helper_float_recip_s(fp0, cpu_env, fp0);
7c979afd 9360 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9361 tcg_temp_free_i32(fp0);
b6d96bed 9362 }
57fa1fb3 9363 break;
bf4120ad 9364 case OPC_RSQRT_S:
b6d96bed 9365 {
a7812ae4 9366 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9367
7c979afd 9368 gen_load_fpr32(ctx, fp0, fs);
895c2d04 9369 gen_helper_float_rsqrt_s(fp0, cpu_env, fp0);
7c979afd 9370 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9371 tcg_temp_free_i32(fp0);
b6d96bed 9372 }
57fa1fb3 9373 break;
e7f16abb
LA
9374 case OPC_MADDF_S:
9375 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 9376 {
a7812ae4
PB
9377 TCGv_i32 fp0 = tcg_temp_new_i32();
9378 TCGv_i32 fp1 = tcg_temp_new_i32();
e7f16abb 9379 TCGv_i32 fp2 = tcg_temp_new_i32();
7c979afd
LA
9380 gen_load_fpr32(ctx, fp0, fs);
9381 gen_load_fpr32(ctx, fp1, ft);
9382 gen_load_fpr32(ctx, fp2, fd);
e7f16abb 9383 gen_helper_float_maddf_s(fp2, cpu_env, fp0, fp1, fp2);
7c979afd 9384 gen_store_fpr32(ctx, fp2, fd);
e7f16abb 9385 tcg_temp_free_i32(fp2);
a7812ae4 9386 tcg_temp_free_i32(fp1);
a7812ae4 9387 tcg_temp_free_i32(fp0);
b6d96bed 9388 }
57fa1fb3 9389 break;
e7f16abb
LA
9390 case OPC_MSUBF_S:
9391 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 9392 {
a7812ae4 9393 TCGv_i32 fp0 = tcg_temp_new_i32();
e7f16abb
LA
9394 TCGv_i32 fp1 = tcg_temp_new_i32();
9395 TCGv_i32 fp2 = tcg_temp_new_i32();
7c979afd
LA
9396 gen_load_fpr32(ctx, fp0, fs);
9397 gen_load_fpr32(ctx, fp1, ft);
9398 gen_load_fpr32(ctx, fp2, fd);
e7f16abb 9399 gen_helper_float_msubf_s(fp2, cpu_env, fp0, fp1, fp2);
7c979afd 9400 gen_store_fpr32(ctx, fp2, fd);
e7f16abb
LA
9401 tcg_temp_free_i32(fp2);
9402 tcg_temp_free_i32(fp1);
a7812ae4 9403 tcg_temp_free_i32(fp0);
b6d96bed 9404 }
57fa1fb3 9405 break;
e7f16abb
LA
9406 case OPC_RINT_S:
9407 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 9408 {
a7812ae4 9409 TCGv_i32 fp0 = tcg_temp_new_i32();
7c979afd 9410 gen_load_fpr32(ctx, fp0, fs);
e7f16abb 9411 gen_helper_float_rint_s(fp0, cpu_env, fp0);
7c979afd 9412 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9413 tcg_temp_free_i32(fp0);
b6d96bed 9414 }
57fa1fb3 9415 break;
e7f16abb
LA
9416 case OPC_CLASS_S:
9417 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 9418 {
e7f16abb 9419 TCGv_i32 fp0 = tcg_temp_new_i32();
7c979afd 9420 gen_load_fpr32(ctx, fp0, fs);
af39bc8c 9421 gen_helper_float_class_s(fp0, cpu_env, fp0);
7c979afd 9422 gen_store_fpr32(ctx, fp0, fd);
e7f16abb 9423 tcg_temp_free_i32(fp0);
e7f16abb
LA
9424 }
9425 break;
9426 case OPC_MIN_S: /* OPC_RECIP2_S */
9427 if (ctx->insn_flags & ISA_MIPS32R6) {
9428 /* OPC_MIN_S */
a7812ae4
PB
9429 TCGv_i32 fp0 = tcg_temp_new_i32();
9430 TCGv_i32 fp1 = tcg_temp_new_i32();
e7f16abb 9431 TCGv_i32 fp2 = tcg_temp_new_i32();
7c979afd
LA
9432 gen_load_fpr32(ctx, fp0, fs);
9433 gen_load_fpr32(ctx, fp1, ft);
e7f16abb 9434 gen_helper_float_min_s(fp2, cpu_env, fp0, fp1);
7c979afd 9435 gen_store_fpr32(ctx, fp2, fd);
e7f16abb
LA
9436 tcg_temp_free_i32(fp2);
9437 tcg_temp_free_i32(fp1);
9438 tcg_temp_free_i32(fp0);
e7f16abb
LA
9439 } else {
9440 /* OPC_RECIP2_S */
9441 check_cp1_64bitmode(ctx);
9442 {
9443 TCGv_i32 fp0 = tcg_temp_new_i32();
9444 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 9445
7c979afd
LA
9446 gen_load_fpr32(ctx, fp0, fs);
9447 gen_load_fpr32(ctx, fp1, ft);
e7f16abb
LA
9448 gen_helper_float_recip2_s(fp0, cpu_env, fp0, fp1);
9449 tcg_temp_free_i32(fp1);
7c979afd 9450 gen_store_fpr32(ctx, fp0, fd);
e7f16abb
LA
9451 tcg_temp_free_i32(fp0);
9452 }
e7f16abb
LA
9453 }
9454 break;
9455 case OPC_MINA_S: /* OPC_RECIP1_S */
9456 if (ctx->insn_flags & ISA_MIPS32R6) {
9457 /* OPC_MINA_S */
9458 TCGv_i32 fp0 = tcg_temp_new_i32();
9459 TCGv_i32 fp1 = tcg_temp_new_i32();
9460 TCGv_i32 fp2 = tcg_temp_new_i32();
7c979afd
LA
9461 gen_load_fpr32(ctx, fp0, fs);
9462 gen_load_fpr32(ctx, fp1, ft);
e7f16abb 9463 gen_helper_float_mina_s(fp2, cpu_env, fp0, fp1);
7c979afd 9464 gen_store_fpr32(ctx, fp2, fd);
e7f16abb
LA
9465 tcg_temp_free_i32(fp2);
9466 tcg_temp_free_i32(fp1);
9467 tcg_temp_free_i32(fp0);
e7f16abb
LA
9468 } else {
9469 /* OPC_RECIP1_S */
9470 check_cp1_64bitmode(ctx);
9471 {
9472 TCGv_i32 fp0 = tcg_temp_new_i32();
9473
7c979afd 9474 gen_load_fpr32(ctx, fp0, fs);
e7f16abb 9475 gen_helper_float_recip1_s(fp0, cpu_env, fp0);
7c979afd 9476 gen_store_fpr32(ctx, fp0, fd);
e7f16abb
LA
9477 tcg_temp_free_i32(fp0);
9478 }
e7f16abb
LA
9479 }
9480 break;
9481 case OPC_MAX_S: /* OPC_RSQRT1_S */
9482 if (ctx->insn_flags & ISA_MIPS32R6) {
9483 /* OPC_MAX_S */
9484 TCGv_i32 fp0 = tcg_temp_new_i32();
9485 TCGv_i32 fp1 = tcg_temp_new_i32();
7c979afd
LA
9486 gen_load_fpr32(ctx, fp0, fs);
9487 gen_load_fpr32(ctx, fp1, ft);
e7f16abb 9488 gen_helper_float_max_s(fp1, cpu_env, fp0, fp1);
7c979afd 9489 gen_store_fpr32(ctx, fp1, fd);
e7f16abb
LA
9490 tcg_temp_free_i32(fp1);
9491 tcg_temp_free_i32(fp0);
e7f16abb
LA
9492 } else {
9493 /* OPC_RSQRT1_S */
9494 check_cp1_64bitmode(ctx);
9495 {
9496 TCGv_i32 fp0 = tcg_temp_new_i32();
9497
7c979afd 9498 gen_load_fpr32(ctx, fp0, fs);
e7f16abb 9499 gen_helper_float_rsqrt1_s(fp0, cpu_env, fp0);
7c979afd 9500 gen_store_fpr32(ctx, fp0, fd);
e7f16abb
LA
9501 tcg_temp_free_i32(fp0);
9502 }
e7f16abb
LA
9503 }
9504 break;
9505 case OPC_MAXA_S: /* OPC_RSQRT2_S */
9506 if (ctx->insn_flags & ISA_MIPS32R6) {
9507 /* OPC_MAXA_S */
9508 TCGv_i32 fp0 = tcg_temp_new_i32();
9509 TCGv_i32 fp1 = tcg_temp_new_i32();
7c979afd
LA
9510 gen_load_fpr32(ctx, fp0, fs);
9511 gen_load_fpr32(ctx, fp1, ft);
e7f16abb 9512 gen_helper_float_maxa_s(fp1, cpu_env, fp0, fp1);
7c979afd 9513 gen_store_fpr32(ctx, fp1, fd);
a7812ae4 9514 tcg_temp_free_i32(fp1);
a7812ae4 9515 tcg_temp_free_i32(fp0);
e7f16abb
LA
9516 } else {
9517 /* OPC_RSQRT2_S */
9518 check_cp1_64bitmode(ctx);
9519 {
9520 TCGv_i32 fp0 = tcg_temp_new_i32();
9521 TCGv_i32 fp1 = tcg_temp_new_i32();
9522
7c979afd
LA
9523 gen_load_fpr32(ctx, fp0, fs);
9524 gen_load_fpr32(ctx, fp1, ft);
e7f16abb
LA
9525 gen_helper_float_rsqrt2_s(fp0, cpu_env, fp0, fp1);
9526 tcg_temp_free_i32(fp1);
7c979afd 9527 gen_store_fpr32(ctx, fp0, fd);
e7f16abb
LA
9528 tcg_temp_free_i32(fp0);
9529 }
b6d96bed 9530 }
57fa1fb3 9531 break;
bf4120ad 9532 case OPC_CVT_D_S:
5e755519 9533 check_cp1_registers(ctx, fd);
b6d96bed 9534 {
a7812ae4
PB
9535 TCGv_i32 fp32 = tcg_temp_new_i32();
9536 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 9537
7c979afd 9538 gen_load_fpr32(ctx, fp32, fs);
895c2d04 9539 gen_helper_float_cvtd_s(fp64, cpu_env, fp32);
a7812ae4 9540 tcg_temp_free_i32(fp32);
b6d96bed 9541 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 9542 tcg_temp_free_i64(fp64);
b6d96bed 9543 }
5a5012ec 9544 break;
bf4120ad 9545 case OPC_CVT_W_S:
b6d96bed 9546 {
a7812ae4 9547 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9548
7c979afd 9549 gen_load_fpr32(ctx, fp0, fs);
87552089
AM
9550 if (ctx->nan2008) {
9551 gen_helper_float_cvt_2008_w_s(fp0, cpu_env, fp0);
9552 } else {
9553 gen_helper_float_cvt_w_s(fp0, cpu_env, fp0);
9554 }
7c979afd 9555 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9556 tcg_temp_free_i32(fp0);
b6d96bed 9557 }
5a5012ec 9558 break;
bf4120ad 9559 case OPC_CVT_L_S:
5e755519 9560 check_cp1_64bitmode(ctx);
b6d96bed 9561 {
a7812ae4
PB
9562 TCGv_i32 fp32 = tcg_temp_new_i32();
9563 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 9564
7c979afd 9565 gen_load_fpr32(ctx, fp32, fs);
87552089
AM
9566 if (ctx->nan2008) {
9567 gen_helper_float_cvt_2008_l_s(fp64, cpu_env, fp32);
9568 } else {
9569 gen_helper_float_cvt_l_s(fp64, cpu_env, fp32);
9570 }
a7812ae4 9571 tcg_temp_free_i32(fp32);
b6d96bed 9572 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 9573 tcg_temp_free_i64(fp64);
b6d96bed 9574 }
5a5012ec 9575 break;
bf4120ad 9576 case OPC_CVT_PS_S:
e29c9628 9577 check_ps(ctx);
b6d96bed 9578 {
a7812ae4
PB
9579 TCGv_i64 fp64 = tcg_temp_new_i64();
9580 TCGv_i32 fp32_0 = tcg_temp_new_i32();
9581 TCGv_i32 fp32_1 = tcg_temp_new_i32();
b6d96bed 9582
7c979afd
LA
9583 gen_load_fpr32(ctx, fp32_0, fs);
9584 gen_load_fpr32(ctx, fp32_1, ft);
13d24f49 9585 tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0);
a7812ae4
PB
9586 tcg_temp_free_i32(fp32_1);
9587 tcg_temp_free_i32(fp32_0);
36aa55dc 9588 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 9589 tcg_temp_free_i64(fp64);
b6d96bed 9590 }
5a5012ec 9591 break;
bf4120ad
NF
9592 case OPC_CMP_F_S:
9593 case OPC_CMP_UN_S:
9594 case OPC_CMP_EQ_S:
9595 case OPC_CMP_UEQ_S:
9596 case OPC_CMP_OLT_S:
9597 case OPC_CMP_ULT_S:
9598 case OPC_CMP_OLE_S:
9599 case OPC_CMP_ULE_S:
9600 case OPC_CMP_SF_S:
9601 case OPC_CMP_NGLE_S:
9602 case OPC_CMP_SEQ_S:
9603 case OPC_CMP_NGL_S:
9604 case OPC_CMP_LT_S:
9605 case OPC_CMP_NGE_S:
9606 case OPC_CMP_LE_S:
9607 case OPC_CMP_NGT_S:
fecd2646 9608 check_insn_opc_removed(ctx, ISA_MIPS32R6);
8153667c
NF
9609 if (ctx->opcode & (1 << 6)) {
9610 gen_cmpabs_s(ctx, func-48, ft, fs, cc);
8153667c
NF
9611 } else {
9612 gen_cmp_s(ctx, func-48, ft, fs, cc);
5a1e8ffb 9613 }
5a5012ec 9614 break;
bf4120ad 9615 case OPC_ADD_D:
5e755519 9616 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 9617 {
a7812ae4
PB
9618 TCGv_i64 fp0 = tcg_temp_new_i64();
9619 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9620
9621 gen_load_fpr64(ctx, fp0, fs);
9622 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9623 gen_helper_float_add_d(fp0, cpu_env, fp0, fp1);
a7812ae4 9624 tcg_temp_free_i64(fp1);
b6d96bed 9625 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9626 tcg_temp_free_i64(fp0);
b6d96bed 9627 }
6ea83fed 9628 break;
bf4120ad 9629 case OPC_SUB_D:
5e755519 9630 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 9631 {
a7812ae4
PB
9632 TCGv_i64 fp0 = tcg_temp_new_i64();
9633 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9634
9635 gen_load_fpr64(ctx, fp0, fs);
9636 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9637 gen_helper_float_sub_d(fp0, cpu_env, fp0, fp1);
a7812ae4 9638 tcg_temp_free_i64(fp1);
b6d96bed 9639 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9640 tcg_temp_free_i64(fp0);
b6d96bed 9641 }
6ea83fed 9642 break;
bf4120ad 9643 case OPC_MUL_D:
5e755519 9644 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 9645 {
a7812ae4
PB
9646 TCGv_i64 fp0 = tcg_temp_new_i64();
9647 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9648
9649 gen_load_fpr64(ctx, fp0, fs);
9650 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9651 gen_helper_float_mul_d(fp0, cpu_env, fp0, fp1);
a7812ae4 9652 tcg_temp_free_i64(fp1);
b6d96bed 9653 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9654 tcg_temp_free_i64(fp0);
b6d96bed 9655 }
6ea83fed 9656 break;
bf4120ad 9657 case OPC_DIV_D:
5e755519 9658 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 9659 {
a7812ae4
PB
9660 TCGv_i64 fp0 = tcg_temp_new_i64();
9661 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9662
9663 gen_load_fpr64(ctx, fp0, fs);
9664 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9665 gen_helper_float_div_d(fp0, cpu_env, fp0, fp1);
a7812ae4 9666 tcg_temp_free_i64(fp1);
b6d96bed 9667 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9668 tcg_temp_free_i64(fp0);
b6d96bed 9669 }
6ea83fed 9670 break;
bf4120ad 9671 case OPC_SQRT_D:
5e755519 9672 check_cp1_registers(ctx, fs | fd);
b6d96bed 9673 {
a7812ae4 9674 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9675
9676 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9677 gen_helper_float_sqrt_d(fp0, cpu_env, fp0);
b6d96bed 9678 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9679 tcg_temp_free_i64(fp0);
b6d96bed 9680 }
6ea83fed 9681 break;
bf4120ad 9682 case OPC_ABS_D:
5e755519 9683 check_cp1_registers(ctx, fs | fd);
b6d96bed 9684 {
a7812ae4 9685 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9686
9687 gen_load_fpr64(ctx, fp0, fs);
6be77480
AM
9688 if (ctx->abs2008) {
9689 tcg_gen_andi_i64(fp0, fp0, 0x7fffffffffffffffULL);
9690 } else {
9691 gen_helper_float_abs_d(fp0, fp0);
9692 }
b6d96bed 9693 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9694 tcg_temp_free_i64(fp0);
b6d96bed 9695 }
6ea83fed 9696 break;
bf4120ad 9697 case OPC_MOV_D:
5e755519 9698 check_cp1_registers(ctx, fs | fd);
b6d96bed 9699 {
a7812ae4 9700 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9701
9702 gen_load_fpr64(ctx, fp0, fs);
9703 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9704 tcg_temp_free_i64(fp0);
b6d96bed 9705 }
6ea83fed 9706 break;
bf4120ad 9707 case OPC_NEG_D:
5e755519 9708 check_cp1_registers(ctx, fs | fd);
b6d96bed 9709 {
a7812ae4 9710 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9711
9712 gen_load_fpr64(ctx, fp0, fs);
6be77480
AM
9713 if (ctx->abs2008) {
9714 tcg_gen_xori_i64(fp0, fp0, 1ULL << 63);
9715 } else {
9716 gen_helper_float_chs_d(fp0, fp0);
9717 }
b6d96bed 9718 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9719 tcg_temp_free_i64(fp0);
b6d96bed 9720 }
6ea83fed 9721 break;
bf4120ad 9722 case OPC_ROUND_L_D:
5e755519 9723 check_cp1_64bitmode(ctx);
b6d96bed 9724 {
a7812ae4 9725 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9726
9727 gen_load_fpr64(ctx, fp0, fs);
87552089
AM
9728 if (ctx->nan2008) {
9729 gen_helper_float_round_2008_l_d(fp0, cpu_env, fp0);
9730 } else {
9731 gen_helper_float_round_l_d(fp0, cpu_env, fp0);
9732 }
b6d96bed 9733 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9734 tcg_temp_free_i64(fp0);
b6d96bed 9735 }
5a5012ec 9736 break;
bf4120ad 9737 case OPC_TRUNC_L_D:
5e755519 9738 check_cp1_64bitmode(ctx);
b6d96bed 9739 {
a7812ae4 9740 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9741
9742 gen_load_fpr64(ctx, fp0, fs);
87552089
AM
9743 if (ctx->nan2008) {
9744 gen_helper_float_trunc_2008_l_d(fp0, cpu_env, fp0);
9745 } else {
9746 gen_helper_float_trunc_l_d(fp0, cpu_env, fp0);
9747 }
b6d96bed 9748 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9749 tcg_temp_free_i64(fp0);
b6d96bed 9750 }
5a5012ec 9751 break;
bf4120ad 9752 case OPC_CEIL_L_D:
5e755519 9753 check_cp1_64bitmode(ctx);
b6d96bed 9754 {
a7812ae4 9755 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9756
9757 gen_load_fpr64(ctx, fp0, fs);
87552089
AM
9758 if (ctx->nan2008) {
9759 gen_helper_float_ceil_2008_l_d(fp0, cpu_env, fp0);
9760 } else {
9761 gen_helper_float_ceil_l_d(fp0, cpu_env, fp0);
9762 }
b6d96bed 9763 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9764 tcg_temp_free_i64(fp0);
b6d96bed 9765 }
5a5012ec 9766 break;
bf4120ad 9767 case OPC_FLOOR_L_D:
5e755519 9768 check_cp1_64bitmode(ctx);
b6d96bed 9769 {
a7812ae4 9770 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9771
9772 gen_load_fpr64(ctx, fp0, fs);
87552089
AM
9773 if (ctx->nan2008) {
9774 gen_helper_float_floor_2008_l_d(fp0, cpu_env, fp0);
9775 } else {
9776 gen_helper_float_floor_l_d(fp0, cpu_env, fp0);
9777 }
b6d96bed 9778 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9779 tcg_temp_free_i64(fp0);
b6d96bed 9780 }
5a5012ec 9781 break;
bf4120ad 9782 case OPC_ROUND_W_D:
5e755519 9783 check_cp1_registers(ctx, fs);
b6d96bed 9784 {
a7812ae4
PB
9785 TCGv_i32 fp32 = tcg_temp_new_i32();
9786 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
9787
9788 gen_load_fpr64(ctx, fp64, fs);
87552089
AM
9789 if (ctx->nan2008) {
9790 gen_helper_float_round_2008_w_d(fp32, cpu_env, fp64);
9791 } else {
9792 gen_helper_float_round_w_d(fp32, cpu_env, fp64);
9793 }
a7812ae4 9794 tcg_temp_free_i64(fp64);
7c979afd 9795 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 9796 tcg_temp_free_i32(fp32);
b6d96bed 9797 }
6ea83fed 9798 break;
bf4120ad 9799 case OPC_TRUNC_W_D:
5e755519 9800 check_cp1_registers(ctx, fs);
b6d96bed 9801 {
a7812ae4
PB
9802 TCGv_i32 fp32 = tcg_temp_new_i32();
9803 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
9804
9805 gen_load_fpr64(ctx, fp64, fs);
87552089
AM
9806 if (ctx->nan2008) {
9807 gen_helper_float_trunc_2008_w_d(fp32, cpu_env, fp64);
9808 } else {
9809 gen_helper_float_trunc_w_d(fp32, cpu_env, fp64);
9810 }
a7812ae4 9811 tcg_temp_free_i64(fp64);
7c979afd 9812 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 9813 tcg_temp_free_i32(fp32);
b6d96bed 9814 }
6ea83fed 9815 break;
bf4120ad 9816 case OPC_CEIL_W_D:
5e755519 9817 check_cp1_registers(ctx, fs);
b6d96bed 9818 {
a7812ae4
PB
9819 TCGv_i32 fp32 = tcg_temp_new_i32();
9820 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
9821
9822 gen_load_fpr64(ctx, fp64, fs);
87552089
AM
9823 if (ctx->nan2008) {
9824 gen_helper_float_ceil_2008_w_d(fp32, cpu_env, fp64);
9825 } else {
9826 gen_helper_float_ceil_w_d(fp32, cpu_env, fp64);
9827 }
a7812ae4 9828 tcg_temp_free_i64(fp64);
7c979afd 9829 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 9830 tcg_temp_free_i32(fp32);
b6d96bed 9831 }
6ea83fed 9832 break;
bf4120ad 9833 case OPC_FLOOR_W_D:
5e755519 9834 check_cp1_registers(ctx, fs);
b6d96bed 9835 {
a7812ae4
PB
9836 TCGv_i32 fp32 = tcg_temp_new_i32();
9837 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
9838
9839 gen_load_fpr64(ctx, fp64, fs);
87552089
AM
9840 if (ctx->nan2008) {
9841 gen_helper_float_floor_2008_w_d(fp32, cpu_env, fp64);
9842 } else {
9843 gen_helper_float_floor_w_d(fp32, cpu_env, fp64);
9844 }
a7812ae4 9845 tcg_temp_free_i64(fp64);
7c979afd 9846 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 9847 tcg_temp_free_i32(fp32);
b6d96bed 9848 }
6ea83fed 9849 break;
e7f16abb
LA
9850 case OPC_SEL_D:
9851 check_insn(ctx, ISA_MIPS32R6);
9852 gen_sel_d(ctx, op1, fd, ft, fs);
e7f16abb
LA
9853 break;
9854 case OPC_SELEQZ_D:
9855 check_insn(ctx, ISA_MIPS32R6);
9856 gen_sel_d(ctx, op1, fd, ft, fs);
e7f16abb
LA
9857 break;
9858 case OPC_SELNEZ_D:
9859 check_insn(ctx, ISA_MIPS32R6);
9860 gen_sel_d(ctx, op1, fd, ft, fs);
e7f16abb 9861 break;
bf4120ad 9862 case OPC_MOVCF_D:
fecd2646 9863 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b6d96bed 9864 gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
dd016883 9865 break;
bf4120ad 9866 case OPC_MOVZ_D:
fecd2646 9867 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a16336e4 9868 {
42a268c2 9869 TCGLabel *l1 = gen_new_label();
c9297f4d 9870 TCGv_i64 fp0;
a16336e4 9871
c9297f4d
AJ
9872 if (ft != 0) {
9873 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
9874 }
9875 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9876 gen_load_fpr64(ctx, fp0, fs);
9877 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9878 tcg_temp_free_i64(fp0);
a16336e4
TS
9879 gen_set_label(l1);
9880 }
5a5012ec 9881 break;
bf4120ad 9882 case OPC_MOVN_D:
fecd2646 9883 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a16336e4 9884 {
42a268c2 9885 TCGLabel *l1 = gen_new_label();
c9297f4d
AJ
9886 TCGv_i64 fp0;
9887
9888 if (ft != 0) {
9889 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
9890 fp0 = tcg_temp_new_i64();
9891 gen_load_fpr64(ctx, fp0, fs);
9892 gen_store_fpr64(ctx, fp0, fd);
9893 tcg_temp_free_i64(fp0);
9894 gen_set_label(l1);
9895 }
a16336e4 9896 }
6ea83fed 9897 break;
bf4120ad 9898 case OPC_RECIP_D:
ca6c7803 9899 check_cp1_registers(ctx, fs | fd);
b6d96bed 9900 {
a7812ae4 9901 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9902
9903 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9904 gen_helper_float_recip_d(fp0, cpu_env, fp0);
b6d96bed 9905 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9906 tcg_temp_free_i64(fp0);
b6d96bed 9907 }
57fa1fb3 9908 break;
bf4120ad 9909 case OPC_RSQRT_D:
ca6c7803 9910 check_cp1_registers(ctx, fs | fd);
b6d96bed 9911 {
a7812ae4 9912 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9913
9914 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9915 gen_helper_float_rsqrt_d(fp0, cpu_env, fp0);
b6d96bed 9916 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9917 tcg_temp_free_i64(fp0);
b6d96bed 9918 }
57fa1fb3 9919 break;
e7f16abb
LA
9920 case OPC_MADDF_D:
9921 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 9922 {
a7812ae4
PB
9923 TCGv_i64 fp0 = tcg_temp_new_i64();
9924 TCGv_i64 fp1 = tcg_temp_new_i64();
e7f16abb 9925 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
9926 gen_load_fpr64(ctx, fp0, fs);
9927 gen_load_fpr64(ctx, fp1, ft);
e7f16abb
LA
9928 gen_load_fpr64(ctx, fp2, fd);
9929 gen_helper_float_maddf_d(fp2, cpu_env, fp0, fp1, fp2);
9930 gen_store_fpr64(ctx, fp2, fd);
9931 tcg_temp_free_i64(fp2);
a7812ae4 9932 tcg_temp_free_i64(fp1);
a7812ae4 9933 tcg_temp_free_i64(fp0);
b6d96bed 9934 }
57fa1fb3 9935 break;
e7f16abb
LA
9936 case OPC_MSUBF_D:
9937 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 9938 {
a7812ae4 9939 TCGv_i64 fp0 = tcg_temp_new_i64();
e7f16abb
LA
9940 TCGv_i64 fp1 = tcg_temp_new_i64();
9941 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed 9942 gen_load_fpr64(ctx, fp0, fs);
e7f16abb
LA
9943 gen_load_fpr64(ctx, fp1, ft);
9944 gen_load_fpr64(ctx, fp2, fd);
9945 gen_helper_float_msubf_d(fp2, cpu_env, fp0, fp1, fp2);
9946 gen_store_fpr64(ctx, fp2, fd);
9947 tcg_temp_free_i64(fp2);
9948 tcg_temp_free_i64(fp1);
a7812ae4 9949 tcg_temp_free_i64(fp0);
b6d96bed 9950 }
57fa1fb3 9951 break;
e7f16abb
LA
9952 case OPC_RINT_D:
9953 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 9954 {
a7812ae4 9955 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 9956 gen_load_fpr64(ctx, fp0, fs);
e7f16abb 9957 gen_helper_float_rint_d(fp0, cpu_env, fp0);
b6d96bed 9958 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9959 tcg_temp_free_i64(fp0);
b6d96bed 9960 }
57fa1fb3 9961 break;
e7f16abb
LA
9962 case OPC_CLASS_D:
9963 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 9964 {
e7f16abb
LA
9965 TCGv_i64 fp0 = tcg_temp_new_i64();
9966 gen_load_fpr64(ctx, fp0, fs);
af39bc8c 9967 gen_helper_float_class_d(fp0, cpu_env, fp0);
e7f16abb
LA
9968 gen_store_fpr64(ctx, fp0, fd);
9969 tcg_temp_free_i64(fp0);
e7f16abb
LA
9970 }
9971 break;
9972 case OPC_MIN_D: /* OPC_RECIP2_D */
9973 if (ctx->insn_flags & ISA_MIPS32R6) {
9974 /* OPC_MIN_D */
a7812ae4
PB
9975 TCGv_i64 fp0 = tcg_temp_new_i64();
9976 TCGv_i64 fp1 = tcg_temp_new_i64();
e7f16abb
LA
9977 gen_load_fpr64(ctx, fp0, fs);
9978 gen_load_fpr64(ctx, fp1, ft);
9979 gen_helper_float_min_d(fp1, cpu_env, fp0, fp1);
9980 gen_store_fpr64(ctx, fp1, fd);
9981 tcg_temp_free_i64(fp1);
9982 tcg_temp_free_i64(fp0);
e7f16abb
LA
9983 } else {
9984 /* OPC_RECIP2_D */
9985 check_cp1_64bitmode(ctx);
9986 {
9987 TCGv_i64 fp0 = tcg_temp_new_i64();
9988 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed 9989
e7f16abb
LA
9990 gen_load_fpr64(ctx, fp0, fs);
9991 gen_load_fpr64(ctx, fp1, ft);
9992 gen_helper_float_recip2_d(fp0, cpu_env, fp0, fp1);
9993 tcg_temp_free_i64(fp1);
9994 gen_store_fpr64(ctx, fp0, fd);
9995 tcg_temp_free_i64(fp0);
9996 }
e7f16abb
LA
9997 }
9998 break;
9999 case OPC_MINA_D: /* OPC_RECIP1_D */
10000 if (ctx->insn_flags & ISA_MIPS32R6) {
10001 /* OPC_MINA_D */
10002 TCGv_i64 fp0 = tcg_temp_new_i64();
10003 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
10004 gen_load_fpr64(ctx, fp0, fs);
10005 gen_load_fpr64(ctx, fp1, ft);
e7f16abb
LA
10006 gen_helper_float_mina_d(fp1, cpu_env, fp0, fp1);
10007 gen_store_fpr64(ctx, fp1, fd);
10008 tcg_temp_free_i64(fp1);
10009 tcg_temp_free_i64(fp0);
e7f16abb
LA
10010 } else {
10011 /* OPC_RECIP1_D */
10012 check_cp1_64bitmode(ctx);
10013 {
10014 TCGv_i64 fp0 = tcg_temp_new_i64();
10015
10016 gen_load_fpr64(ctx, fp0, fs);
10017 gen_helper_float_recip1_d(fp0, cpu_env, fp0);
10018 gen_store_fpr64(ctx, fp0, fd);
10019 tcg_temp_free_i64(fp0);
10020 }
e7f16abb
LA
10021 }
10022 break;
10023 case OPC_MAX_D: /* OPC_RSQRT1_D */
10024 if (ctx->insn_flags & ISA_MIPS32R6) {
10025 /* OPC_MAX_D */
10026 TCGv_i64 fp0 = tcg_temp_new_i64();
10027 TCGv_i64 fp1 = tcg_temp_new_i64();
10028 gen_load_fpr64(ctx, fp0, fs);
10029 gen_load_fpr64(ctx, fp1, ft);
10030 gen_helper_float_max_d(fp1, cpu_env, fp0, fp1);
10031 gen_store_fpr64(ctx, fp1, fd);
a7812ae4 10032 tcg_temp_free_i64(fp1);
a7812ae4 10033 tcg_temp_free_i64(fp0);
e7f16abb
LA
10034 } else {
10035 /* OPC_RSQRT1_D */
10036 check_cp1_64bitmode(ctx);
10037 {
10038 TCGv_i64 fp0 = tcg_temp_new_i64();
10039
10040 gen_load_fpr64(ctx, fp0, fs);
10041 gen_helper_float_rsqrt1_d(fp0, cpu_env, fp0);
10042 gen_store_fpr64(ctx, fp0, fd);
10043 tcg_temp_free_i64(fp0);
10044 }
e7f16abb
LA
10045 }
10046 break;
10047 case OPC_MAXA_D: /* OPC_RSQRT2_D */
10048 if (ctx->insn_flags & ISA_MIPS32R6) {
10049 /* OPC_MAXA_D */
10050 TCGv_i64 fp0 = tcg_temp_new_i64();
10051 TCGv_i64 fp1 = tcg_temp_new_i64();
10052 gen_load_fpr64(ctx, fp0, fs);
10053 gen_load_fpr64(ctx, fp1, ft);
10054 gen_helper_float_maxa_d(fp1, cpu_env, fp0, fp1);
10055 gen_store_fpr64(ctx, fp1, fd);
10056 tcg_temp_free_i64(fp1);
10057 tcg_temp_free_i64(fp0);
e7f16abb
LA
10058 } else {
10059 /* OPC_RSQRT2_D */
10060 check_cp1_64bitmode(ctx);
10061 {
10062 TCGv_i64 fp0 = tcg_temp_new_i64();
10063 TCGv_i64 fp1 = tcg_temp_new_i64();
10064
10065 gen_load_fpr64(ctx, fp0, fs);
10066 gen_load_fpr64(ctx, fp1, ft);
10067 gen_helper_float_rsqrt2_d(fp0, cpu_env, fp0, fp1);
10068 tcg_temp_free_i64(fp1);
10069 gen_store_fpr64(ctx, fp0, fd);
10070 tcg_temp_free_i64(fp0);
10071 }
b6d96bed 10072 }
57fa1fb3 10073 break;
bf4120ad
NF
10074 case OPC_CMP_F_D:
10075 case OPC_CMP_UN_D:
10076 case OPC_CMP_EQ_D:
10077 case OPC_CMP_UEQ_D:
10078 case OPC_CMP_OLT_D:
10079 case OPC_CMP_ULT_D:
10080 case OPC_CMP_OLE_D:
10081 case OPC_CMP_ULE_D:
10082 case OPC_CMP_SF_D:
10083 case OPC_CMP_NGLE_D:
10084 case OPC_CMP_SEQ_D:
10085 case OPC_CMP_NGL_D:
10086 case OPC_CMP_LT_D:
10087 case OPC_CMP_NGE_D:
10088 case OPC_CMP_LE_D:
10089 case OPC_CMP_NGT_D:
fecd2646 10090 check_insn_opc_removed(ctx, ISA_MIPS32R6);
8153667c
NF
10091 if (ctx->opcode & (1 << 6)) {
10092 gen_cmpabs_d(ctx, func-48, ft, fs, cc);
8153667c
NF
10093 } else {
10094 gen_cmp_d(ctx, func-48, ft, fs, cc);
5a1e8ffb 10095 }
6ea83fed 10096 break;
bf4120ad 10097 case OPC_CVT_S_D:
5e755519 10098 check_cp1_registers(ctx, fs);
b6d96bed 10099 {
a7812ae4
PB
10100 TCGv_i32 fp32 = tcg_temp_new_i32();
10101 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
10102
10103 gen_load_fpr64(ctx, fp64, fs);
895c2d04 10104 gen_helper_float_cvts_d(fp32, cpu_env, fp64);
a7812ae4 10105 tcg_temp_free_i64(fp64);
7c979afd 10106 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 10107 tcg_temp_free_i32(fp32);
b6d96bed 10108 }
5a5012ec 10109 break;
bf4120ad 10110 case OPC_CVT_W_D:
5e755519 10111 check_cp1_registers(ctx, fs);
b6d96bed 10112 {
a7812ae4
PB
10113 TCGv_i32 fp32 = tcg_temp_new_i32();
10114 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
10115
10116 gen_load_fpr64(ctx, fp64, fs);
87552089
AM
10117 if (ctx->nan2008) {
10118 gen_helper_float_cvt_2008_w_d(fp32, cpu_env, fp64);
10119 } else {
10120 gen_helper_float_cvt_w_d(fp32, cpu_env, fp64);
10121 }
a7812ae4 10122 tcg_temp_free_i64(fp64);
7c979afd 10123 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 10124 tcg_temp_free_i32(fp32);
b6d96bed 10125 }
5a5012ec 10126 break;
bf4120ad 10127 case OPC_CVT_L_D:
5e755519 10128 check_cp1_64bitmode(ctx);
b6d96bed 10129 {
a7812ae4 10130 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
10131
10132 gen_load_fpr64(ctx, fp0, fs);
87552089
AM
10133 if (ctx->nan2008) {
10134 gen_helper_float_cvt_2008_l_d(fp0, cpu_env, fp0);
10135 } else {
10136 gen_helper_float_cvt_l_d(fp0, cpu_env, fp0);
10137 }
b6d96bed 10138 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10139 tcg_temp_free_i64(fp0);
b6d96bed 10140 }
5a5012ec 10141 break;
bf4120ad 10142 case OPC_CVT_S_W:
b6d96bed 10143 {
a7812ae4 10144 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 10145
7c979afd 10146 gen_load_fpr32(ctx, fp0, fs);
895c2d04 10147 gen_helper_float_cvts_w(fp0, cpu_env, fp0);
7c979afd 10148 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 10149 tcg_temp_free_i32(fp0);
b6d96bed 10150 }
6ea83fed 10151 break;
bf4120ad 10152 case OPC_CVT_D_W:
5e755519 10153 check_cp1_registers(ctx, fd);
b6d96bed 10154 {
a7812ae4
PB
10155 TCGv_i32 fp32 = tcg_temp_new_i32();
10156 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 10157
7c979afd 10158 gen_load_fpr32(ctx, fp32, fs);
895c2d04 10159 gen_helper_float_cvtd_w(fp64, cpu_env, fp32);
a7812ae4 10160 tcg_temp_free_i32(fp32);
b6d96bed 10161 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 10162 tcg_temp_free_i64(fp64);
b6d96bed 10163 }
5a5012ec 10164 break;
bf4120ad 10165 case OPC_CVT_S_L:
5e755519 10166 check_cp1_64bitmode(ctx);
b6d96bed 10167 {
a7812ae4
PB
10168 TCGv_i32 fp32 = tcg_temp_new_i32();
10169 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
10170
10171 gen_load_fpr64(ctx, fp64, fs);
895c2d04 10172 gen_helper_float_cvts_l(fp32, cpu_env, fp64);
a7812ae4 10173 tcg_temp_free_i64(fp64);
7c979afd 10174 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 10175 tcg_temp_free_i32(fp32);
b6d96bed 10176 }
5a5012ec 10177 break;
bf4120ad 10178 case OPC_CVT_D_L:
5e755519 10179 check_cp1_64bitmode(ctx);
b6d96bed 10180 {
a7812ae4 10181 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
10182
10183 gen_load_fpr64(ctx, fp0, fs);
895c2d04 10184 gen_helper_float_cvtd_l(fp0, cpu_env, fp0);
b6d96bed 10185 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10186 tcg_temp_free_i64(fp0);
b6d96bed 10187 }
5a5012ec 10188 break;
bf4120ad 10189 case OPC_CVT_PS_PW:
e29c9628 10190 check_ps(ctx);
b6d96bed 10191 {
a7812ae4 10192 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
10193
10194 gen_load_fpr64(ctx, fp0, fs);
895c2d04 10195 gen_helper_float_cvtps_pw(fp0, cpu_env, fp0);
b6d96bed 10196 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10197 tcg_temp_free_i64(fp0);
b6d96bed 10198 }
5a5012ec 10199 break;
bf4120ad 10200 case OPC_ADD_PS:
e29c9628 10201 check_ps(ctx);
b6d96bed 10202 {
a7812ae4
PB
10203 TCGv_i64 fp0 = tcg_temp_new_i64();
10204 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
10205
10206 gen_load_fpr64(ctx, fp0, fs);
10207 gen_load_fpr64(ctx, fp1, ft);
895c2d04 10208 gen_helper_float_add_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 10209 tcg_temp_free_i64(fp1);
b6d96bed 10210 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10211 tcg_temp_free_i64(fp0);
b6d96bed 10212 }
6ea83fed 10213 break;
bf4120ad 10214 case OPC_SUB_PS:
e29c9628 10215 check_ps(ctx);
b6d96bed 10216 {
a7812ae4
PB
10217 TCGv_i64 fp0 = tcg_temp_new_i64();
10218 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
10219
10220 gen_load_fpr64(ctx, fp0, fs);
10221 gen_load_fpr64(ctx, fp1, ft);
895c2d04 10222 gen_helper_float_sub_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 10223 tcg_temp_free_i64(fp1);
b6d96bed 10224 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10225 tcg_temp_free_i64(fp0);
b6d96bed 10226 }
6ea83fed 10227 break;
bf4120ad 10228 case OPC_MUL_PS:
e29c9628 10229 check_ps(ctx);
b6d96bed 10230 {
a7812ae4
PB
10231 TCGv_i64 fp0 = tcg_temp_new_i64();
10232 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
10233
10234 gen_load_fpr64(ctx, fp0, fs);
10235 gen_load_fpr64(ctx, fp1, ft);
895c2d04 10236 gen_helper_float_mul_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 10237 tcg_temp_free_i64(fp1);
b6d96bed 10238 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10239 tcg_temp_free_i64(fp0);
b6d96bed 10240 }
6ea83fed 10241 break;
bf4120ad 10242 case OPC_ABS_PS:
e29c9628 10243 check_ps(ctx);
b6d96bed 10244 {
a7812ae4 10245 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
10246
10247 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 10248 gen_helper_float_abs_ps(fp0, fp0);
b6d96bed 10249 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10250 tcg_temp_free_i64(fp0);
b6d96bed 10251 }
6ea83fed 10252 break;
bf4120ad 10253 case OPC_MOV_PS:
e29c9628 10254 check_ps(ctx);
b6d96bed 10255 {
a7812ae4 10256 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
10257
10258 gen_load_fpr64(ctx, fp0, fs);
10259 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10260 tcg_temp_free_i64(fp0);
b6d96bed 10261 }
6ea83fed 10262 break;
bf4120ad 10263 case OPC_NEG_PS:
e29c9628 10264 check_ps(ctx);
b6d96bed 10265 {
a7812ae4 10266 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
10267
10268 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 10269 gen_helper_float_chs_ps(fp0, fp0);
b6d96bed 10270 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10271 tcg_temp_free_i64(fp0);
b6d96bed 10272 }
6ea83fed 10273 break;
bf4120ad 10274 case OPC_MOVCF_PS:
e29c9628 10275 check_ps(ctx);
7f6613ce 10276 gen_movcf_ps(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
6ea83fed 10277 break;
bf4120ad 10278 case OPC_MOVZ_PS:
e29c9628 10279 check_ps(ctx);
a16336e4 10280 {
42a268c2 10281 TCGLabel *l1 = gen_new_label();
30a3848b 10282 TCGv_i64 fp0;
a16336e4 10283
c9297f4d
AJ
10284 if (ft != 0)
10285 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
10286 fp0 = tcg_temp_new_i64();
10287 gen_load_fpr64(ctx, fp0, fs);
10288 gen_store_fpr64(ctx, fp0, fd);
10289 tcg_temp_free_i64(fp0);
a16336e4
TS
10290 gen_set_label(l1);
10291 }
6ea83fed 10292 break;
bf4120ad 10293 case OPC_MOVN_PS:
e29c9628 10294 check_ps(ctx);
a16336e4 10295 {
42a268c2 10296 TCGLabel *l1 = gen_new_label();
30a3848b 10297 TCGv_i64 fp0;
c9297f4d
AJ
10298
10299 if (ft != 0) {
10300 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
10301 fp0 = tcg_temp_new_i64();
10302 gen_load_fpr64(ctx, fp0, fs);
10303 gen_store_fpr64(ctx, fp0, fd);
10304 tcg_temp_free_i64(fp0);
10305 gen_set_label(l1);
10306 }
a16336e4 10307 }
6ea83fed 10308 break;
bf4120ad 10309 case OPC_ADDR_PS:
e29c9628 10310 check_ps(ctx);
b6d96bed 10311 {
a7812ae4
PB
10312 TCGv_i64 fp0 = tcg_temp_new_i64();
10313 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
10314
10315 gen_load_fpr64(ctx, fp0, ft);
10316 gen_load_fpr64(ctx, fp1, fs);
895c2d04 10317 gen_helper_float_addr_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 10318 tcg_temp_free_i64(fp1);
b6d96bed 10319 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10320 tcg_temp_free_i64(fp0);
b6d96bed 10321 }
fbcc6828 10322 break;
bf4120ad 10323 case OPC_MULR_PS:
e29c9628 10324 check_ps(ctx);
b6d96bed 10325 {
a7812ae4
PB
10326 TCGv_i64 fp0 = tcg_temp_new_i64();
10327 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
10328
10329 gen_load_fpr64(ctx, fp0, ft);
10330 gen_load_fpr64(ctx, fp1, fs);
895c2d04 10331 gen_helper_float_mulr_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 10332 tcg_temp_free_i64(fp1);
b6d96bed 10333 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10334 tcg_temp_free_i64(fp0);
b6d96bed 10335 }
57fa1fb3 10336 break;
bf4120ad 10337 case OPC_RECIP2_PS:
e29c9628 10338 check_ps(ctx);
b6d96bed 10339 {
a7812ae4
PB
10340 TCGv_i64 fp0 = tcg_temp_new_i64();
10341 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
10342
10343 gen_load_fpr64(ctx, fp0, fs);
d22d7289 10344 gen_load_fpr64(ctx, fp1, ft);
895c2d04 10345 gen_helper_float_recip2_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 10346 tcg_temp_free_i64(fp1);
b6d96bed 10347 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10348 tcg_temp_free_i64(fp0);
b6d96bed 10349 }
57fa1fb3 10350 break;
bf4120ad 10351 case OPC_RECIP1_PS:
e29c9628 10352 check_ps(ctx);
b6d96bed 10353 {
a7812ae4 10354 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
10355
10356 gen_load_fpr64(ctx, fp0, fs);
895c2d04 10357 gen_helper_float_recip1_ps(fp0, cpu_env, fp0);
b6d96bed 10358 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10359 tcg_temp_free_i64(fp0);
b6d96bed 10360 }
57fa1fb3 10361 break;
bf4120ad 10362 case OPC_RSQRT1_PS:
e29c9628 10363 check_ps(ctx);
b6d96bed 10364 {
a7812ae4 10365 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
10366
10367 gen_load_fpr64(ctx, fp0, fs);
895c2d04 10368 gen_helper_float_rsqrt1_ps(fp0, cpu_env, fp0);
b6d96bed 10369 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10370 tcg_temp_free_i64(fp0);
b6d96bed 10371 }
57fa1fb3 10372 break;
bf4120ad 10373 case OPC_RSQRT2_PS:
e29c9628 10374 check_ps(ctx);
b6d96bed 10375 {
a7812ae4
PB
10376 TCGv_i64 fp0 = tcg_temp_new_i64();
10377 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
10378
10379 gen_load_fpr64(ctx, fp0, fs);
10380 gen_load_fpr64(ctx, fp1, ft);
895c2d04 10381 gen_helper_float_rsqrt2_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 10382 tcg_temp_free_i64(fp1);
b6d96bed 10383 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10384 tcg_temp_free_i64(fp0);
b6d96bed 10385 }
57fa1fb3 10386 break;
bf4120ad 10387 case OPC_CVT_S_PU:
5e755519 10388 check_cp1_64bitmode(ctx);
b6d96bed 10389 {
a7812ae4 10390 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 10391
7f6613ce 10392 gen_load_fpr32h(ctx, fp0, fs);
895c2d04 10393 gen_helper_float_cvts_pu(fp0, cpu_env, fp0);
7c979afd 10394 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 10395 tcg_temp_free_i32(fp0);
b6d96bed 10396 }
dd016883 10397 break;
bf4120ad 10398 case OPC_CVT_PW_PS:
e29c9628 10399 check_ps(ctx);
b6d96bed 10400 {
a7812ae4 10401 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
10402
10403 gen_load_fpr64(ctx, fp0, fs);
895c2d04 10404 gen_helper_float_cvtpw_ps(fp0, cpu_env, fp0);
b6d96bed 10405 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10406 tcg_temp_free_i64(fp0);
b6d96bed 10407 }
6ea83fed 10408 break;
bf4120ad 10409 case OPC_CVT_S_PL:
5e755519 10410 check_cp1_64bitmode(ctx);
b6d96bed 10411 {
a7812ae4 10412 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 10413
7c979afd 10414 gen_load_fpr32(ctx, fp0, fs);
895c2d04 10415 gen_helper_float_cvts_pl(fp0, cpu_env, fp0);
7c979afd 10416 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 10417 tcg_temp_free_i32(fp0);
b6d96bed 10418 }
6ea83fed 10419 break;
bf4120ad 10420 case OPC_PLL_PS:
e29c9628 10421 check_ps(ctx);
b6d96bed 10422 {
a7812ae4
PB
10423 TCGv_i32 fp0 = tcg_temp_new_i32();
10424 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 10425
7c979afd
LA
10426 gen_load_fpr32(ctx, fp0, fs);
10427 gen_load_fpr32(ctx, fp1, ft);
7f6613ce 10428 gen_store_fpr32h(ctx, fp0, fd);
7c979afd 10429 gen_store_fpr32(ctx, fp1, fd);
a7812ae4
PB
10430 tcg_temp_free_i32(fp0);
10431 tcg_temp_free_i32(fp1);
b6d96bed 10432 }
6ea83fed 10433 break;
bf4120ad 10434 case OPC_PLU_PS:
e29c9628 10435 check_ps(ctx);
b6d96bed 10436 {
a7812ae4
PB
10437 TCGv_i32 fp0 = tcg_temp_new_i32();
10438 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 10439
7c979afd 10440 gen_load_fpr32(ctx, fp0, fs);
7f6613ce 10441 gen_load_fpr32h(ctx, fp1, ft);
7c979afd 10442 gen_store_fpr32(ctx, fp1, fd);
7f6613ce 10443 gen_store_fpr32h(ctx, fp0, fd);
a7812ae4
PB
10444 tcg_temp_free_i32(fp0);
10445 tcg_temp_free_i32(fp1);
b6d96bed 10446 }
5a5012ec 10447 break;
bf4120ad 10448 case OPC_PUL_PS:
e29c9628 10449 check_ps(ctx);
b6d96bed 10450 {
a7812ae4
PB
10451 TCGv_i32 fp0 = tcg_temp_new_i32();
10452 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 10453
7f6613ce 10454 gen_load_fpr32h(ctx, fp0, fs);
7c979afd
LA
10455 gen_load_fpr32(ctx, fp1, ft);
10456 gen_store_fpr32(ctx, fp1, fd);
7f6613ce 10457 gen_store_fpr32h(ctx, fp0, fd);
a7812ae4
PB
10458 tcg_temp_free_i32(fp0);
10459 tcg_temp_free_i32(fp1);
b6d96bed 10460 }
5a5012ec 10461 break;
bf4120ad 10462 case OPC_PUU_PS:
e29c9628 10463 check_ps(ctx);
b6d96bed 10464 {
a7812ae4
PB
10465 TCGv_i32 fp0 = tcg_temp_new_i32();
10466 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 10467
7f6613ce
PJ
10468 gen_load_fpr32h(ctx, fp0, fs);
10469 gen_load_fpr32h(ctx, fp1, ft);
7c979afd 10470 gen_store_fpr32(ctx, fp1, fd);
7f6613ce 10471 gen_store_fpr32h(ctx, fp0, fd);
a7812ae4
PB
10472 tcg_temp_free_i32(fp0);
10473 tcg_temp_free_i32(fp1);
b6d96bed 10474 }
5a5012ec 10475 break;
bf4120ad
NF
10476 case OPC_CMP_F_PS:
10477 case OPC_CMP_UN_PS:
10478 case OPC_CMP_EQ_PS:
10479 case OPC_CMP_UEQ_PS:
10480 case OPC_CMP_OLT_PS:
10481 case OPC_CMP_ULT_PS:
10482 case OPC_CMP_OLE_PS:
10483 case OPC_CMP_ULE_PS:
10484 case OPC_CMP_SF_PS:
10485 case OPC_CMP_NGLE_PS:
10486 case OPC_CMP_SEQ_PS:
10487 case OPC_CMP_NGL_PS:
10488 case OPC_CMP_LT_PS:
10489 case OPC_CMP_NGE_PS:
10490 case OPC_CMP_LE_PS:
10491 case OPC_CMP_NGT_PS:
8153667c
NF
10492 if (ctx->opcode & (1 << 6)) {
10493 gen_cmpabs_ps(ctx, func-48, ft, fs, cc);
8153667c
NF
10494 } else {
10495 gen_cmp_ps(ctx, func-48, ft, fs, cc);
5a1e8ffb 10496 }
6ea83fed 10497 break;
5a5012ec 10498 default:
9d68ac14 10499 MIPS_INVAL("farith");
9c708c7f 10500 generate_exception_end(ctx, EXCP_RI);
6ea83fed
FB
10501 return;
10502 }
6ea83fed 10503}
6af0bf9c 10504
5a5012ec 10505/* Coprocessor 3 (FPU) */
5e755519
TS
10506static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
10507 int fd, int fs, int base, int index)
7a387fff 10508{
4e2474d6 10509 TCGv t0 = tcg_temp_new();
7a387fff 10510
93b12ccc 10511 if (base == 0) {
6c5c1e20 10512 gen_load_gpr(t0, index);
93b12ccc 10513 } else if (index == 0) {
6c5c1e20 10514 gen_load_gpr(t0, base);
93b12ccc 10515 } else {
05168674 10516 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]);
93b12ccc 10517 }
5a5012ec 10518 /* Don't do NOP if destination is zero: we must perform the actual
ead9360e 10519 memory access. */
5a5012ec
TS
10520 switch (opc) {
10521 case OPC_LWXC1:
8c0ab41f 10522 check_cop1x(ctx);
b6d96bed 10523 {
a7812ae4 10524 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 10525
5f68f5ae 10526 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
585c88d5 10527 tcg_gen_trunc_tl_i32(fp0, t0);
7c979afd 10528 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 10529 tcg_temp_free_i32(fp0);
b6d96bed 10530 }
5a5012ec
TS
10531 break;
10532 case OPC_LDXC1:
8c0ab41f
AJ
10533 check_cop1x(ctx);
10534 check_cp1_registers(ctx, fd);
b6d96bed 10535 {
a7812ae4 10536 TCGv_i64 fp0 = tcg_temp_new_i64();
5f68f5ae 10537 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
b6d96bed 10538 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10539 tcg_temp_free_i64(fp0);
b6d96bed 10540 }
5a5012ec
TS
10541 break;
10542 case OPC_LUXC1:
8c0ab41f 10543 check_cp1_64bitmode(ctx);
6c5c1e20 10544 tcg_gen_andi_tl(t0, t0, ~0x7);
b6d96bed 10545 {
a7812ae4 10546 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 10547
5f68f5ae 10548 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
b6d96bed 10549 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10550 tcg_temp_free_i64(fp0);
b6d96bed 10551 }
5a5012ec
TS
10552 break;
10553 case OPC_SWXC1:
8c0ab41f 10554 check_cop1x(ctx);
b6d96bed 10555 {
a7812ae4 10556 TCGv_i32 fp0 = tcg_temp_new_i32();
7c979afd 10557 gen_load_fpr32(ctx, fp0, fs);
5f68f5ae 10558 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL);
a7812ae4 10559 tcg_temp_free_i32(fp0);
b6d96bed 10560 }
5a5012ec
TS
10561 break;
10562 case OPC_SDXC1:
8c0ab41f
AJ
10563 check_cop1x(ctx);
10564 check_cp1_registers(ctx, fs);
b6d96bed 10565 {
a7812ae4 10566 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 10567 gen_load_fpr64(ctx, fp0, fs);
5f68f5ae 10568 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
a7812ae4 10569 tcg_temp_free_i64(fp0);
b6d96bed 10570 }
5a5012ec
TS
10571 break;
10572 case OPC_SUXC1:
8c0ab41f 10573 check_cp1_64bitmode(ctx);
6c5c1e20 10574 tcg_gen_andi_tl(t0, t0, ~0x7);
b6d96bed 10575 {
a7812ae4 10576 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 10577 gen_load_fpr64(ctx, fp0, fs);
5f68f5ae 10578 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
a7812ae4 10579 tcg_temp_free_i64(fp0);
b6d96bed 10580 }
5a5012ec 10581 break;
5a5012ec 10582 }
6c5c1e20 10583 tcg_temp_free(t0);
5a5012ec
TS
10584}
10585
5e755519
TS
10586static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
10587 int fd, int fr, int fs, int ft)
5a5012ec 10588{
5a5012ec
TS
10589 switch (opc) {
10590 case OPC_ALNV_PS:
e29c9628 10591 check_ps(ctx);
a16336e4 10592 {
a7812ae4 10593 TCGv t0 = tcg_temp_local_new();
c905fdac
AJ
10594 TCGv_i32 fp = tcg_temp_new_i32();
10595 TCGv_i32 fph = tcg_temp_new_i32();
42a268c2
RH
10596 TCGLabel *l1 = gen_new_label();
10597 TCGLabel *l2 = gen_new_label();
a16336e4 10598
6c5c1e20
TS
10599 gen_load_gpr(t0, fr);
10600 tcg_gen_andi_tl(t0, t0, 0x7);
6c5c1e20
TS
10601
10602 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
7c979afd 10603 gen_load_fpr32(ctx, fp, fs);
7f6613ce 10604 gen_load_fpr32h(ctx, fph, fs);
7c979afd 10605 gen_store_fpr32(ctx, fp, fd);
7f6613ce 10606 gen_store_fpr32h(ctx, fph, fd);
a16336e4
TS
10607 tcg_gen_br(l2);
10608 gen_set_label(l1);
6c5c1e20
TS
10609 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
10610 tcg_temp_free(t0);
a16336e4 10611#ifdef TARGET_WORDS_BIGENDIAN
7c979afd 10612 gen_load_fpr32(ctx, fp, fs);
7f6613ce
PJ
10613 gen_load_fpr32h(ctx, fph, ft);
10614 gen_store_fpr32h(ctx, fp, fd);
7c979afd 10615 gen_store_fpr32(ctx, fph, fd);
a16336e4 10616#else
7f6613ce 10617 gen_load_fpr32h(ctx, fph, fs);
7c979afd
LA
10618 gen_load_fpr32(ctx, fp, ft);
10619 gen_store_fpr32(ctx, fph, fd);
7f6613ce 10620 gen_store_fpr32h(ctx, fp, fd);
a16336e4
TS
10621#endif
10622 gen_set_label(l2);
c905fdac
AJ
10623 tcg_temp_free_i32(fp);
10624 tcg_temp_free_i32(fph);
a16336e4 10625 }
5a5012ec
TS
10626 break;
10627 case OPC_MADD_S:
b8aa4598 10628 check_cop1x(ctx);
b6d96bed 10629 {
a7812ae4
PB
10630 TCGv_i32 fp0 = tcg_temp_new_i32();
10631 TCGv_i32 fp1 = tcg_temp_new_i32();
10632 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed 10633
7c979afd
LA
10634 gen_load_fpr32(ctx, fp0, fs);
10635 gen_load_fpr32(ctx, fp1, ft);
10636 gen_load_fpr32(ctx, fp2, fr);
b3d6cd44 10637 gen_helper_float_madd_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10638 tcg_temp_free_i32(fp0);
10639 tcg_temp_free_i32(fp1);
7c979afd 10640 gen_store_fpr32(ctx, fp2, fd);
a7812ae4 10641 tcg_temp_free_i32(fp2);
b6d96bed 10642 }
5a5012ec
TS
10643 break;
10644 case OPC_MADD_D:
b8aa4598
TS
10645 check_cop1x(ctx);
10646 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 10647 {
a7812ae4
PB
10648 TCGv_i64 fp0 = tcg_temp_new_i64();
10649 TCGv_i64 fp1 = tcg_temp_new_i64();
10650 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10651
10652 gen_load_fpr64(ctx, fp0, fs);
10653 gen_load_fpr64(ctx, fp1, ft);
10654 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10655 gen_helper_float_madd_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10656 tcg_temp_free_i64(fp0);
10657 tcg_temp_free_i64(fp1);
b6d96bed 10658 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10659 tcg_temp_free_i64(fp2);
b6d96bed 10660 }
5a5012ec
TS
10661 break;
10662 case OPC_MADD_PS:
e29c9628 10663 check_ps(ctx);
b6d96bed 10664 {
a7812ae4
PB
10665 TCGv_i64 fp0 = tcg_temp_new_i64();
10666 TCGv_i64 fp1 = tcg_temp_new_i64();
10667 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10668
10669 gen_load_fpr64(ctx, fp0, fs);
10670 gen_load_fpr64(ctx, fp1, ft);
10671 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10672 gen_helper_float_madd_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10673 tcg_temp_free_i64(fp0);
10674 tcg_temp_free_i64(fp1);
b6d96bed 10675 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10676 tcg_temp_free_i64(fp2);
b6d96bed 10677 }
5a5012ec
TS
10678 break;
10679 case OPC_MSUB_S:
b8aa4598 10680 check_cop1x(ctx);
b6d96bed 10681 {
a7812ae4
PB
10682 TCGv_i32 fp0 = tcg_temp_new_i32();
10683 TCGv_i32 fp1 = tcg_temp_new_i32();
10684 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed 10685
7c979afd
LA
10686 gen_load_fpr32(ctx, fp0, fs);
10687 gen_load_fpr32(ctx, fp1, ft);
10688 gen_load_fpr32(ctx, fp2, fr);
b3d6cd44 10689 gen_helper_float_msub_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10690 tcg_temp_free_i32(fp0);
10691 tcg_temp_free_i32(fp1);
7c979afd 10692 gen_store_fpr32(ctx, fp2, fd);
a7812ae4 10693 tcg_temp_free_i32(fp2);
b6d96bed 10694 }
5a5012ec
TS
10695 break;
10696 case OPC_MSUB_D:
b8aa4598
TS
10697 check_cop1x(ctx);
10698 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 10699 {
a7812ae4
PB
10700 TCGv_i64 fp0 = tcg_temp_new_i64();
10701 TCGv_i64 fp1 = tcg_temp_new_i64();
10702 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10703
10704 gen_load_fpr64(ctx, fp0, fs);
10705 gen_load_fpr64(ctx, fp1, ft);
10706 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10707 gen_helper_float_msub_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10708 tcg_temp_free_i64(fp0);
10709 tcg_temp_free_i64(fp1);
b6d96bed 10710 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10711 tcg_temp_free_i64(fp2);
b6d96bed 10712 }
5a5012ec
TS
10713 break;
10714 case OPC_MSUB_PS:
e29c9628 10715 check_ps(ctx);
b6d96bed 10716 {
a7812ae4
PB
10717 TCGv_i64 fp0 = tcg_temp_new_i64();
10718 TCGv_i64 fp1 = tcg_temp_new_i64();
10719 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10720
10721 gen_load_fpr64(ctx, fp0, fs);
10722 gen_load_fpr64(ctx, fp1, ft);
10723 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10724 gen_helper_float_msub_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10725 tcg_temp_free_i64(fp0);
10726 tcg_temp_free_i64(fp1);
b6d96bed 10727 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10728 tcg_temp_free_i64(fp2);
b6d96bed 10729 }
5a5012ec
TS
10730 break;
10731 case OPC_NMADD_S:
b8aa4598 10732 check_cop1x(ctx);
b6d96bed 10733 {
a7812ae4
PB
10734 TCGv_i32 fp0 = tcg_temp_new_i32();
10735 TCGv_i32 fp1 = tcg_temp_new_i32();
10736 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed 10737
7c979afd
LA
10738 gen_load_fpr32(ctx, fp0, fs);
10739 gen_load_fpr32(ctx, fp1, ft);
10740 gen_load_fpr32(ctx, fp2, fr);
b3d6cd44 10741 gen_helper_float_nmadd_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10742 tcg_temp_free_i32(fp0);
10743 tcg_temp_free_i32(fp1);
7c979afd 10744 gen_store_fpr32(ctx, fp2, fd);
a7812ae4 10745 tcg_temp_free_i32(fp2);
b6d96bed 10746 }
5a5012ec
TS
10747 break;
10748 case OPC_NMADD_D:
b8aa4598
TS
10749 check_cop1x(ctx);
10750 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 10751 {
a7812ae4
PB
10752 TCGv_i64 fp0 = tcg_temp_new_i64();
10753 TCGv_i64 fp1 = tcg_temp_new_i64();
10754 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10755
10756 gen_load_fpr64(ctx, fp0, fs);
10757 gen_load_fpr64(ctx, fp1, ft);
10758 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10759 gen_helper_float_nmadd_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10760 tcg_temp_free_i64(fp0);
10761 tcg_temp_free_i64(fp1);
b6d96bed 10762 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10763 tcg_temp_free_i64(fp2);
b6d96bed 10764 }
5a5012ec
TS
10765 break;
10766 case OPC_NMADD_PS:
e29c9628 10767 check_ps(ctx);
b6d96bed 10768 {
a7812ae4
PB
10769 TCGv_i64 fp0 = tcg_temp_new_i64();
10770 TCGv_i64 fp1 = tcg_temp_new_i64();
10771 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10772
10773 gen_load_fpr64(ctx, fp0, fs);
10774 gen_load_fpr64(ctx, fp1, ft);
10775 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10776 gen_helper_float_nmadd_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10777 tcg_temp_free_i64(fp0);
10778 tcg_temp_free_i64(fp1);
b6d96bed 10779 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10780 tcg_temp_free_i64(fp2);
b6d96bed 10781 }
5a5012ec
TS
10782 break;
10783 case OPC_NMSUB_S:
b8aa4598 10784 check_cop1x(ctx);
b6d96bed 10785 {
a7812ae4
PB
10786 TCGv_i32 fp0 = tcg_temp_new_i32();
10787 TCGv_i32 fp1 = tcg_temp_new_i32();
10788 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed 10789
7c979afd
LA
10790 gen_load_fpr32(ctx, fp0, fs);
10791 gen_load_fpr32(ctx, fp1, ft);
10792 gen_load_fpr32(ctx, fp2, fr);
b3d6cd44 10793 gen_helper_float_nmsub_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10794 tcg_temp_free_i32(fp0);
10795 tcg_temp_free_i32(fp1);
7c979afd 10796 gen_store_fpr32(ctx, fp2, fd);
a7812ae4 10797 tcg_temp_free_i32(fp2);
b6d96bed 10798 }
5a5012ec
TS
10799 break;
10800 case OPC_NMSUB_D:
b8aa4598
TS
10801 check_cop1x(ctx);
10802 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 10803 {
a7812ae4
PB
10804 TCGv_i64 fp0 = tcg_temp_new_i64();
10805 TCGv_i64 fp1 = tcg_temp_new_i64();
10806 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10807
10808 gen_load_fpr64(ctx, fp0, fs);
10809 gen_load_fpr64(ctx, fp1, ft);
10810 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10811 gen_helper_float_nmsub_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10812 tcg_temp_free_i64(fp0);
10813 tcg_temp_free_i64(fp1);
b6d96bed 10814 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10815 tcg_temp_free_i64(fp2);
b6d96bed 10816 }
5a5012ec
TS
10817 break;
10818 case OPC_NMSUB_PS:
e29c9628 10819 check_ps(ctx);
b6d96bed 10820 {
a7812ae4
PB
10821 TCGv_i64 fp0 = tcg_temp_new_i64();
10822 TCGv_i64 fp1 = tcg_temp_new_i64();
10823 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10824
10825 gen_load_fpr64(ctx, fp0, fs);
10826 gen_load_fpr64(ctx, fp1, ft);
10827 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10828 gen_helper_float_nmsub_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10829 tcg_temp_free_i64(fp0);
10830 tcg_temp_free_i64(fp1);
b6d96bed 10831 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10832 tcg_temp_free_i64(fp2);
b6d96bed 10833 }
5a5012ec 10834 break;
923617a3 10835 default:
9d68ac14 10836 MIPS_INVAL("flt3_arith");
9c708c7f 10837 generate_exception_end(ctx, EXCP_RI);
5a5012ec
TS
10838 return;
10839 }
7a387fff
TS
10840}
10841
b00c7218 10842static void gen_rdhwr(DisasContext *ctx, int rt, int rd, int sel)
26ebe468
NF
10843{
10844 TCGv t0;
10845
b3167288
RH
10846#if !defined(CONFIG_USER_ONLY)
10847 /* The Linux kernel will emulate rdhwr if it's not supported natively.
10848 Therefore only check the ISA in system mode. */
d75c135e 10849 check_insn(ctx, ISA_MIPS32R2);
b3167288 10850#endif
26ebe468
NF
10851 t0 = tcg_temp_new();
10852
10853 switch (rd) {
10854 case 0:
895c2d04 10855 gen_helper_rdhwr_cpunum(t0, cpu_env);
26ebe468
NF
10856 gen_store_gpr(t0, rt);
10857 break;
10858 case 1:
895c2d04 10859 gen_helper_rdhwr_synci_step(t0, cpu_env);
26ebe468
NF
10860 gen_store_gpr(t0, rt);
10861 break;
10862 case 2:
eeb3bba8 10863 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
d673a68d
JH
10864 gen_io_start();
10865 }
895c2d04 10866 gen_helper_rdhwr_cc(t0, cpu_env);
eeb3bba8 10867 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
d673a68d
JH
10868 gen_io_end();
10869 }
26ebe468 10870 gen_store_gpr(t0, rt);
d673a68d 10871 /* Break the TB to be able to take timer interrupts immediately
b28425ba 10872 after reading count. DISAS_STOP isn't sufficient, we need to ensure
d673a68d 10873 we break completely out of translated code. */
eeb3bba8
EC
10874 gen_save_pc(ctx->base.pc_next + 4);
10875 ctx->base.is_jmp = DISAS_EXIT;
26ebe468
NF
10876 break;
10877 case 3:
895c2d04 10878 gen_helper_rdhwr_ccres(t0, cpu_env);
26ebe468
NF
10879 gen_store_gpr(t0, rt);
10880 break;
b00c7218
YK
10881 case 4:
10882 check_insn(ctx, ISA_MIPS32R6);
10883 if (sel != 0) {
10884 /* Performance counter registers are not implemented other than
10885 * control register 0.
10886 */
10887 generate_exception(ctx, EXCP_RI);
10888 }
10889 gen_helper_rdhwr_performance(t0, cpu_env);
10890 gen_store_gpr(t0, rt);
10891 break;
10892 case 5:
10893 check_insn(ctx, ISA_MIPS32R6);
10894 gen_helper_rdhwr_xnp(t0, cpu_env);
10895 gen_store_gpr(t0, rt);
10896 break;
26ebe468
NF
10897 case 29:
10898#if defined(CONFIG_USER_ONLY)
d279279e
PJ
10899 tcg_gen_ld_tl(t0, cpu_env,
10900 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
26ebe468
NF
10901 gen_store_gpr(t0, rt);
10902 break;
10903#else
d279279e
PJ
10904 if ((ctx->hflags & MIPS_HFLAG_CP0) ||
10905 (ctx->hflags & MIPS_HFLAG_HWRENA_ULR)) {
10906 tcg_gen_ld_tl(t0, cpu_env,
10907 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
10908 gen_store_gpr(t0, rt);
10909 } else {
9c708c7f 10910 generate_exception_end(ctx, EXCP_RI);
d279279e
PJ
10911 }
10912 break;
26ebe468
NF
10913#endif
10914 default: /* Invalid */
10915 MIPS_INVAL("rdhwr");
9c708c7f 10916 generate_exception_end(ctx, EXCP_RI);
26ebe468
NF
10917 break;
10918 }
10919 tcg_temp_free(t0);
10920}
10921
a5f53390
LA
10922static inline void clear_branch_hflags(DisasContext *ctx)
10923{
10924 ctx->hflags &= ~MIPS_HFLAG_BMASK;
eeb3bba8 10925 if (ctx->base.is_jmp == DISAS_NEXT) {
a5f53390
LA
10926 save_cpu_state(ctx, 0);
10927 } else {
10928 /* it is not safe to save ctx->hflags as hflags may be changed
10929 in execution time by the instruction in delay / forbidden slot. */
10930 tcg_gen_andi_i32(hflags, hflags, ~MIPS_HFLAG_BMASK);
10931 }
10932}
10933
31837be3 10934static void gen_branch(DisasContext *ctx, int insn_bytes)
c9602061
NF
10935{
10936 if (ctx->hflags & MIPS_HFLAG_BMASK) {
364d4831 10937 int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
c9602061 10938 /* Branches completion */
a5f53390 10939 clear_branch_hflags(ctx);
eeb3bba8 10940 ctx->base.is_jmp = DISAS_NORETURN;
c9602061 10941 /* FIXME: Need to clear can_do_io. */
364d4831 10942 switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
339cd2a8 10943 case MIPS_HFLAG_FBNSLOT:
eeb3bba8 10944 gen_goto_tb(ctx, 0, ctx->base.pc_next + insn_bytes);
339cd2a8 10945 break;
c9602061
NF
10946 case MIPS_HFLAG_B:
10947 /* unconditional branch */
364d4831
NF
10948 if (proc_hflags & MIPS_HFLAG_BX) {
10949 tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
10950 }
c9602061
NF
10951 gen_goto_tb(ctx, 0, ctx->btarget);
10952 break;
10953 case MIPS_HFLAG_BL:
10954 /* blikely taken case */
c9602061
NF
10955 gen_goto_tb(ctx, 0, ctx->btarget);
10956 break;
10957 case MIPS_HFLAG_BC:
10958 /* Conditional branch */
c9602061 10959 {
42a268c2 10960 TCGLabel *l1 = gen_new_label();
c9602061
NF
10961
10962 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
eeb3bba8 10963 gen_goto_tb(ctx, 1, ctx->base.pc_next + insn_bytes);
c9602061
NF
10964 gen_set_label(l1);
10965 gen_goto_tb(ctx, 0, ctx->btarget);
10966 }
10967 break;
10968 case MIPS_HFLAG_BR:
10969 /* unconditional branch to register */
d75c135e 10970 if (ctx->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
364d4831
NF
10971 TCGv t0 = tcg_temp_new();
10972 TCGv_i32 t1 = tcg_temp_new_i32();
10973
10974 tcg_gen_andi_tl(t0, btarget, 0x1);
10975 tcg_gen_trunc_tl_i32(t1, t0);
10976 tcg_temp_free(t0);
10977 tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
10978 tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
10979 tcg_gen_or_i32(hflags, hflags, t1);
10980 tcg_temp_free_i32(t1);
10981
10982 tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
10983 } else {
10984 tcg_gen_mov_tl(cpu_PC, btarget);
10985 }
eeb3bba8 10986 if (ctx->base.singlestep_enabled) {
c9602061 10987 save_cpu_state(ctx, 0);
9c708c7f 10988 gen_helper_raise_exception_debug(cpu_env);
c9602061 10989 }
7f11636d 10990 tcg_gen_lookup_and_goto_ptr();
c9602061
NF
10991 break;
10992 default:
a5f53390
LA
10993 fprintf(stderr, "unknown branch 0x%x\n", proc_hflags);
10994 abort();
c9602061
NF
10995 }
10996 }
10997}
10998
6893f074
YK
10999/* Compact Branches */
11000static void gen_compute_compact_branch(DisasContext *ctx, uint32_t opc,
11001 int rs, int rt, int32_t offset)
11002{
11003 int bcond_compute = 0;
11004 TCGv t0 = tcg_temp_new();
11005 TCGv t1 = tcg_temp_new();
65935f07 11006 int m16_lowbit = (ctx->hflags & MIPS_HFLAG_M16) != 0;
6893f074
YK
11007
11008 if (ctx->hflags & MIPS_HFLAG_BMASK) {
11009#ifdef MIPS_DEBUG_DISAS
11010 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
eeb3bba8 11011 "\n", ctx->base.pc_next);
6893f074 11012#endif
9c708c7f 11013 generate_exception_end(ctx, EXCP_RI);
6893f074
YK
11014 goto out;
11015 }
11016
11017 /* Load needed operands and calculate btarget */
11018 switch (opc) {
11019 /* compact branch */
11020 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
11021 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
11022 gen_load_gpr(t0, rs);
11023 gen_load_gpr(t1, rt);
11024 bcond_compute = 1;
eeb3bba8 11025 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
6893f074
YK
11026 if (rs <= rt && rs == 0) {
11027 /* OPC_BEQZALC, OPC_BNEZALC */
eeb3bba8 11028 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
6893f074
YK
11029 }
11030 break;
11031 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
11032 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
11033 gen_load_gpr(t0, rs);
11034 gen_load_gpr(t1, rt);
11035 bcond_compute = 1;
eeb3bba8 11036 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
6893f074
YK
11037 break;
11038 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
11039 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
11040 if (rs == 0 || rs == rt) {
11041 /* OPC_BLEZALC, OPC_BGEZALC */
11042 /* OPC_BGTZALC, OPC_BLTZALC */
eeb3bba8 11043 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
6893f074
YK
11044 }
11045 gen_load_gpr(t0, rs);
11046 gen_load_gpr(t1, rt);
11047 bcond_compute = 1;
eeb3bba8 11048 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
6893f074
YK
11049 break;
11050 case OPC_BC:
11051 case OPC_BALC:
eeb3bba8 11052 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
6893f074
YK
11053 break;
11054 case OPC_BEQZC:
11055 case OPC_BNEZC:
11056 if (rs != 0) {
11057 /* OPC_BEQZC, OPC_BNEZC */
11058 gen_load_gpr(t0, rs);
11059 bcond_compute = 1;
eeb3bba8 11060 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
6893f074
YK
11061 } else {
11062 /* OPC_JIC, OPC_JIALC */
11063 TCGv tbase = tcg_temp_new();
11064 TCGv toffset = tcg_temp_new();
11065
11066 gen_load_gpr(tbase, rt);
11067 tcg_gen_movi_tl(toffset, offset);
11068 gen_op_addr_add(ctx, btarget, tbase, toffset);
11069 tcg_temp_free(tbase);
11070 tcg_temp_free(toffset);
11071 }
11072 break;
11073 default:
11074 MIPS_INVAL("Compact branch/jump");
9c708c7f 11075 generate_exception_end(ctx, EXCP_RI);
6893f074
YK
11076 goto out;
11077 }
11078
11079 if (bcond_compute == 0) {
11080 /* Uncoditional compact branch */
11081 switch (opc) {
11082 case OPC_JIALC:
eeb3bba8 11083 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
6893f074
YK
11084 /* Fallthrough */
11085 case OPC_JIC:
11086 ctx->hflags |= MIPS_HFLAG_BR;
11087 break;
11088 case OPC_BALC:
eeb3bba8 11089 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
6893f074
YK
11090 /* Fallthrough */
11091 case OPC_BC:
11092 ctx->hflags |= MIPS_HFLAG_B;
11093 break;
11094 default:
11095 MIPS_INVAL("Compact branch/jump");
9c708c7f 11096 generate_exception_end(ctx, EXCP_RI);
6893f074
YK
11097 goto out;
11098 }
11099
11100 /* Generating branch here as compact branches don't have delay slot */
11101 gen_branch(ctx, 4);
11102 } else {
11103 /* Conditional compact branch */
11104 TCGLabel *fs = gen_new_label();
11105 save_cpu_state(ctx, 0);
11106
11107 switch (opc) {
11108 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
11109 if (rs == 0 && rt != 0) {
11110 /* OPC_BLEZALC */
11111 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
11112 } else if (rs != 0 && rt != 0 && rs == rt) {
11113 /* OPC_BGEZALC */
11114 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
11115 } else {
11116 /* OPC_BGEUC */
11117 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU), t0, t1, fs);
11118 }
11119 break;
11120 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
11121 if (rs == 0 && rt != 0) {
11122 /* OPC_BGTZALC */
11123 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
11124 } else if (rs != 0 && rt != 0 && rs == rt) {
11125 /* OPC_BLTZALC */
11126 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
11127 } else {
11128 /* OPC_BLTUC */
11129 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU), t0, t1, fs);
11130 }
11131 break;
11132 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
11133 if (rs == 0 && rt != 0) {
11134 /* OPC_BLEZC */
11135 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
11136 } else if (rs != 0 && rt != 0 && rs == rt) {
11137 /* OPC_BGEZC */
11138 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
11139 } else {
11140 /* OPC_BGEC */
11141 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE), t0, t1, fs);
11142 }
11143 break;
11144 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
11145 if (rs == 0 && rt != 0) {
11146 /* OPC_BGTZC */
11147 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
11148 } else if (rs != 0 && rt != 0 && rs == rt) {
11149 /* OPC_BLTZC */
11150 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
11151 } else {
11152 /* OPC_BLTC */
11153 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT), t0, t1, fs);
11154 }
11155 break;
11156 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
11157 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
11158 if (rs >= rt) {
11159 /* OPC_BOVC, OPC_BNVC */
11160 TCGv t2 = tcg_temp_new();
11161 TCGv t3 = tcg_temp_new();
11162 TCGv t4 = tcg_temp_new();
11163 TCGv input_overflow = tcg_temp_new();
11164
11165 gen_load_gpr(t0, rs);
11166 gen_load_gpr(t1, rt);
11167 tcg_gen_ext32s_tl(t2, t0);
11168 tcg_gen_setcond_tl(TCG_COND_NE, input_overflow, t2, t0);
11169 tcg_gen_ext32s_tl(t3, t1);
11170 tcg_gen_setcond_tl(TCG_COND_NE, t4, t3, t1);
11171 tcg_gen_or_tl(input_overflow, input_overflow, t4);
11172
11173 tcg_gen_add_tl(t4, t2, t3);
11174 tcg_gen_ext32s_tl(t4, t4);
11175 tcg_gen_xor_tl(t2, t2, t3);
11176 tcg_gen_xor_tl(t3, t4, t3);
11177 tcg_gen_andc_tl(t2, t3, t2);
11178 tcg_gen_setcondi_tl(TCG_COND_LT, t4, t2, 0);
11179 tcg_gen_or_tl(t4, t4, input_overflow);
11180 if (opc == OPC_BOVC) {
11181 /* OPC_BOVC */
11182 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t4, 0, fs);
11183 } else {
11184 /* OPC_BNVC */
11185 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t4, 0, fs);
11186 }
11187 tcg_temp_free(input_overflow);
11188 tcg_temp_free(t4);
11189 tcg_temp_free(t3);
11190 tcg_temp_free(t2);
11191 } else if (rs < rt && rs == 0) {
11192 /* OPC_BEQZALC, OPC_BNEZALC */
11193 if (opc == OPC_BEQZALC) {
11194 /* OPC_BEQZALC */
11195 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t1, 0, fs);
11196 } else {
11197 /* OPC_BNEZALC */
11198 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t1, 0, fs);
11199 }
11200 } else {
11201 /* OPC_BEQC, OPC_BNEC */
11202 if (opc == OPC_BEQC) {
11203 /* OPC_BEQC */
11204 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_EQ), t0, t1, fs);
11205 } else {
11206 /* OPC_BNEC */
11207 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_NE), t0, t1, fs);
11208 }
11209 }
11210 break;
11211 case OPC_BEQZC:
11212 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t0, 0, fs);
11213 break;
11214 case OPC_BNEZC:
11215 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t0, 0, fs);
11216 break;
11217 default:
11218 MIPS_INVAL("Compact conditional branch/jump");
9c708c7f 11219 generate_exception_end(ctx, EXCP_RI);
6893f074
YK
11220 goto out;
11221 }
11222
11223 /* Generating branch here as compact branches don't have delay slot */
11224 gen_goto_tb(ctx, 1, ctx->btarget);
11225 gen_set_label(fs);
11226
11227 ctx->hflags |= MIPS_HFLAG_FBNSLOT;
6893f074
YK
11228 }
11229
11230out:
11231 tcg_temp_free(t0);
11232 tcg_temp_free(t1);
11233}
11234
7a387fff 11235/* ISA extensions (ASEs) */
6af0bf9c 11236/* MIPS16 extension to MIPS32 */
6ea219d0
NF
11237
11238/* MIPS16 major opcodes */
11239enum {
11240 M16_OPC_ADDIUSP = 0x00,
11241 M16_OPC_ADDIUPC = 0x01,
11242 M16_OPC_B = 0x02,
11243 M16_OPC_JAL = 0x03,
11244 M16_OPC_BEQZ = 0x04,
11245 M16_OPC_BNEQZ = 0x05,
11246 M16_OPC_SHIFT = 0x06,
11247 M16_OPC_LD = 0x07,
11248 M16_OPC_RRIA = 0x08,
11249 M16_OPC_ADDIU8 = 0x09,
11250 M16_OPC_SLTI = 0x0a,
11251 M16_OPC_SLTIU = 0x0b,
11252 M16_OPC_I8 = 0x0c,
11253 M16_OPC_LI = 0x0d,
11254 M16_OPC_CMPI = 0x0e,
11255 M16_OPC_SD = 0x0f,
11256 M16_OPC_LB = 0x10,
11257 M16_OPC_LH = 0x11,
11258 M16_OPC_LWSP = 0x12,
11259 M16_OPC_LW = 0x13,
11260 M16_OPC_LBU = 0x14,
11261 M16_OPC_LHU = 0x15,
11262 M16_OPC_LWPC = 0x16,
11263 M16_OPC_LWU = 0x17,
11264 M16_OPC_SB = 0x18,
11265 M16_OPC_SH = 0x19,
11266 M16_OPC_SWSP = 0x1a,
11267 M16_OPC_SW = 0x1b,
11268 M16_OPC_RRR = 0x1c,
11269 M16_OPC_RR = 0x1d,
11270 M16_OPC_EXTEND = 0x1e,
11271 M16_OPC_I64 = 0x1f
11272};
11273
11274/* I8 funct field */
11275enum {
11276 I8_BTEQZ = 0x0,
11277 I8_BTNEZ = 0x1,
11278 I8_SWRASP = 0x2,
11279 I8_ADJSP = 0x3,
11280 I8_SVRS = 0x4,
11281 I8_MOV32R = 0x5,
11282 I8_MOVR32 = 0x7
11283};
11284
11285/* RRR f field */
11286enum {
11287 RRR_DADDU = 0x0,
11288 RRR_ADDU = 0x1,
11289 RRR_DSUBU = 0x2,
11290 RRR_SUBU = 0x3
11291};
11292
11293/* RR funct field */
11294enum {
11295 RR_JR = 0x00,
11296 RR_SDBBP = 0x01,
11297 RR_SLT = 0x02,
11298 RR_SLTU = 0x03,
11299 RR_SLLV = 0x04,
11300 RR_BREAK = 0x05,
11301 RR_SRLV = 0x06,
11302 RR_SRAV = 0x07,
11303 RR_DSRL = 0x08,
11304 RR_CMP = 0x0a,
11305 RR_NEG = 0x0b,
11306 RR_AND = 0x0c,
11307 RR_OR = 0x0d,
11308 RR_XOR = 0x0e,
11309 RR_NOT = 0x0f,
11310 RR_MFHI = 0x10,
11311 RR_CNVT = 0x11,
11312 RR_MFLO = 0x12,
11313 RR_DSRA = 0x13,
11314 RR_DSLLV = 0x14,
11315 RR_DSRLV = 0x16,
11316 RR_DSRAV = 0x17,
11317 RR_MULT = 0x18,
11318 RR_MULTU = 0x19,
11319 RR_DIV = 0x1a,
11320 RR_DIVU = 0x1b,
11321 RR_DMULT = 0x1c,
11322 RR_DMULTU = 0x1d,
11323 RR_DDIV = 0x1e,
11324 RR_DDIVU = 0x1f
11325};
11326
11327/* I64 funct field */
11328enum {
11329 I64_LDSP = 0x0,
11330 I64_SDSP = 0x1,
11331 I64_SDRASP = 0x2,
11332 I64_DADJSP = 0x3,
11333 I64_LDPC = 0x4,
364d4831 11334 I64_DADDIU5 = 0x5,
6ea219d0
NF
11335 I64_DADDIUPC = 0x6,
11336 I64_DADDIUSP = 0x7
11337};
11338
11339/* RR ry field for CNVT */
11340enum {
11341 RR_RY_CNVT_ZEB = 0x0,
11342 RR_RY_CNVT_ZEH = 0x1,
11343 RR_RY_CNVT_ZEW = 0x2,
11344 RR_RY_CNVT_SEB = 0x4,
11345 RR_RY_CNVT_SEH = 0x5,
11346 RR_RY_CNVT_SEW = 0x6,
11347};
11348
364d4831
NF
11349static int xlat (int r)
11350{
11351 static int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
11352
11353 return map[r];
11354}
11355
11356static void gen_mips16_save (DisasContext *ctx,
11357 int xsregs, int aregs,
11358 int do_ra, int do_s0, int do_s1,
11359 int framesize)
11360{
11361 TCGv t0 = tcg_temp_new();
11362 TCGv t1 = tcg_temp_new();
c48245f0 11363 TCGv t2 = tcg_temp_new();
364d4831
NF
11364 int args, astatic;
11365
11366 switch (aregs) {
11367 case 0:
11368 case 1:
11369 case 2:
11370 case 3:
11371 case 11:
11372 args = 0;
11373 break;
11374 case 4:
11375 case 5:
11376 case 6:
11377 case 7:
11378 args = 1;
11379 break;
11380 case 8:
11381 case 9:
11382 case 10:
11383 args = 2;
11384 break;
11385 case 12:
11386 case 13:
11387 args = 3;
11388 break;
11389 case 14:
11390 args = 4;
11391 break;
11392 default:
9c708c7f 11393 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
11394 return;
11395 }
11396
11397 switch (args) {
11398 case 4:
11399 gen_base_offset_addr(ctx, t0, 29, 12);
11400 gen_load_gpr(t1, 7);
5f68f5ae 11401 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
364d4831
NF
11402 /* Fall through */
11403 case 3:
11404 gen_base_offset_addr(ctx, t0, 29, 8);
11405 gen_load_gpr(t1, 6);
5f68f5ae 11406 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
364d4831
NF
11407 /* Fall through */
11408 case 2:
11409 gen_base_offset_addr(ctx, t0, 29, 4);
11410 gen_load_gpr(t1, 5);
5f68f5ae 11411 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
364d4831
NF
11412 /* Fall through */
11413 case 1:
11414 gen_base_offset_addr(ctx, t0, 29, 0);
11415 gen_load_gpr(t1, 4);
5f68f5ae 11416 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
364d4831
NF
11417 }
11418
11419 gen_load_gpr(t0, 29);
11420
5f68f5ae 11421#define DECR_AND_STORE(reg) do { \
c48245f0
MR
11422 tcg_gen_movi_tl(t2, -4); \
11423 gen_op_addr_add(ctx, t0, t0, t2); \
5f68f5ae
AJ
11424 gen_load_gpr(t1, reg); \
11425 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); \
364d4831
NF
11426 } while (0)
11427
11428 if (do_ra) {
11429 DECR_AND_STORE(31);
11430 }
11431
11432 switch (xsregs) {
11433 case 7:
11434 DECR_AND_STORE(30);
11435 /* Fall through */
11436 case 6:
11437 DECR_AND_STORE(23);
11438 /* Fall through */
11439 case 5:
11440 DECR_AND_STORE(22);
11441 /* Fall through */
11442 case 4:
11443 DECR_AND_STORE(21);
11444 /* Fall through */
11445 case 3:
11446 DECR_AND_STORE(20);
11447 /* Fall through */
11448 case 2:
11449 DECR_AND_STORE(19);
11450 /* Fall through */
11451 case 1:
11452 DECR_AND_STORE(18);
11453 }
11454
11455 if (do_s1) {
11456 DECR_AND_STORE(17);
11457 }
11458 if (do_s0) {
11459 DECR_AND_STORE(16);
11460 }
11461
11462 switch (aregs) {
11463 case 0:
11464 case 4:
11465 case 8:
11466 case 12:
11467 case 14:
11468 astatic = 0;
11469 break;
11470 case 1:
11471 case 5:
11472 case 9:
11473 case 13:
11474 astatic = 1;
11475 break;
11476 case 2:
11477 case 6:
11478 case 10:
11479 astatic = 2;
11480 break;
11481 case 3:
11482 case 7:
11483 astatic = 3;
11484 break;
11485 case 11:
11486 astatic = 4;
11487 break;
11488 default:
9c708c7f 11489 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
11490 return;
11491 }
11492
11493 if (astatic > 0) {
11494 DECR_AND_STORE(7);
11495 if (astatic > 1) {
11496 DECR_AND_STORE(6);
11497 if (astatic > 2) {
11498 DECR_AND_STORE(5);
11499 if (astatic > 3) {
11500 DECR_AND_STORE(4);
11501 }
11502 }
11503 }
11504 }
11505#undef DECR_AND_STORE
11506
c48245f0
MR
11507 tcg_gen_movi_tl(t2, -framesize);
11508 gen_op_addr_add(ctx, cpu_gpr[29], cpu_gpr[29], t2);
364d4831
NF
11509 tcg_temp_free(t0);
11510 tcg_temp_free(t1);
c48245f0 11511 tcg_temp_free(t2);
364d4831
NF
11512}
11513
11514static void gen_mips16_restore (DisasContext *ctx,
11515 int xsregs, int aregs,
11516 int do_ra, int do_s0, int do_s1,
11517 int framesize)
11518{
11519 int astatic;
11520 TCGv t0 = tcg_temp_new();
11521 TCGv t1 = tcg_temp_new();
c48245f0 11522 TCGv t2 = tcg_temp_new();
364d4831 11523
c48245f0
MR
11524 tcg_gen_movi_tl(t2, framesize);
11525 gen_op_addr_add(ctx, t0, cpu_gpr[29], t2);
364d4831 11526
5f68f5ae 11527#define DECR_AND_LOAD(reg) do { \
c48245f0
MR
11528 tcg_gen_movi_tl(t2, -4); \
11529 gen_op_addr_add(ctx, t0, t0, t2); \
5f68f5ae
AJ
11530 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL); \
11531 gen_store_gpr(t1, reg); \
364d4831
NF
11532 } while (0)
11533
11534 if (do_ra) {
11535 DECR_AND_LOAD(31);
11536 }
11537
11538 switch (xsregs) {
11539 case 7:
11540 DECR_AND_LOAD(30);
11541 /* Fall through */
11542 case 6:
11543 DECR_AND_LOAD(23);
11544 /* Fall through */
11545 case 5:
11546 DECR_AND_LOAD(22);
11547 /* Fall through */
11548 case 4:
11549 DECR_AND_LOAD(21);
11550 /* Fall through */
11551 case 3:
11552 DECR_AND_LOAD(20);
11553 /* Fall through */
11554 case 2:
11555 DECR_AND_LOAD(19);
11556 /* Fall through */
11557 case 1:
11558 DECR_AND_LOAD(18);
11559 }
11560
11561 if (do_s1) {
11562 DECR_AND_LOAD(17);
11563 }
11564 if (do_s0) {
11565 DECR_AND_LOAD(16);
11566 }
11567
11568 switch (aregs) {
11569 case 0:
11570 case 4:
11571 case 8:
11572 case 12:
11573 case 14:
11574 astatic = 0;
11575 break;
11576 case 1:
11577 case 5:
11578 case 9:
11579 case 13:
11580 astatic = 1;
11581 break;
11582 case 2:
11583 case 6:
11584 case 10:
11585 astatic = 2;
11586 break;
11587 case 3:
11588 case 7:
11589 astatic = 3;
11590 break;
11591 case 11:
11592 astatic = 4;
11593 break;
11594 default:
9c708c7f 11595 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
11596 return;
11597 }
11598
11599 if (astatic > 0) {
11600 DECR_AND_LOAD(7);
11601 if (astatic > 1) {
11602 DECR_AND_LOAD(6);
11603 if (astatic > 2) {
11604 DECR_AND_LOAD(5);
11605 if (astatic > 3) {
11606 DECR_AND_LOAD(4);
11607 }
11608 }
11609 }
11610 }
11611#undef DECR_AND_LOAD
11612
c48245f0
MR
11613 tcg_gen_movi_tl(t2, framesize);
11614 gen_op_addr_add(ctx, cpu_gpr[29], cpu_gpr[29], t2);
364d4831
NF
11615 tcg_temp_free(t0);
11616 tcg_temp_free(t1);
c48245f0 11617 tcg_temp_free(t2);
364d4831
NF
11618}
11619
11620static void gen_addiupc (DisasContext *ctx, int rx, int imm,
11621 int is_64_bit, int extended)
11622{
11623 TCGv t0;
11624
11625 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9c708c7f 11626 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
11627 return;
11628 }
11629
11630 t0 = tcg_temp_new();
11631
11632 tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
11633 tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
11634 if (!is_64_bit) {
11635 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
11636 }
11637
11638 tcg_temp_free(t0);
11639}
11640
0d74a222
LA
11641static void gen_cache_operation(DisasContext *ctx, uint32_t op, int base,
11642 int16_t offset)
11643{
11644 TCGv_i32 t0 = tcg_const_i32(op);
11645 TCGv t1 = tcg_temp_new();
11646 gen_base_offset_addr(ctx, t1, base, offset);
11647 gen_helper_cache(cpu_env, t1, t0);
11648}
11649
364d4831 11650#if defined(TARGET_MIPS64)
d75c135e 11651static void decode_i64_mips16 (DisasContext *ctx,
364d4831
NF
11652 int ry, int funct, int16_t offset,
11653 int extended)
11654{
11655 switch (funct) {
11656 case I64_LDSP:
d9224450 11657 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11658 check_mips_64(ctx);
11659 offset = extended ? offset : offset << 3;
d75c135e 11660 gen_ld(ctx, OPC_LD, ry, 29, offset);
364d4831
NF
11661 break;
11662 case I64_SDSP:
d9224450 11663 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11664 check_mips_64(ctx);
11665 offset = extended ? offset : offset << 3;
5c13fdfd 11666 gen_st(ctx, OPC_SD, ry, 29, offset);
364d4831
NF
11667 break;
11668 case I64_SDRASP:
d9224450 11669 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11670 check_mips_64(ctx);
11671 offset = extended ? offset : (ctx->opcode & 0xff) << 3;
5c13fdfd 11672 gen_st(ctx, OPC_SD, 31, 29, offset);
364d4831
NF
11673 break;
11674 case I64_DADJSP:
d9224450 11675 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11676 check_mips_64(ctx);
11677 offset = extended ? offset : ((int8_t)ctx->opcode) << 3;
d75c135e 11678 gen_arith_imm(ctx, OPC_DADDIU, 29, 29, offset);
364d4831
NF
11679 break;
11680 case I64_LDPC:
d9224450
MR
11681 check_insn(ctx, ISA_MIPS3);
11682 check_mips_64(ctx);
364d4831 11683 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9c708c7f 11684 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
11685 } else {
11686 offset = extended ? offset : offset << 3;
d75c135e 11687 gen_ld(ctx, OPC_LDPC, ry, 0, offset);
364d4831
NF
11688 }
11689 break;
11690 case I64_DADDIU5:
d9224450 11691 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11692 check_mips_64(ctx);
11693 offset = extended ? offset : ((int8_t)(offset << 3)) >> 3;
d75c135e 11694 gen_arith_imm(ctx, OPC_DADDIU, ry, ry, offset);
364d4831
NF
11695 break;
11696 case I64_DADDIUPC:
d9224450 11697 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11698 check_mips_64(ctx);
11699 offset = extended ? offset : offset << 2;
11700 gen_addiupc(ctx, ry, offset, 1, extended);
11701 break;
11702 case I64_DADDIUSP:
d9224450 11703 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11704 check_mips_64(ctx);
11705 offset = extended ? offset : offset << 2;
d75c135e 11706 gen_arith_imm(ctx, OPC_DADDIU, ry, 29, offset);
364d4831
NF
11707 break;
11708 }
11709}
11710#endif
11711
240ce26a 11712static int decode_extended_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
364d4831 11713{
eeb3bba8 11714 int extend = cpu_lduw_code(env, ctx->base.pc_next + 2);
364d4831
NF
11715 int op, rx, ry, funct, sa;
11716 int16_t imm, offset;
11717
11718 ctx->opcode = (ctx->opcode << 16) | extend;
11719 op = (ctx->opcode >> 11) & 0x1f;
11720 sa = (ctx->opcode >> 22) & 0x1f;
11721 funct = (ctx->opcode >> 8) & 0x7;
11722 rx = xlat((ctx->opcode >> 8) & 0x7);
11723 ry = xlat((ctx->opcode >> 5) & 0x7);
11724 offset = imm = (int16_t) (((ctx->opcode >> 16) & 0x1f) << 11
11725 | ((ctx->opcode >> 21) & 0x3f) << 5
11726 | (ctx->opcode & 0x1f));
11727
11728 /* The extended opcodes cleverly reuse the opcodes from their 16-bit
11729 counterparts. */
11730 switch (op) {
11731 case M16_OPC_ADDIUSP:
d75c135e 11732 gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
364d4831
NF
11733 break;
11734 case M16_OPC_ADDIUPC:
11735 gen_addiupc(ctx, rx, imm, 0, 1);
11736 break;
11737 case M16_OPC_B:
b231c103 11738 gen_compute_branch(ctx, OPC_BEQ, 4, 0, 0, offset << 1, 0);
364d4831
NF
11739 /* No delay slot, so just process as a normal instruction */
11740 break;
11741 case M16_OPC_BEQZ:
b231c103 11742 gen_compute_branch(ctx, OPC_BEQ, 4, rx, 0, offset << 1, 0);
364d4831
NF
11743 /* No delay slot, so just process as a normal instruction */
11744 break;
11745 case M16_OPC_BNEQZ:
b231c103 11746 gen_compute_branch(ctx, OPC_BNE, 4, rx, 0, offset << 1, 0);
364d4831
NF
11747 /* No delay slot, so just process as a normal instruction */
11748 break;
11749 case M16_OPC_SHIFT:
11750 switch (ctx->opcode & 0x3) {
11751 case 0x0:
d75c135e 11752 gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
364d4831
NF
11753 break;
11754 case 0x1:
11755#if defined(TARGET_MIPS64)
11756 check_mips_64(ctx);
d75c135e 11757 gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
364d4831 11758#else
9c708c7f 11759 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
11760#endif
11761 break;
11762 case 0x2:
d75c135e 11763 gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
364d4831
NF
11764 break;
11765 case 0x3:
d75c135e 11766 gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
364d4831
NF
11767 break;
11768 }
11769 break;
11770#if defined(TARGET_MIPS64)
11771 case M16_OPC_LD:
d9224450 11772 check_insn(ctx, ISA_MIPS3);
d75de749 11773 check_mips_64(ctx);
d75c135e 11774 gen_ld(ctx, OPC_LD, ry, rx, offset);
364d4831
NF
11775 break;
11776#endif
11777 case M16_OPC_RRIA:
11778 imm = ctx->opcode & 0xf;
11779 imm = imm | ((ctx->opcode >> 20) & 0x7f) << 4;
11780 imm = imm | ((ctx->opcode >> 16) & 0xf) << 11;
11781 imm = (int16_t) (imm << 1) >> 1;
11782 if ((ctx->opcode >> 4) & 0x1) {
11783#if defined(TARGET_MIPS64)
11784 check_mips_64(ctx);
d75c135e 11785 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
364d4831 11786#else
9c708c7f 11787 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
11788#endif
11789 } else {
d75c135e 11790 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
364d4831
NF
11791 }
11792 break;
11793 case M16_OPC_ADDIU8:
d75c135e 11794 gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
364d4831
NF
11795 break;
11796 case M16_OPC_SLTI:
d75c135e 11797 gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
364d4831
NF
11798 break;
11799 case M16_OPC_SLTIU:
d75c135e 11800 gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
364d4831
NF
11801 break;
11802 case M16_OPC_I8:
11803 switch (funct) {
11804 case I8_BTEQZ:
b231c103 11805 gen_compute_branch(ctx, OPC_BEQ, 4, 24, 0, offset << 1, 0);
364d4831
NF
11806 break;
11807 case I8_BTNEZ:
b231c103 11808 gen_compute_branch(ctx, OPC_BNE, 4, 24, 0, offset << 1, 0);
364d4831
NF
11809 break;
11810 case I8_SWRASP:
5c13fdfd 11811 gen_st(ctx, OPC_SW, 31, 29, imm);
364d4831
NF
11812 break;
11813 case I8_ADJSP:
d75c135e 11814 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm);
364d4831
NF
11815 break;
11816 case I8_SVRS:
d9224450 11817 check_insn(ctx, ISA_MIPS32);
364d4831
NF
11818 {
11819 int xsregs = (ctx->opcode >> 24) & 0x7;
11820 int aregs = (ctx->opcode >> 16) & 0xf;
11821 int do_ra = (ctx->opcode >> 6) & 0x1;
11822 int do_s0 = (ctx->opcode >> 5) & 0x1;
11823 int do_s1 = (ctx->opcode >> 4) & 0x1;
11824 int framesize = (((ctx->opcode >> 20) & 0xf) << 4
11825 | (ctx->opcode & 0xf)) << 3;
11826
11827 if (ctx->opcode & (1 << 7)) {
11828 gen_mips16_save(ctx, xsregs, aregs,
11829 do_ra, do_s0, do_s1,
11830 framesize);
11831 } else {
11832 gen_mips16_restore(ctx, xsregs, aregs,
11833 do_ra, do_s0, do_s1,
11834 framesize);
11835 }
11836 }
11837 break;
11838 default:
9c708c7f 11839 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
11840 break;
11841 }
11842 break;
11843 case M16_OPC_LI:
11844 tcg_gen_movi_tl(cpu_gpr[rx], (uint16_t) imm);
11845 break;
11846 case M16_OPC_CMPI:
11847 tcg_gen_xori_tl(cpu_gpr[24], cpu_gpr[rx], (uint16_t) imm);
11848 break;
11849#if defined(TARGET_MIPS64)
11850 case M16_OPC_SD:
d9224450
MR
11851 check_insn(ctx, ISA_MIPS3);
11852 check_mips_64(ctx);
5c13fdfd 11853 gen_st(ctx, OPC_SD, ry, rx, offset);
364d4831
NF
11854 break;
11855#endif
11856 case M16_OPC_LB:
d75c135e 11857 gen_ld(ctx, OPC_LB, ry, rx, offset);
364d4831
NF
11858 break;
11859 case M16_OPC_LH:
d75c135e 11860 gen_ld(ctx, OPC_LH, ry, rx, offset);
364d4831
NF
11861 break;
11862 case M16_OPC_LWSP:
d75c135e 11863 gen_ld(ctx, OPC_LW, rx, 29, offset);
364d4831
NF
11864 break;
11865 case M16_OPC_LW:
d75c135e 11866 gen_ld(ctx, OPC_LW, ry, rx, offset);
364d4831
NF
11867 break;
11868 case M16_OPC_LBU:
d75c135e 11869 gen_ld(ctx, OPC_LBU, ry, rx, offset);
364d4831
NF
11870 break;
11871 case M16_OPC_LHU:
d75c135e 11872 gen_ld(ctx, OPC_LHU, ry, rx, offset);
364d4831
NF
11873 break;
11874 case M16_OPC_LWPC:
d75c135e 11875 gen_ld(ctx, OPC_LWPC, rx, 0, offset);
364d4831
NF
11876 break;
11877#if defined(TARGET_MIPS64)
11878 case M16_OPC_LWU:
d9224450
MR
11879 check_insn(ctx, ISA_MIPS3);
11880 check_mips_64(ctx);
d75c135e 11881 gen_ld(ctx, OPC_LWU, ry, rx, offset);
364d4831
NF
11882 break;
11883#endif
11884 case M16_OPC_SB:
5c13fdfd 11885 gen_st(ctx, OPC_SB, ry, rx, offset);
364d4831
NF
11886 break;
11887 case M16_OPC_SH:
5c13fdfd 11888 gen_st(ctx, OPC_SH, ry, rx, offset);
364d4831
NF
11889 break;
11890 case M16_OPC_SWSP:
5c13fdfd 11891 gen_st(ctx, OPC_SW, rx, 29, offset);
364d4831
NF
11892 break;
11893 case M16_OPC_SW:
5c13fdfd 11894 gen_st(ctx, OPC_SW, ry, rx, offset);
364d4831
NF
11895 break;
11896#if defined(TARGET_MIPS64)
11897 case M16_OPC_I64:
d75c135e 11898 decode_i64_mips16(ctx, ry, funct, offset, 1);
364d4831
NF
11899 break;
11900#endif
11901 default:
9c708c7f 11902 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
11903 break;
11904 }
11905
11906 return 4;
11907}
11908
3b3c1694
LA
11909static inline bool is_uhi(int sdbbp_code)
11910{
11911#ifdef CONFIG_USER_ONLY
11912 return false;
11913#else
11914 return semihosting_enabled() && sdbbp_code == 1;
11915#endif
11916}
11917
240ce26a 11918static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
364d4831
NF
11919{
11920 int rx, ry;
11921 int sa;
11922 int op, cnvt_op, op1, offset;
11923 int funct;
11924 int n_bytes;
11925
11926 op = (ctx->opcode >> 11) & 0x1f;
11927 sa = (ctx->opcode >> 2) & 0x7;
11928 sa = sa == 0 ? 8 : sa;
11929 rx = xlat((ctx->opcode >> 8) & 0x7);
11930 cnvt_op = (ctx->opcode >> 5) & 0x7;
11931 ry = xlat((ctx->opcode >> 5) & 0x7);
11932 op1 = offset = ctx->opcode & 0x1f;
11933
11934 n_bytes = 2;
11935
11936 switch (op) {
11937 case M16_OPC_ADDIUSP:
11938 {
11939 int16_t imm = ((uint8_t) ctx->opcode) << 2;
11940
d75c135e 11941 gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
364d4831
NF
11942 }
11943 break;
11944 case M16_OPC_ADDIUPC:
11945 gen_addiupc(ctx, rx, ((uint8_t) ctx->opcode) << 2, 0, 0);
11946 break;
11947 case M16_OPC_B:
11948 offset = (ctx->opcode & 0x7ff) << 1;
11949 offset = (int16_t)(offset << 4) >> 4;
b231c103 11950 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, offset, 0);
364d4831
NF
11951 /* No delay slot, so just process as a normal instruction */
11952 break;
11953 case M16_OPC_JAL:
eeb3bba8 11954 offset = cpu_lduw_code(env, ctx->base.pc_next + 2);
364d4831
NF
11955 offset = (((ctx->opcode & 0x1f) << 21)
11956 | ((ctx->opcode >> 5) & 0x1f) << 16
11957 | offset) << 2;
b231c103
YK
11958 op = ((ctx->opcode >> 10) & 0x1) ? OPC_JALX : OPC_JAL;
11959 gen_compute_branch(ctx, op, 4, rx, ry, offset, 2);
364d4831 11960 n_bytes = 4;
364d4831
NF
11961 break;
11962 case M16_OPC_BEQZ:
b231c103
YK
11963 gen_compute_branch(ctx, OPC_BEQ, 2, rx, 0,
11964 ((int8_t)ctx->opcode) << 1, 0);
364d4831
NF
11965 /* No delay slot, so just process as a normal instruction */
11966 break;
11967 case M16_OPC_BNEQZ:
b231c103
YK
11968 gen_compute_branch(ctx, OPC_BNE, 2, rx, 0,
11969 ((int8_t)ctx->opcode) << 1, 0);
364d4831
NF
11970 /* No delay slot, so just process as a normal instruction */
11971 break;
11972 case M16_OPC_SHIFT:
11973 switch (ctx->opcode & 0x3) {
11974 case 0x0:
d75c135e 11975 gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
364d4831
NF
11976 break;
11977 case 0x1:
11978#if defined(TARGET_MIPS64)
d9224450 11979 check_insn(ctx, ISA_MIPS3);
364d4831 11980 check_mips_64(ctx);
d75c135e 11981 gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
364d4831 11982#else
9c708c7f 11983 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
11984#endif
11985 break;
11986 case 0x2:
d75c135e 11987 gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
364d4831
NF
11988 break;
11989 case 0x3:
d75c135e 11990 gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
364d4831
NF
11991 break;
11992 }
11993 break;
11994#if defined(TARGET_MIPS64)
11995 case M16_OPC_LD:
d9224450 11996 check_insn(ctx, ISA_MIPS3);
364d4831 11997 check_mips_64(ctx);
d75c135e 11998 gen_ld(ctx, OPC_LD, ry, rx, offset << 3);
364d4831
NF
11999 break;
12000#endif
12001 case M16_OPC_RRIA:
12002 {
12003 int16_t imm = (int8_t)((ctx->opcode & 0xf) << 4) >> 4;
12004
12005 if ((ctx->opcode >> 4) & 1) {
12006#if defined(TARGET_MIPS64)
d9224450 12007 check_insn(ctx, ISA_MIPS3);
364d4831 12008 check_mips_64(ctx);
d75c135e 12009 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
364d4831 12010#else
9c708c7f 12011 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
12012#endif
12013 } else {
d75c135e 12014 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
364d4831
NF
12015 }
12016 }
12017 break;
12018 case M16_OPC_ADDIU8:
12019 {
12020 int16_t imm = (int8_t) ctx->opcode;
12021
d75c135e 12022 gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
364d4831
NF
12023 }
12024 break;
12025 case M16_OPC_SLTI:
12026 {
12027 int16_t imm = (uint8_t) ctx->opcode;
d75c135e 12028 gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
364d4831
NF
12029 }
12030 break;
12031 case M16_OPC_SLTIU:
12032 {
12033 int16_t imm = (uint8_t) ctx->opcode;
d75c135e 12034 gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
364d4831
NF
12035 }
12036 break;
12037 case M16_OPC_I8:
12038 {
12039 int reg32;
12040
12041 funct = (ctx->opcode >> 8) & 0x7;
12042 switch (funct) {
12043 case I8_BTEQZ:
12044 gen_compute_branch(ctx, OPC_BEQ, 2, 24, 0,
b231c103 12045 ((int8_t)ctx->opcode) << 1, 0);
364d4831
NF
12046 break;
12047 case I8_BTNEZ:
12048 gen_compute_branch(ctx, OPC_BNE, 2, 24, 0,
b231c103 12049 ((int8_t)ctx->opcode) << 1, 0);
364d4831
NF
12050 break;
12051 case I8_SWRASP:
5c13fdfd 12052 gen_st(ctx, OPC_SW, 31, 29, (ctx->opcode & 0xff) << 2);
364d4831
NF
12053 break;
12054 case I8_ADJSP:
d75c135e 12055 gen_arith_imm(ctx, OPC_ADDIU, 29, 29,
364d4831
NF
12056 ((int8_t)ctx->opcode) << 3);
12057 break;
12058 case I8_SVRS:
d9224450 12059 check_insn(ctx, ISA_MIPS32);
364d4831
NF
12060 {
12061 int do_ra = ctx->opcode & (1 << 6);
12062 int do_s0 = ctx->opcode & (1 << 5);
12063 int do_s1 = ctx->opcode & (1 << 4);
12064 int framesize = ctx->opcode & 0xf;
12065
12066 if (framesize == 0) {
12067 framesize = 128;
12068 } else {
12069 framesize = framesize << 3;
12070 }
12071
12072 if (ctx->opcode & (1 << 7)) {
12073 gen_mips16_save(ctx, 0, 0,
12074 do_ra, do_s0, do_s1, framesize);
12075 } else {
12076 gen_mips16_restore(ctx, 0, 0,
12077 do_ra, do_s0, do_s1, framesize);
12078 }
12079 }
12080 break;
12081 case I8_MOV32R:
12082 {
12083 int rz = xlat(ctx->opcode & 0x7);
12084
12085 reg32 = (((ctx->opcode >> 3) & 0x3) << 3) |
12086 ((ctx->opcode >> 5) & 0x7);
d75c135e 12087 gen_arith(ctx, OPC_ADDU, reg32, rz, 0);
364d4831
NF
12088 }
12089 break;
12090 case I8_MOVR32:
12091 reg32 = ctx->opcode & 0x1f;
d75c135e 12092 gen_arith(ctx, OPC_ADDU, ry, reg32, 0);
364d4831
NF
12093 break;
12094 default:
9c708c7f 12095 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
12096 break;
12097 }
12098 }
12099 break;
12100 case M16_OPC_LI:
12101 {
12102 int16_t imm = (uint8_t) ctx->opcode;
12103
d75c135e 12104 gen_arith_imm(ctx, OPC_ADDIU, rx, 0, imm);
364d4831
NF
12105 }
12106 break;
12107 case M16_OPC_CMPI:
12108 {
12109 int16_t imm = (uint8_t) ctx->opcode;
d75c135e 12110 gen_logic_imm(ctx, OPC_XORI, 24, rx, imm);
364d4831
NF
12111 }
12112 break;
12113#if defined(TARGET_MIPS64)
12114 case M16_OPC_SD:
d9224450 12115 check_insn(ctx, ISA_MIPS3);
364d4831 12116 check_mips_64(ctx);
5c13fdfd 12117 gen_st(ctx, OPC_SD, ry, rx, offset << 3);
364d4831
NF
12118 break;
12119#endif
12120 case M16_OPC_LB:
d75c135e 12121 gen_ld(ctx, OPC_LB, ry, rx, offset);
364d4831
NF
12122 break;
12123 case M16_OPC_LH:
d75c135e 12124 gen_ld(ctx, OPC_LH, ry, rx, offset << 1);
364d4831
NF
12125 break;
12126 case M16_OPC_LWSP:
d75c135e 12127 gen_ld(ctx, OPC_LW, rx, 29, ((uint8_t)ctx->opcode) << 2);
364d4831
NF
12128 break;
12129 case M16_OPC_LW:
d75c135e 12130 gen_ld(ctx, OPC_LW, ry, rx, offset << 2);
364d4831
NF
12131 break;
12132 case M16_OPC_LBU:
d75c135e 12133 gen_ld(ctx, OPC_LBU, ry, rx, offset);
364d4831
NF
12134 break;
12135 case M16_OPC_LHU:
d75c135e 12136 gen_ld(ctx, OPC_LHU, ry, rx, offset << 1);
364d4831
NF
12137 break;
12138 case M16_OPC_LWPC:
d75c135e 12139 gen_ld(ctx, OPC_LWPC, rx, 0, ((uint8_t)ctx->opcode) << 2);
364d4831
NF
12140 break;
12141#if defined (TARGET_MIPS64)
12142 case M16_OPC_LWU:
d9224450 12143 check_insn(ctx, ISA_MIPS3);
364d4831 12144 check_mips_64(ctx);
d75c135e 12145 gen_ld(ctx, OPC_LWU, ry, rx, offset << 2);
364d4831
NF
12146 break;
12147#endif
12148 case M16_OPC_SB:
5c13fdfd 12149 gen_st(ctx, OPC_SB, ry, rx, offset);
364d4831
NF
12150 break;
12151 case M16_OPC_SH:
5c13fdfd 12152 gen_st(ctx, OPC_SH, ry, rx, offset << 1);
364d4831
NF
12153 break;
12154 case M16_OPC_SWSP:
5c13fdfd 12155 gen_st(ctx, OPC_SW, rx, 29, ((uint8_t)ctx->opcode) << 2);
364d4831
NF
12156 break;
12157 case M16_OPC_SW:
5c13fdfd 12158 gen_st(ctx, OPC_SW, ry, rx, offset << 2);
364d4831
NF
12159 break;
12160 case M16_OPC_RRR:
12161 {
12162 int rz = xlat((ctx->opcode >> 2) & 0x7);
12163 int mips32_op;
12164
12165 switch (ctx->opcode & 0x3) {
12166 case RRR_ADDU:
12167 mips32_op = OPC_ADDU;
12168 break;
12169 case RRR_SUBU:
12170 mips32_op = OPC_SUBU;
12171 break;
12172#if defined(TARGET_MIPS64)
12173 case RRR_DADDU:
12174 mips32_op = OPC_DADDU;
d9224450 12175 check_insn(ctx, ISA_MIPS3);
364d4831
NF
12176 check_mips_64(ctx);
12177 break;
12178 case RRR_DSUBU:
12179 mips32_op = OPC_DSUBU;
d9224450 12180 check_insn(ctx, ISA_MIPS3);
364d4831
NF
12181 check_mips_64(ctx);
12182 break;
12183#endif
12184 default:
9c708c7f 12185 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
12186 goto done;
12187 }
12188
d75c135e 12189 gen_arith(ctx, mips32_op, rz, rx, ry);
364d4831
NF
12190 done:
12191 ;
12192 }
12193 break;
12194 case M16_OPC_RR:
12195 switch (op1) {
12196 case RR_JR:
12197 {
12198 int nd = (ctx->opcode >> 7) & 0x1;
12199 int link = (ctx->opcode >> 6) & 0x1;
12200 int ra = (ctx->opcode >> 5) & 0x1;
12201
d9224450
MR
12202 if (nd) {
12203 check_insn(ctx, ISA_MIPS32);
12204 }
12205
364d4831 12206 if (link) {
b231c103 12207 op = OPC_JALR;
364d4831
NF
12208 } else {
12209 op = OPC_JR;
12210 }
12211
b231c103
YK
12212 gen_compute_branch(ctx, op, 2, ra ? 31 : rx, 31, 0,
12213 (nd ? 0 : 2));
364d4831
NF
12214 }
12215 break;
12216 case RR_SDBBP:
3b3c1694
LA
12217 if (is_uhi(extract32(ctx->opcode, 5, 6))) {
12218 gen_helper_do_semihosting(cpu_env);
12219 } else {
12220 /* XXX: not clear which exception should be raised
12221 * when in debug mode...
12222 */
12223 check_insn(ctx, ISA_MIPS32);
9c708c7f 12224 generate_exception_end(ctx, EXCP_DBp);
3b3c1694 12225 }
364d4831
NF
12226 break;
12227 case RR_SLT:
d75c135e 12228 gen_slt(ctx, OPC_SLT, 24, rx, ry);
364d4831
NF
12229 break;
12230 case RR_SLTU:
d75c135e 12231 gen_slt(ctx, OPC_SLTU, 24, rx, ry);
364d4831
NF
12232 break;
12233 case RR_BREAK:
9c708c7f 12234 generate_exception_end(ctx, EXCP_BREAK);
364d4831
NF
12235 break;
12236 case RR_SLLV:
d75c135e 12237 gen_shift(ctx, OPC_SLLV, ry, rx, ry);
364d4831
NF
12238 break;
12239 case RR_SRLV:
d75c135e 12240 gen_shift(ctx, OPC_SRLV, ry, rx, ry);
364d4831
NF
12241 break;
12242 case RR_SRAV:
d75c135e 12243 gen_shift(ctx, OPC_SRAV, ry, rx, ry);
364d4831
NF
12244 break;
12245#if defined (TARGET_MIPS64)
12246 case RR_DSRL:
d9224450 12247 check_insn(ctx, ISA_MIPS3);
364d4831 12248 check_mips_64(ctx);
d75c135e 12249 gen_shift_imm(ctx, OPC_DSRL, ry, ry, sa);
364d4831
NF
12250 break;
12251#endif
12252 case RR_CMP:
d75c135e 12253 gen_logic(ctx, OPC_XOR, 24, rx, ry);
364d4831
NF
12254 break;
12255 case RR_NEG:
d75c135e 12256 gen_arith(ctx, OPC_SUBU, rx, 0, ry);
364d4831
NF
12257 break;
12258 case RR_AND:
d75c135e 12259 gen_logic(ctx, OPC_AND, rx, rx, ry);
364d4831
NF
12260 break;
12261 case RR_OR:
d75c135e 12262 gen_logic(ctx, OPC_OR, rx, rx, ry);
364d4831
NF
12263 break;
12264 case RR_XOR:
d75c135e 12265 gen_logic(ctx, OPC_XOR, rx, rx, ry);
364d4831
NF
12266 break;
12267 case RR_NOT:
d75c135e 12268 gen_logic(ctx, OPC_NOR, rx, ry, 0);
364d4831
NF
12269 break;
12270 case RR_MFHI:
26135ead 12271 gen_HILO(ctx, OPC_MFHI, 0, rx);
364d4831
NF
12272 break;
12273 case RR_CNVT:
d9224450 12274 check_insn(ctx, ISA_MIPS32);
364d4831
NF
12275 switch (cnvt_op) {
12276 case RR_RY_CNVT_ZEB:
12277 tcg_gen_ext8u_tl(cpu_gpr[rx], cpu_gpr[rx]);
12278 break;
12279 case RR_RY_CNVT_ZEH:
12280 tcg_gen_ext16u_tl(cpu_gpr[rx], cpu_gpr[rx]);
12281 break;
12282 case RR_RY_CNVT_SEB:
12283 tcg_gen_ext8s_tl(cpu_gpr[rx], cpu_gpr[rx]);
12284 break;
12285 case RR_RY_CNVT_SEH:
12286 tcg_gen_ext16s_tl(cpu_gpr[rx], cpu_gpr[rx]);
12287 break;
12288#if defined (TARGET_MIPS64)
12289 case RR_RY_CNVT_ZEW:
d9224450 12290 check_insn(ctx, ISA_MIPS64);
364d4831
NF
12291 check_mips_64(ctx);
12292 tcg_gen_ext32u_tl(cpu_gpr[rx], cpu_gpr[rx]);
12293 break;
12294 case RR_RY_CNVT_SEW:
d9224450 12295 check_insn(ctx, ISA_MIPS64);
364d4831
NF
12296 check_mips_64(ctx);
12297 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
12298 break;
12299#endif
12300 default:
9c708c7f 12301 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
12302 break;
12303 }
12304 break;
12305 case RR_MFLO:
26135ead 12306 gen_HILO(ctx, OPC_MFLO, 0, rx);
364d4831
NF
12307 break;
12308#if defined (TARGET_MIPS64)
12309 case RR_DSRA:
d9224450 12310 check_insn(ctx, ISA_MIPS3);
364d4831 12311 check_mips_64(ctx);
d75c135e 12312 gen_shift_imm(ctx, OPC_DSRA, ry, ry, sa);
364d4831
NF
12313 break;
12314 case RR_DSLLV:
d9224450 12315 check_insn(ctx, ISA_MIPS3);
364d4831 12316 check_mips_64(ctx);
d75c135e 12317 gen_shift(ctx, OPC_DSLLV, ry, rx, ry);
364d4831
NF
12318 break;
12319 case RR_DSRLV:
d9224450 12320 check_insn(ctx, ISA_MIPS3);
364d4831 12321 check_mips_64(ctx);
d75c135e 12322 gen_shift(ctx, OPC_DSRLV, ry, rx, ry);
364d4831
NF
12323 break;
12324 case RR_DSRAV:
d9224450 12325 check_insn(ctx, ISA_MIPS3);
364d4831 12326 check_mips_64(ctx);
d75c135e 12327 gen_shift(ctx, OPC_DSRAV, ry, rx, ry);
364d4831
NF
12328 break;
12329#endif
12330 case RR_MULT:
26135ead 12331 gen_muldiv(ctx, OPC_MULT, 0, rx, ry);
364d4831
NF
12332 break;
12333 case RR_MULTU:
26135ead 12334 gen_muldiv(ctx, OPC_MULTU, 0, rx, ry);
364d4831
NF
12335 break;
12336 case RR_DIV:
26135ead 12337 gen_muldiv(ctx, OPC_DIV, 0, rx, ry);
364d4831
NF
12338 break;
12339 case RR_DIVU:
26135ead 12340 gen_muldiv(ctx, OPC_DIVU, 0, rx, ry);
364d4831
NF
12341 break;
12342#if defined (TARGET_MIPS64)
12343 case RR_DMULT:
d9224450 12344 check_insn(ctx, ISA_MIPS3);
364d4831 12345 check_mips_64(ctx);
26135ead 12346 gen_muldiv(ctx, OPC_DMULT, 0, rx, ry);
364d4831
NF
12347 break;
12348 case RR_DMULTU:
d9224450 12349 check_insn(ctx, ISA_MIPS3);
364d4831 12350 check_mips_64(ctx);
26135ead 12351 gen_muldiv(ctx, OPC_DMULTU, 0, rx, ry);
364d4831
NF
12352 break;
12353 case RR_DDIV:
d9224450 12354 check_insn(ctx, ISA_MIPS3);
364d4831 12355 check_mips_64(ctx);
26135ead 12356 gen_muldiv(ctx, OPC_DDIV, 0, rx, ry);
364d4831
NF
12357 break;
12358 case RR_DDIVU:
d9224450 12359 check_insn(ctx, ISA_MIPS3);
364d4831 12360 check_mips_64(ctx);
26135ead 12361 gen_muldiv(ctx, OPC_DDIVU, 0, rx, ry);
364d4831
NF
12362 break;
12363#endif
12364 default:
9c708c7f 12365 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
12366 break;
12367 }
12368 break;
12369 case M16_OPC_EXTEND:
240ce26a 12370 decode_extended_mips16_opc(env, ctx);
364d4831
NF
12371 n_bytes = 4;
12372 break;
12373#if defined(TARGET_MIPS64)
12374 case M16_OPC_I64:
12375 funct = (ctx->opcode >> 8) & 0x7;
d75c135e 12376 decode_i64_mips16(ctx, ry, funct, offset, 0);
364d4831
NF
12377 break;
12378#endif
12379 default:
9c708c7f 12380 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
12381 break;
12382 }
12383
12384 return n_bytes;
12385}
12386
211da992 12387/* microMIPS extension to MIPS32/MIPS64 */
6af0bf9c 12388
211da992
CWR
12389/*
12390 * microMIPS32/microMIPS64 major opcodes
12391 *
12392 * 1. MIPS Architecture for Programmers Volume II-B:
12393 * The microMIPS32 Instruction Set (Revision 3.05)
12394 *
12395 * Table 6.2 microMIPS32 Encoding of Major Opcode Field
12396 *
12397 * 2. MIPS Architecture For Programmers Volume II-A:
12398 * The MIPS64 Instruction Set (Revision 3.51)
12399 */
6af0bf9c 12400
3c824109
NF
12401enum {
12402 POOL32A = 0x00,
12403 POOL16A = 0x01,
12404 LBU16 = 0x02,
12405 MOVE16 = 0x03,
12406 ADDI32 = 0x04,
3a1f4268
YK
12407 R6_LUI = 0x04,
12408 AUI = 0x04,
3c824109
NF
12409 LBU32 = 0x05,
12410 SB32 = 0x06,
12411 LB32 = 0x07,
12412
12413 POOL32B = 0x08,
12414 POOL16B = 0x09,
12415 LHU16 = 0x0a,
12416 ANDI16 = 0x0b,
12417 ADDIU32 = 0x0c,
12418 LHU32 = 0x0d,
12419 SH32 = 0x0e,
12420 LH32 = 0x0f,
12421
12422 POOL32I = 0x10,
12423 POOL16C = 0x11,
12424 LWSP16 = 0x12,
12425 POOL16D = 0x13,
12426 ORI32 = 0x14,
12427 POOL32F = 0x15,
211da992
CWR
12428 POOL32S = 0x16, /* MIPS64 */
12429 DADDIU32 = 0x17, /* MIPS64 */
3c824109
NF
12430
12431 POOL32C = 0x18,
12432 LWGP16 = 0x19,
12433 LW16 = 0x1a,
12434 POOL16E = 0x1b,
12435 XORI32 = 0x1c,
12436 JALS32 = 0x1d,
3a1f4268
YK
12437 BOVC = 0x1d,
12438 BEQC = 0x1d,
12439 BEQZALC = 0x1d,
3c824109 12440 ADDIUPC = 0x1e,
3a1f4268
YK
12441 PCREL = 0x1e,
12442 BNVC = 0x1f,
12443 BNEC = 0x1f,
12444 BNEZALC = 0x1f,
3c824109 12445
3a1f4268
YK
12446 R6_BEQZC = 0x20,
12447 JIC = 0x20,
3c824109
NF
12448 POOL16F = 0x21,
12449 SB16 = 0x22,
12450 BEQZ16 = 0x23,
3a1f4268 12451 BEQZC16 = 0x23,
3c824109
NF
12452 SLTI32 = 0x24,
12453 BEQ32 = 0x25,
3a1f4268 12454 BC = 0x25,
3c824109
NF
12455 SWC132 = 0x26,
12456 LWC132 = 0x27,
12457
3a1f4268 12458 /* 0x29 is reserved */
3c824109 12459 RES_29 = 0x29,
3a1f4268
YK
12460 R6_BNEZC = 0x28,
12461 JIALC = 0x28,
3c824109
NF
12462 SH16 = 0x2a,
12463 BNEZ16 = 0x2b,
3a1f4268 12464 BNEZC16 = 0x2b,
3c824109
NF
12465 SLTIU32 = 0x2c,
12466 BNE32 = 0x2d,
3a1f4268 12467 BALC = 0x2d,
3c824109
NF
12468 SDC132 = 0x2e,
12469 LDC132 = 0x2f,
12470
3a1f4268 12471 /* 0x31 is reserved */
3c824109 12472 RES_31 = 0x31,
3a1f4268
YK
12473 BLEZALC = 0x30,
12474 BGEZALC = 0x30,
12475 BGEUC = 0x30,
3c824109
NF
12476 SWSP16 = 0x32,
12477 B16 = 0x33,
3a1f4268 12478 BC16 = 0x33,
3c824109
NF
12479 ANDI32 = 0x34,
12480 J32 = 0x35,
3a1f4268
YK
12481 BGTZC = 0x35,
12482 BLTZC = 0x35,
12483 BLTC = 0x35,
211da992
CWR
12484 SD32 = 0x36, /* MIPS64 */
12485 LD32 = 0x37, /* MIPS64 */
3c824109 12486
3a1f4268 12487 /* 0x39 is reserved */
3c824109 12488 RES_39 = 0x39,
3a1f4268
YK
12489 BGTZALC = 0x38,
12490 BLTZALC = 0x38,
12491 BLTUC = 0x38,
3c824109
NF
12492 SW16 = 0x3a,
12493 LI16 = 0x3b,
12494 JALX32 = 0x3c,
12495 JAL32 = 0x3d,
3a1f4268
YK
12496 BLEZC = 0x3d,
12497 BGEZC = 0x3d,
12498 BGEC = 0x3d,
3c824109
NF
12499 SW32 = 0x3e,
12500 LW32 = 0x3f
12501};
12502
3a1f4268
YK
12503/* PCREL Instructions perform PC-Relative address calculation. bits 20..16 */
12504enum {
12505 ADDIUPC_00 = 0x00,
c38a1d52
AR
12506 ADDIUPC_01 = 0x01,
12507 ADDIUPC_02 = 0x02,
12508 ADDIUPC_03 = 0x03,
12509 ADDIUPC_04 = 0x04,
12510 ADDIUPC_05 = 0x05,
12511 ADDIUPC_06 = 0x06,
3a1f4268
YK
12512 ADDIUPC_07 = 0x07,
12513 AUIPC = 0x1e,
12514 ALUIPC = 0x1f,
12515 LWPC_08 = 0x08,
c38a1d52
AR
12516 LWPC_09 = 0x09,
12517 LWPC_0A = 0x0A,
12518 LWPC_0B = 0x0B,
12519 LWPC_0C = 0x0C,
12520 LWPC_0D = 0x0D,
12521 LWPC_0E = 0x0E,
3a1f4268
YK
12522 LWPC_0F = 0x0F,
12523};
12524
3c824109
NF
12525/* POOL32A encoding of minor opcode field */
12526
12527enum {
12528 /* These opcodes are distinguished only by bits 9..6; those bits are
12529 * what are recorded below. */
12530 SLL32 = 0x0,
12531 SRL32 = 0x1,
12532 SRA = 0x2,
12533 ROTR = 0x3,
3a1f4268
YK
12534 SELEQZ = 0x5,
12535 SELNEZ = 0x6,
b00c7218 12536 R6_RDHWR = 0x7,
3c824109
NF
12537
12538 SLLV = 0x0,
12539 SRLV = 0x1,
12540 SRAV = 0x2,
12541 ROTRV = 0x3,
12542 ADD = 0x4,
12543 ADDU32 = 0x5,
12544 SUB = 0x6,
12545 SUBU32 = 0x7,
12546 MUL = 0x8,
12547 AND = 0x9,
12548 OR32 = 0xa,
12549 NOR = 0xb,
12550 XOR32 = 0xc,
12551 SLT = 0xd,
12552 SLTU = 0xe,
12553
12554 MOVN = 0x0,
3a1f4268 12555 R6_MUL = 0x0,
3c824109 12556 MOVZ = 0x1,
3a1f4268
YK
12557 MUH = 0x1,
12558 MULU = 0x2,
12559 MUHU = 0x3,
3c824109 12560 LWXS = 0x4,
3a1f4268
YK
12561 R6_DIV = 0x4,
12562 MOD = 0x5,
12563 R6_DIVU = 0x6,
12564 MODU = 0x7,
3c824109
NF
12565
12566 /* The following can be distinguished by their lower 6 bits. */
dbd8af98 12567 BREAK32 = 0x07,
3c824109 12568 INS = 0x0c,
3a1f4268
YK
12569 LSA = 0x0f,
12570 ALIGN = 0x1f,
3c824109 12571 EXT = 0x2c,
bb238210
YK
12572 POOL32AXF = 0x3c,
12573 SIGRIE = 0x3f
3c824109
NF
12574};
12575
12576/* POOL32AXF encoding of minor opcode field extension */
12577
d132c79f
CWR
12578/*
12579 * 1. MIPS Architecture for Programmers Volume II-B:
12580 * The microMIPS32 Instruction Set (Revision 3.05)
12581 *
12582 * Table 6.5 POOL32Axf Encoding of Minor Opcode Extension Field
12583 *
12584 * 2. MIPS Architecture for Programmers VolumeIV-e:
12585 * The MIPS DSP Application-Specific Extension
12586 * to the microMIPS32 Architecture (Revision 2.34)
12587 *
12588 * Table 5.5 POOL32Axf Encoding of Minor Opcode Extension Field
12589 */
12590
3c824109
NF
12591enum {
12592 /* bits 11..6 */
12593 TEQ = 0x00,
12594 TGE = 0x08,
12595 TGEU = 0x10,
12596 TLT = 0x20,
12597 TLTU = 0x28,
12598 TNE = 0x30,
12599
12600 MFC0 = 0x03,
12601 MTC0 = 0x0b,
12602
d132c79f
CWR
12603 /* begin of microMIPS32 DSP */
12604
3c824109
NF
12605 /* bits 13..12 for 0x01 */
12606 MFHI_ACC = 0x0,
12607 MFLO_ACC = 0x1,
12608 MTHI_ACC = 0x2,
12609 MTLO_ACC = 0x3,
12610
12611 /* bits 13..12 for 0x2a */
12612 MADD_ACC = 0x0,
12613 MADDU_ACC = 0x1,
12614 MSUB_ACC = 0x2,
12615 MSUBU_ACC = 0x3,
12616
12617 /* bits 13..12 for 0x32 */
12618 MULT_ACC = 0x0,
6801038b 12619 MULTU_ACC = 0x1,
3c824109 12620
d132c79f
CWR
12621 /* end of microMIPS32 DSP */
12622
3c824109 12623 /* bits 15..12 for 0x2c */
3a1f4268 12624 BITSWAP = 0x0,
3c824109
NF
12625 SEB = 0x2,
12626 SEH = 0x3,
12627 CLO = 0x4,
12628 CLZ = 0x5,
12629 RDHWR = 0x6,
12630 WSBH = 0x7,
12631 MULT = 0x8,
12632 MULTU = 0x9,
12633 DIV = 0xa,
12634 DIVU = 0xb,
12635 MADD = 0xc,
12636 MADDU = 0xd,
12637 MSUB = 0xe,
12638 MSUBU = 0xf,
12639
12640 /* bits 15..12 for 0x34 */
12641 MFC2 = 0x4,
12642 MTC2 = 0x5,
12643 MFHC2 = 0x8,
12644 MTHC2 = 0x9,
12645 CFC2 = 0xc,
12646 CTC2 = 0xd,
12647
12648 /* bits 15..12 for 0x3c */
12649 JALR = 0x0,
12650 JR = 0x0, /* alias */
3a1f4268
YK
12651 JALRC = 0x0,
12652 JRC = 0x0,
3c824109 12653 JALR_HB = 0x1,
3a1f4268 12654 JALRC_HB = 0x1,
3c824109
NF
12655 JALRS = 0x4,
12656 JALRS_HB = 0x5,
12657
12658 /* bits 15..12 for 0x05 */
12659 RDPGPR = 0xe,
12660 WRPGPR = 0xf,
12661
12662 /* bits 15..12 for 0x0d */
12663 TLBP = 0x0,
12664 TLBR = 0x1,
12665 TLBWI = 0x2,
12666 TLBWR = 0x3,
e60ec063
YK
12667 TLBINV = 0x4,
12668 TLBINVF = 0x5,
3c824109
NF
12669 WAIT = 0x9,
12670 IRET = 0xd,
12671 DERET = 0xe,
12672 ERET = 0xf,
12673
12674 /* bits 15..12 for 0x15 */
12675 DMT = 0x0,
12676 DVPE = 0x1,
12677 EMT = 0x2,
12678 EVPE = 0x3,
12679
12680 /* bits 15..12 for 0x1d */
12681 DI = 0x4,
12682 EI = 0x5,
12683
12684 /* bits 15..12 for 0x2d */
12685 SYNC = 0x6,
12686 SYSCALL = 0x8,
12687 SDBBP = 0xd,
12688
12689 /* bits 15..12 for 0x35 */
12690 MFHI32 = 0x0,
12691 MFLO32 = 0x1,
12692 MTHI32 = 0x2,
12693 MTLO32 = 0x3,
12694};
12695
12696/* POOL32B encoding of minor opcode field (bits 15..12) */
12697
12698enum {
12699 LWC2 = 0x0,
12700 LWP = 0x1,
12701 LDP = 0x4,
12702 LWM32 = 0x5,
12703 CACHE = 0x6,
12704 LDM = 0x7,
12705 SWC2 = 0x8,
12706 SWP = 0x9,
12707 SDP = 0xc,
12708 SWM32 = 0xd,
12709 SDM = 0xf
12710};
12711
12712/* POOL32C encoding of minor opcode field (bits 15..12) */
12713
12714enum {
12715 LWL = 0x0,
12716 SWL = 0x8,
12717 LWR = 0x1,
12718 SWR = 0x9,
12719 PREF = 0x2,
8fffc646 12720 ST_EVA = 0xa,
3c824109
NF
12721 LL = 0x3,
12722 SC = 0xb,
12723 LDL = 0x4,
12724 SDL = 0xc,
12725 LDR = 0x5,
12726 SDR = 0xd,
8fffc646 12727 LD_EVA = 0x6,
3c824109
NF
12728 LWU = 0xe,
12729 LLD = 0x7,
12730 SCD = 0xf
12731};
12732
8fffc646
JH
12733/* POOL32C LD-EVA encoding of minor opcode field (bits 11..9) */
12734
12735enum {
12736 LBUE = 0x0,
12737 LHUE = 0x1,
12738 LWLE = 0x2,
12739 LWRE = 0x3,
12740 LBE = 0x4,
12741 LHE = 0x5,
12742 LLE = 0x6,
12743 LWE = 0x7,
12744};
12745
12746/* POOL32C ST-EVA encoding of minor opcode field (bits 11..9) */
12747
12748enum {
12749 SWLE = 0x0,
12750 SWRE = 0x1,
12751 PREFE = 0x2,
12752 CACHEE = 0x3,
12753 SBE = 0x4,
12754 SHE = 0x5,
12755 SCE = 0x6,
12756 SWE = 0x7,
12757};
12758
3c824109
NF
12759/* POOL32F encoding of minor opcode field (bits 5..0) */
12760
12761enum {
12762 /* These are the bit 7..6 values */
12763 ADD_FMT = 0x0,
3c824109
NF
12764
12765 SUB_FMT = 0x1,
3c824109
NF
12766
12767 MUL_FMT = 0x2,
12768
12769 DIV_FMT = 0x3,
12770
12771 /* These are the bit 8..6 values */
3a1f4268 12772 MOVN_FMT = 0x0,
3c824109
NF
12773 RSQRT2_FMT = 0x0,
12774 MOVF_FMT = 0x0,
3a1f4268
YK
12775 RINT_FMT = 0x0,
12776 SELNEZ_FMT = 0x0,
3c824109 12777
3a1f4268 12778 MOVZ_FMT = 0x1,
3c824109
NF
12779 LWXC1 = 0x1,
12780 MOVT_FMT = 0x1,
3a1f4268
YK
12781 CLASS_FMT = 0x1,
12782 SELEQZ_FMT = 0x1,
3c824109
NF
12783
12784 PLL_PS = 0x2,
12785 SWXC1 = 0x2,
3a1f4268 12786 SEL_FMT = 0x2,
3c824109
NF
12787
12788 PLU_PS = 0x3,
12789 LDXC1 = 0x3,
12790
3a1f4268 12791 MOVN_FMT_04 = 0x4,
3c824109
NF
12792 PUL_PS = 0x4,
12793 SDXC1 = 0x4,
12794 RECIP2_FMT = 0x4,
12795
3a1f4268 12796 MOVZ_FMT_05 = 0x05,
3c824109
NF
12797 PUU_PS = 0x5,
12798 LUXC1 = 0x5,
12799
12800 CVT_PS_S = 0x6,
12801 SUXC1 = 0x6,
12802 ADDR_PS = 0x6,
12803 PREFX = 0x6,
3a1f4268 12804 MADDF_FMT = 0x6,
3c824109
NF
12805
12806 MULR_PS = 0x7,
3a1f4268 12807 MSUBF_FMT = 0x7,
3c824109
NF
12808
12809 MADD_S = 0x01,
12810 MADD_D = 0x09,
12811 MADD_PS = 0x11,
12812 ALNV_PS = 0x19,
12813 MSUB_S = 0x21,
12814 MSUB_D = 0x29,
12815 MSUB_PS = 0x31,
12816
12817 NMADD_S = 0x02,
12818 NMADD_D = 0x0a,
12819 NMADD_PS = 0x12,
12820 NMSUB_S = 0x22,
12821 NMSUB_D = 0x2a,
12822 NMSUB_PS = 0x32,
12823
3a1f4268
YK
12824 MIN_FMT = 0x3,
12825 MAX_FMT = 0xb,
12826 MINA_FMT = 0x23,
12827 MAXA_FMT = 0x2b,
3c824109
NF
12828 POOL32FXF = 0x3b,
12829
12830 CABS_COND_FMT = 0x1c, /* MIPS3D */
3a1f4268
YK
12831 C_COND_FMT = 0x3c,
12832
12833 CMP_CONDN_S = 0x5,
12834 CMP_CONDN_D = 0x15
3c824109
NF
12835};
12836
12837/* POOL32Fxf encoding of minor opcode extension field */
12838
12839enum {
12840 CVT_L = 0x04,
12841 RSQRT_FMT = 0x08,
12842 FLOOR_L = 0x0c,
12843 CVT_PW_PS = 0x1c,
12844 CVT_W = 0x24,
12845 SQRT_FMT = 0x28,
12846 FLOOR_W = 0x2c,
12847 CVT_PS_PW = 0x3c,
12848 CFC1 = 0x40,
12849 RECIP_FMT = 0x48,
12850 CEIL_L = 0x4c,
12851 CTC1 = 0x60,
12852 CEIL_W = 0x6c,
12853 MFC1 = 0x80,
12854 CVT_S_PL = 0x84,
12855 TRUNC_L = 0x8c,
12856 MTC1 = 0xa0,
12857 CVT_S_PU = 0xa4,
12858 TRUNC_W = 0xac,
12859 MFHC1 = 0xc0,
12860 ROUND_L = 0xcc,
12861 MTHC1 = 0xe0,
12862 ROUND_W = 0xec,
12863
12864 MOV_FMT = 0x01,
12865 MOVF = 0x05,
12866 ABS_FMT = 0x0d,
12867 RSQRT1_FMT = 0x1d,
12868 MOVT = 0x25,
12869 NEG_FMT = 0x2d,
12870 CVT_D = 0x4d,
12871 RECIP1_FMT = 0x5d,
12872 CVT_S = 0x6d
12873};
12874
12875/* POOL32I encoding of minor opcode field (bits 25..21) */
12876
12877enum {
12878 BLTZ = 0x00,
12879 BLTZAL = 0x01,
12880 BGEZ = 0x02,
12881 BGEZAL = 0x03,
12882 BLEZ = 0x04,
12883 BNEZC = 0x05,
12884 BGTZ = 0x06,
12885 BEQZC = 0x07,
12886 TLTI = 0x08,
3a1f4268 12887 BC1EQZC = 0x08,
3c824109 12888 TGEI = 0x09,
3a1f4268 12889 BC1NEZC = 0x09,
3c824109 12890 TLTIU = 0x0a,
3a1f4268 12891 BC2EQZC = 0x0a,
3c824109 12892 TGEIU = 0x0b,
3a1f4268 12893 BC2NEZC = 0x0a,
3c824109 12894 TNEI = 0x0c,
3a1f4268 12895 R6_SYNCI = 0x0c,
3c824109
NF
12896 LUI = 0x0d,
12897 TEQI = 0x0e,
12898 SYNCI = 0x10,
12899 BLTZALS = 0x11,
12900 BGEZALS = 0x13,
12901 BC2F = 0x14,
12902 BC2T = 0x15,
12903 BPOSGE64 = 0x1a,
12904 BPOSGE32 = 0x1b,
12905 /* These overlap and are distinguished by bit16 of the instruction */
12906 BC1F = 0x1c,
12907 BC1T = 0x1d,
12908 BC1ANY2F = 0x1c,
12909 BC1ANY2T = 0x1d,
12910 BC1ANY4F = 0x1e,
12911 BC1ANY4T = 0x1f
12912};
12913
12914/* POOL16A encoding of minor opcode field */
12915
12916enum {
12917 ADDU16 = 0x0,
12918 SUBU16 = 0x1
12919};
12920
12921/* POOL16B encoding of minor opcode field */
12922
12923enum {
12924 SLL16 = 0x0,
12925 SRL16 = 0x1
12926};
12927
12928/* POOL16C encoding of minor opcode field */
12929
12930enum {
12931 NOT16 = 0x00,
12932 XOR16 = 0x04,
12933 AND16 = 0x08,
12934 OR16 = 0x0c,
12935 LWM16 = 0x10,
12936 SWM16 = 0x14,
12937 JR16 = 0x18,
12938 JRC16 = 0x1a,
12939 JALR16 = 0x1c,
12940 JALR16S = 0x1e,
12941 MFHI16 = 0x20,
12942 MFLO16 = 0x24,
12943 BREAK16 = 0x28,
12944 SDBBP16 = 0x2c,
12945 JRADDIUSP = 0x30
12946};
12947
3a1f4268
YK
12948/* R6 POOL16C encoding of minor opcode field (bits 0..5) */
12949
12950enum {
12951 R6_NOT16 = 0x00,
12952 R6_AND16 = 0x01,
12953 R6_LWM16 = 0x02,
12954 R6_JRC16 = 0x03,
12955 MOVEP = 0x04,
c38a1d52
AR
12956 MOVEP_05 = 0x05,
12957 MOVEP_06 = 0x06,
3a1f4268
YK
12958 MOVEP_07 = 0x07,
12959 R6_XOR16 = 0x08,
12960 R6_OR16 = 0x09,
12961 R6_SWM16 = 0x0a,
12962 JALRC16 = 0x0b,
12963 MOVEP_0C = 0x0c,
c38a1d52
AR
12964 MOVEP_0D = 0x0d,
12965 MOVEP_0E = 0x0e,
3a1f4268
YK
12966 MOVEP_0F = 0x0f,
12967 JRCADDIUSP = 0x13,
12968 R6_BREAK16 = 0x1b,
12969 R6_SDBBP16 = 0x3b
12970};
12971
3c824109
NF
12972/* POOL16D encoding of minor opcode field */
12973
12974enum {
12975 ADDIUS5 = 0x0,
12976 ADDIUSP = 0x1
12977};
12978
12979/* POOL16E encoding of minor opcode field */
12980
12981enum {
12982 ADDIUR2 = 0x0,
12983 ADDIUR1SP = 0x1
12984};
12985
12986static int mmreg (int r)
12987{
12988 static const int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
12989
12990 return map[r];
12991}
12992
12993/* Used for 16-bit store instructions. */
12994static int mmreg2 (int r)
12995{
12996 static const int map[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
12997
12998 return map[r];
12999}
13000
13001#define uMIPS_RD(op) ((op >> 7) & 0x7)
13002#define uMIPS_RS(op) ((op >> 4) & 0x7)
13003#define uMIPS_RS2(op) uMIPS_RS(op)
13004#define uMIPS_RS1(op) ((op >> 1) & 0x7)
13005#define uMIPS_RD5(op) ((op >> 5) & 0x1f)
13006#define uMIPS_RS5(op) (op & 0x1f)
13007
13008/* Signed immediate */
13009#define SIMM(op, start, width) \
13010 ((int32_t)(((op >> start) & ((~0U) >> (32-width))) \
13011 << (32-width)) \
13012 >> (32-width))
13013/* Zero-extended immediate */
13014#define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
13015
d75c135e 13016static void gen_addiur1sp(DisasContext *ctx)
3c824109
NF
13017{
13018 int rd = mmreg(uMIPS_RD(ctx->opcode));
13019
d75c135e 13020 gen_arith_imm(ctx, OPC_ADDIU, rd, 29, ((ctx->opcode >> 1) & 0x3f) << 2);
3c824109
NF
13021}
13022
d75c135e 13023static void gen_addiur2(DisasContext *ctx)
3c824109
NF
13024{
13025 static const int decoded_imm[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
13026 int rd = mmreg(uMIPS_RD(ctx->opcode));
13027 int rs = mmreg(uMIPS_RS(ctx->opcode));
13028
d75c135e 13029 gen_arith_imm(ctx, OPC_ADDIU, rd, rs, decoded_imm[ZIMM(ctx->opcode, 1, 3)]);
3c824109
NF
13030}
13031
d75c135e 13032static void gen_addiusp(DisasContext *ctx)
3c824109
NF
13033{
13034 int encoded = ZIMM(ctx->opcode, 1, 9);
13035 int decoded;
13036
13037 if (encoded <= 1) {
13038 decoded = 256 + encoded;
13039 } else if (encoded <= 255) {
13040 decoded = encoded;
13041 } else if (encoded <= 509) {
13042 decoded = encoded - 512;
13043 } else {
13044 decoded = encoded - 768;
13045 }
13046
d75c135e 13047 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, decoded << 2);
3c824109
NF
13048}
13049
d75c135e 13050static void gen_addius5(DisasContext *ctx)
3c824109
NF
13051{
13052 int imm = SIMM(ctx->opcode, 1, 4);
13053 int rd = (ctx->opcode >> 5) & 0x1f;
13054
d75c135e 13055 gen_arith_imm(ctx, OPC_ADDIU, rd, rd, imm);
3c824109
NF
13056}
13057
d75c135e 13058static void gen_andi16(DisasContext *ctx)
3c824109
NF
13059{
13060 static const int decoded_imm[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
13061 31, 32, 63, 64, 255, 32768, 65535 };
13062 int rd = mmreg(uMIPS_RD(ctx->opcode));
13063 int rs = mmreg(uMIPS_RS(ctx->opcode));
13064 int encoded = ZIMM(ctx->opcode, 0, 4);
13065
d75c135e 13066 gen_logic_imm(ctx, OPC_ANDI, rd, rs, decoded_imm[encoded]);
3c824109
NF
13067}
13068
13069static void gen_ldst_multiple (DisasContext *ctx, uint32_t opc, int reglist,
13070 int base, int16_t offset)
13071{
13072 TCGv t0, t1;
13073 TCGv_i32 t2;
13074
13075 if (ctx->hflags & MIPS_HFLAG_BMASK) {
9c708c7f 13076 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
13077 return;
13078 }
13079
13080 t0 = tcg_temp_new();
13081
13082 gen_base_offset_addr(ctx, t0, base, offset);
13083
13084 t1 = tcg_const_tl(reglist);
13085 t2 = tcg_const_i32(ctx->mem_idx);
6af0bf9c 13086
3c824109
NF
13087 save_cpu_state(ctx, 1);
13088 switch (opc) {
13089 case LWM32:
895c2d04 13090 gen_helper_lwm(cpu_env, t0, t1, t2);
3c824109
NF
13091 break;
13092 case SWM32:
895c2d04 13093 gen_helper_swm(cpu_env, t0, t1, t2);
3c824109
NF
13094 break;
13095#ifdef TARGET_MIPS64
13096 case LDM:
895c2d04 13097 gen_helper_ldm(cpu_env, t0, t1, t2);
3c824109
NF
13098 break;
13099 case SDM:
895c2d04 13100 gen_helper_sdm(cpu_env, t0, t1, t2);
3c824109 13101 break;
6af0bf9c 13102#endif
3c824109 13103 }
3c824109 13104 tcg_temp_free(t0);
33087598 13105 tcg_temp_free(t1);
3c824109
NF
13106 tcg_temp_free_i32(t2);
13107}
6af0bf9c 13108
3c824109 13109
240ce26a 13110static void gen_pool16c_insn(DisasContext *ctx)
6af0bf9c 13111{
3c824109
NF
13112 int rd = mmreg((ctx->opcode >> 3) & 0x7);
13113 int rs = mmreg(ctx->opcode & 0x7);
6af0bf9c 13114
3c824109
NF
13115 switch (((ctx->opcode) >> 4) & 0x3f) {
13116 case NOT16 + 0:
13117 case NOT16 + 1:
13118 case NOT16 + 2:
13119 case NOT16 + 3:
d75c135e 13120 gen_logic(ctx, OPC_NOR, rd, rs, 0);
3c824109
NF
13121 break;
13122 case XOR16 + 0:
13123 case XOR16 + 1:
13124 case XOR16 + 2:
13125 case XOR16 + 3:
d75c135e 13126 gen_logic(ctx, OPC_XOR, rd, rd, rs);
3c824109
NF
13127 break;
13128 case AND16 + 0:
13129 case AND16 + 1:
13130 case AND16 + 2:
13131 case AND16 + 3:
d75c135e 13132 gen_logic(ctx, OPC_AND, rd, rd, rs);
3c824109
NF
13133 break;
13134 case OR16 + 0:
13135 case OR16 + 1:
13136 case OR16 + 2:
13137 case OR16 + 3:
d75c135e 13138 gen_logic(ctx, OPC_OR, rd, rd, rs);
3c824109
NF
13139 break;
13140 case LWM16 + 0:
13141 case LWM16 + 1:
13142 case LWM16 + 2:
13143 case LWM16 + 3:
13144 {
13145 static const int lwm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
13146 int offset = ZIMM(ctx->opcode, 0, 4);
13147
13148 gen_ldst_multiple(ctx, LWM32, lwm_convert[(ctx->opcode >> 4) & 0x3],
13149 29, offset << 2);
13150 }
13151 break;
13152 case SWM16 + 0:
13153 case SWM16 + 1:
13154 case SWM16 + 2:
13155 case SWM16 + 3:
13156 {
13157 static const int swm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
13158 int offset = ZIMM(ctx->opcode, 0, 4);
13159
13160 gen_ldst_multiple(ctx, SWM32, swm_convert[(ctx->opcode >> 4) & 0x3],
13161 29, offset << 2);
13162 }
13163 break;
13164 case JR16 + 0:
13165 case JR16 + 1:
13166 {
13167 int reg = ctx->opcode & 0x1f;
13168
b231c103 13169 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 4);
3c824109 13170 }
3c824109
NF
13171 break;
13172 case JRC16 + 0:
13173 case JRC16 + 1:
13174 {
13175 int reg = ctx->opcode & 0x1f;
b231c103 13176 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 0);
3c824109
NF
13177 /* Let normal delay slot handling in our caller take us
13178 to the branch target. */
13179 }
13180 break;
13181 case JALR16 + 0:
13182 case JALR16 + 1:
b231c103
YK
13183 gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 4);
13184 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
13185 break;
3c824109
NF
13186 case JALR16S + 0:
13187 case JALR16S + 1:
b231c103
YK
13188 gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 2);
13189 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
3c824109
NF
13190 break;
13191 case MFHI16 + 0:
13192 case MFHI16 + 1:
26135ead 13193 gen_HILO(ctx, OPC_MFHI, 0, uMIPS_RS5(ctx->opcode));
3c824109
NF
13194 break;
13195 case MFLO16 + 0:
13196 case MFLO16 + 1:
26135ead 13197 gen_HILO(ctx, OPC_MFLO, 0, uMIPS_RS5(ctx->opcode));
3c824109
NF
13198 break;
13199 case BREAK16:
9c708c7f 13200 generate_exception_end(ctx, EXCP_BREAK);
3c824109
NF
13201 break;
13202 case SDBBP16:
3b3c1694
LA
13203 if (is_uhi(extract32(ctx->opcode, 0, 4))) {
13204 gen_helper_do_semihosting(cpu_env);
13205 } else {
13206 /* XXX: not clear which exception should be raised
13207 * when in debug mode...
13208 */
13209 check_insn(ctx, ISA_MIPS32);
9c708c7f 13210 generate_exception_end(ctx, EXCP_DBp);
3b3c1694 13211 }
3c824109
NF
13212 break;
13213 case JRADDIUSP + 0:
13214 case JRADDIUSP + 1:
13215 {
13216 int imm = ZIMM(ctx->opcode, 0, 5);
b231c103 13217 gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0, 0);
d75c135e 13218 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
3c824109
NF
13219 /* Let normal delay slot handling in our caller take us
13220 to the branch target. */
13221 }
13222 break;
13223 default:
9c708c7f 13224 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
13225 break;
13226 }
13227}
13228
ed7ce6c0
YK
13229static inline void gen_movep(DisasContext *ctx, int enc_dest, int enc_rt,
13230 int enc_rs)
13231{
13232 int rd, rs, re, rt;
13233 static const int rd_enc[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
13234 static const int re_enc[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
13235 static const int rs_rt_enc[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
13236 rd = rd_enc[enc_dest];
13237 re = re_enc[enc_dest];
13238 rs = rs_rt_enc[enc_rs];
13239 rt = rs_rt_enc[enc_rt];
13240 if (rs) {
13241 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
13242 } else {
13243 tcg_gen_movi_tl(cpu_gpr[rd], 0);
13244 }
13245 if (rt) {
13246 tcg_gen_mov_tl(cpu_gpr[re], cpu_gpr[rt]);
13247 } else {
13248 tcg_gen_movi_tl(cpu_gpr[re], 0);
13249 }
13250}
13251
13252static void gen_pool16c_r6_insn(DisasContext *ctx)
13253{
13254 int rt = mmreg((ctx->opcode >> 7) & 0x7);
13255 int rs = mmreg((ctx->opcode >> 4) & 0x7);
13256
13257 switch (ctx->opcode & 0xf) {
13258 case R6_NOT16:
13259 gen_logic(ctx, OPC_NOR, rt, rs, 0);
13260 break;
13261 case R6_AND16:
13262 gen_logic(ctx, OPC_AND, rt, rt, rs);
13263 break;
13264 case R6_LWM16:
13265 {
13266 int lwm_converted = 0x11 + extract32(ctx->opcode, 8, 2);
13267 int offset = extract32(ctx->opcode, 4, 4);
13268 gen_ldst_multiple(ctx, LWM32, lwm_converted, 29, offset << 2);
13269 }
13270 break;
13271 case R6_JRC16: /* JRCADDIUSP */
13272 if ((ctx->opcode >> 4) & 1) {
13273 /* JRCADDIUSP */
13274 int imm = extract32(ctx->opcode, 5, 5);
13275 gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0, 0);
13276 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
13277 } else {
13278 /* JRC16 */
13279 int rs = extract32(ctx->opcode, 5, 5);
13280 gen_compute_branch(ctx, OPC_JR, 2, rs, 0, 0, 0);
13281 }
13282 break;
c38a1d52
AR
13283 case MOVEP:
13284 case MOVEP_05:
13285 case MOVEP_06:
13286 case MOVEP_07:
13287 case MOVEP_0C:
13288 case MOVEP_0D:
13289 case MOVEP_0E:
13290 case MOVEP_0F:
ed7ce6c0
YK
13291 {
13292 int enc_dest = uMIPS_RD(ctx->opcode);
13293 int enc_rt = uMIPS_RS2(ctx->opcode);
13294 int enc_rs = (ctx->opcode & 3) | ((ctx->opcode >> 1) & 4);
13295 gen_movep(ctx, enc_dest, enc_rt, enc_rs);
13296 }
13297 break;
13298 case R6_XOR16:
13299 gen_logic(ctx, OPC_XOR, rt, rt, rs);
13300 break;
13301 case R6_OR16:
13302 gen_logic(ctx, OPC_OR, rt, rt, rs);
13303 break;
13304 case R6_SWM16:
13305 {
13306 int swm_converted = 0x11 + extract32(ctx->opcode, 8, 2);
13307 int offset = extract32(ctx->opcode, 4, 4);
13308 gen_ldst_multiple(ctx, SWM32, swm_converted, 29, offset << 2);
13309 }
13310 break;
13311 case JALRC16: /* BREAK16, SDBBP16 */
13312 switch (ctx->opcode & 0x3f) {
13313 case JALRC16:
13314 case JALRC16 + 0x20:
13315 /* JALRC16 */
13316 gen_compute_branch(ctx, OPC_JALR, 2, (ctx->opcode >> 5) & 0x1f,
13317 31, 0, 0);
13318 break;
13319 case R6_BREAK16:
13320 /* BREAK16 */
13321 generate_exception(ctx, EXCP_BREAK);
13322 break;
13323 case R6_SDBBP16:
13324 /* SDBBP16 */
060ebfef
LA
13325 if (is_uhi(extract32(ctx->opcode, 6, 4))) {
13326 gen_helper_do_semihosting(cpu_env);
ed7ce6c0 13327 } else {
060ebfef
LA
13328 if (ctx->hflags & MIPS_HFLAG_SBRI) {
13329 generate_exception(ctx, EXCP_RI);
13330 } else {
13331 generate_exception(ctx, EXCP_DBp);
13332 }
ed7ce6c0
YK
13333 }
13334 break;
13335 }
13336 break;
13337 default:
13338 generate_exception(ctx, EXCP_RI);
13339 break;
13340 }
13341}
13342
3c824109
NF
13343static void gen_ldxs (DisasContext *ctx, int base, int index, int rd)
13344{
13345 TCGv t0 = tcg_temp_new();
13346 TCGv t1 = tcg_temp_new();
13347
13348 gen_load_gpr(t0, base);
13349
13350 if (index != 0) {
13351 gen_load_gpr(t1, index);
13352 tcg_gen_shli_tl(t1, t1, 2);
13353 gen_op_addr_add(ctx, t0, t1, t0);
13354 }
13355
5f68f5ae 13356 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
3c824109
NF
13357 gen_store_gpr(t1, rd);
13358
13359 tcg_temp_free(t0);
13360 tcg_temp_free(t1);
13361}
13362
13363static void gen_ldst_pair (DisasContext *ctx, uint32_t opc, int rd,
13364 int base, int16_t offset)
13365{
3c824109
NF
13366 TCGv t0, t1;
13367
36c6711b 13368 if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31) {
9c708c7f 13369 generate_exception_end(ctx, EXCP_RI);
d796321b
FB
13370 return;
13371 }
13372
3c824109
NF
13373 t0 = tcg_temp_new();
13374 t1 = tcg_temp_new();
8e9ade68 13375
3c824109
NF
13376 gen_base_offset_addr(ctx, t0, base, offset);
13377
13378 switch (opc) {
13379 case LWP:
36c6711b 13380 if (rd == base) {
9c708c7f 13381 generate_exception_end(ctx, EXCP_RI);
36c6711b
EJ
13382 return;
13383 }
5f68f5ae 13384 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
3c824109
NF
13385 gen_store_gpr(t1, rd);
13386 tcg_gen_movi_tl(t1, 4);
13387 gen_op_addr_add(ctx, t0, t0, t1);
5f68f5ae 13388 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
3c824109 13389 gen_store_gpr(t1, rd+1);
3c824109
NF
13390 break;
13391 case SWP:
3c824109 13392 gen_load_gpr(t1, rd);
5f68f5ae 13393 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
3c824109
NF
13394 tcg_gen_movi_tl(t1, 4);
13395 gen_op_addr_add(ctx, t0, t0, t1);
13396 gen_load_gpr(t1, rd+1);
5f68f5ae 13397 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
3c824109
NF
13398 break;
13399#ifdef TARGET_MIPS64
13400 case LDP:
36c6711b 13401 if (rd == base) {
9c708c7f 13402 generate_exception_end(ctx, EXCP_RI);
36c6711b
EJ
13403 return;
13404 }
5f68f5ae 13405 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
3c824109
NF
13406 gen_store_gpr(t1, rd);
13407 tcg_gen_movi_tl(t1, 8);
13408 gen_op_addr_add(ctx, t0, t0, t1);
5f68f5ae 13409 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
3c824109 13410 gen_store_gpr(t1, rd+1);
3c824109
NF
13411 break;
13412 case SDP:
3c824109 13413 gen_load_gpr(t1, rd);
5f68f5ae 13414 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
3c824109
NF
13415 tcg_gen_movi_tl(t1, 8);
13416 gen_op_addr_add(ctx, t0, t0, t1);
13417 gen_load_gpr(t1, rd+1);
5f68f5ae 13418 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
3c824109
NF
13419 break;
13420#endif
6af0bf9c 13421 }
3c824109
NF
13422 tcg_temp_free(t0);
13423 tcg_temp_free(t1);
13424}
618b0fe9 13425
d208ac0c
LA
13426static void gen_sync(int stype)
13427{
13428 TCGBar tcg_mo = TCG_BAR_SC;
13429
13430 switch (stype) {
13431 case 0x4: /* SYNC_WMB */
13432 tcg_mo |= TCG_MO_ST_ST;
13433 break;
13434 case 0x10: /* SYNC_MB */
13435 tcg_mo |= TCG_MO_ALL;
13436 break;
13437 case 0x11: /* SYNC_ACQUIRE */
13438 tcg_mo |= TCG_MO_LD_LD | TCG_MO_LD_ST;
13439 break;
13440 case 0x12: /* SYNC_RELEASE */
13441 tcg_mo |= TCG_MO_ST_ST | TCG_MO_LD_ST;
13442 break;
13443 case 0x13: /* SYNC_RMB */
13444 tcg_mo |= TCG_MO_LD_LD;
13445 break;
13446 default:
13447 tcg_mo |= TCG_MO_ALL;
13448 break;
13449 }
13450
13451 tcg_gen_mb(tcg_mo);
13452}
13453
240ce26a 13454static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
3c824109
NF
13455{
13456 int extension = (ctx->opcode >> 6) & 0x3f;
13457 int minor = (ctx->opcode >> 12) & 0xf;
13458 uint32_t mips32_op;
13459
13460 switch (extension) {
13461 case TEQ:
13462 mips32_op = OPC_TEQ;
13463 goto do_trap;
13464 case TGE:
13465 mips32_op = OPC_TGE;
13466 goto do_trap;
13467 case TGEU:
13468 mips32_op = OPC_TGEU;
13469 goto do_trap;
13470 case TLT:
13471 mips32_op = OPC_TLT;
13472 goto do_trap;
13473 case TLTU:
13474 mips32_op = OPC_TLTU;
13475 goto do_trap;
13476 case TNE:
13477 mips32_op = OPC_TNE;
13478 do_trap:
13479 gen_trap(ctx, mips32_op, rs, rt, -1);
13480 break;
13481#ifndef CONFIG_USER_ONLY
13482 case MFC0:
13483 case MFC0 + 32:
2e15497c 13484 check_cp0_enabled(ctx);
3c824109
NF
13485 if (rt == 0) {
13486 /* Treat as NOP. */
13487 break;
13488 }
d75c135e 13489 gen_mfc0(ctx, cpu_gpr[rt], rs, (ctx->opcode >> 11) & 0x7);
3c824109
NF
13490 break;
13491 case MTC0:
13492 case MTC0 + 32:
2e15497c 13493 check_cp0_enabled(ctx);
3c824109
NF
13494 {
13495 TCGv t0 = tcg_temp_new();
618b0fe9 13496
3c824109 13497 gen_load_gpr(t0, rt);
d75c135e 13498 gen_mtc0(ctx, t0, rs, (ctx->opcode >> 11) & 0x7);
3c824109
NF
13499 tcg_temp_free(t0);
13500 }
13501 break;
13502#endif
a1fc6246
LA
13503 case 0x2a:
13504 switch (minor & 3) {
13505 case MADD_ACC:
13506 gen_muldiv(ctx, OPC_MADD, (ctx->opcode >> 14) & 3, rs, rt);
13507 break;
13508 case MADDU_ACC:
13509 gen_muldiv(ctx, OPC_MADDU, (ctx->opcode >> 14) & 3, rs, rt);
13510 break;
13511 case MSUB_ACC:
13512 gen_muldiv(ctx, OPC_MSUB, (ctx->opcode >> 14) & 3, rs, rt);
13513 break;
13514 case MSUBU_ACC:
13515 gen_muldiv(ctx, OPC_MSUBU, (ctx->opcode >> 14) & 3, rs, rt);
13516 break;
13517 default:
13518 goto pool32axf_invalid;
13519 }
13520 break;
13521 case 0x32:
13522 switch (minor & 3) {
13523 case MULT_ACC:
13524 gen_muldiv(ctx, OPC_MULT, (ctx->opcode >> 14) & 3, rs, rt);
13525 break;
13526 case MULTU_ACC:
13527 gen_muldiv(ctx, OPC_MULTU, (ctx->opcode >> 14) & 3, rs, rt);
13528 break;
13529 default:
13530 goto pool32axf_invalid;
13531 }
13532 break;
3c824109
NF
13533 case 0x2c:
13534 switch (minor) {
e0332095
YK
13535 case BITSWAP:
13536 check_insn(ctx, ISA_MIPS32R6);
13537 gen_bitswap(ctx, OPC_BITSWAP, rs, rt);
13538 break;
3c824109
NF
13539 case SEB:
13540 gen_bshfl(ctx, OPC_SEB, rs, rt);
13541 break;
13542 case SEH:
13543 gen_bshfl(ctx, OPC_SEH, rs, rt);
13544 break;
13545 case CLO:
13546 mips32_op = OPC_CLO;
13547 goto do_cl;
13548 case CLZ:
13549 mips32_op = OPC_CLZ;
13550 do_cl:
d75c135e 13551 check_insn(ctx, ISA_MIPS32);
3c824109
NF
13552 gen_cl(ctx, mips32_op, rt, rs);
13553 break;
13554 case RDHWR:
b00c7218
YK
13555 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13556 gen_rdhwr(ctx, rt, rs, 0);
3c824109
NF
13557 break;
13558 case WSBH:
13559 gen_bshfl(ctx, OPC_WSBH, rs, rt);
13560 break;
13561 case MULT:
9e8f441a 13562 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 13563 mips32_op = OPC_MULT;
26135ead 13564 goto do_mul;
3c824109 13565 case MULTU:
9e8f441a 13566 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 13567 mips32_op = OPC_MULTU;
26135ead 13568 goto do_mul;
3c824109 13569 case DIV:
9e8f441a 13570 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 13571 mips32_op = OPC_DIV;
26135ead 13572 goto do_div;
3c824109 13573 case DIVU:
9e8f441a 13574 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 13575 mips32_op = OPC_DIVU;
26135ead
RS
13576 goto do_div;
13577 do_div:
13578 check_insn(ctx, ISA_MIPS32);
13579 gen_muldiv(ctx, mips32_op, 0, rs, rt);
13580 break;
3c824109 13581 case MADD:
9e8f441a 13582 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 13583 mips32_op = OPC_MADD;
26135ead 13584 goto do_mul;
3c824109 13585 case MADDU:
9e8f441a 13586 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 13587 mips32_op = OPC_MADDU;
26135ead 13588 goto do_mul;
3c824109 13589 case MSUB:
9e8f441a 13590 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 13591 mips32_op = OPC_MSUB;
26135ead 13592 goto do_mul;
3c824109 13593 case MSUBU:
9e8f441a 13594 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 13595 mips32_op = OPC_MSUBU;
26135ead 13596 do_mul:
d75c135e 13597 check_insn(ctx, ISA_MIPS32);
a1fc6246 13598 gen_muldiv(ctx, mips32_op, 0, rs, rt);
3c824109
NF
13599 break;
13600 default:
13601 goto pool32axf_invalid;
13602 }
13603 break;
13604 case 0x34:
13605 switch (minor) {
13606 case MFC2:
13607 case MTC2:
13608 case MFHC2:
13609 case MTHC2:
13610 case CFC2:
13611 case CTC2:
13612 generate_exception_err(ctx, EXCP_CpU, 2);
13613 break;
13614 default:
13615 goto pool32axf_invalid;
13616 }
13617 break;
13618 case 0x3c:
13619 switch (minor) {
65935f07
YK
13620 case JALR: /* JALRC */
13621 case JALR_HB: /* JALRC_HB */
13622 if (ctx->insn_flags & ISA_MIPS32R6) {
13623 /* JALRC, JALRC_HB */
13624 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 0);
13625 } else {
13626 /* JALR, JALR_HB */
13627 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 4);
13628 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
13629 }
3c824109
NF
13630 break;
13631 case JALRS:
13632 case JALRS_HB:
9e8f441a 13633 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
13634 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 2);
13635 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
3c824109
NF
13636 break;
13637 default:
13638 goto pool32axf_invalid;
13639 }
13640 break;
13641 case 0x05:
13642 switch (minor) {
13643 case RDPGPR:
2e15497c 13644 check_cp0_enabled(ctx);
d75c135e 13645 check_insn(ctx, ISA_MIPS32R2);
1bf5902d 13646 gen_load_srsgpr(rs, rt);
3c824109
NF
13647 break;
13648 case WRPGPR:
2e15497c 13649 check_cp0_enabled(ctx);
d75c135e 13650 check_insn(ctx, ISA_MIPS32R2);
1bf5902d 13651 gen_store_srsgpr(rs, rt);
3c824109
NF
13652 break;
13653 default:
13654 goto pool32axf_invalid;
13655 }
13656 break;
13657#ifndef CONFIG_USER_ONLY
13658 case 0x0d:
13659 switch (minor) {
13660 case TLBP:
13661 mips32_op = OPC_TLBP;
13662 goto do_cp0;
13663 case TLBR:
13664 mips32_op = OPC_TLBR;
13665 goto do_cp0;
13666 case TLBWI:
13667 mips32_op = OPC_TLBWI;
13668 goto do_cp0;
13669 case TLBWR:
13670 mips32_op = OPC_TLBWR;
13671 goto do_cp0;
e60ec063
YK
13672 case TLBINV:
13673 mips32_op = OPC_TLBINV;
13674 goto do_cp0;
13675 case TLBINVF:
13676 mips32_op = OPC_TLBINVF;
13677 goto do_cp0;
3c824109
NF
13678 case WAIT:
13679 mips32_op = OPC_WAIT;
13680 goto do_cp0;
13681 case DERET:
13682 mips32_op = OPC_DERET;
13683 goto do_cp0;
13684 case ERET:
13685 mips32_op = OPC_ERET;
13686 do_cp0:
13687 gen_cp0(env, ctx, mips32_op, rt, rs);
13688 break;
13689 default:
13690 goto pool32axf_invalid;
13691 }
13692 break;
13693 case 0x1d:
13694 switch (minor) {
13695 case DI:
2e15497c 13696 check_cp0_enabled(ctx);
3c824109
NF
13697 {
13698 TCGv t0 = tcg_temp_new();
13699
13700 save_cpu_state(ctx, 1);
895c2d04 13701 gen_helper_di(t0, cpu_env);
3c824109
NF
13702 gen_store_gpr(t0, rs);
13703 /* Stop translation as we may have switched the execution mode */
eeb3bba8 13704 ctx->base.is_jmp = DISAS_STOP;
3c824109
NF
13705 tcg_temp_free(t0);
13706 }
13707 break;
13708 case EI:
2e15497c 13709 check_cp0_enabled(ctx);
3c824109
NF
13710 {
13711 TCGv t0 = tcg_temp_new();
13712
13713 save_cpu_state(ctx, 1);
895c2d04 13714 gen_helper_ei(t0, cpu_env);
3c824109 13715 gen_store_gpr(t0, rs);
b28425ba 13716 /* DISAS_STOP isn't sufficient, we need to ensure we break out
b74cddcb 13717 of translated code to check for pending interrupts. */
eeb3bba8
EC
13718 gen_save_pc(ctx->base.pc_next + 4);
13719 ctx->base.is_jmp = DISAS_EXIT;
3c824109
NF
13720 tcg_temp_free(t0);
13721 }
13722 break;
13723 default:
13724 goto pool32axf_invalid;
13725 }
13726 break;
13727#endif
13728 case 0x2d:
13729 switch (minor) {
13730 case SYNC:
d208ac0c 13731 gen_sync(extract32(ctx->opcode, 16, 5));
3c824109
NF
13732 break;
13733 case SYSCALL:
9c708c7f 13734 generate_exception_end(ctx, EXCP_SYSCALL);
3c824109
NF
13735 break;
13736 case SDBBP:
3b3c1694
LA
13737 if (is_uhi(extract32(ctx->opcode, 16, 10))) {
13738 gen_helper_do_semihosting(cpu_env);
13739 } else {
13740 check_insn(ctx, ISA_MIPS32);
e0332095 13741 if (ctx->hflags & MIPS_HFLAG_SBRI) {
9c708c7f 13742 generate_exception_end(ctx, EXCP_RI);
e0332095 13743 } else {
9c708c7f 13744 generate_exception_end(ctx, EXCP_DBp);
e0332095 13745 }
3b3c1694 13746 }
3c824109
NF
13747 break;
13748 default:
13749 goto pool32axf_invalid;
13750 }
13751 break;
a1fc6246 13752 case 0x01:
26135ead 13753 switch (minor & 3) {
a1fc6246 13754 case MFHI_ACC:
26135ead 13755 gen_HILO(ctx, OPC_MFHI, minor >> 2, rs);
3c824109 13756 break;
a1fc6246 13757 case MFLO_ACC:
26135ead 13758 gen_HILO(ctx, OPC_MFLO, minor >> 2, rs);
3c824109 13759 break;
a1fc6246 13760 case MTHI_ACC:
26135ead 13761 gen_HILO(ctx, OPC_MTHI, minor >> 2, rs);
3c824109 13762 break;
a1fc6246 13763 case MTLO_ACC:
26135ead 13764 gen_HILO(ctx, OPC_MTLO, minor >> 2, rs);
3c824109
NF
13765 break;
13766 default:
13767 goto pool32axf_invalid;
13768 }
13769 break;
a1fc6246 13770 case 0x35:
9e8f441a 13771 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a1fc6246
LA
13772 switch (minor) {
13773 case MFHI32:
13774 gen_HILO(ctx, OPC_MFHI, 0, rs);
13775 break;
13776 case MFLO32:
13777 gen_HILO(ctx, OPC_MFLO, 0, rs);
13778 break;
13779 case MTHI32:
13780 gen_HILO(ctx, OPC_MTHI, 0, rs);
13781 break;
13782 case MTLO32:
13783 gen_HILO(ctx, OPC_MTLO, 0, rs);
13784 break;
13785 default:
13786 goto pool32axf_invalid;
13787 }
13788 break;
3c824109
NF
13789 default:
13790 pool32axf_invalid:
13791 MIPS_INVAL("pool32axf");
9c708c7f 13792 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
13793 break;
13794 }
13795}
13796
13797/* Values for microMIPS fmt field. Variable-width, depending on which
13798 formats the instruction supports. */
13799
13800enum {
13801 FMT_SD_S = 0,
13802 FMT_SD_D = 1,
13803
13804 FMT_SDPS_S = 0,
13805 FMT_SDPS_D = 1,
13806 FMT_SDPS_PS = 2,
13807
13808 FMT_SWL_S = 0,
13809 FMT_SWL_W = 1,
13810 FMT_SWL_L = 2,
13811
13812 FMT_DWL_D = 0,
13813 FMT_DWL_W = 1,
13814 FMT_DWL_L = 2
13815};
13816
d75c135e 13817static void gen_pool32fxf(DisasContext *ctx, int rt, int rs)
3c824109
NF
13818{
13819 int extension = (ctx->opcode >> 6) & 0x3ff;
13820 uint32_t mips32_op;
13821
13822#define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
13823#define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
13824#define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
13825
13826 switch (extension) {
13827 case FLOAT_1BIT_FMT(CFC1, 0):
13828 mips32_op = OPC_CFC1;
13829 goto do_cp1;
13830 case FLOAT_1BIT_FMT(CTC1, 0):
13831 mips32_op = OPC_CTC1;
13832 goto do_cp1;
13833 case FLOAT_1BIT_FMT(MFC1, 0):
13834 mips32_op = OPC_MFC1;
13835 goto do_cp1;
13836 case FLOAT_1BIT_FMT(MTC1, 0):
13837 mips32_op = OPC_MTC1;
13838 goto do_cp1;
13839 case FLOAT_1BIT_FMT(MFHC1, 0):
13840 mips32_op = OPC_MFHC1;
13841 goto do_cp1;
13842 case FLOAT_1BIT_FMT(MTHC1, 0):
13843 mips32_op = OPC_MTHC1;
13844 do_cp1:
13845 gen_cp1(ctx, mips32_op, rt, rs);
13846 break;
13847
13848 /* Reciprocal square root */
13849 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_S):
13850 mips32_op = OPC_RSQRT_S;
13851 goto do_unaryfp;
13852 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_D):
13853 mips32_op = OPC_RSQRT_D;
13854 goto do_unaryfp;
13855
13856 /* Square root */
13857 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_S):
13858 mips32_op = OPC_SQRT_S;
13859 goto do_unaryfp;
13860 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_D):
13861 mips32_op = OPC_SQRT_D;
13862 goto do_unaryfp;
13863
13864 /* Reciprocal */
13865 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_S):
13866 mips32_op = OPC_RECIP_S;
13867 goto do_unaryfp;
13868 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_D):
13869 mips32_op = OPC_RECIP_D;
13870 goto do_unaryfp;
13871
13872 /* Floor */
13873 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_S):
13874 mips32_op = OPC_FLOOR_L_S;
13875 goto do_unaryfp;
13876 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_D):
13877 mips32_op = OPC_FLOOR_L_D;
13878 goto do_unaryfp;
13879 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_S):
13880 mips32_op = OPC_FLOOR_W_S;
13881 goto do_unaryfp;
13882 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_D):
13883 mips32_op = OPC_FLOOR_W_D;
13884 goto do_unaryfp;
13885
13886 /* Ceiling */
13887 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_S):
13888 mips32_op = OPC_CEIL_L_S;
13889 goto do_unaryfp;
13890 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_D):
13891 mips32_op = OPC_CEIL_L_D;
13892 goto do_unaryfp;
13893 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_S):
13894 mips32_op = OPC_CEIL_W_S;
13895 goto do_unaryfp;
13896 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_D):
13897 mips32_op = OPC_CEIL_W_D;
13898 goto do_unaryfp;
13899
13900 /* Truncation */
13901 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_S):
13902 mips32_op = OPC_TRUNC_L_S;
13903 goto do_unaryfp;
13904 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_D):
13905 mips32_op = OPC_TRUNC_L_D;
13906 goto do_unaryfp;
13907 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_S):
13908 mips32_op = OPC_TRUNC_W_S;
13909 goto do_unaryfp;
13910 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_D):
13911 mips32_op = OPC_TRUNC_W_D;
13912 goto do_unaryfp;
13913
13914 /* Round */
13915 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_S):
13916 mips32_op = OPC_ROUND_L_S;
13917 goto do_unaryfp;
13918 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_D):
13919 mips32_op = OPC_ROUND_L_D;
13920 goto do_unaryfp;
13921 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_S):
13922 mips32_op = OPC_ROUND_W_S;
13923 goto do_unaryfp;
13924 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_D):
13925 mips32_op = OPC_ROUND_W_D;
13926 goto do_unaryfp;
13927
13928 /* Integer to floating-point conversion */
13929 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_S):
13930 mips32_op = OPC_CVT_L_S;
13931 goto do_unaryfp;
13932 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_D):
13933 mips32_op = OPC_CVT_L_D;
13934 goto do_unaryfp;
13935 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_S):
13936 mips32_op = OPC_CVT_W_S;
13937 goto do_unaryfp;
13938 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_D):
13939 mips32_op = OPC_CVT_W_D;
13940 goto do_unaryfp;
13941
13942 /* Paired-foo conversions */
13943 case FLOAT_1BIT_FMT(CVT_S_PL, 0):
13944 mips32_op = OPC_CVT_S_PL;
13945 goto do_unaryfp;
13946 case FLOAT_1BIT_FMT(CVT_S_PU, 0):
13947 mips32_op = OPC_CVT_S_PU;
13948 goto do_unaryfp;
13949 case FLOAT_1BIT_FMT(CVT_PW_PS, 0):
13950 mips32_op = OPC_CVT_PW_PS;
13951 goto do_unaryfp;
13952 case FLOAT_1BIT_FMT(CVT_PS_PW, 0):
13953 mips32_op = OPC_CVT_PS_PW;
13954 goto do_unaryfp;
13955
13956 /* Floating-point moves */
13957 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_S):
13958 mips32_op = OPC_MOV_S;
13959 goto do_unaryfp;
13960 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_D):
13961 mips32_op = OPC_MOV_D;
13962 goto do_unaryfp;
13963 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_PS):
13964 mips32_op = OPC_MOV_PS;
13965 goto do_unaryfp;
13966
13967 /* Absolute value */
13968 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_S):
13969 mips32_op = OPC_ABS_S;
13970 goto do_unaryfp;
13971 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_D):
13972 mips32_op = OPC_ABS_D;
13973 goto do_unaryfp;
13974 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_PS):
13975 mips32_op = OPC_ABS_PS;
13976 goto do_unaryfp;
13977
13978 /* Negation */
13979 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_S):
13980 mips32_op = OPC_NEG_S;
13981 goto do_unaryfp;
13982 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_D):
13983 mips32_op = OPC_NEG_D;
13984 goto do_unaryfp;
13985 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_PS):
13986 mips32_op = OPC_NEG_PS;
13987 goto do_unaryfp;
13988
13989 /* Reciprocal square root step */
13990 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_S):
13991 mips32_op = OPC_RSQRT1_S;
13992 goto do_unaryfp;
13993 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_D):
13994 mips32_op = OPC_RSQRT1_D;
13995 goto do_unaryfp;
13996 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_PS):
13997 mips32_op = OPC_RSQRT1_PS;
13998 goto do_unaryfp;
13999
14000 /* Reciprocal step */
14001 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_S):
14002 mips32_op = OPC_RECIP1_S;
14003 goto do_unaryfp;
14004 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_D):
14005 mips32_op = OPC_RECIP1_S;
14006 goto do_unaryfp;
14007 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_PS):
14008 mips32_op = OPC_RECIP1_PS;
14009 goto do_unaryfp;
14010
14011 /* Conversions from double */
14012 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_S):
14013 mips32_op = OPC_CVT_D_S;
14014 goto do_unaryfp;
14015 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_W):
14016 mips32_op = OPC_CVT_D_W;
14017 goto do_unaryfp;
14018 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_L):
14019 mips32_op = OPC_CVT_D_L;
14020 goto do_unaryfp;
14021
14022 /* Conversions from single */
14023 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_D):
14024 mips32_op = OPC_CVT_S_D;
14025 goto do_unaryfp;
14026 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_W):
14027 mips32_op = OPC_CVT_S_W;
14028 goto do_unaryfp;
14029 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_L):
14030 mips32_op = OPC_CVT_S_L;
14031 do_unaryfp:
14032 gen_farith(ctx, mips32_op, -1, rs, rt, 0);
14033 break;
14034
14035 /* Conditional moves on floating-point codes */
14036 case COND_FLOAT_MOV(MOVT, 0):
14037 case COND_FLOAT_MOV(MOVT, 1):
14038 case COND_FLOAT_MOV(MOVT, 2):
14039 case COND_FLOAT_MOV(MOVT, 3):
14040 case COND_FLOAT_MOV(MOVT, 4):
14041 case COND_FLOAT_MOV(MOVT, 5):
14042 case COND_FLOAT_MOV(MOVT, 6):
14043 case COND_FLOAT_MOV(MOVT, 7):
9e8f441a 14044 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14045 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 1);
14046 break;
14047 case COND_FLOAT_MOV(MOVF, 0):
14048 case COND_FLOAT_MOV(MOVF, 1):
14049 case COND_FLOAT_MOV(MOVF, 2):
14050 case COND_FLOAT_MOV(MOVF, 3):
14051 case COND_FLOAT_MOV(MOVF, 4):
14052 case COND_FLOAT_MOV(MOVF, 5):
14053 case COND_FLOAT_MOV(MOVF, 6):
14054 case COND_FLOAT_MOV(MOVF, 7):
9e8f441a 14055 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14056 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 0);
14057 break;
14058 default:
14059 MIPS_INVAL("pool32fxf");
9c708c7f 14060 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
14061 break;
14062 }
14063}
14064
f60eeb0c 14065static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx)
3c824109
NF
14066{
14067 int32_t offset;
14068 uint16_t insn;
14069 int rt, rs, rd, rr;
14070 int16_t imm;
8fffc646 14071 uint32_t op, minor, minor2, mips32_op;
3c824109
NF
14072 uint32_t cond, fmt, cc;
14073
eeb3bba8 14074 insn = cpu_lduw_code(env, ctx->base.pc_next + 2);
3c824109
NF
14075 ctx->opcode = (ctx->opcode << 16) | insn;
14076
14077 rt = (ctx->opcode >> 21) & 0x1f;
14078 rs = (ctx->opcode >> 16) & 0x1f;
14079 rd = (ctx->opcode >> 11) & 0x1f;
14080 rr = (ctx->opcode >> 6) & 0x1f;
14081 imm = (int16_t) ctx->opcode;
14082
14083 op = (ctx->opcode >> 26) & 0x3f;
14084 switch (op) {
14085 case POOL32A:
14086 minor = ctx->opcode & 0x3f;
14087 switch (minor) {
14088 case 0x00:
14089 minor = (ctx->opcode >> 6) & 0xf;
14090 switch (minor) {
14091 case SLL32:
14092 mips32_op = OPC_SLL;
14093 goto do_shifti;
14094 case SRA:
14095 mips32_op = OPC_SRA;
14096 goto do_shifti;
14097 case SRL32:
14098 mips32_op = OPC_SRL;
14099 goto do_shifti;
14100 case ROTR:
14101 mips32_op = OPC_ROTR;
14102 do_shifti:
d75c135e 14103 gen_shift_imm(ctx, mips32_op, rt, rs, rd);
3c824109 14104 break;
e0332095
YK
14105 case SELEQZ:
14106 check_insn(ctx, ISA_MIPS32R6);
14107 gen_cond_move(ctx, OPC_SELEQZ, rd, rs, rt);
14108 break;
14109 case SELNEZ:
14110 check_insn(ctx, ISA_MIPS32R6);
14111 gen_cond_move(ctx, OPC_SELNEZ, rd, rs, rt);
14112 break;
b00c7218
YK
14113 case R6_RDHWR:
14114 check_insn(ctx, ISA_MIPS32R6);
14115 gen_rdhwr(ctx, rt, rs, extract32(ctx->opcode, 11, 3));
14116 break;
3c824109
NF
14117 default:
14118 goto pool32a_invalid;
14119 }
14120 break;
14121 case 0x10:
14122 minor = (ctx->opcode >> 6) & 0xf;
14123 switch (minor) {
14124 /* Arithmetic */
14125 case ADD:
14126 mips32_op = OPC_ADD;
14127 goto do_arith;
14128 case ADDU32:
14129 mips32_op = OPC_ADDU;
14130 goto do_arith;
14131 case SUB:
14132 mips32_op = OPC_SUB;
14133 goto do_arith;
14134 case SUBU32:
14135 mips32_op = OPC_SUBU;
14136 goto do_arith;
14137 case MUL:
9e8f441a 14138 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14139 mips32_op = OPC_MUL;
14140 do_arith:
d75c135e 14141 gen_arith(ctx, mips32_op, rd, rs, rt);
3c824109
NF
14142 break;
14143 /* Shifts */
14144 case SLLV:
14145 mips32_op = OPC_SLLV;
14146 goto do_shift;
14147 case SRLV:
14148 mips32_op = OPC_SRLV;
14149 goto do_shift;
14150 case SRAV:
14151 mips32_op = OPC_SRAV;
14152 goto do_shift;
14153 case ROTRV:
14154 mips32_op = OPC_ROTRV;
14155 do_shift:
d75c135e 14156 gen_shift(ctx, mips32_op, rd, rs, rt);
3c824109
NF
14157 break;
14158 /* Logical operations */
14159 case AND:
14160 mips32_op = OPC_AND;
14161 goto do_logic;
14162 case OR32:
14163 mips32_op = OPC_OR;
14164 goto do_logic;
14165 case NOR:
14166 mips32_op = OPC_NOR;
14167 goto do_logic;
14168 case XOR32:
14169 mips32_op = OPC_XOR;
14170 do_logic:
d75c135e 14171 gen_logic(ctx, mips32_op, rd, rs, rt);
3c824109
NF
14172 break;
14173 /* Set less than */
14174 case SLT:
14175 mips32_op = OPC_SLT;
14176 goto do_slt;
14177 case SLTU:
14178 mips32_op = OPC_SLTU;
14179 do_slt:
d75c135e 14180 gen_slt(ctx, mips32_op, rd, rs, rt);
3c824109
NF
14181 break;
14182 default:
14183 goto pool32a_invalid;
14184 }
14185 break;
14186 case 0x18:
14187 minor = (ctx->opcode >> 6) & 0xf;
14188 switch (minor) {
14189 /* Conditional moves */
e0332095
YK
14190 case MOVN: /* MUL */
14191 if (ctx->insn_flags & ISA_MIPS32R6) {
14192 /* MUL */
14193 gen_r6_muldiv(ctx, R6_OPC_MUL, rd, rs, rt);
14194 } else {
14195 /* MOVN */
14196 gen_cond_move(ctx, OPC_MOVN, rd, rs, rt);
14197 }
14198 break;
14199 case MOVZ: /* MUH */
14200 if (ctx->insn_flags & ISA_MIPS32R6) {
14201 /* MUH */
14202 gen_r6_muldiv(ctx, R6_OPC_MUH, rd, rs, rt);
14203 } else {
14204 /* MOVZ */
14205 gen_cond_move(ctx, OPC_MOVZ, rd, rs, rt);
14206 }
14207 break;
14208 case MULU:
14209 check_insn(ctx, ISA_MIPS32R6);
14210 gen_r6_muldiv(ctx, R6_OPC_MULU, rd, rs, rt);
14211 break;
14212 case MUHU:
14213 check_insn(ctx, ISA_MIPS32R6);
14214 gen_r6_muldiv(ctx, R6_OPC_MUHU, rd, rs, rt);
14215 break;
14216 case LWXS: /* DIV */
14217 if (ctx->insn_flags & ISA_MIPS32R6) {
14218 /* DIV */
14219 gen_r6_muldiv(ctx, R6_OPC_DIV, rd, rs, rt);
14220 } else {
14221 /* LWXS */
14222 gen_ldxs(ctx, rs, rt, rd);
14223 }
14224 break;
14225 case MOD:
14226 check_insn(ctx, ISA_MIPS32R6);
14227 gen_r6_muldiv(ctx, R6_OPC_MOD, rd, rs, rt);
14228 break;
14229 case R6_DIVU:
14230 check_insn(ctx, ISA_MIPS32R6);
14231 gen_r6_muldiv(ctx, R6_OPC_DIVU, rd, rs, rt);
3c824109 14232 break;
e0332095
YK
14233 case MODU:
14234 check_insn(ctx, ISA_MIPS32R6);
14235 gen_r6_muldiv(ctx, R6_OPC_MODU, rd, rs, rt);
3c824109
NF
14236 break;
14237 default:
14238 goto pool32a_invalid;
14239 }
14240 break;
14241 case INS:
14242 gen_bitops(ctx, OPC_INS, rt, rs, rr, rd);
14243 return;
e0332095
YK
14244 case LSA:
14245 check_insn(ctx, ISA_MIPS32R6);
14246 gen_lsa(ctx, OPC_LSA, rd, rs, rt,
14247 extract32(ctx->opcode, 9, 2));
14248 break;
14249 case ALIGN:
14250 check_insn(ctx, ISA_MIPS32R6);
14251 gen_align(ctx, OPC_ALIGN, rd, rs, rt,
14252 extract32(ctx->opcode, 9, 2));
14253 break;
3c824109
NF
14254 case EXT:
14255 gen_bitops(ctx, OPC_EXT, rt, rs, rr, rd);
14256 return;
14257 case POOL32AXF:
240ce26a 14258 gen_pool32axf(env, ctx, rt, rs);
3c824109 14259 break;
dbd8af98 14260 case BREAK32:
9c708c7f 14261 generate_exception_end(ctx, EXCP_BREAK);
3c824109 14262 break;
bb238210
YK
14263 case SIGRIE:
14264 check_insn(ctx, ISA_MIPS32R6);
14265 generate_exception_end(ctx, EXCP_RI);
14266 break;
3c824109
NF
14267 default:
14268 pool32a_invalid:
14269 MIPS_INVAL("pool32a");
9c708c7f 14270 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
14271 break;
14272 }
14273 break;
14274 case POOL32B:
14275 minor = (ctx->opcode >> 12) & 0xf;
14276 switch (minor) {
14277 case CACHE:
2e15497c 14278 check_cp0_enabled(ctx);
0d74a222
LA
14279 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
14280 gen_cache_operation(ctx, rt, rs, imm);
14281 }
3c824109
NF
14282 break;
14283 case LWC2:
14284 case SWC2:
14285 /* COP2: Not implemented. */
14286 generate_exception_err(ctx, EXCP_CpU, 2);
14287 break;
3c824109
NF
14288#ifdef TARGET_MIPS64
14289 case LDP:
14290 case SDP:
d9224450
MR
14291 check_insn(ctx, ISA_MIPS3);
14292 check_mips_64(ctx);
14293 /* Fallthrough */
3c824109 14294#endif
d9224450
MR
14295 case LWP:
14296 case SWP:
3c824109
NF
14297 gen_ldst_pair(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
14298 break;
3c824109
NF
14299#ifdef TARGET_MIPS64
14300 case LDM:
14301 case SDM:
d9224450
MR
14302 check_insn(ctx, ISA_MIPS3);
14303 check_mips_64(ctx);
14304 /* Fallthrough */
3c824109 14305#endif
d9224450
MR
14306 case LWM32:
14307 case SWM32:
3c824109
NF
14308 gen_ldst_multiple(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
14309 break;
14310 default:
14311 MIPS_INVAL("pool32b");
9c708c7f 14312 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
14313 break;
14314 }
14315 break;
14316 case POOL32F:
5ab5c041 14317 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
3c824109
NF
14318 minor = ctx->opcode & 0x3f;
14319 check_cp1_enabled(ctx);
14320 switch (minor) {
14321 case ALNV_PS:
9e8f441a 14322 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14323 mips32_op = OPC_ALNV_PS;
14324 goto do_madd;
14325 case MADD_S:
9e8f441a 14326 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14327 mips32_op = OPC_MADD_S;
14328 goto do_madd;
14329 case MADD_D:
9e8f441a 14330 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14331 mips32_op = OPC_MADD_D;
14332 goto do_madd;
14333 case MADD_PS:
9e8f441a 14334 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14335 mips32_op = OPC_MADD_PS;
14336 goto do_madd;
14337 case MSUB_S:
9e8f441a 14338 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14339 mips32_op = OPC_MSUB_S;
14340 goto do_madd;
14341 case MSUB_D:
9e8f441a 14342 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14343 mips32_op = OPC_MSUB_D;
14344 goto do_madd;
14345 case MSUB_PS:
9e8f441a 14346 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14347 mips32_op = OPC_MSUB_PS;
14348 goto do_madd;
14349 case NMADD_S:
9e8f441a 14350 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14351 mips32_op = OPC_NMADD_S;
14352 goto do_madd;
14353 case NMADD_D:
9e8f441a 14354 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14355 mips32_op = OPC_NMADD_D;
14356 goto do_madd;
14357 case NMADD_PS:
9e8f441a 14358 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14359 mips32_op = OPC_NMADD_PS;
14360 goto do_madd;
14361 case NMSUB_S:
9e8f441a 14362 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14363 mips32_op = OPC_NMSUB_S;
14364 goto do_madd;
14365 case NMSUB_D:
9e8f441a 14366 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14367 mips32_op = OPC_NMSUB_D;
14368 goto do_madd;
14369 case NMSUB_PS:
9e8f441a 14370 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14371 mips32_op = OPC_NMSUB_PS;
14372 do_madd:
14373 gen_flt3_arith(ctx, mips32_op, rd, rr, rs, rt);
14374 break;
14375 case CABS_COND_FMT:
9e8f441a 14376 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14377 cond = (ctx->opcode >> 6) & 0xf;
14378 cc = (ctx->opcode >> 13) & 0x7;
14379 fmt = (ctx->opcode >> 10) & 0x3;
14380 switch (fmt) {
14381 case 0x0:
14382 gen_cmpabs_s(ctx, cond, rt, rs, cc);
14383 break;
14384 case 0x1:
14385 gen_cmpabs_d(ctx, cond, rt, rs, cc);
14386 break;
14387 case 0x2:
14388 gen_cmpabs_ps(ctx, cond, rt, rs, cc);
14389 break;
14390 default:
14391 goto pool32f_invalid;
14392 }
14393 break;
14394 case C_COND_FMT:
9e8f441a 14395 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14396 cond = (ctx->opcode >> 6) & 0xf;
14397 cc = (ctx->opcode >> 13) & 0x7;
14398 fmt = (ctx->opcode >> 10) & 0x3;
14399 switch (fmt) {
14400 case 0x0:
14401 gen_cmp_s(ctx, cond, rt, rs, cc);
14402 break;
14403 case 0x1:
14404 gen_cmp_d(ctx, cond, rt, rs, cc);
14405 break;
14406 case 0x2:
14407 gen_cmp_ps(ctx, cond, rt, rs, cc);
14408 break;
14409 default:
14410 goto pool32f_invalid;
14411 }
14412 break;
2a24a7ba
YK
14413 case CMP_CONDN_S:
14414 check_insn(ctx, ISA_MIPS32R6);
14415 gen_r6_cmp_s(ctx, (ctx->opcode >> 6) & 0x1f, rt, rs, rd);
14416 break;
14417 case CMP_CONDN_D:
14418 check_insn(ctx, ISA_MIPS32R6);
14419 gen_r6_cmp_d(ctx, (ctx->opcode >> 6) & 0x1f, rt, rs, rd);
14420 break;
3c824109 14421 case POOL32FXF:
d75c135e 14422 gen_pool32fxf(ctx, rt, rs);
3c824109
NF
14423 break;
14424 case 0x00:
14425 /* PLL foo */
14426 switch ((ctx->opcode >> 6) & 0x7) {
14427 case PLL_PS:
14428 mips32_op = OPC_PLL_PS;
14429 goto do_ps;
14430 case PLU_PS:
14431 mips32_op = OPC_PLU_PS;
14432 goto do_ps;
14433 case PUL_PS:
14434 mips32_op = OPC_PUL_PS;
14435 goto do_ps;
14436 case PUU_PS:
14437 mips32_op = OPC_PUU_PS;
14438 goto do_ps;
14439 case CVT_PS_S:
9e8f441a 14440 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14441 mips32_op = OPC_CVT_PS_S;
14442 do_ps:
14443 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
14444 break;
14445 default:
14446 goto pool32f_invalid;
14447 }
14448 break;
2a24a7ba
YK
14449 case MIN_FMT:
14450 check_insn(ctx, ISA_MIPS32R6);
14451 switch ((ctx->opcode >> 9) & 0x3) {
14452 case FMT_SDPS_S:
14453 gen_farith(ctx, OPC_MIN_S, rt, rs, rd, 0);
14454 break;
14455 case FMT_SDPS_D:
14456 gen_farith(ctx, OPC_MIN_D, rt, rs, rd, 0);
14457 break;
14458 default:
14459 goto pool32f_invalid;
14460 }
14461 break;
3c824109
NF
14462 case 0x08:
14463 /* [LS][WDU]XC1 */
14464 switch ((ctx->opcode >> 6) & 0x7) {
14465 case LWXC1:
9e8f441a 14466 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14467 mips32_op = OPC_LWXC1;
14468 goto do_ldst_cp1;
14469 case SWXC1:
9e8f441a 14470 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14471 mips32_op = OPC_SWXC1;
14472 goto do_ldst_cp1;
14473 case LDXC1:
9e8f441a 14474 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14475 mips32_op = OPC_LDXC1;
14476 goto do_ldst_cp1;
14477 case SDXC1:
9e8f441a 14478 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14479 mips32_op = OPC_SDXC1;
14480 goto do_ldst_cp1;
14481 case LUXC1:
9e8f441a 14482 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14483 mips32_op = OPC_LUXC1;
14484 goto do_ldst_cp1;
14485 case SUXC1:
9e8f441a 14486 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14487 mips32_op = OPC_SUXC1;
14488 do_ldst_cp1:
14489 gen_flt3_ldst(ctx, mips32_op, rd, rd, rt, rs);
14490 break;
14491 default:
14492 goto pool32f_invalid;
14493 }
14494 break;
2a24a7ba
YK
14495 case MAX_FMT:
14496 check_insn(ctx, ISA_MIPS32R6);
14497 switch ((ctx->opcode >> 9) & 0x3) {
14498 case FMT_SDPS_S:
14499 gen_farith(ctx, OPC_MAX_S, rt, rs, rd, 0);
14500 break;
14501 case FMT_SDPS_D:
14502 gen_farith(ctx, OPC_MAX_D, rt, rs, rd, 0);
14503 break;
14504 default:
14505 goto pool32f_invalid;
14506 }
14507 break;
3c824109
NF
14508 case 0x18:
14509 /* 3D insns */
9e8f441a 14510 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14511 fmt = (ctx->opcode >> 9) & 0x3;
14512 switch ((ctx->opcode >> 6) & 0x7) {
14513 case RSQRT2_FMT:
14514 switch (fmt) {
14515 case FMT_SDPS_S:
14516 mips32_op = OPC_RSQRT2_S;
14517 goto do_3d;
14518 case FMT_SDPS_D:
14519 mips32_op = OPC_RSQRT2_D;
14520 goto do_3d;
14521 case FMT_SDPS_PS:
14522 mips32_op = OPC_RSQRT2_PS;
14523 goto do_3d;
14524 default:
14525 goto pool32f_invalid;
14526 }
14527 break;
14528 case RECIP2_FMT:
14529 switch (fmt) {
14530 case FMT_SDPS_S:
14531 mips32_op = OPC_RECIP2_S;
14532 goto do_3d;
14533 case FMT_SDPS_D:
14534 mips32_op = OPC_RECIP2_D;
14535 goto do_3d;
14536 case FMT_SDPS_PS:
14537 mips32_op = OPC_RECIP2_PS;
14538 goto do_3d;
14539 default:
14540 goto pool32f_invalid;
14541 }
14542 break;
14543 case ADDR_PS:
14544 mips32_op = OPC_ADDR_PS;
14545 goto do_3d;
14546 case MULR_PS:
14547 mips32_op = OPC_MULR_PS;
14548 do_3d:
14549 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
14550 break;
14551 default:
14552 goto pool32f_invalid;
14553 }
14554 break;
14555 case 0x20:
2a24a7ba 14556 /* MOV[FT].fmt, PREFX, RINT.fmt, CLASS.fmt*/
3c824109
NF
14557 cc = (ctx->opcode >> 13) & 0x7;
14558 fmt = (ctx->opcode >> 9) & 0x3;
14559 switch ((ctx->opcode >> 6) & 0x7) {
2a24a7ba
YK
14560 case MOVF_FMT: /* RINT_FMT */
14561 if (ctx->insn_flags & ISA_MIPS32R6) {
14562 /* RINT_FMT */
14563 switch (fmt) {
14564 case FMT_SDPS_S:
14565 gen_farith(ctx, OPC_RINT_S, 0, rt, rs, 0);
14566 break;
14567 case FMT_SDPS_D:
14568 gen_farith(ctx, OPC_RINT_D, 0, rt, rs, 0);
14569 break;
14570 default:
14571 goto pool32f_invalid;
14572 }
14573 } else {
14574 /* MOVF_FMT */
14575 switch (fmt) {
14576 case FMT_SDPS_S:
14577 gen_movcf_s(ctx, rs, rt, cc, 0);
14578 break;
14579 case FMT_SDPS_D:
14580 gen_movcf_d(ctx, rs, rt, cc, 0);
14581 break;
14582 case FMT_SDPS_PS:
14583 check_ps(ctx);
14584 gen_movcf_ps(ctx, rs, rt, cc, 0);
14585 break;
14586 default:
14587 goto pool32f_invalid;
14588 }
3c824109
NF
14589 }
14590 break;
2a24a7ba
YK
14591 case MOVT_FMT: /* CLASS_FMT */
14592 if (ctx->insn_flags & ISA_MIPS32R6) {
14593 /* CLASS_FMT */
14594 switch (fmt) {
14595 case FMT_SDPS_S:
14596 gen_farith(ctx, OPC_CLASS_S, 0, rt, rs, 0);
14597 break;
14598 case FMT_SDPS_D:
14599 gen_farith(ctx, OPC_CLASS_D, 0, rt, rs, 0);
14600 break;
14601 default:
14602 goto pool32f_invalid;
14603 }
14604 } else {
14605 /* MOVT_FMT */
14606 switch (fmt) {
14607 case FMT_SDPS_S:
14608 gen_movcf_s(ctx, rs, rt, cc, 1);
14609 break;
14610 case FMT_SDPS_D:
14611 gen_movcf_d(ctx, rs, rt, cc, 1);
14612 break;
14613 case FMT_SDPS_PS:
14614 check_ps(ctx);
14615 gen_movcf_ps(ctx, rs, rt, cc, 1);
14616 break;
14617 default:
14618 goto pool32f_invalid;
14619 }
3c824109
NF
14620 }
14621 break;
14622 case PREFX:
9e8f441a 14623 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14624 break;
14625 default:
14626 goto pool32f_invalid;
14627 }
14628 break;
14629#define FINSN_3ARG_SDPS(prfx) \
14630 switch ((ctx->opcode >> 8) & 0x3) { \
14631 case FMT_SDPS_S: \
14632 mips32_op = OPC_##prfx##_S; \
14633 goto do_fpop; \
14634 case FMT_SDPS_D: \
14635 mips32_op = OPC_##prfx##_D; \
14636 goto do_fpop; \
14637 case FMT_SDPS_PS: \
e29c9628 14638 check_ps(ctx); \
3c824109
NF
14639 mips32_op = OPC_##prfx##_PS; \
14640 goto do_fpop; \
14641 default: \
14642 goto pool32f_invalid; \
14643 }
2a24a7ba
YK
14644 case MINA_FMT:
14645 check_insn(ctx, ISA_MIPS32R6);
14646 switch ((ctx->opcode >> 9) & 0x3) {
14647 case FMT_SDPS_S:
14648 gen_farith(ctx, OPC_MINA_S, rt, rs, rd, 0);
14649 break;
14650 case FMT_SDPS_D:
14651 gen_farith(ctx, OPC_MINA_D, rt, rs, rd, 0);
14652 break;
14653 default:
14654 goto pool32f_invalid;
14655 }
14656 break;
14657 case MAXA_FMT:
14658 check_insn(ctx, ISA_MIPS32R6);
14659 switch ((ctx->opcode >> 9) & 0x3) {
14660 case FMT_SDPS_S:
14661 gen_farith(ctx, OPC_MAXA_S, rt, rs, rd, 0);
14662 break;
14663 case FMT_SDPS_D:
14664 gen_farith(ctx, OPC_MAXA_D, rt, rs, rd, 0);
14665 break;
14666 default:
14667 goto pool32f_invalid;
14668 }
14669 break;
3c824109
NF
14670 case 0x30:
14671 /* regular FP ops */
14672 switch ((ctx->opcode >> 6) & 0x3) {
14673 case ADD_FMT:
14674 FINSN_3ARG_SDPS(ADD);
14675 break;
14676 case SUB_FMT:
14677 FINSN_3ARG_SDPS(SUB);
14678 break;
14679 case MUL_FMT:
14680 FINSN_3ARG_SDPS(MUL);
14681 break;
14682 case DIV_FMT:
14683 fmt = (ctx->opcode >> 8) & 0x3;
14684 if (fmt == 1) {
14685 mips32_op = OPC_DIV_D;
14686 } else if (fmt == 0) {
14687 mips32_op = OPC_DIV_S;
14688 } else {
14689 goto pool32f_invalid;
14690 }
14691 goto do_fpop;
14692 default:
14693 goto pool32f_invalid;
14694 }
14695 break;
14696 case 0x38:
14697 /* cmovs */
2a24a7ba
YK
14698 switch ((ctx->opcode >> 6) & 0x7) {
14699 case MOVN_FMT: /* SELNEZ_FMT */
14700 if (ctx->insn_flags & ISA_MIPS32R6) {
14701 /* SELNEZ_FMT */
14702 switch ((ctx->opcode >> 9) & 0x3) {
14703 case FMT_SDPS_S:
14704 gen_sel_s(ctx, OPC_SELNEZ_S, rd, rt, rs);
14705 break;
14706 case FMT_SDPS_D:
14707 gen_sel_d(ctx, OPC_SELNEZ_D, rd, rt, rs);
14708 break;
14709 default:
14710 goto pool32f_invalid;
14711 }
14712 } else {
14713 /* MOVN_FMT */
14714 FINSN_3ARG_SDPS(MOVN);
14715 }
14716 break;
14717 case MOVN_FMT_04:
14718 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14719 FINSN_3ARG_SDPS(MOVN);
14720 break;
2a24a7ba
YK
14721 case MOVZ_FMT: /* SELEQZ_FMT */
14722 if (ctx->insn_flags & ISA_MIPS32R6) {
14723 /* SELEQZ_FMT */
14724 switch ((ctx->opcode >> 9) & 0x3) {
14725 case FMT_SDPS_S:
14726 gen_sel_s(ctx, OPC_SELEQZ_S, rd, rt, rs);
14727 break;
14728 case FMT_SDPS_D:
14729 gen_sel_d(ctx, OPC_SELEQZ_D, rd, rt, rs);
14730 break;
14731 default:
14732 goto pool32f_invalid;
14733 }
14734 } else {
14735 /* MOVZ_FMT */
14736 FINSN_3ARG_SDPS(MOVZ);
14737 }
14738 break;
14739 case MOVZ_FMT_05:
14740 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14741 FINSN_3ARG_SDPS(MOVZ);
14742 break;
2a24a7ba
YK
14743 case SEL_FMT:
14744 check_insn(ctx, ISA_MIPS32R6);
14745 switch ((ctx->opcode >> 9) & 0x3) {
14746 case FMT_SDPS_S:
14747 gen_sel_s(ctx, OPC_SEL_S, rd, rt, rs);
14748 break;
14749 case FMT_SDPS_D:
14750 gen_sel_d(ctx, OPC_SEL_D, rd, rt, rs);
14751 break;
14752 default:
14753 goto pool32f_invalid;
14754 }
14755 break;
14756 case MADDF_FMT:
14757 check_insn(ctx, ISA_MIPS32R6);
14758 switch ((ctx->opcode >> 9) & 0x3) {
14759 case FMT_SDPS_S:
14760 mips32_op = OPC_MADDF_S;
14761 goto do_fpop;
14762 case FMT_SDPS_D:
14763 mips32_op = OPC_MADDF_D;
14764 goto do_fpop;
14765 default:
14766 goto pool32f_invalid;
14767 }
14768 break;
14769 case MSUBF_FMT:
14770 check_insn(ctx, ISA_MIPS32R6);
14771 switch ((ctx->opcode >> 9) & 0x3) {
14772 case FMT_SDPS_S:
14773 mips32_op = OPC_MSUBF_S;
14774 goto do_fpop;
14775 case FMT_SDPS_D:
14776 mips32_op = OPC_MSUBF_D;
14777 goto do_fpop;
14778 default:
14779 goto pool32f_invalid;
14780 }
14781 break;
3c824109
NF
14782 default:
14783 goto pool32f_invalid;
14784 }
14785 break;
14786 do_fpop:
14787 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
14788 break;
14789 default:
14790 pool32f_invalid:
14791 MIPS_INVAL("pool32f");
9c708c7f 14792 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
14793 break;
14794 }
14795 } else {
14796 generate_exception_err(ctx, EXCP_CpU, 1);
14797 }
14798 break;
14799 case POOL32I:
14800 minor = (ctx->opcode >> 21) & 0x1f;
14801 switch (minor) {
14802 case BLTZ:
9e8f441a 14803 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
14804 gen_compute_branch(ctx, OPC_BLTZ, 4, rs, -1, imm << 1, 4);
14805 break;
3c824109 14806 case BLTZAL:
9e8f441a 14807 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
14808 gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 4);
14809 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14810 break;
3c824109 14811 case BLTZALS:
9e8f441a 14812 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
14813 gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 2);
14814 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14815 break;
3c824109 14816 case BGEZ:
9e8f441a 14817 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
14818 gen_compute_branch(ctx, OPC_BGEZ, 4, rs, -1, imm << 1, 4);
14819 break;
3c824109 14820 case BGEZAL:
9e8f441a 14821 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
14822 gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 4);
14823 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14824 break;
3c824109 14825 case BGEZALS:
9e8f441a 14826 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
14827 gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 2);
14828 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14829 break;
3c824109 14830 case BLEZ:
9e8f441a 14831 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
14832 gen_compute_branch(ctx, OPC_BLEZ, 4, rs, -1, imm << 1, 4);
14833 break;
3c824109 14834 case BGTZ:
9e8f441a 14835 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103 14836 gen_compute_branch(ctx, OPC_BGTZ, 4, rs, -1, imm << 1, 4);
3c824109
NF
14837 break;
14838
14839 /* Traps */
65935f07
YK
14840 case TLTI: /* BC1EQZC */
14841 if (ctx->insn_flags & ISA_MIPS32R6) {
14842 /* BC1EQZC */
14843 check_cp1_enabled(ctx);
14844 gen_compute_branch1_r6(ctx, OPC_BC1EQZ, rs, imm << 1, 0);
14845 } else {
14846 /* TLTI */
14847 mips32_op = OPC_TLTI;
14848 goto do_trapi;
14849 }
14850 break;
14851 case TGEI: /* BC1NEZC */
14852 if (ctx->insn_flags & ISA_MIPS32R6) {
14853 /* BC1NEZC */
14854 check_cp1_enabled(ctx);
14855 gen_compute_branch1_r6(ctx, OPC_BC1NEZ, rs, imm << 1, 0);
14856 } else {
14857 /* TGEI */
14858 mips32_op = OPC_TGEI;
14859 goto do_trapi;
14860 }
14861 break;
3c824109 14862 case TLTIU:
9e8f441a 14863 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14864 mips32_op = OPC_TLTIU;
14865 goto do_trapi;
14866 case TGEIU:
9e8f441a 14867 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14868 mips32_op = OPC_TGEIU;
14869 goto do_trapi;
3b4a5489
YK
14870 case TNEI: /* SYNCI */
14871 if (ctx->insn_flags & ISA_MIPS32R6) {
14872 /* SYNCI */
14873 /* Break the TB to be able to sync copied instructions
14874 immediately */
eeb3bba8 14875 ctx->base.is_jmp = DISAS_STOP;
3b4a5489
YK
14876 } else {
14877 /* TNEI */
14878 mips32_op = OPC_TNEI;
14879 goto do_trapi;
14880 }
14881 break;
3c824109 14882 case TEQI:
9e8f441a 14883 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14884 mips32_op = OPC_TEQI;
14885 do_trapi:
14886 gen_trap(ctx, mips32_op, rs, -1, imm);
14887 break;
14888
14889 case BNEZC:
14890 case BEQZC:
9e8f441a 14891 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 14892 gen_compute_branch(ctx, minor == BNEZC ? OPC_BNE : OPC_BEQ,
b231c103 14893 4, rs, 0, imm << 1, 0);
3c824109
NF
14894 /* Compact branches don't have a delay slot, so just let
14895 the normal delay slot handling take us to the branch
14896 target. */
14897 break;
14898 case LUI:
9e8f441a 14899 check_insn_opc_removed(ctx, ISA_MIPS32R6);
5e88759a 14900 gen_logic_imm(ctx, OPC_LUI, rs, 0, imm);
3c824109
NF
14901 break;
14902 case SYNCI:
9e8f441a 14903 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a83bddd6
DZ
14904 /* Break the TB to be able to sync copied instructions
14905 immediately */
eeb3bba8 14906 ctx->base.is_jmp = DISAS_STOP;
3c824109
NF
14907 break;
14908 case BC2F:
14909 case BC2T:
9e8f441a 14910 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14911 /* COP2: Not implemented. */
14912 generate_exception_err(ctx, EXCP_CpU, 2);
14913 break;
14914 case BC1F:
9e8f441a 14915 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14916 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1FANY2 : OPC_BC1F;
14917 goto do_cp1branch;
14918 case BC1T:
9e8f441a 14919 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14920 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1TANY2 : OPC_BC1T;
14921 goto do_cp1branch;
14922 case BC1ANY4F:
9e8f441a 14923 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14924 mips32_op = OPC_BC1FANY4;
14925 goto do_cp1mips3d;
14926 case BC1ANY4T:
9e8f441a 14927 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14928 mips32_op = OPC_BC1TANY4;
14929 do_cp1mips3d:
14930 check_cop1x(ctx);
d75c135e 14931 check_insn(ctx, ASE_MIPS3D);
3c824109
NF
14932 /* Fall through */
14933 do_cp1branch:
272f458d
MR
14934 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
14935 check_cp1_enabled(ctx);
14936 gen_compute_branch1(ctx, mips32_op,
14937 (ctx->opcode >> 18) & 0x7, imm << 1);
14938 } else {
14939 generate_exception_err(ctx, EXCP_CpU, 1);
14940 }
3c824109
NF
14941 break;
14942 case BPOSGE64:
14943 case BPOSGE32:
14944 /* MIPS DSP: not implemented */
14945 /* Fall through */
14946 default:
14947 MIPS_INVAL("pool32i");
9c708c7f 14948 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
14949 break;
14950 }
14951 break;
14952 case POOL32C:
14953 minor = (ctx->opcode >> 12) & 0xf;
3b4a5489
YK
14954 offset = sextract32(ctx->opcode, 0,
14955 (ctx->insn_flags & ISA_MIPS32R6) ? 9 : 12);
3c824109
NF
14956 switch (minor) {
14957 case LWL:
9e8f441a 14958 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 14959 mips32_op = OPC_LWL;
5c13fdfd 14960 goto do_ld_lr;
3c824109 14961 case SWL:
9e8f441a 14962 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 14963 mips32_op = OPC_SWL;
5c13fdfd 14964 goto do_st_lr;
3c824109 14965 case LWR:
9e8f441a 14966 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 14967 mips32_op = OPC_LWR;
5c13fdfd 14968 goto do_ld_lr;
3c824109 14969 case SWR:
9e8f441a 14970 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 14971 mips32_op = OPC_SWR;
5c13fdfd 14972 goto do_st_lr;
3c824109
NF
14973#if defined(TARGET_MIPS64)
14974 case LDL:
d9224450
MR
14975 check_insn(ctx, ISA_MIPS3);
14976 check_mips_64(ctx);
9e8f441a 14977 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 14978 mips32_op = OPC_LDL;
5c13fdfd 14979 goto do_ld_lr;
3c824109 14980 case SDL:
d9224450
MR
14981 check_insn(ctx, ISA_MIPS3);
14982 check_mips_64(ctx);
9e8f441a 14983 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 14984 mips32_op = OPC_SDL;
5c13fdfd 14985 goto do_st_lr;
3c824109 14986 case LDR:
d9224450
MR
14987 check_insn(ctx, ISA_MIPS3);
14988 check_mips_64(ctx);
9e8f441a 14989 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 14990 mips32_op = OPC_LDR;
5c13fdfd 14991 goto do_ld_lr;
3c824109 14992 case SDR:
d9224450
MR
14993 check_insn(ctx, ISA_MIPS3);
14994 check_mips_64(ctx);
9e8f441a 14995 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 14996 mips32_op = OPC_SDR;
5c13fdfd 14997 goto do_st_lr;
3c824109 14998 case LWU:
d9224450
MR
14999 check_insn(ctx, ISA_MIPS3);
15000 check_mips_64(ctx);
3c824109 15001 mips32_op = OPC_LWU;
5c13fdfd 15002 goto do_ld_lr;
3c824109 15003 case LLD:
d9224450
MR
15004 check_insn(ctx, ISA_MIPS3);
15005 check_mips_64(ctx);
3c824109 15006 mips32_op = OPC_LLD;
5c13fdfd 15007 goto do_ld_lr;
3c824109
NF
15008#endif
15009 case LL:
15010 mips32_op = OPC_LL;
5c13fdfd
AJ
15011 goto do_ld_lr;
15012 do_ld_lr:
3b4a5489 15013 gen_ld(ctx, mips32_op, rt, rs, offset);
5c13fdfd
AJ
15014 break;
15015 do_st_lr:
8fffc646 15016 gen_st(ctx, mips32_op, rt, rs, offset);
3c824109
NF
15017 break;
15018 case SC:
3b4a5489 15019 gen_st_cond(ctx, OPC_SC, rt, rs, offset);
3c824109
NF
15020 break;
15021#if defined(TARGET_MIPS64)
15022 case SCD:
d9224450
MR
15023 check_insn(ctx, ISA_MIPS3);
15024 check_mips_64(ctx);
3b4a5489 15025 gen_st_cond(ctx, OPC_SCD, rt, rs, offset);
3c824109
NF
15026 break;
15027#endif
8fffc646
JH
15028 case LD_EVA:
15029 if (!ctx->eva) {
15030 MIPS_INVAL("pool32c ld-eva");
15031 generate_exception_end(ctx, EXCP_RI);
15032 break;
15033 }
15034 check_cp0_enabled(ctx);
15035
15036 minor2 = (ctx->opcode >> 9) & 0x7;
15037 offset = sextract32(ctx->opcode, 0, 9);
15038 switch (minor2) {
15039 case LBUE:
15040 mips32_op = OPC_LBUE;
15041 goto do_ld_lr;
15042 case LHUE:
15043 mips32_op = OPC_LHUE;
15044 goto do_ld_lr;
15045 case LWLE:
15046 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15047 mips32_op = OPC_LWLE;
15048 goto do_ld_lr;
15049 case LWRE:
15050 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15051 mips32_op = OPC_LWRE;
15052 goto do_ld_lr;
15053 case LBE:
15054 mips32_op = OPC_LBE;
15055 goto do_ld_lr;
15056 case LHE:
15057 mips32_op = OPC_LHE;
15058 goto do_ld_lr;
15059 case LLE:
15060 mips32_op = OPC_LLE;
15061 goto do_ld_lr;
15062 case LWE:
15063 mips32_op = OPC_LWE;
15064 goto do_ld_lr;
15065 };
15066 break;
15067 case ST_EVA:
15068 if (!ctx->eva) {
15069 MIPS_INVAL("pool32c st-eva");
15070 generate_exception_end(ctx, EXCP_RI);
15071 break;
15072 }
15073 check_cp0_enabled(ctx);
15074
15075 minor2 = (ctx->opcode >> 9) & 0x7;
15076 offset = sextract32(ctx->opcode, 0, 9);
15077 switch (minor2) {
15078 case SWLE:
15079 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15080 mips32_op = OPC_SWLE;
15081 goto do_st_lr;
15082 case SWRE:
15083 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15084 mips32_op = OPC_SWRE;
15085 goto do_st_lr;
15086 case PREFE:
15087 /* Treat as no-op */
15088 if ((ctx->insn_flags & ISA_MIPS32R6) && (rt >= 24)) {
15089 /* hint codes 24-31 are reserved and signal RI */
15090 generate_exception(ctx, EXCP_RI);
15091 }
15092 break;
15093 case CACHEE:
15094 /* Treat as no-op */
15095 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
15096 gen_cache_operation(ctx, rt, rs, offset);
15097 }
15098 break;
15099 case SBE:
15100 mips32_op = OPC_SBE;
15101 goto do_st_lr;
15102 case SHE:
15103 mips32_op = OPC_SHE;
15104 goto do_st_lr;
15105 case SCE:
15106 gen_st_cond(ctx, OPC_SCE, rt, rs, offset);
15107 break;
15108 case SWE:
15109 mips32_op = OPC_SWE;
15110 goto do_st_lr;
15111 };
15112 break;
3c824109
NF
15113 case PREF:
15114 /* Treat as no-op */
3b4a5489
YK
15115 if ((ctx->insn_flags & ISA_MIPS32R6) && (rt >= 24)) {
15116 /* hint codes 24-31 are reserved and signal RI */
15117 generate_exception(ctx, EXCP_RI);
15118 }
3c824109
NF
15119 break;
15120 default:
15121 MIPS_INVAL("pool32c");
9c708c7f 15122 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
15123 break;
15124 }
15125 break;
ab39ee45
YK
15126 case ADDI32: /* AUI, LUI */
15127 if (ctx->insn_flags & ISA_MIPS32R6) {
15128 /* AUI, LUI */
15129 gen_logic_imm(ctx, OPC_LUI, rt, rs, imm);
15130 } else {
15131 /* ADDI32 */
15132 mips32_op = OPC_ADDI;
15133 goto do_addi;
15134 }
15135 break;
3c824109
NF
15136 case ADDIU32:
15137 mips32_op = OPC_ADDIU;
15138 do_addi:
d75c135e 15139 gen_arith_imm(ctx, mips32_op, rt, rs, imm);
3c824109
NF
15140 break;
15141
15142 /* Logical operations */
15143 case ORI32:
15144 mips32_op = OPC_ORI;
15145 goto do_logici;
15146 case XORI32:
15147 mips32_op = OPC_XORI;
15148 goto do_logici;
15149 case ANDI32:
15150 mips32_op = OPC_ANDI;
15151 do_logici:
d75c135e 15152 gen_logic_imm(ctx, mips32_op, rt, rs, imm);
3c824109
NF
15153 break;
15154
15155 /* Set less than immediate */
15156 case SLTI32:
15157 mips32_op = OPC_SLTI;
15158 goto do_slti;
15159 case SLTIU32:
15160 mips32_op = OPC_SLTIU;
15161 do_slti:
d75c135e 15162 gen_slt_imm(ctx, mips32_op, rt, rs, imm);
3c824109
NF
15163 break;
15164 case JALX32:
9e8f441a 15165 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 15166 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
b231c103
YK
15167 gen_compute_branch(ctx, OPC_JALX, 4, rt, rs, offset, 4);
15168 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
3c824109 15169 break;
65935f07
YK
15170 case JALS32: /* BOVC, BEQC, BEQZALC */
15171 if (ctx->insn_flags & ISA_MIPS32R6) {
15172 if (rs >= rt) {
15173 /* BOVC */
15174 mips32_op = OPC_BOVC;
15175 } else if (rs < rt && rs == 0) {
15176 /* BEQZALC */
15177 mips32_op = OPC_BEQZALC;
15178 } else {
15179 /* BEQC */
15180 mips32_op = OPC_BEQC;
15181 }
15182 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
15183 } else {
15184 /* JALS32 */
15185 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 1;
15186 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs, offset, 2);
15187 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
15188 }
3c824109 15189 break;
65935f07
YK
15190 case BEQ32: /* BC */
15191 if (ctx->insn_flags & ISA_MIPS32R6) {
15192 /* BC */
15193 gen_compute_compact_branch(ctx, OPC_BC, 0, 0,
15194 sextract32(ctx->opcode << 1, 0, 27));
15195 } else {
15196 /* BEQ32 */
15197 gen_compute_branch(ctx, OPC_BEQ, 4, rt, rs, imm << 1, 4);
15198 }
3c824109 15199 break;
65935f07
YK
15200 case BNE32: /* BALC */
15201 if (ctx->insn_flags & ISA_MIPS32R6) {
15202 /* BALC */
15203 gen_compute_compact_branch(ctx, OPC_BALC, 0, 0,
15204 sextract32(ctx->opcode << 1, 0, 27));
15205 } else {
15206 /* BNE32 */
15207 gen_compute_branch(ctx, OPC_BNE, 4, rt, rs, imm << 1, 4);
15208 }
3c824109 15209 break;
65935f07
YK
15210 case J32: /* BGTZC, BLTZC, BLTC */
15211 if (ctx->insn_flags & ISA_MIPS32R6) {
15212 if (rs == 0 && rt != 0) {
15213 /* BGTZC */
15214 mips32_op = OPC_BGTZC;
15215 } else if (rs != 0 && rt != 0 && rs == rt) {
15216 /* BLTZC */
15217 mips32_op = OPC_BLTZC;
15218 } else {
15219 /* BLTC */
15220 mips32_op = OPC_BLTC;
15221 }
15222 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
15223 } else {
15224 /* J32 */
15225 gen_compute_branch(ctx, OPC_J, 4, rt, rs,
15226 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
15227 }
3c824109 15228 break;
65935f07
YK
15229 case JAL32: /* BLEZC, BGEZC, BGEC */
15230 if (ctx->insn_flags & ISA_MIPS32R6) {
15231 if (rs == 0 && rt != 0) {
15232 /* BLEZC */
15233 mips32_op = OPC_BLEZC;
15234 } else if (rs != 0 && rt != 0 && rs == rt) {
15235 /* BGEZC */
15236 mips32_op = OPC_BGEZC;
15237 } else {
15238 /* BGEC */
15239 mips32_op = OPC_BGEC;
15240 }
15241 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
15242 } else {
15243 /* JAL32 */
15244 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs,
15245 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
15246 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
15247 }
3c824109
NF
15248 break;
15249 /* Floating point (COP1) */
15250 case LWC132:
15251 mips32_op = OPC_LWC1;
15252 goto do_cop1;
15253 case LDC132:
15254 mips32_op = OPC_LDC1;
15255 goto do_cop1;
15256 case SWC132:
15257 mips32_op = OPC_SWC1;
15258 goto do_cop1;
15259 case SDC132:
15260 mips32_op = OPC_SDC1;
15261 do_cop1:
5ab5c041 15262 gen_cop1_ldst(ctx, mips32_op, rt, rs, imm);
3c824109 15263 break;
ab39ee45
YK
15264 case ADDIUPC: /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
15265 if (ctx->insn_flags & ISA_MIPS32R6) {
15266 /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
15267 switch ((ctx->opcode >> 16) & 0x1f) {
c38a1d52
AR
15268 case ADDIUPC_00:
15269 case ADDIUPC_01:
15270 case ADDIUPC_02:
15271 case ADDIUPC_03:
15272 case ADDIUPC_04:
15273 case ADDIUPC_05:
15274 case ADDIUPC_06:
15275 case ADDIUPC_07:
eeb3bba8 15276 gen_pcrel(ctx, OPC_ADDIUPC, ctx->base.pc_next & ~0x3, rt);
ab39ee45
YK
15277 break;
15278 case AUIPC:
eeb3bba8 15279 gen_pcrel(ctx, OPC_AUIPC, ctx->base.pc_next, rt);
ab39ee45
YK
15280 break;
15281 case ALUIPC:
eeb3bba8 15282 gen_pcrel(ctx, OPC_ALUIPC, ctx->base.pc_next, rt);
ab39ee45 15283 break;
c38a1d52
AR
15284 case LWPC_08:
15285 case LWPC_09:
15286 case LWPC_0A:
15287 case LWPC_0B:
15288 case LWPC_0C:
15289 case LWPC_0D:
15290 case LWPC_0E:
15291 case LWPC_0F:
eeb3bba8 15292 gen_pcrel(ctx, R6_OPC_LWPC, ctx->base.pc_next & ~0x3, rt);
ab39ee45
YK
15293 break;
15294 default:
15295 generate_exception(ctx, EXCP_RI);
15296 break;
15297 }
15298 } else {
15299 /* ADDIUPC */
3c824109
NF
15300 int reg = mmreg(ZIMM(ctx->opcode, 23, 3));
15301 int offset = SIMM(ctx->opcode, 0, 23) << 2;
15302
15303 gen_addiupc(ctx, reg, offset, 0, 0);
15304 }
15305 break;
65935f07
YK
15306 case BNVC: /* BNEC, BNEZALC */
15307 check_insn(ctx, ISA_MIPS32R6);
15308 if (rs >= rt) {
15309 /* BNVC */
15310 mips32_op = OPC_BNVC;
15311 } else if (rs < rt && rs == 0) {
15312 /* BNEZALC */
15313 mips32_op = OPC_BNEZALC;
15314 } else {
15315 /* BNEC */
15316 mips32_op = OPC_BNEC;
15317 }
15318 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
15319 break;
15320 case R6_BNEZC: /* JIALC */
15321 check_insn(ctx, ISA_MIPS32R6);
15322 if (rt != 0) {
15323 /* BNEZC */
15324 gen_compute_compact_branch(ctx, OPC_BNEZC, rt, 0,
15325 sextract32(ctx->opcode << 1, 0, 22));
15326 } else {
15327 /* JIALC */
15328 gen_compute_compact_branch(ctx, OPC_JIALC, 0, rs, imm);
15329 }
15330 break;
15331 case R6_BEQZC: /* JIC */
15332 check_insn(ctx, ISA_MIPS32R6);
15333 if (rt != 0) {
15334 /* BEQZC */
15335 gen_compute_compact_branch(ctx, OPC_BEQZC, rt, 0,
15336 sextract32(ctx->opcode << 1, 0, 22));
15337 } else {
15338 /* JIC */
15339 gen_compute_compact_branch(ctx, OPC_JIC, 0, rs, imm);
15340 }
15341 break;
15342 case BLEZALC: /* BGEZALC, BGEUC */
15343 check_insn(ctx, ISA_MIPS32R6);
15344 if (rs == 0 && rt != 0) {
15345 /* BLEZALC */
15346 mips32_op = OPC_BLEZALC;
15347 } else if (rs != 0 && rt != 0 && rs == rt) {
15348 /* BGEZALC */
15349 mips32_op = OPC_BGEZALC;
15350 } else {
15351 /* BGEUC */
15352 mips32_op = OPC_BGEUC;
15353 }
15354 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
15355 break;
15356 case BGTZALC: /* BLTZALC, BLTUC */
15357 check_insn(ctx, ISA_MIPS32R6);
15358 if (rs == 0 && rt != 0) {
15359 /* BGTZALC */
15360 mips32_op = OPC_BGTZALC;
15361 } else if (rs != 0 && rt != 0 && rs == rt) {
15362 /* BLTZALC */
15363 mips32_op = OPC_BLTZALC;
15364 } else {
15365 /* BLTUC */
15366 mips32_op = OPC_BLTUC;
15367 }
15368 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
15369 break;
3c824109
NF
15370 /* Loads and stores */
15371 case LB32:
15372 mips32_op = OPC_LB;
5c13fdfd 15373 goto do_ld;
3c824109
NF
15374 case LBU32:
15375 mips32_op = OPC_LBU;
5c13fdfd 15376 goto do_ld;
3c824109
NF
15377 case LH32:
15378 mips32_op = OPC_LH;
5c13fdfd 15379 goto do_ld;
3c824109
NF
15380 case LHU32:
15381 mips32_op = OPC_LHU;
5c13fdfd 15382 goto do_ld;
3c824109
NF
15383 case LW32:
15384 mips32_op = OPC_LW;
5c13fdfd 15385 goto do_ld;
3c824109
NF
15386#ifdef TARGET_MIPS64
15387 case LD32:
d9224450
MR
15388 check_insn(ctx, ISA_MIPS3);
15389 check_mips_64(ctx);
3c824109 15390 mips32_op = OPC_LD;
5c13fdfd 15391 goto do_ld;
3c824109 15392 case SD32:
d9224450
MR
15393 check_insn(ctx, ISA_MIPS3);
15394 check_mips_64(ctx);
3c824109 15395 mips32_op = OPC_SD;
5c13fdfd 15396 goto do_st;
3c824109
NF
15397#endif
15398 case SB32:
15399 mips32_op = OPC_SB;
5c13fdfd 15400 goto do_st;
3c824109
NF
15401 case SH32:
15402 mips32_op = OPC_SH;
5c13fdfd 15403 goto do_st;
3c824109
NF
15404 case SW32:
15405 mips32_op = OPC_SW;
5c13fdfd
AJ
15406 goto do_st;
15407 do_ld:
d75c135e 15408 gen_ld(ctx, mips32_op, rt, rs, imm);
5c13fdfd
AJ
15409 break;
15410 do_st:
15411 gen_st(ctx, mips32_op, rt, rs, imm);
3c824109
NF
15412 break;
15413 default:
9c708c7f 15414 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
15415 break;
15416 }
15417}
15418
240ce26a 15419static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx)
3c824109
NF
15420{
15421 uint32_t op;
15422
15423 /* make sure instructions are on a halfword boundary */
eeb3bba8
EC
15424 if (ctx->base.pc_next & 0x1) {
15425 env->CP0_BadVAddr = ctx->base.pc_next;
9c708c7f 15426 generate_exception_end(ctx, EXCP_AdEL);
3c824109
NF
15427 return 2;
15428 }
15429
15430 op = (ctx->opcode >> 10) & 0x3f;
15431 /* Enforce properly-sized instructions in a delay slot */
b231c103
YK
15432 if (ctx->hflags & MIPS_HFLAG_BDS_STRICT) {
15433 switch (op & 0x7) { /* MSB-3..MSB-5 */
15434 case 0:
15435 /* POOL32A, POOL32B, POOL32I, POOL32C */
15436 case 4:
15437 /* ADDI32, ADDIU32, ORI32, XORI32, SLTI32, SLTIU32, ANDI32, JALX32 */
15438 case 5:
15439 /* LBU32, LHU32, POOL32F, JALS32, BEQ32, BNE32, J32, JAL32 */
15440 case 6:
15441 /* SB32, SH32, ADDIUPC, SWC132, SDC132, SW32 */
15442 case 7:
15443 /* LB32, LH32, LWC132, LDC132, LW32 */
15444 if (ctx->hflags & MIPS_HFLAG_BDS16) {
9c708c7f 15445 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
15446 return 2;
15447 }
15448 break;
b231c103
YK
15449 case 1:
15450 /* POOL16A, POOL16B, POOL16C, LWGP16, POOL16F */
15451 case 2:
15452 /* LBU16, LHU16, LWSP16, LW16, SB16, SH16, SWSP16, SW16 */
15453 case 3:
15454 /* MOVE16, ANDI16, POOL16D, POOL16E, BEQZ16, BNEZ16, B16, LI16 */
15455 if (ctx->hflags & MIPS_HFLAG_BDS32) {
9c708c7f 15456 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
15457 return 2;
15458 }
15459 break;
3c824109
NF
15460 }
15461 }
b231c103 15462
3c824109
NF
15463 switch (op) {
15464 case POOL16A:
15465 {
15466 int rd = mmreg(uMIPS_RD(ctx->opcode));
15467 int rs1 = mmreg(uMIPS_RS1(ctx->opcode));
15468 int rs2 = mmreg(uMIPS_RS2(ctx->opcode));
15469 uint32_t opc = 0;
15470
15471 switch (ctx->opcode & 0x1) {
15472 case ADDU16:
15473 opc = OPC_ADDU;
15474 break;
15475 case SUBU16:
15476 opc = OPC_SUBU;
15477 break;
15478 }
ed7ce6c0
YK
15479 if (ctx->insn_flags & ISA_MIPS32R6) {
15480 /* In the Release 6 the register number location in
15481 * the instruction encoding has changed.
15482 */
15483 gen_arith(ctx, opc, rs1, rd, rs2);
15484 } else {
15485 gen_arith(ctx, opc, rd, rs1, rs2);
15486 }
3c824109
NF
15487 }
15488 break;
15489 case POOL16B:
15490 {
15491 int rd = mmreg(uMIPS_RD(ctx->opcode));
15492 int rs = mmreg(uMIPS_RS(ctx->opcode));
15493 int amount = (ctx->opcode >> 1) & 0x7;
15494 uint32_t opc = 0;
15495 amount = amount == 0 ? 8 : amount;
15496
15497 switch (ctx->opcode & 0x1) {
15498 case SLL16:
15499 opc = OPC_SLL;
15500 break;
15501 case SRL16:
15502 opc = OPC_SRL;
15503 break;
15504 }
15505
d75c135e 15506 gen_shift_imm(ctx, opc, rd, rs, amount);
3c824109
NF
15507 }
15508 break;
15509 case POOL16C:
ed7ce6c0
YK
15510 if (ctx->insn_flags & ISA_MIPS32R6) {
15511 gen_pool16c_r6_insn(ctx);
15512 } else {
15513 gen_pool16c_insn(ctx);
15514 }
3c824109
NF
15515 break;
15516 case LWGP16:
15517 {
15518 int rd = mmreg(uMIPS_RD(ctx->opcode));
15519 int rb = 28; /* GP */
15520 int16_t offset = SIMM(ctx->opcode, 0, 7) << 2;
15521
d75c135e 15522 gen_ld(ctx, OPC_LW, rd, rb, offset);
3c824109
NF
15523 }
15524 break;
15525 case POOL16F:
9e8f441a 15526 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 15527 if (ctx->opcode & 1) {
9c708c7f 15528 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
15529 } else {
15530 /* MOVEP */
15531 int enc_dest = uMIPS_RD(ctx->opcode);
15532 int enc_rt = uMIPS_RS2(ctx->opcode);
15533 int enc_rs = uMIPS_RS1(ctx->opcode);
ed7ce6c0 15534 gen_movep(ctx, enc_dest, enc_rt, enc_rs);
3c824109
NF
15535 }
15536 break;
15537 case LBU16:
15538 {
15539 int rd = mmreg(uMIPS_RD(ctx->opcode));
15540 int rb = mmreg(uMIPS_RS(ctx->opcode));
15541 int16_t offset = ZIMM(ctx->opcode, 0, 4);
15542 offset = (offset == 0xf ? -1 : offset);
15543
d75c135e 15544 gen_ld(ctx, OPC_LBU, rd, rb, offset);
3c824109
NF
15545 }
15546 break;
15547 case LHU16:
15548 {
15549 int rd = mmreg(uMIPS_RD(ctx->opcode));
15550 int rb = mmreg(uMIPS_RS(ctx->opcode));
15551 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
15552
d75c135e 15553 gen_ld(ctx, OPC_LHU, rd, rb, offset);
3c824109
NF
15554 }
15555 break;
15556 case LWSP16:
15557 {
15558 int rd = (ctx->opcode >> 5) & 0x1f;
15559 int rb = 29; /* SP */
15560 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
15561
d75c135e 15562 gen_ld(ctx, OPC_LW, rd, rb, offset);
3c824109
NF
15563 }
15564 break;
15565 case LW16:
15566 {
15567 int rd = mmreg(uMIPS_RD(ctx->opcode));
15568 int rb = mmreg(uMIPS_RS(ctx->opcode));
15569 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
15570
d75c135e 15571 gen_ld(ctx, OPC_LW, rd, rb, offset);
3c824109
NF
15572 }
15573 break;
15574 case SB16:
15575 {
15576 int rd = mmreg2(uMIPS_RD(ctx->opcode));
15577 int rb = mmreg(uMIPS_RS(ctx->opcode));
15578 int16_t offset = ZIMM(ctx->opcode, 0, 4);
15579
5c13fdfd 15580 gen_st(ctx, OPC_SB, rd, rb, offset);
3c824109
NF
15581 }
15582 break;
15583 case SH16:
15584 {
15585 int rd = mmreg2(uMIPS_RD(ctx->opcode));
15586 int rb = mmreg(uMIPS_RS(ctx->opcode));
15587 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
15588
5c13fdfd 15589 gen_st(ctx, OPC_SH, rd, rb, offset);
3c824109
NF
15590 }
15591 break;
15592 case SWSP16:
15593 {
15594 int rd = (ctx->opcode >> 5) & 0x1f;
15595 int rb = 29; /* SP */
15596 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
15597
5c13fdfd 15598 gen_st(ctx, OPC_SW, rd, rb, offset);
3c824109
NF
15599 }
15600 break;
15601 case SW16:
15602 {
15603 int rd = mmreg2(uMIPS_RD(ctx->opcode));
15604 int rb = mmreg(uMIPS_RS(ctx->opcode));
15605 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
15606
5c13fdfd 15607 gen_st(ctx, OPC_SW, rd, rb, offset);
3c824109
NF
15608 }
15609 break;
15610 case MOVE16:
15611 {
15612 int rd = uMIPS_RD5(ctx->opcode);
15613 int rs = uMIPS_RS5(ctx->opcode);
15614
7215d7e7 15615 gen_arith(ctx, OPC_ADDU, rd, rs, 0);
3c824109
NF
15616 }
15617 break;
15618 case ANDI16:
d75c135e 15619 gen_andi16(ctx);
3c824109
NF
15620 break;
15621 case POOL16D:
15622 switch (ctx->opcode & 0x1) {
15623 case ADDIUS5:
d75c135e 15624 gen_addius5(ctx);
3c824109
NF
15625 break;
15626 case ADDIUSP:
d75c135e 15627 gen_addiusp(ctx);
3c824109
NF
15628 break;
15629 }
15630 break;
15631 case POOL16E:
15632 switch (ctx->opcode & 0x1) {
15633 case ADDIUR2:
d75c135e 15634 gen_addiur2(ctx);
3c824109
NF
15635 break;
15636 case ADDIUR1SP:
d75c135e 15637 gen_addiur1sp(ctx);
3c824109
NF
15638 break;
15639 }
15640 break;
65935f07 15641 case B16: /* BC16 */
3c824109 15642 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0,
65935f07
YK
15643 sextract32(ctx->opcode, 0, 10) << 1,
15644 (ctx->insn_flags & ISA_MIPS32R6) ? 0 : 4);
3c824109 15645 break;
65935f07
YK
15646 case BNEZ16: /* BNEZC16 */
15647 case BEQZ16: /* BEQZC16 */
3c824109
NF
15648 gen_compute_branch(ctx, op == BNEZ16 ? OPC_BNE : OPC_BEQ, 2,
15649 mmreg(uMIPS_RD(ctx->opcode)),
65935f07
YK
15650 0, sextract32(ctx->opcode, 0, 7) << 1,
15651 (ctx->insn_flags & ISA_MIPS32R6) ? 0 : 4);
15652
3c824109
NF
15653 break;
15654 case LI16:
15655 {
15656 int reg = mmreg(uMIPS_RD(ctx->opcode));
15657 int imm = ZIMM(ctx->opcode, 0, 7);
15658
15659 imm = (imm == 0x7f ? -1 : imm);
15660 tcg_gen_movi_tl(cpu_gpr[reg], imm);
15661 }
15662 break;
3c824109 15663 case RES_29:
3c824109 15664 case RES_31:
3c824109 15665 case RES_39:
9c708c7f 15666 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
15667 break;
15668 default:
f60eeb0c 15669 decode_micromips32_opc(env, ctx);
3c824109
NF
15670 return 4;
15671 }
15672
15673 return 2;
15674}
15675
15676/* SmartMIPS extension to MIPS32 */
15677
15678#if defined(TARGET_MIPS64)
15679
15680/* MDMX extension to MIPS64 */
15681
15682#endif
15683
9b1a1d68 15684/* MIPSDSP functions. */
d75c135e 15685static void gen_mipsdsp_ld(DisasContext *ctx, uint32_t opc,
9b1a1d68
JL
15686 int rd, int base, int offset)
15687{
9b1a1d68
JL
15688 TCGv t0;
15689
9b1a1d68
JL
15690 check_dsp(ctx);
15691 t0 = tcg_temp_new();
15692
15693 if (base == 0) {
15694 gen_load_gpr(t0, offset);
15695 } else if (offset == 0) {
15696 gen_load_gpr(t0, base);
15697 } else {
15698 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[offset]);
15699 }
15700
9b1a1d68
JL
15701 switch (opc) {
15702 case OPC_LBUX:
5f68f5ae 15703 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB);
9b1a1d68 15704 gen_store_gpr(t0, rd);
9b1a1d68
JL
15705 break;
15706 case OPC_LHX:
5f68f5ae 15707 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW);
9b1a1d68 15708 gen_store_gpr(t0, rd);
9b1a1d68
JL
15709 break;
15710 case OPC_LWX:
5f68f5ae 15711 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
9b1a1d68 15712 gen_store_gpr(t0, rd);
9b1a1d68
JL
15713 break;
15714#if defined(TARGET_MIPS64)
15715 case OPC_LDX:
5f68f5ae 15716 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
9b1a1d68 15717 gen_store_gpr(t0, rd);
9b1a1d68
JL
15718 break;
15719#endif
15720 }
9b1a1d68
JL
15721 tcg_temp_free(t0);
15722}
15723
461c08df
JL
15724static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
15725 int ret, int v1, int v2)
15726{
461c08df
JL
15727 TCGv v1_t;
15728 TCGv v2_t;
15729
15730 if (ret == 0) {
15731 /* Treat as NOP. */
461c08df
JL
15732 return;
15733 }
15734
15735 v1_t = tcg_temp_new();
15736 v2_t = tcg_temp_new();
15737
15738 gen_load_gpr(v1_t, v1);
15739 gen_load_gpr(v2_t, v2);
15740
15741 switch (op1) {
15742 /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
15743 case OPC_MULT_G_2E:
15744 check_dspr2(ctx);
15745 switch (op2) {
15746 case OPC_ADDUH_QB:
15747 gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t);
15748 break;
15749 case OPC_ADDUH_R_QB:
15750 gen_helper_adduh_r_qb(cpu_gpr[ret], v1_t, v2_t);
15751 break;
15752 case OPC_ADDQH_PH:
15753 gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t);
15754 break;
15755 case OPC_ADDQH_R_PH:
15756 gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
15757 break;
15758 case OPC_ADDQH_W:
15759 gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t);
15760 break;
15761 case OPC_ADDQH_R_W:
15762 gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t);
15763 break;
15764 case OPC_SUBUH_QB:
15765 gen_helper_subuh_qb(cpu_gpr[ret], v1_t, v2_t);
15766 break;
15767 case OPC_SUBUH_R_QB:
15768 gen_helper_subuh_r_qb(cpu_gpr[ret], v1_t, v2_t);
15769 break;
15770 case OPC_SUBQH_PH:
15771 gen_helper_subqh_ph(cpu_gpr[ret], v1_t, v2_t);
15772 break;
15773 case OPC_SUBQH_R_PH:
15774 gen_helper_subqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
15775 break;
15776 case OPC_SUBQH_W:
15777 gen_helper_subqh_w(cpu_gpr[ret], v1_t, v2_t);
15778 break;
15779 case OPC_SUBQH_R_W:
15780 gen_helper_subqh_r_w(cpu_gpr[ret], v1_t, v2_t);
15781 break;
15782 }
15783 break;
15784 case OPC_ABSQ_S_PH_DSP:
15785 switch (op2) {
15786 case OPC_ABSQ_S_QB:
15787 check_dspr2(ctx);
15788 gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, cpu_env);
15789 break;
15790 case OPC_ABSQ_S_PH:
15791 check_dsp(ctx);
15792 gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, cpu_env);
15793 break;
15794 case OPC_ABSQ_S_W:
15795 check_dsp(ctx);
15796 gen_helper_absq_s_w(cpu_gpr[ret], v2_t, cpu_env);
15797 break;
15798 case OPC_PRECEQ_W_PHL:
15799 check_dsp(ctx);
15800 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000);
15801 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
15802 break;
15803 case OPC_PRECEQ_W_PHR:
15804 check_dsp(ctx);
15805 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF);
15806 tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16);
15807 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
15808 break;
15809 case OPC_PRECEQU_PH_QBL:
15810 check_dsp(ctx);
15811 gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t);
15812 break;
15813 case OPC_PRECEQU_PH_QBR:
15814 check_dsp(ctx);
15815 gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t);
15816 break;
15817 case OPC_PRECEQU_PH_QBLA:
15818 check_dsp(ctx);
15819 gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t);
15820 break;
15821 case OPC_PRECEQU_PH_QBRA:
15822 check_dsp(ctx);
15823 gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t);
15824 break;
15825 case OPC_PRECEU_PH_QBL:
15826 check_dsp(ctx);
15827 gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t);
15828 break;
15829 case OPC_PRECEU_PH_QBR:
15830 check_dsp(ctx);
15831 gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t);
15832 break;
15833 case OPC_PRECEU_PH_QBLA:
15834 check_dsp(ctx);
15835 gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t);
15836 break;
15837 case OPC_PRECEU_PH_QBRA:
15838 check_dsp(ctx);
15839 gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t);
15840 break;
15841 }
15842 break;
15843 case OPC_ADDU_QB_DSP:
15844 switch (op2) {
15845 case OPC_ADDQ_PH:
15846 check_dsp(ctx);
15847 gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15848 break;
15849 case OPC_ADDQ_S_PH:
15850 check_dsp(ctx);
15851 gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15852 break;
15853 case OPC_ADDQ_S_W:
15854 check_dsp(ctx);
15855 gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15856 break;
15857 case OPC_ADDU_QB:
15858 check_dsp(ctx);
15859 gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15860 break;
15861 case OPC_ADDU_S_QB:
15862 check_dsp(ctx);
15863 gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15864 break;
15865 case OPC_ADDU_PH:
15866 check_dspr2(ctx);
15867 gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15868 break;
15869 case OPC_ADDU_S_PH:
15870 check_dspr2(ctx);
15871 gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15872 break;
15873 case OPC_SUBQ_PH:
15874 check_dsp(ctx);
15875 gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15876 break;
15877 case OPC_SUBQ_S_PH:
15878 check_dsp(ctx);
15879 gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15880 break;
15881 case OPC_SUBQ_S_W:
15882 check_dsp(ctx);
15883 gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15884 break;
15885 case OPC_SUBU_QB:
15886 check_dsp(ctx);
15887 gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15888 break;
15889 case OPC_SUBU_S_QB:
15890 check_dsp(ctx);
15891 gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15892 break;
15893 case OPC_SUBU_PH:
15894 check_dspr2(ctx);
15895 gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15896 break;
15897 case OPC_SUBU_S_PH:
15898 check_dspr2(ctx);
15899 gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15900 break;
15901 case OPC_ADDSC:
15902 check_dsp(ctx);
15903 gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15904 break;
15905 case OPC_ADDWC:
15906 check_dsp(ctx);
15907 gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15908 break;
15909 case OPC_MODSUB:
15910 check_dsp(ctx);
15911 gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t);
15912 break;
15913 case OPC_RADDU_W_QB:
15914 check_dsp(ctx);
15915 gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t);
15916 break;
15917 }
15918 break;
15919 case OPC_CMPU_EQ_QB_DSP:
15920 switch (op2) {
15921 case OPC_PRECR_QB_PH:
15922 check_dspr2(ctx);
15923 gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t);
15924 break;
15925 case OPC_PRECRQ_QB_PH:
15926 check_dsp(ctx);
15927 gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t);
15928 break;
15929 case OPC_PRECR_SRA_PH_W:
15930 check_dspr2(ctx);
15931 {
15932 TCGv_i32 sa_t = tcg_const_i32(v2);
15933 gen_helper_precr_sra_ph_w(cpu_gpr[ret], sa_t, v1_t,
15934 cpu_gpr[ret]);
15935 tcg_temp_free_i32(sa_t);
15936 break;
15937 }
15938 case OPC_PRECR_SRA_R_PH_W:
15939 check_dspr2(ctx);
15940 {
15941 TCGv_i32 sa_t = tcg_const_i32(v2);
15942 gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t,
15943 cpu_gpr[ret]);
15944 tcg_temp_free_i32(sa_t);
15945 break;
15946 }
15947 case OPC_PRECRQ_PH_W:
15948 check_dsp(ctx);
15949 gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t);
15950 break;
15951 case OPC_PRECRQ_RS_PH_W:
15952 check_dsp(ctx);
15953 gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15954 break;
15955 case OPC_PRECRQU_S_QB_PH:
15956 check_dsp(ctx);
15957 gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15958 break;
15959 }
15960 break;
15961#ifdef TARGET_MIPS64
15962 case OPC_ABSQ_S_QH_DSP:
15963 switch (op2) {
15964 case OPC_PRECEQ_L_PWL:
15965 check_dsp(ctx);
15966 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull);
15967 break;
15968 case OPC_PRECEQ_L_PWR:
15969 check_dsp(ctx);
15970 tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32);
15971 break;
15972 case OPC_PRECEQ_PW_QHL:
15973 check_dsp(ctx);
15974 gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t);
15975 break;
15976 case OPC_PRECEQ_PW_QHR:
15977 check_dsp(ctx);
15978 gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t);
15979 break;
15980 case OPC_PRECEQ_PW_QHLA:
15981 check_dsp(ctx);
15982 gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t);
15983 break;
15984 case OPC_PRECEQ_PW_QHRA:
15985 check_dsp(ctx);
15986 gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t);
15987 break;
15988 case OPC_PRECEQU_QH_OBL:
15989 check_dsp(ctx);
15990 gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t);
15991 break;
15992 case OPC_PRECEQU_QH_OBR:
15993 check_dsp(ctx);
15994 gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t);
15995 break;
15996 case OPC_PRECEQU_QH_OBLA:
15997 check_dsp(ctx);
15998 gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t);
15999 break;
16000 case OPC_PRECEQU_QH_OBRA:
16001 check_dsp(ctx);
16002 gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t);
16003 break;
16004 case OPC_PRECEU_QH_OBL:
16005 check_dsp(ctx);
16006 gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t);
16007 break;
16008 case OPC_PRECEU_QH_OBR:
16009 check_dsp(ctx);
16010 gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t);
16011 break;
16012 case OPC_PRECEU_QH_OBLA:
16013 check_dsp(ctx);
16014 gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t);
16015 break;
16016 case OPC_PRECEU_QH_OBRA:
16017 check_dsp(ctx);
16018 gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t);
16019 break;
16020 case OPC_ABSQ_S_OB:
16021 check_dspr2(ctx);
16022 gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, cpu_env);
16023 break;
16024 case OPC_ABSQ_S_PW:
16025 check_dsp(ctx);
16026 gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, cpu_env);
16027 break;
16028 case OPC_ABSQ_S_QH:
16029 check_dsp(ctx);
16030 gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, cpu_env);
16031 break;
16032 }
16033 break;
16034 case OPC_ADDU_OB_DSP:
16035 switch (op2) {
16036 case OPC_RADDU_L_OB:
16037 check_dsp(ctx);
16038 gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t);
16039 break;
16040 case OPC_SUBQ_PW:
16041 check_dsp(ctx);
16042 gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16043 break;
16044 case OPC_SUBQ_S_PW:
16045 check_dsp(ctx);
16046 gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16047 break;
16048 case OPC_SUBQ_QH:
16049 check_dsp(ctx);
16050 gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16051 break;
16052 case OPC_SUBQ_S_QH:
16053 check_dsp(ctx);
16054 gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16055 break;
16056 case OPC_SUBU_OB:
16057 check_dsp(ctx);
16058 gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16059 break;
16060 case OPC_SUBU_S_OB:
16061 check_dsp(ctx);
16062 gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16063 break;
16064 case OPC_SUBU_QH:
16065 check_dspr2(ctx);
16066 gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16067 break;
16068 case OPC_SUBU_S_QH:
16069 check_dspr2(ctx);
16070 gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16071 break;
16072 case OPC_SUBUH_OB:
16073 check_dspr2(ctx);
16074 gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t);
16075 break;
16076 case OPC_SUBUH_R_OB:
16077 check_dspr2(ctx);
16078 gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t);
16079 break;
16080 case OPC_ADDQ_PW:
16081 check_dsp(ctx);
16082 gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16083 break;
16084 case OPC_ADDQ_S_PW:
16085 check_dsp(ctx);
16086 gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16087 break;
16088 case OPC_ADDQ_QH:
16089 check_dsp(ctx);
16090 gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16091 break;
16092 case OPC_ADDQ_S_QH:
16093 check_dsp(ctx);
16094 gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16095 break;
16096 case OPC_ADDU_OB:
16097 check_dsp(ctx);
16098 gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16099 break;
16100 case OPC_ADDU_S_OB:
16101 check_dsp(ctx);
16102 gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16103 break;
16104 case OPC_ADDU_QH:
16105 check_dspr2(ctx);
16106 gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16107 break;
16108 case OPC_ADDU_S_QH:
16109 check_dspr2(ctx);
16110 gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16111 break;
16112 case OPC_ADDUH_OB:
16113 check_dspr2(ctx);
16114 gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t);
16115 break;
16116 case OPC_ADDUH_R_OB:
16117 check_dspr2(ctx);
16118 gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t);
16119 break;
16120 }
16121 break;
16122 case OPC_CMPU_EQ_OB_DSP:
16123 switch (op2) {
16124 case OPC_PRECR_OB_QH:
16125 check_dspr2(ctx);
16126 gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t);
16127 break;
16128 case OPC_PRECR_SRA_QH_PW:
16129 check_dspr2(ctx);
16130 {
16131 TCGv_i32 ret_t = tcg_const_i32(ret);
16132 gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t);
16133 tcg_temp_free_i32(ret_t);
16134 break;
16135 }
16136 case OPC_PRECR_SRA_R_QH_PW:
16137 check_dspr2(ctx);
16138 {
16139 TCGv_i32 sa_v = tcg_const_i32(ret);
16140 gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v);
16141 tcg_temp_free_i32(sa_v);
16142 break;
16143 }
16144 case OPC_PRECRQ_OB_QH:
16145 check_dsp(ctx);
16146 gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t);
16147 break;
16148 case OPC_PRECRQ_PW_L:
16149 check_dsp(ctx);
16150 gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t);
16151 break;
16152 case OPC_PRECRQ_QH_PW:
16153 check_dsp(ctx);
16154 gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t);
16155 break;
16156 case OPC_PRECRQ_RS_QH_PW:
16157 check_dsp(ctx);
16158 gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16159 break;
16160 case OPC_PRECRQU_S_OB_QH:
16161 check_dsp(ctx);
16162 gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16163 break;
16164 }
16165 break;
16166#endif
16167 }
16168
16169 tcg_temp_free(v1_t);
16170 tcg_temp_free(v2_t);
461c08df 16171}
9b1a1d68 16172
77c5fa8b
JL
16173static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc,
16174 int ret, int v1, int v2)
16175{
16176 uint32_t op2;
77c5fa8b
JL
16177 TCGv t0;
16178 TCGv v1_t;
16179 TCGv v2_t;
16180
16181 if (ret == 0) {
16182 /* Treat as NOP. */
77c5fa8b
JL
16183 return;
16184 }
16185
16186 t0 = tcg_temp_new();
16187 v1_t = tcg_temp_new();
16188 v2_t = tcg_temp_new();
16189
16190 tcg_gen_movi_tl(t0, v1);
16191 gen_load_gpr(v1_t, v1);
16192 gen_load_gpr(v2_t, v2);
16193
16194 switch (opc) {
16195 case OPC_SHLL_QB_DSP:
16196 {
16197 op2 = MASK_SHLL_QB(ctx->opcode);
16198 switch (op2) {
16199 case OPC_SHLL_QB:
16200 check_dsp(ctx);
16201 gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, cpu_env);
16202 break;
16203 case OPC_SHLLV_QB:
16204 check_dsp(ctx);
16205 gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16206 break;
16207 case OPC_SHLL_PH:
16208 check_dsp(ctx);
16209 gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
16210 break;
16211 case OPC_SHLLV_PH:
16212 check_dsp(ctx);
16213 gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16214 break;
16215 case OPC_SHLL_S_PH:
16216 check_dsp(ctx);
16217 gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
16218 break;
16219 case OPC_SHLLV_S_PH:
16220 check_dsp(ctx);
16221 gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16222 break;
16223 case OPC_SHLL_S_W:
16224 check_dsp(ctx);
16225 gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, cpu_env);
16226 break;
16227 case OPC_SHLLV_S_W:
16228 check_dsp(ctx);
16229 gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16230 break;
16231 case OPC_SHRL_QB:
16232 check_dsp(ctx);
16233 gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t);
16234 break;
16235 case OPC_SHRLV_QB:
16236 check_dsp(ctx);
16237 gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t);
16238 break;
16239 case OPC_SHRL_PH:
16240 check_dspr2(ctx);
16241 gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t);
16242 break;
16243 case OPC_SHRLV_PH:
16244 check_dspr2(ctx);
16245 gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t);
16246 break;
16247 case OPC_SHRA_QB:
16248 check_dspr2(ctx);
16249 gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t);
16250 break;
16251 case OPC_SHRA_R_QB:
16252 check_dspr2(ctx);
16253 gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t);
16254 break;
16255 case OPC_SHRAV_QB:
16256 check_dspr2(ctx);
16257 gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t);
16258 break;
16259 case OPC_SHRAV_R_QB:
16260 check_dspr2(ctx);
16261 gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t);
16262 break;
16263 case OPC_SHRA_PH:
16264 check_dsp(ctx);
16265 gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t);
16266 break;
16267 case OPC_SHRA_R_PH:
16268 check_dsp(ctx);
16269 gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t);
16270 break;
16271 case OPC_SHRAV_PH:
16272 check_dsp(ctx);
16273 gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t);
16274 break;
16275 case OPC_SHRAV_R_PH:
16276 check_dsp(ctx);
16277 gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t);
16278 break;
16279 case OPC_SHRA_R_W:
16280 check_dsp(ctx);
16281 gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t);
16282 break;
16283 case OPC_SHRAV_R_W:
16284 check_dsp(ctx);
16285 gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t);
16286 break;
16287 default: /* Invalid */
16288 MIPS_INVAL("MASK SHLL.QB");
9c708c7f 16289 generate_exception_end(ctx, EXCP_RI);
77c5fa8b
JL
16290 break;
16291 }
16292 break;
16293 }
16294#ifdef TARGET_MIPS64
16295 case OPC_SHLL_OB_DSP:
16296 op2 = MASK_SHLL_OB(ctx->opcode);
16297 switch (op2) {
16298 case OPC_SHLL_PW:
16299 check_dsp(ctx);
16300 gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
16301 break;
16302 case OPC_SHLLV_PW:
16303 check_dsp(ctx);
16304 gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
16305 break;
16306 case OPC_SHLL_S_PW:
16307 check_dsp(ctx);
16308 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
16309 break;
16310 case OPC_SHLLV_S_PW:
16311 check_dsp(ctx);
16312 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
16313 break;
16314 case OPC_SHLL_OB:
16315 check_dsp(ctx);
16316 gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, cpu_env);
16317 break;
16318 case OPC_SHLLV_OB:
16319 check_dsp(ctx);
16320 gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, cpu_env);
16321 break;
16322 case OPC_SHLL_QH:
16323 check_dsp(ctx);
16324 gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
16325 break;
16326 case OPC_SHLLV_QH:
16327 check_dsp(ctx);
16328 gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
16329 break;
16330 case OPC_SHLL_S_QH:
16331 check_dsp(ctx);
16332 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
16333 break;
16334 case OPC_SHLLV_S_QH:
16335 check_dsp(ctx);
16336 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
16337 break;
16338 case OPC_SHRA_OB:
16339 check_dspr2(ctx);
16340 gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0);
16341 break;
16342 case OPC_SHRAV_OB:
16343 check_dspr2(ctx);
16344 gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t);
16345 break;
16346 case OPC_SHRA_R_OB:
16347 check_dspr2(ctx);
16348 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0);
16349 break;
16350 case OPC_SHRAV_R_OB:
16351 check_dspr2(ctx);
16352 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t);
16353 break;
16354 case OPC_SHRA_PW:
16355 check_dsp(ctx);
16356 gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0);
16357 break;
16358 case OPC_SHRAV_PW:
16359 check_dsp(ctx);
16360 gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t);
16361 break;
16362 case OPC_SHRA_R_PW:
16363 check_dsp(ctx);
16364 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0);
16365 break;
16366 case OPC_SHRAV_R_PW:
16367 check_dsp(ctx);
16368 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t);
16369 break;
16370 case OPC_SHRA_QH:
16371 check_dsp(ctx);
16372 gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0);
16373 break;
16374 case OPC_SHRAV_QH:
16375 check_dsp(ctx);
16376 gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t);
16377 break;
16378 case OPC_SHRA_R_QH:
16379 check_dsp(ctx);
16380 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0);
16381 break;
16382 case OPC_SHRAV_R_QH:
16383 check_dsp(ctx);
16384 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t);
16385 break;
16386 case OPC_SHRL_OB:
16387 check_dsp(ctx);
16388 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0);
16389 break;
16390 case OPC_SHRLV_OB:
16391 check_dsp(ctx);
16392 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t);
16393 break;
16394 case OPC_SHRL_QH:
16395 check_dspr2(ctx);
16396 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0);
16397 break;
16398 case OPC_SHRLV_QH:
16399 check_dspr2(ctx);
16400 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t);
16401 break;
16402 default: /* Invalid */
16403 MIPS_INVAL("MASK SHLL.OB");
9c708c7f 16404 generate_exception_end(ctx, EXCP_RI);
77c5fa8b
JL
16405 break;
16406 }
16407 break;
16408#endif
16409 }
16410
16411 tcg_temp_free(t0);
16412 tcg_temp_free(v1_t);
16413 tcg_temp_free(v2_t);
77c5fa8b
JL
16414}
16415
a22260ae
JL
16416static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2,
16417 int ret, int v1, int v2, int check_ret)
16418{
a22260ae
JL
16419 TCGv_i32 t0;
16420 TCGv v1_t;
16421 TCGv v2_t;
16422
16423 if ((ret == 0) && (check_ret == 1)) {
16424 /* Treat as NOP. */
a22260ae
JL
16425 return;
16426 }
16427
16428 t0 = tcg_temp_new_i32();
16429 v1_t = tcg_temp_new();
16430 v2_t = tcg_temp_new();
16431
16432 tcg_gen_movi_i32(t0, ret);
16433 gen_load_gpr(v1_t, v1);
16434 gen_load_gpr(v2_t, v2);
16435
16436 switch (op1) {
16437 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
16438 * the same mask and op1. */
16439 case OPC_MULT_G_2E:
639eadb9 16440 check_dspr2(ctx);
a22260ae
JL
16441 switch (op2) {
16442 case OPC_MUL_PH:
16443 gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16444 break;
16445 case OPC_MUL_S_PH:
16446 gen_helper_mul_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16447 break;
16448 case OPC_MULQ_S_W:
16449 gen_helper_mulq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16450 break;
16451 case OPC_MULQ_RS_W:
16452 gen_helper_mulq_rs_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16453 break;
16454 }
16455 break;
16456 case OPC_DPA_W_PH_DSP:
16457 switch (op2) {
16458 case OPC_DPAU_H_QBL:
16459 check_dsp(ctx);
16460 gen_helper_dpau_h_qbl(t0, v1_t, v2_t, cpu_env);
16461 break;
16462 case OPC_DPAU_H_QBR:
16463 check_dsp(ctx);
16464 gen_helper_dpau_h_qbr(t0, v1_t, v2_t, cpu_env);
16465 break;
16466 case OPC_DPSU_H_QBL:
16467 check_dsp(ctx);
16468 gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, cpu_env);
16469 break;
16470 case OPC_DPSU_H_QBR:
16471 check_dsp(ctx);
16472 gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, cpu_env);
16473 break;
16474 case OPC_DPA_W_PH:
16475 check_dspr2(ctx);
16476 gen_helper_dpa_w_ph(t0, v1_t, v2_t, cpu_env);
16477 break;
16478 case OPC_DPAX_W_PH:
16479 check_dspr2(ctx);
16480 gen_helper_dpax_w_ph(t0, v1_t, v2_t, cpu_env);
16481 break;
16482 case OPC_DPAQ_S_W_PH:
16483 check_dsp(ctx);
16484 gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
16485 break;
16486 case OPC_DPAQX_S_W_PH:
16487 check_dspr2(ctx);
16488 gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
16489 break;
16490 case OPC_DPAQX_SA_W_PH:
16491 check_dspr2(ctx);
16492 gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
16493 break;
16494 case OPC_DPS_W_PH:
16495 check_dspr2(ctx);
16496 gen_helper_dps_w_ph(t0, v1_t, v2_t, cpu_env);
16497 break;
16498 case OPC_DPSX_W_PH:
16499 check_dspr2(ctx);
16500 gen_helper_dpsx_w_ph(t0, v1_t, v2_t, cpu_env);
16501 break;
16502 case OPC_DPSQ_S_W_PH:
16503 check_dsp(ctx);
16504 gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, cpu_env);
16505 break;
16506 case OPC_DPSQX_S_W_PH:
16507 check_dspr2(ctx);
16508 gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
16509 break;
16510 case OPC_DPSQX_SA_W_PH:
16511 check_dspr2(ctx);
16512 gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
16513 break;
16514 case OPC_MULSAQ_S_W_PH:
16515 check_dsp(ctx);
16516 gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
16517 break;
16518 case OPC_DPAQ_SA_L_W:
16519 check_dsp(ctx);
16520 gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, cpu_env);
16521 break;
16522 case OPC_DPSQ_SA_L_W:
16523 check_dsp(ctx);
16524 gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, cpu_env);
16525 break;
16526 case OPC_MAQ_S_W_PHL:
16527 check_dsp(ctx);
16528 gen_helper_maq_s_w_phl(t0, v1_t, v2_t, cpu_env);
16529 break;
16530 case OPC_MAQ_S_W_PHR:
16531 check_dsp(ctx);
16532 gen_helper_maq_s_w_phr(t0, v1_t, v2_t, cpu_env);
16533 break;
16534 case OPC_MAQ_SA_W_PHL:
16535 check_dsp(ctx);
16536 gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, cpu_env);
16537 break;
16538 case OPC_MAQ_SA_W_PHR:
16539 check_dsp(ctx);
16540 gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, cpu_env);
16541 break;
16542 case OPC_MULSA_W_PH:
16543 check_dspr2(ctx);
16544 gen_helper_mulsa_w_ph(t0, v1_t, v2_t, cpu_env);
16545 break;
16546 }
16547 break;
16548#ifdef TARGET_MIPS64
16549 case OPC_DPAQ_W_QH_DSP:
16550 {
16551 int ac = ret & 0x03;
16552 tcg_gen_movi_i32(t0, ac);
16553
16554 switch (op2) {
16555 case OPC_DMADD:
16556 check_dsp(ctx);
16557 gen_helper_dmadd(v1_t, v2_t, t0, cpu_env);
16558 break;
16559 case OPC_DMADDU:
16560 check_dsp(ctx);
16561 gen_helper_dmaddu(v1_t, v2_t, t0, cpu_env);
16562 break;
16563 case OPC_DMSUB:
16564 check_dsp(ctx);
16565 gen_helper_dmsub(v1_t, v2_t, t0, cpu_env);
16566 break;
16567 case OPC_DMSUBU:
16568 check_dsp(ctx);
16569 gen_helper_dmsubu(v1_t, v2_t, t0, cpu_env);
16570 break;
16571 case OPC_DPA_W_QH:
16572 check_dspr2(ctx);
16573 gen_helper_dpa_w_qh(v1_t, v2_t, t0, cpu_env);
16574 break;
16575 case OPC_DPAQ_S_W_QH:
16576 check_dsp(ctx);
16577 gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
16578 break;
16579 case OPC_DPAQ_SA_L_PW:
16580 check_dsp(ctx);
16581 gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
16582 break;
16583 case OPC_DPAU_H_OBL:
16584 check_dsp(ctx);
16585 gen_helper_dpau_h_obl(v1_t, v2_t, t0, cpu_env);
16586 break;
16587 case OPC_DPAU_H_OBR:
16588 check_dsp(ctx);
16589 gen_helper_dpau_h_obr(v1_t, v2_t, t0, cpu_env);
16590 break;
16591 case OPC_DPS_W_QH:
16592 check_dspr2(ctx);
16593 gen_helper_dps_w_qh(v1_t, v2_t, t0, cpu_env);
16594 break;
16595 case OPC_DPSQ_S_W_QH:
16596 check_dsp(ctx);
16597 gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, cpu_env);
16598 break;
16599 case OPC_DPSQ_SA_L_PW:
16600 check_dsp(ctx);
16601 gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
16602 break;
16603 case OPC_DPSU_H_OBL:
16604 check_dsp(ctx);
16605 gen_helper_dpsu_h_obl(v1_t, v2_t, t0, cpu_env);
16606 break;
16607 case OPC_DPSU_H_OBR:
16608 check_dsp(ctx);
16609 gen_helper_dpsu_h_obr(v1_t, v2_t, t0, cpu_env);
16610 break;
16611 case OPC_MAQ_S_L_PWL:
16612 check_dsp(ctx);
16613 gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, cpu_env);
16614 break;
16615 case OPC_MAQ_S_L_PWR:
16616 check_dsp(ctx);
16617 gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, cpu_env);
16618 break;
16619 case OPC_MAQ_S_W_QHLL:
16620 check_dsp(ctx);
16621 gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, cpu_env);
16622 break;
16623 case OPC_MAQ_SA_W_QHLL:
16624 check_dsp(ctx);
16625 gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, cpu_env);
16626 break;
16627 case OPC_MAQ_S_W_QHLR:
16628 check_dsp(ctx);
16629 gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, cpu_env);
16630 break;
16631 case OPC_MAQ_SA_W_QHLR:
16632 check_dsp(ctx);
16633 gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, cpu_env);
16634 break;
16635 case OPC_MAQ_S_W_QHRL:
16636 check_dsp(ctx);
16637 gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, cpu_env);
16638 break;
16639 case OPC_MAQ_SA_W_QHRL:
16640 check_dsp(ctx);
16641 gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, cpu_env);
16642 break;
16643 case OPC_MAQ_S_W_QHRR:
16644 check_dsp(ctx);
16645 gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, cpu_env);
16646 break;
16647 case OPC_MAQ_SA_W_QHRR:
16648 check_dsp(ctx);
16649 gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, cpu_env);
16650 break;
16651 case OPC_MULSAQ_S_L_PW:
16652 check_dsp(ctx);
16653 gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, cpu_env);
16654 break;
16655 case OPC_MULSAQ_S_W_QH:
16656 check_dsp(ctx);
16657 gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
16658 break;
16659 }
16660 }
16661 break;
16662#endif
16663 case OPC_ADDU_QB_DSP:
16664 switch (op2) {
16665 case OPC_MULEU_S_PH_QBL:
16666 check_dsp(ctx);
16667 gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16668 break;
16669 case OPC_MULEU_S_PH_QBR:
16670 check_dsp(ctx);
16671 gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16672 break;
16673 case OPC_MULQ_RS_PH:
16674 check_dsp(ctx);
16675 gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16676 break;
16677 case OPC_MULEQ_S_W_PHL:
16678 check_dsp(ctx);
16679 gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16680 break;
16681 case OPC_MULEQ_S_W_PHR:
16682 check_dsp(ctx);
16683 gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16684 break;
16685 case OPC_MULQ_S_PH:
16686 check_dspr2(ctx);
16687 gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16688 break;
16689 }
16690 break;
16691#ifdef TARGET_MIPS64
16692 case OPC_ADDU_OB_DSP:
16693 switch (op2) {
16694 case OPC_MULEQ_S_PW_QHL:
16695 check_dsp(ctx);
16696 gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16697 break;
16698 case OPC_MULEQ_S_PW_QHR:
16699 check_dsp(ctx);
16700 gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16701 break;
16702 case OPC_MULEU_S_QH_OBL:
16703 check_dsp(ctx);
16704 gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16705 break;
16706 case OPC_MULEU_S_QH_OBR:
16707 check_dsp(ctx);
16708 gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16709 break;
16710 case OPC_MULQ_RS_QH:
16711 check_dsp(ctx);
16712 gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16713 break;
16714 }
16715 break;
16716#endif
16717 }
16718
16719 tcg_temp_free_i32(t0);
16720 tcg_temp_free(v1_t);
16721 tcg_temp_free(v2_t);
a22260ae
JL
16722}
16723
d75c135e 16724static void gen_mipsdsp_bitinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
1cb6686c
JL
16725 int ret, int val)
16726{
1cb6686c
JL
16727 int16_t imm;
16728 TCGv t0;
16729 TCGv val_t;
16730
16731 if (ret == 0) {
16732 /* Treat as NOP. */
1cb6686c
JL
16733 return;
16734 }
16735
16736 t0 = tcg_temp_new();
16737 val_t = tcg_temp_new();
16738 gen_load_gpr(val_t, val);
16739
16740 switch (op1) {
16741 case OPC_ABSQ_S_PH_DSP:
16742 switch (op2) {
16743 case OPC_BITREV:
16744 check_dsp(ctx);
16745 gen_helper_bitrev(cpu_gpr[ret], val_t);
16746 break;
16747 case OPC_REPL_QB:
16748 check_dsp(ctx);
16749 {
16750 target_long result;
16751 imm = (ctx->opcode >> 16) & 0xFF;
16752 result = (uint32_t)imm << 24 |
16753 (uint32_t)imm << 16 |
16754 (uint32_t)imm << 8 |
16755 (uint32_t)imm;
16756 result = (int32_t)result;
16757 tcg_gen_movi_tl(cpu_gpr[ret], result);
16758 }
16759 break;
16760 case OPC_REPLV_QB:
16761 check_dsp(ctx);
16762 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
16763 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
16764 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16765 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
16766 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16767 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
16768 break;
16769 case OPC_REPL_PH:
16770 check_dsp(ctx);
16771 {
16772 imm = (ctx->opcode >> 16) & 0x03FF;
c4aaba92 16773 imm = (int16_t)(imm << 6) >> 6;
1cb6686c
JL
16774 tcg_gen_movi_tl(cpu_gpr[ret], \
16775 (target_long)((int32_t)imm << 16 | \
c4aaba92 16776 (uint16_t)imm));
1cb6686c
JL
16777 }
16778 break;
16779 case OPC_REPLV_PH:
16780 check_dsp(ctx);
16781 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
16782 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
16783 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16784 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
16785 break;
16786 }
16787 break;
16788#ifdef TARGET_MIPS64
16789 case OPC_ABSQ_S_QH_DSP:
16790 switch (op2) {
16791 case OPC_REPL_OB:
16792 check_dsp(ctx);
16793 {
16794 target_long temp;
16795
16796 imm = (ctx->opcode >> 16) & 0xFF;
16797 temp = ((uint64_t)imm << 8) | (uint64_t)imm;
16798 temp = (temp << 16) | temp;
16799 temp = (temp << 32) | temp;
16800 tcg_gen_movi_tl(cpu_gpr[ret], temp);
16801 break;
16802 }
16803 case OPC_REPL_PW:
16804 check_dsp(ctx);
16805 {
16806 target_long temp;
16807
16808 imm = (ctx->opcode >> 16) & 0x03FF;
16809 imm = (int16_t)(imm << 6) >> 6;
16810 temp = ((target_long)imm << 32) \
16811 | ((target_long)imm & 0xFFFFFFFF);
16812 tcg_gen_movi_tl(cpu_gpr[ret], temp);
16813 break;
16814 }
16815 case OPC_REPL_QH:
16816 check_dsp(ctx);
16817 {
16818 target_long temp;
16819
16820 imm = (ctx->opcode >> 16) & 0x03FF;
16821 imm = (int16_t)(imm << 6) >> 6;
16822
16823 temp = ((uint64_t)(uint16_t)imm << 48) |
16824 ((uint64_t)(uint16_t)imm << 32) |
16825 ((uint64_t)(uint16_t)imm << 16) |
16826 (uint64_t)(uint16_t)imm;
16827 tcg_gen_movi_tl(cpu_gpr[ret], temp);
16828 break;
16829 }
16830 case OPC_REPLV_OB:
16831 check_dsp(ctx);
16832 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
16833 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
16834 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16835 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
16836 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16837 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
16838 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16839 break;
16840 case OPC_REPLV_PW:
16841 check_dsp(ctx);
16842 tcg_gen_ext32u_i64(cpu_gpr[ret], val_t);
16843 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
16844 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16845 break;
16846 case OPC_REPLV_QH:
16847 check_dsp(ctx);
16848 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
16849 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
16850 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16851 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
16852 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16853 break;
16854 }
16855 break;
16856#endif
16857 }
16858 tcg_temp_free(t0);
16859 tcg_temp_free(val_t);
1cb6686c
JL
16860}
16861
26690560
JL
16862static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx,
16863 uint32_t op1, uint32_t op2,
16864 int ret, int v1, int v2, int check_ret)
16865{
26690560
JL
16866 TCGv t1;
16867 TCGv v1_t;
16868 TCGv v2_t;
16869
16870 if ((ret == 0) && (check_ret == 1)) {
16871 /* Treat as NOP. */
26690560
JL
16872 return;
16873 }
16874
26690560
JL
16875 t1 = tcg_temp_new();
16876 v1_t = tcg_temp_new();
16877 v2_t = tcg_temp_new();
16878
16879 gen_load_gpr(v1_t, v1);
16880 gen_load_gpr(v2_t, v2);
16881
16882 switch (op1) {
26690560
JL
16883 case OPC_CMPU_EQ_QB_DSP:
16884 switch (op2) {
16885 case OPC_CMPU_EQ_QB:
16886 check_dsp(ctx);
16887 gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
16888 break;
16889 case OPC_CMPU_LT_QB:
16890 check_dsp(ctx);
16891 gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
16892 break;
16893 case OPC_CMPU_LE_QB:
16894 check_dsp(ctx);
16895 gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
16896 break;
16897 case OPC_CMPGU_EQ_QB:
16898 check_dsp(ctx);
16899 gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t);
16900 break;
16901 case OPC_CMPGU_LT_QB:
16902 check_dsp(ctx);
16903 gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t);
16904 break;
16905 case OPC_CMPGU_LE_QB:
16906 check_dsp(ctx);
16907 gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t);
16908 break;
16909 case OPC_CMPGDU_EQ_QB:
16910 check_dspr2(ctx);
16911 gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t);
16912 tcg_gen_mov_tl(cpu_gpr[ret], t1);
16913 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
16914 tcg_gen_shli_tl(t1, t1, 24);
16915 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
16916 break;
16917 case OPC_CMPGDU_LT_QB:
16918 check_dspr2(ctx);
16919 gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t);
16920 tcg_gen_mov_tl(cpu_gpr[ret], t1);
16921 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
16922 tcg_gen_shli_tl(t1, t1, 24);
16923 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
16924 break;
16925 case OPC_CMPGDU_LE_QB:
16926 check_dspr2(ctx);
16927 gen_helper_cmpgu_le_qb(t1, v1_t, v2_t);
16928 tcg_gen_mov_tl(cpu_gpr[ret], t1);
16929 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
16930 tcg_gen_shli_tl(t1, t1, 24);
16931 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
16932 break;
16933 case OPC_CMP_EQ_PH:
16934 check_dsp(ctx);
16935 gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
16936 break;
16937 case OPC_CMP_LT_PH:
16938 check_dsp(ctx);
16939 gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
16940 break;
16941 case OPC_CMP_LE_PH:
16942 check_dsp(ctx);
16943 gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
16944 break;
16945 case OPC_PICK_QB:
16946 check_dsp(ctx);
16947 gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16948 break;
16949 case OPC_PICK_PH:
16950 check_dsp(ctx);
16951 gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16952 break;
16953 case OPC_PACKRL_PH:
16954 check_dsp(ctx);
16955 gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t);
16956 break;
16957 }
16958 break;
16959#ifdef TARGET_MIPS64
16960 case OPC_CMPU_EQ_OB_DSP:
16961 switch (op2) {
16962 case OPC_CMP_EQ_PW:
16963 check_dsp(ctx);
16964 gen_helper_cmp_eq_pw(v1_t, v2_t, cpu_env);
16965 break;
16966 case OPC_CMP_LT_PW:
16967 check_dsp(ctx);
16968 gen_helper_cmp_lt_pw(v1_t, v2_t, cpu_env);
16969 break;
16970 case OPC_CMP_LE_PW:
16971 check_dsp(ctx);
16972 gen_helper_cmp_le_pw(v1_t, v2_t, cpu_env);
16973 break;
16974 case OPC_CMP_EQ_QH:
16975 check_dsp(ctx);
16976 gen_helper_cmp_eq_qh(v1_t, v2_t, cpu_env);
16977 break;
16978 case OPC_CMP_LT_QH:
16979 check_dsp(ctx);
16980 gen_helper_cmp_lt_qh(v1_t, v2_t, cpu_env);
16981 break;
16982 case OPC_CMP_LE_QH:
16983 check_dsp(ctx);
16984 gen_helper_cmp_le_qh(v1_t, v2_t, cpu_env);
16985 break;
16986 case OPC_CMPGDU_EQ_OB:
16987 check_dspr2(ctx);
16988 gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16989 break;
16990 case OPC_CMPGDU_LT_OB:
16991 check_dspr2(ctx);
16992 gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16993 break;
16994 case OPC_CMPGDU_LE_OB:
16995 check_dspr2(ctx);
16996 gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16997 break;
16998 case OPC_CMPGU_EQ_OB:
16999 check_dsp(ctx);
17000 gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t);
17001 break;
17002 case OPC_CMPGU_LT_OB:
17003 check_dsp(ctx);
17004 gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t);
17005 break;
17006 case OPC_CMPGU_LE_OB:
17007 check_dsp(ctx);
17008 gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t);
17009 break;
17010 case OPC_CMPU_EQ_OB:
17011 check_dsp(ctx);
17012 gen_helper_cmpu_eq_ob(v1_t, v2_t, cpu_env);
17013 break;
17014 case OPC_CMPU_LT_OB:
17015 check_dsp(ctx);
17016 gen_helper_cmpu_lt_ob(v1_t, v2_t, cpu_env);
17017 break;
17018 case OPC_CMPU_LE_OB:
17019 check_dsp(ctx);
17020 gen_helper_cmpu_le_ob(v1_t, v2_t, cpu_env);
17021 break;
17022 case OPC_PACKRL_PW:
17023 check_dsp(ctx);
17024 gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t);
17025 break;
17026 case OPC_PICK_OB:
17027 check_dsp(ctx);
17028 gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
17029 break;
17030 case OPC_PICK_PW:
17031 check_dsp(ctx);
17032 gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
17033 break;
17034 case OPC_PICK_QH:
17035 check_dsp(ctx);
17036 gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
17037 break;
17038 }
17039 break;
df6126a7
AJ
17040#endif
17041 }
17042
17043 tcg_temp_free(t1);
17044 tcg_temp_free(v1_t);
17045 tcg_temp_free(v2_t);
df6126a7
AJ
17046}
17047
17048static void gen_mipsdsp_append(CPUMIPSState *env, DisasContext *ctx,
17049 uint32_t op1, int rt, int rs, int sa)
17050{
df6126a7
AJ
17051 TCGv t0;
17052
17053 check_dspr2(ctx);
17054
17055 if (rt == 0) {
17056 /* Treat as NOP. */
df6126a7
AJ
17057 return;
17058 }
17059
17060 t0 = tcg_temp_new();
17061 gen_load_gpr(t0, rs);
17062
17063 switch (op1) {
17064 case OPC_APPEND_DSP:
17065 switch (MASK_APPEND(ctx->opcode)) {
17066 case OPC_APPEND:
17067 if (sa != 0) {
17068 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 32 - sa);
17069 }
17070 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
17071 break;
17072 case OPC_PREPEND:
17073 if (sa != 0) {
17074 tcg_gen_ext32u_tl(cpu_gpr[rt], cpu_gpr[rt]);
17075 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
17076 tcg_gen_shli_tl(t0, t0, 32 - sa);
17077 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
17078 }
17079 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
17080 break;
17081 case OPC_BALIGN:
17082 sa &= 3;
17083 if (sa != 0 && sa != 2) {
17084 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
17085 tcg_gen_ext32u_tl(t0, t0);
17086 tcg_gen_shri_tl(t0, t0, 8 * (4 - sa));
17087 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
17088 }
17089 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
17090 break;
17091 default: /* Invalid */
17092 MIPS_INVAL("MASK APPEND");
9c708c7f 17093 generate_exception_end(ctx, EXCP_RI);
df6126a7
AJ
17094 break;
17095 }
17096 break;
17097#ifdef TARGET_MIPS64
26690560 17098 case OPC_DAPPEND_DSP:
df6126a7 17099 switch (MASK_DAPPEND(ctx->opcode)) {
26690560 17100 case OPC_DAPPEND:
df6126a7
AJ
17101 if (sa != 0) {
17102 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 64 - sa);
17103 }
26690560
JL
17104 break;
17105 case OPC_PREPENDD:
df6126a7
AJ
17106 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], 0x20 | sa);
17107 tcg_gen_shli_tl(t0, t0, 64 - (0x20 | sa));
17108 tcg_gen_or_tl(cpu_gpr[rt], t0, t0);
26690560
JL
17109 break;
17110 case OPC_PREPENDW:
df6126a7
AJ
17111 if (sa != 0) {
17112 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
17113 tcg_gen_shli_tl(t0, t0, 64 - sa);
17114 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
17115 }
26690560
JL
17116 break;
17117 case OPC_DBALIGN:
df6126a7
AJ
17118 sa &= 7;
17119 if (sa != 0 && sa != 2 && sa != 4) {
17120 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
17121 tcg_gen_shri_tl(t0, t0, 8 * (8 - sa));
17122 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
17123 }
26690560
JL
17124 break;
17125 default: /* Invalid */
17126 MIPS_INVAL("MASK DAPPEND");
9c708c7f 17127 generate_exception_end(ctx, EXCP_RI);
26690560
JL
17128 break;
17129 }
17130 break;
17131#endif
17132 }
df6126a7 17133 tcg_temp_free(t0);
26690560
JL
17134}
17135
b53371ed
JL
17136static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
17137 int ret, int v1, int v2, int check_ret)
17138
17139{
b53371ed
JL
17140 TCGv t0;
17141 TCGv t1;
17142 TCGv v1_t;
17143 TCGv v2_t;
17144 int16_t imm;
17145
17146 if ((ret == 0) && (check_ret == 1)) {
17147 /* Treat as NOP. */
b53371ed
JL
17148 return;
17149 }
17150
17151 t0 = tcg_temp_new();
17152 t1 = tcg_temp_new();
17153 v1_t = tcg_temp_new();
17154 v2_t = tcg_temp_new();
17155
17156 gen_load_gpr(v1_t, v1);
17157 gen_load_gpr(v2_t, v2);
17158
17159 switch (op1) {
17160 case OPC_EXTR_W_DSP:
17161 check_dsp(ctx);
17162 switch (op2) {
17163 case OPC_EXTR_W:
17164 tcg_gen_movi_tl(t0, v2);
17165 tcg_gen_movi_tl(t1, v1);
17166 gen_helper_extr_w(cpu_gpr[ret], t0, t1, cpu_env);
17167 break;
17168 case OPC_EXTR_R_W:
17169 tcg_gen_movi_tl(t0, v2);
17170 tcg_gen_movi_tl(t1, v1);
17171 gen_helper_extr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
17172 break;
17173 case OPC_EXTR_RS_W:
17174 tcg_gen_movi_tl(t0, v2);
17175 tcg_gen_movi_tl(t1, v1);
17176 gen_helper_extr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
17177 break;
17178 case OPC_EXTR_S_H:
17179 tcg_gen_movi_tl(t0, v2);
17180 tcg_gen_movi_tl(t1, v1);
17181 gen_helper_extr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
17182 break;
17183 case OPC_EXTRV_S_H:
17184 tcg_gen_movi_tl(t0, v2);
17185 gen_helper_extr_s_h(cpu_gpr[ret], t0, v1_t, cpu_env);
17186 break;
17187 case OPC_EXTRV_W:
17188 tcg_gen_movi_tl(t0, v2);
17189 gen_helper_extr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
17190 break;
17191 case OPC_EXTRV_R_W:
17192 tcg_gen_movi_tl(t0, v2);
17193 gen_helper_extr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
17194 break;
17195 case OPC_EXTRV_RS_W:
17196 tcg_gen_movi_tl(t0, v2);
17197 gen_helper_extr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
17198 break;
17199 case OPC_EXTP:
17200 tcg_gen_movi_tl(t0, v2);
17201 tcg_gen_movi_tl(t1, v1);
17202 gen_helper_extp(cpu_gpr[ret], t0, t1, cpu_env);
17203 break;
17204 case OPC_EXTPV:
17205 tcg_gen_movi_tl(t0, v2);
17206 gen_helper_extp(cpu_gpr[ret], t0, v1_t, cpu_env);
17207 break;
17208 case OPC_EXTPDP:
17209 tcg_gen_movi_tl(t0, v2);
17210 tcg_gen_movi_tl(t1, v1);
17211 gen_helper_extpdp(cpu_gpr[ret], t0, t1, cpu_env);
17212 break;
17213 case OPC_EXTPDPV:
17214 tcg_gen_movi_tl(t0, v2);
17215 gen_helper_extpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
17216 break;
17217 case OPC_SHILO:
17218 imm = (ctx->opcode >> 20) & 0x3F;
17219 tcg_gen_movi_tl(t0, ret);
17220 tcg_gen_movi_tl(t1, imm);
17221 gen_helper_shilo(t0, t1, cpu_env);
17222 break;
17223 case OPC_SHILOV:
17224 tcg_gen_movi_tl(t0, ret);
17225 gen_helper_shilo(t0, v1_t, cpu_env);
17226 break;
17227 case OPC_MTHLIP:
17228 tcg_gen_movi_tl(t0, ret);
17229 gen_helper_mthlip(t0, v1_t, cpu_env);
17230 break;
17231 case OPC_WRDSP:
17232 imm = (ctx->opcode >> 11) & 0x3FF;
17233 tcg_gen_movi_tl(t0, imm);
17234 gen_helper_wrdsp(v1_t, t0, cpu_env);
17235 break;
17236 case OPC_RDDSP:
17237 imm = (ctx->opcode >> 16) & 0x03FF;
17238 tcg_gen_movi_tl(t0, imm);
17239 gen_helper_rddsp(cpu_gpr[ret], t0, cpu_env);
17240 break;
17241 }
17242 break;
17243#ifdef TARGET_MIPS64
17244 case OPC_DEXTR_W_DSP:
17245 check_dsp(ctx);
17246 switch (op2) {
17247 case OPC_DMTHLIP:
17248 tcg_gen_movi_tl(t0, ret);
17249 gen_helper_dmthlip(v1_t, t0, cpu_env);
17250 break;
17251 case OPC_DSHILO:
17252 {
17253 int shift = (ctx->opcode >> 19) & 0x7F;
17254 int ac = (ctx->opcode >> 11) & 0x03;
17255 tcg_gen_movi_tl(t0, shift);
17256 tcg_gen_movi_tl(t1, ac);
17257 gen_helper_dshilo(t0, t1, cpu_env);
17258 break;
17259 }
17260 case OPC_DSHILOV:
17261 {
17262 int ac = (ctx->opcode >> 11) & 0x03;
17263 tcg_gen_movi_tl(t0, ac);
17264 gen_helper_dshilo(v1_t, t0, cpu_env);
17265 break;
17266 }
17267 case OPC_DEXTP:
17268 tcg_gen_movi_tl(t0, v2);
17269 tcg_gen_movi_tl(t1, v1);
17270
17271 gen_helper_dextp(cpu_gpr[ret], t0, t1, cpu_env);
17272 break;
17273 case OPC_DEXTPV:
17274 tcg_gen_movi_tl(t0, v2);
17275 gen_helper_dextp(cpu_gpr[ret], t0, v1_t, cpu_env);
17276 break;
17277 case OPC_DEXTPDP:
17278 tcg_gen_movi_tl(t0, v2);
17279 tcg_gen_movi_tl(t1, v1);
17280 gen_helper_dextpdp(cpu_gpr[ret], t0, t1, cpu_env);
17281 break;
17282 case OPC_DEXTPDPV:
17283 tcg_gen_movi_tl(t0, v2);
17284 gen_helper_dextpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
17285 break;
17286 case OPC_DEXTR_L:
17287 tcg_gen_movi_tl(t0, v2);
17288 tcg_gen_movi_tl(t1, v1);
17289 gen_helper_dextr_l(cpu_gpr[ret], t0, t1, cpu_env);
17290 break;
17291 case OPC_DEXTR_R_L:
17292 tcg_gen_movi_tl(t0, v2);
17293 tcg_gen_movi_tl(t1, v1);
17294 gen_helper_dextr_r_l(cpu_gpr[ret], t0, t1, cpu_env);
17295 break;
17296 case OPC_DEXTR_RS_L:
17297 tcg_gen_movi_tl(t0, v2);
17298 tcg_gen_movi_tl(t1, v1);
17299 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, t1, cpu_env);
17300 break;
17301 case OPC_DEXTR_W:
17302 tcg_gen_movi_tl(t0, v2);
17303 tcg_gen_movi_tl(t1, v1);
17304 gen_helper_dextr_w(cpu_gpr[ret], t0, t1, cpu_env);
17305 break;
17306 case OPC_DEXTR_R_W:
17307 tcg_gen_movi_tl(t0, v2);
17308 tcg_gen_movi_tl(t1, v1);
17309 gen_helper_dextr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
17310 break;
17311 case OPC_DEXTR_RS_W:
17312 tcg_gen_movi_tl(t0, v2);
17313 tcg_gen_movi_tl(t1, v1);
17314 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
17315 break;
17316 case OPC_DEXTR_S_H:
17317 tcg_gen_movi_tl(t0, v2);
17318 tcg_gen_movi_tl(t1, v1);
17319 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
17320 break;
17321 case OPC_DEXTRV_S_H:
17322 tcg_gen_movi_tl(t0, v2);
17323 tcg_gen_movi_tl(t1, v1);
17324 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
17325 break;
17326 case OPC_DEXTRV_L:
17327 tcg_gen_movi_tl(t0, v2);
17328 gen_helper_dextr_l(cpu_gpr[ret], t0, v1_t, cpu_env);
17329 break;
17330 case OPC_DEXTRV_R_L:
17331 tcg_gen_movi_tl(t0, v2);
17332 gen_helper_dextr_r_l(cpu_gpr[ret], t0, v1_t, cpu_env);
17333 break;
17334 case OPC_DEXTRV_RS_L:
17335 tcg_gen_movi_tl(t0, v2);
17336 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, v1_t, cpu_env);
17337 break;
17338 case OPC_DEXTRV_W:
17339 tcg_gen_movi_tl(t0, v2);
17340 gen_helper_dextr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
17341 break;
17342 case OPC_DEXTRV_R_W:
17343 tcg_gen_movi_tl(t0, v2);
17344 gen_helper_dextr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
17345 break;
17346 case OPC_DEXTRV_RS_W:
17347 tcg_gen_movi_tl(t0, v2);
17348 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
17349 break;
17350 }
17351 break;
17352#endif
17353 }
17354
17355 tcg_temp_free(t0);
17356 tcg_temp_free(t1);
17357 tcg_temp_free(v1_t);
17358 tcg_temp_free(v2_t);
b53371ed
JL
17359}
17360
9b1a1d68
JL
17361/* End MIPSDSP functions. */
17362
10dc65db
LA
17363static void decode_opc_special_r6(CPUMIPSState *env, DisasContext *ctx)
17364{
4267d3e6 17365 int rs, rt, rd, sa;
b42ee5e1 17366 uint32_t op1, op2;
10dc65db
LA
17367
17368 rs = (ctx->opcode >> 21) & 0x1f;
17369 rt = (ctx->opcode >> 16) & 0x1f;
17370 rd = (ctx->opcode >> 11) & 0x1f;
4267d3e6 17371 sa = (ctx->opcode >> 6) & 0x1f;
10dc65db
LA
17372
17373 op1 = MASK_SPECIAL(ctx->opcode);
17374 switch (op1) {
d4ea6acd 17375 case OPC_LSA:
1f1b4c00 17376 gen_lsa(ctx, op1, rd, rs, rt, extract32(ctx->opcode, 6, 2));
d4ea6acd 17377 break;
c2e19f3c
AM
17378 case OPC_MULT:
17379 case OPC_MULTU:
17380 case OPC_DIV:
17381 case OPC_DIVU:
b42ee5e1
LA
17382 op2 = MASK_R6_MULDIV(ctx->opcode);
17383 switch (op2) {
17384 case R6_OPC_MUL:
17385 case R6_OPC_MUH:
17386 case R6_OPC_MULU:
17387 case R6_OPC_MUHU:
17388 case R6_OPC_DIV:
17389 case R6_OPC_MOD:
17390 case R6_OPC_DIVU:
17391 case R6_OPC_MODU:
17392 gen_r6_muldiv(ctx, op2, rd, rs, rt);
17393 break;
17394 default:
17395 MIPS_INVAL("special_r6 muldiv");
9c708c7f 17396 generate_exception_end(ctx, EXCP_RI);
b42ee5e1
LA
17397 break;
17398 }
17399 break;
10dc65db
LA
17400 case OPC_SELEQZ:
17401 case OPC_SELNEZ:
17402 gen_cond_move(ctx, op1, rd, rs, rt);
17403 break;
4267d3e6
LA
17404 case R6_OPC_CLO:
17405 case R6_OPC_CLZ:
17406 if (rt == 0 && sa == 1) {
17407 /* Major opcode and function field is shared with preR6 MFHI/MTHI.
17408 We need additionally to check other fields */
17409 gen_cl(ctx, op1, rd, rs);
17410 } else {
9c708c7f 17411 generate_exception_end(ctx, EXCP_RI);
4267d3e6
LA
17412 }
17413 break;
17414 case R6_OPC_SDBBP:
3b3c1694
LA
17415 if (is_uhi(extract32(ctx->opcode, 6, 20))) {
17416 gen_helper_do_semihosting(cpu_env);
faf1f68b 17417 } else {
3b3c1694 17418 if (ctx->hflags & MIPS_HFLAG_SBRI) {
9c708c7f 17419 generate_exception_end(ctx, EXCP_RI);
3b3c1694 17420 } else {
9c708c7f 17421 generate_exception_end(ctx, EXCP_DBp);
3b3c1694 17422 }
faf1f68b 17423 }
4267d3e6 17424 break;
b42ee5e1 17425#if defined(TARGET_MIPS64)
d4ea6acd
LA
17426 case OPC_DLSA:
17427 check_mips_64(ctx);
1f1b4c00 17428 gen_lsa(ctx, op1, rd, rs, rt, extract32(ctx->opcode, 6, 2));
d4ea6acd 17429 break;
4267d3e6
LA
17430 case R6_OPC_DCLO:
17431 case R6_OPC_DCLZ:
17432 if (rt == 0 && sa == 1) {
17433 /* Major opcode and function field is shared with preR6 MFHI/MTHI.
17434 We need additionally to check other fields */
17435 check_mips_64(ctx);
17436 gen_cl(ctx, op1, rd, rs);
17437 } else {
9c708c7f 17438 generate_exception_end(ctx, EXCP_RI);
4267d3e6
LA
17439 }
17440 break;
c2e19f3c
AM
17441 case OPC_DMULT:
17442 case OPC_DMULTU:
17443 case OPC_DDIV:
17444 case OPC_DDIVU:
17445
b42ee5e1
LA
17446 op2 = MASK_R6_MULDIV(ctx->opcode);
17447 switch (op2) {
17448 case R6_OPC_DMUL:
17449 case R6_OPC_DMUH:
17450 case R6_OPC_DMULU:
17451 case R6_OPC_DMUHU:
17452 case R6_OPC_DDIV:
17453 case R6_OPC_DMOD:
17454 case R6_OPC_DDIVU:
17455 case R6_OPC_DMODU:
17456 check_mips_64(ctx);
17457 gen_r6_muldiv(ctx, op2, rd, rs, rt);
17458 break;
17459 default:
17460 MIPS_INVAL("special_r6 muldiv");
9c708c7f 17461 generate_exception_end(ctx, EXCP_RI);
b42ee5e1
LA
17462 break;
17463 }
17464 break;
17465#endif
10dc65db
LA
17466 default: /* Invalid */
17467 MIPS_INVAL("special_r6");
9c708c7f 17468 generate_exception_end(ctx, EXCP_RI);
10dc65db
LA
17469 break;
17470 }
17471}
17472
17473static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx)
17474{
b42ee5e1 17475 int rs, rt, rd, sa;
10dc65db
LA
17476 uint32_t op1;
17477
17478 rs = (ctx->opcode >> 21) & 0x1f;
17479 rt = (ctx->opcode >> 16) & 0x1f;
17480 rd = (ctx->opcode >> 11) & 0x1f;
b42ee5e1 17481 sa = (ctx->opcode >> 6) & 0x1f;
10dc65db
LA
17482
17483 op1 = MASK_SPECIAL(ctx->opcode);
17484 switch (op1) {
17485 case OPC_MOVN: /* Conditional move */
17486 case OPC_MOVZ:
17487 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32 |
17488 INSN_LOONGSON2E | INSN_LOONGSON2F);
17489 gen_cond_move(ctx, op1, rd, rs, rt);
17490 break;
17491 case OPC_MFHI: /* Move from HI/LO */
17492 case OPC_MFLO:
17493 gen_HILO(ctx, op1, rs & 3, rd);
17494 break;
17495 case OPC_MTHI:
17496 case OPC_MTLO: /* Move to HI/LO */
17497 gen_HILO(ctx, op1, rd & 3, rs);
17498 break;
17499 case OPC_MOVCI:
17500 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
17501 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
17502 check_cp1_enabled(ctx);
17503 gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
17504 (ctx->opcode >> 16) & 1);
17505 } else {
17506 generate_exception_err(ctx, EXCP_CpU, 1);
17507 }
17508 break;
b42ee5e1
LA
17509 case OPC_MULT:
17510 case OPC_MULTU:
17511 if (sa) {
17512 check_insn(ctx, INSN_VR54XX);
17513 op1 = MASK_MUL_VR54XX(ctx->opcode);
17514 gen_mul_vr54xx(ctx, op1, rd, rs, rt);
17515 } else {
17516 gen_muldiv(ctx, op1, rd & 3, rs, rt);
17517 }
17518 break;
17519 case OPC_DIV:
17520 case OPC_DIVU:
17521 gen_muldiv(ctx, op1, 0, rs, rt);
17522 break;
17523#if defined(TARGET_MIPS64)
c2e19f3c
AM
17524 case OPC_DMULT:
17525 case OPC_DMULTU:
17526 case OPC_DDIV:
17527 case OPC_DDIVU:
b42ee5e1
LA
17528 check_insn(ctx, ISA_MIPS3);
17529 check_mips_64(ctx);
17530 gen_muldiv(ctx, op1, 0, rs, rt);
17531 break;
17532#endif
0aefa333 17533 case OPC_JR:
b231c103 17534 gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
0aefa333 17535 break;
4267d3e6
LA
17536 case OPC_SPIM:
17537#ifdef MIPS_STRICT_STANDARD
17538 MIPS_INVAL("SPIM");
9c708c7f 17539 generate_exception_end(ctx, EXCP_RI);
4267d3e6
LA
17540#else
17541 /* Implemented as RI exception for now. */
17542 MIPS_INVAL("spim (unofficial)");
9c708c7f 17543 generate_exception_end(ctx, EXCP_RI);
4267d3e6
LA
17544#endif
17545 break;
10dc65db
LA
17546 default: /* Invalid */
17547 MIPS_INVAL("special_legacy");
9c708c7f 17548 generate_exception_end(ctx, EXCP_RI);
10dc65db
LA
17549 break;
17550 }
17551}
17552
099e5b4d 17553static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx)
3c824109 17554{
3c824109 17555 int rs, rt, rd, sa;
099e5b4d 17556 uint32_t op1;
3c824109 17557
3c824109
NF
17558 rs = (ctx->opcode >> 21) & 0x1f;
17559 rt = (ctx->opcode >> 16) & 0x1f;
17560 rd = (ctx->opcode >> 11) & 0x1f;
17561 sa = (ctx->opcode >> 6) & 0x1f;
099e5b4d
LA
17562
17563 op1 = MASK_SPECIAL(ctx->opcode);
17564 switch (op1) {
17565 case OPC_SLL: /* Shift with immediate */
339cd2a8
LA
17566 if (sa == 5 && rd == 0 &&
17567 rs == 0 && rt == 0) { /* PAUSE */
17568 if ((ctx->insn_flags & ISA_MIPS32R6) &&
17569 (ctx->hflags & MIPS_HFLAG_BMASK)) {
9c708c7f 17570 generate_exception_end(ctx, EXCP_RI);
339cd2a8
LA
17571 break;
17572 }
17573 }
17574 /* Fallthrough */
099e5b4d
LA
17575 case OPC_SRA:
17576 gen_shift_imm(ctx, op1, rd, rt, sa);
17577 break;
17578 case OPC_SRL:
17579 switch ((ctx->opcode >> 21) & 0x1f) {
17580 case 1:
17581 /* rotr is decoded as srl on non-R2 CPUs */
17582 if (ctx->insn_flags & ISA_MIPS32R2) {
17583 op1 = OPC_ROTR;
ea63e2c3 17584 }
099e5b4d
LA
17585 /* Fallthrough */
17586 case 0:
17587 gen_shift_imm(ctx, op1, rd, rt, sa);
ea63e2c3 17588 break;
099e5b4d 17589 default:
9c708c7f 17590 generate_exception_end(ctx, EXCP_RI);
ea63e2c3 17591 break;
099e5b4d
LA
17592 }
17593 break;
c2e19f3c
AM
17594 case OPC_ADD:
17595 case OPC_ADDU:
17596 case OPC_SUB:
17597 case OPC_SUBU:
099e5b4d
LA
17598 gen_arith(ctx, op1, rd, rs, rt);
17599 break;
17600 case OPC_SLLV: /* Shifts */
17601 case OPC_SRAV:
17602 gen_shift(ctx, op1, rd, rs, rt);
17603 break;
17604 case OPC_SRLV:
17605 switch ((ctx->opcode >> 6) & 0x1f) {
17606 case 1:
17607 /* rotrv is decoded as srlv on non-R2 CPUs */
17608 if (ctx->insn_flags & ISA_MIPS32R2) {
17609 op1 = OPC_ROTRV;
26135ead 17610 }
099e5b4d
LA
17611 /* Fallthrough */
17612 case 0:
17613 gen_shift(ctx, op1, rd, rs, rt);
26135ead 17614 break;
099e5b4d 17615 default:
9c708c7f 17616 generate_exception_end(ctx, EXCP_RI);
6af0bf9c 17617 break;
099e5b4d
LA
17618 }
17619 break;
17620 case OPC_SLT: /* Set on less than */
17621 case OPC_SLTU:
17622 gen_slt(ctx, op1, rd, rs, rt);
17623 break;
17624 case OPC_AND: /* Logic*/
17625 case OPC_OR:
17626 case OPC_NOR:
17627 case OPC_XOR:
17628 gen_logic(ctx, op1, rd, rs, rt);
17629 break;
0aefa333 17630 case OPC_JALR:
b231c103 17631 gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
099e5b4d 17632 break;
c2e19f3c
AM
17633 case OPC_TGE: /* Traps */
17634 case OPC_TGEU:
17635 case OPC_TLT:
17636 case OPC_TLTU:
17637 case OPC_TEQ:
099e5b4d 17638 case OPC_TNE:
d9224450 17639 check_insn(ctx, ISA_MIPS2);
099e5b4d
LA
17640 gen_trap(ctx, op1, rs, rt, -1);
17641 break;
d4ea6acd 17642 case OPC_LSA: /* OPC_PMON */
f7685877
YK
17643 if ((ctx->insn_flags & ISA_MIPS32R6) ||
17644 (env->CP0_Config3 & (1 << CP0C3_MSAP))) {
d4ea6acd
LA
17645 decode_opc_special_r6(env, ctx);
17646 } else {
17647 /* Pmon entry point, also R4010 selsl */
b48cfdff 17648#ifdef MIPS_STRICT_STANDARD
d4ea6acd 17649 MIPS_INVAL("PMON / selsl");
9c708c7f 17650 generate_exception_end(ctx, EXCP_RI);
b48cfdff 17651#else
d4ea6acd 17652 gen_helper_0e0i(pmon, sa);
b48cfdff 17653#endif
d4ea6acd 17654 }
099e5b4d
LA
17655 break;
17656 case OPC_SYSCALL:
9c708c7f 17657 generate_exception_end(ctx, EXCP_SYSCALL);
099e5b4d
LA
17658 break;
17659 case OPC_BREAK:
9c708c7f 17660 generate_exception_end(ctx, EXCP_BREAK);
099e5b4d 17661 break;
099e5b4d 17662 case OPC_SYNC:
d9224450 17663 check_insn(ctx, ISA_MIPS2);
d208ac0c 17664 gen_sync(extract32(ctx->opcode, 6, 5));
099e5b4d 17665 break;
4ad40f36 17666
d26bc211 17667#if defined(TARGET_MIPS64)
099e5b4d
LA
17668 /* MIPS64 specific opcodes */
17669 case OPC_DSLL:
17670 case OPC_DSRA:
17671 case OPC_DSLL32:
17672 case OPC_DSRA32:
17673 check_insn(ctx, ISA_MIPS3);
17674 check_mips_64(ctx);
17675 gen_shift_imm(ctx, op1, rd, rt, sa);
17676 break;
17677 case OPC_DSRL:
17678 switch ((ctx->opcode >> 21) & 0x1f) {
17679 case 1:
17680 /* drotr is decoded as dsrl on non-R2 CPUs */
17681 if (ctx->insn_flags & ISA_MIPS32R2) {
17682 op1 = OPC_DROTR;
ea63e2c3 17683 }
099e5b4d
LA
17684 /* Fallthrough */
17685 case 0:
d75c135e 17686 check_insn(ctx, ISA_MIPS3);
e189e748 17687 check_mips_64(ctx);
099e5b4d 17688 gen_shift_imm(ctx, op1, rd, rt, sa);
7a387fff 17689 break;
099e5b4d 17690 default:
9c708c7f 17691 generate_exception_end(ctx, EXCP_RI);
460f00c4 17692 break;
099e5b4d
LA
17693 }
17694 break;
17695 case OPC_DSRL32:
17696 switch ((ctx->opcode >> 21) & 0x1f) {
17697 case 1:
17698 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
17699 if (ctx->insn_flags & ISA_MIPS32R2) {
17700 op1 = OPC_DROTR32;
ea63e2c3 17701 }
099e5b4d
LA
17702 /* Fallthrough */
17703 case 0:
d75c135e 17704 check_insn(ctx, ISA_MIPS3);
e189e748 17705 check_mips_64(ctx);
099e5b4d 17706 gen_shift_imm(ctx, op1, rd, rt, sa);
7a387fff 17707 break;
099e5b4d 17708 default:
9c708c7f 17709 generate_exception_end(ctx, EXCP_RI);
6af0bf9c
FB
17710 break;
17711 }
17712 break;
c2e19f3c
AM
17713 case OPC_DADD:
17714 case OPC_DADDU:
17715 case OPC_DSUB:
17716 case OPC_DSUBU:
099e5b4d
LA
17717 check_insn(ctx, ISA_MIPS3);
17718 check_mips_64(ctx);
17719 gen_arith(ctx, op1, rd, rs, rt);
17720 break;
17721 case OPC_DSLLV:
17722 case OPC_DSRAV:
17723 check_insn(ctx, ISA_MIPS3);
17724 check_mips_64(ctx);
17725 gen_shift(ctx, op1, rd, rs, rt);
17726 break;
17727 case OPC_DSRLV:
17728 switch ((ctx->opcode >> 6) & 0x1f) {
17729 case 1:
17730 /* drotrv is decoded as dsrlv on non-R2 CPUs */
17731 if (ctx->insn_flags & ISA_MIPS32R2) {
17732 op1 = OPC_DROTRV;
6af0bf9c 17733 }
099e5b4d
LA
17734 /* Fallthrough */
17735 case 0:
17736 check_insn(ctx, ISA_MIPS3);
e189e748 17737 check_mips_64(ctx);
099e5b4d 17738 gen_shift(ctx, op1, rd, rs, rt);
161f85e6 17739 break;
099e5b4d 17740 default:
9c708c7f 17741 generate_exception_end(ctx, EXCP_RI);
6af0bf9c
FB
17742 break;
17743 }
17744 break;
f7685877
YK
17745 case OPC_DLSA:
17746 if ((ctx->insn_flags & ISA_MIPS32R6) ||
17747 (env->CP0_Config3 & (1 << CP0C3_MSAP))) {
17748 decode_opc_special_r6(env, ctx);
17749 }
17750 break;
099e5b4d 17751#endif
10dc65db
LA
17752 default:
17753 if (ctx->insn_flags & ISA_MIPS32R6) {
17754 decode_opc_special_r6(env, ctx);
17755 } else {
17756 decode_opc_special_legacy(env, ctx);
17757 }
17758 }
17759}
17760
10dc65db 17761static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx)
099e5b4d
LA
17762{
17763 int rs, rt, rd;
17764 uint32_t op1;
6c5c1e20 17765
4267d3e6
LA
17766 check_insn_opc_removed(ctx, ISA_MIPS32R6);
17767
099e5b4d
LA
17768 rs = (ctx->opcode >> 21) & 0x1f;
17769 rt = (ctx->opcode >> 16) & 0x1f;
17770 rd = (ctx->opcode >> 11) & 0x1f;
17771
17772 op1 = MASK_SPECIAL2(ctx->opcode);
17773 switch (op1) {
c2e19f3c
AM
17774 case OPC_MADD: /* Multiply and add/sub */
17775 case OPC_MADDU:
17776 case OPC_MSUB:
17777 case OPC_MSUBU:
099e5b4d
LA
17778 check_insn(ctx, ISA_MIPS32);
17779 gen_muldiv(ctx, op1, rd & 3, rs, rt);
17780 break;
17781 case OPC_MUL:
099e5b4d
LA
17782 gen_arith(ctx, op1, rd, rs, rt);
17783 break;
fac5a073
LA
17784 case OPC_DIV_G_2F:
17785 case OPC_DIVU_G_2F:
17786 case OPC_MULT_G_2F:
17787 case OPC_MULTU_G_2F:
17788 case OPC_MOD_G_2F:
17789 case OPC_MODU_G_2F:
17790 check_insn(ctx, INSN_LOONGSON2F);
17791 gen_loongson_integer(ctx, op1, rd, rs, rt);
17792 break;
099e5b4d
LA
17793 case OPC_CLO:
17794 case OPC_CLZ:
17795 check_insn(ctx, ISA_MIPS32);
17796 gen_cl(ctx, op1, rd, rs);
17797 break;
17798 case OPC_SDBBP:
3b3c1694
LA
17799 if (is_uhi(extract32(ctx->opcode, 6, 20))) {
17800 gen_helper_do_semihosting(cpu_env);
17801 } else {
17802 /* XXX: not clear which exception should be raised
17803 * when in debug mode...
17804 */
17805 check_insn(ctx, ISA_MIPS32);
9c708c7f 17806 generate_exception_end(ctx, EXCP_DBp);
3b3c1694 17807 }
099e5b4d 17808 break;
9b1a1d68 17809#if defined(TARGET_MIPS64)
099e5b4d
LA
17810 case OPC_DCLO:
17811 case OPC_DCLZ:
17812 check_insn(ctx, ISA_MIPS64);
17813 check_mips_64(ctx);
17814 gen_cl(ctx, op1, rd, rs);
17815 break;
4267d3e6
LA
17816 case OPC_DMULT_G_2F:
17817 case OPC_DMULTU_G_2F:
17818 case OPC_DDIV_G_2F:
17819 case OPC_DDIVU_G_2F:
17820 case OPC_DMOD_G_2F:
17821 case OPC_DMODU_G_2F:
17822 check_insn(ctx, INSN_LOONGSON2F);
17823 gen_loongson_integer(ctx, op1, rd, rs, rt);
17824 break;
10dc65db 17825#endif
4267d3e6
LA
17826 default: /* Invalid */
17827 MIPS_INVAL("special2_legacy");
9c708c7f 17828 generate_exception_end(ctx, EXCP_RI);
4267d3e6 17829 break;
10dc65db
LA
17830 }
17831}
17832
17833static void decode_opc_special3_r6(CPUMIPSState *env, DisasContext *ctx)
17834{
15eacb9b
YK
17835 int rs, rt, rd, sa;
17836 uint32_t op1, op2;
10dc65db
LA
17837 int16_t imm;
17838
17839 rs = (ctx->opcode >> 21) & 0x1f;
17840 rt = (ctx->opcode >> 16) & 0x1f;
15eacb9b
YK
17841 rd = (ctx->opcode >> 11) & 0x1f;
17842 sa = (ctx->opcode >> 6) & 0x1f;
10dc65db
LA
17843 imm = (int16_t)ctx->opcode >> 7;
17844
17845 op1 = MASK_SPECIAL3(ctx->opcode);
17846 switch (op1) {
bf7910c6
LA
17847 case R6_OPC_PREF:
17848 if (rt >= 24) {
17849 /* hint codes 24-31 are reserved and signal RI */
9c708c7f 17850 generate_exception_end(ctx, EXCP_RI);
bf7910c6
LA
17851 }
17852 /* Treat as NOP. */
17853 break;
17854 case R6_OPC_CACHE:
40d48212 17855 check_cp0_enabled(ctx);
0d74a222
LA
17856 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
17857 gen_cache_operation(ctx, rt, rs, imm);
17858 }
bf7910c6 17859 break;
10dc65db
LA
17860 case R6_OPC_SC:
17861 gen_st_cond(ctx, op1, rt, rs, imm);
17862 break;
17863 case R6_OPC_LL:
17864 gen_ld(ctx, op1, rt, rs, imm);
17865 break;
15eacb9b
YK
17866 case OPC_BSHFL:
17867 {
17868 if (rd == 0) {
17869 /* Treat as NOP. */
17870 break;
17871 }
15eacb9b
YK
17872 op2 = MASK_BSHFL(ctx->opcode);
17873 switch (op2) {
c2e19f3c
AM
17874 case OPC_ALIGN:
17875 case OPC_ALIGN_END:
1f1b4c00 17876 gen_align(ctx, OPC_ALIGN, rd, rs, rt, sa & 3);
15eacb9b
YK
17877 break;
17878 case OPC_BITSWAP:
1f1b4c00 17879 gen_bitswap(ctx, op2, rd, rt);
15eacb9b
YK
17880 break;
17881 }
15eacb9b
YK
17882 }
17883 break;
bf7910c6
LA
17884#if defined(TARGET_MIPS64)
17885 case R6_OPC_SCD:
17886 gen_st_cond(ctx, op1, rt, rs, imm);
17887 break;
17888 case R6_OPC_LLD:
17889 gen_ld(ctx, op1, rt, rs, imm);
17890 break;
15eacb9b
YK
17891 case OPC_DBSHFL:
17892 check_mips_64(ctx);
17893 {
17894 if (rd == 0) {
17895 /* Treat as NOP. */
17896 break;
17897 }
15eacb9b
YK
17898 op2 = MASK_DBSHFL(ctx->opcode);
17899 switch (op2) {
c2e19f3c
AM
17900 case OPC_DALIGN:
17901 case OPC_DALIGN_END:
1f1b4c00 17902 gen_align(ctx, OPC_DALIGN, rd, rs, rt, sa & 7);
15eacb9b
YK
17903 break;
17904 case OPC_DBITSWAP:
1f1b4c00 17905 gen_bitswap(ctx, op2, rd, rt);
15eacb9b
YK
17906 break;
17907 }
1f1b4c00 17908
15eacb9b
YK
17909 }
17910 break;
bf7910c6 17911#endif
10dc65db
LA
17912 default: /* Invalid */
17913 MIPS_INVAL("special3_r6");
9c708c7f 17914 generate_exception_end(ctx, EXCP_RI);
10dc65db
LA
17915 break;
17916 }
17917}
17918
17919static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx)
17920{
fac5a073 17921 int rs, rt, rd;
099e5b4d 17922 uint32_t op1, op2;
099e5b4d
LA
17923
17924 rs = (ctx->opcode >> 21) & 0x1f;
17925 rt = (ctx->opcode >> 16) & 0x1f;
17926 rd = (ctx->opcode >> 11) & 0x1f;
099e5b4d
LA
17927
17928 op1 = MASK_SPECIAL3(ctx->opcode);
17929 switch (op1) {
c2e19f3c
AM
17930 case OPC_DIV_G_2E:
17931 case OPC_DIVU_G_2E:
17932 case OPC_MOD_G_2E:
17933 case OPC_MODU_G_2E:
17934 case OPC_MULT_G_2E:
17935 case OPC_MULTU_G_2E:
099e5b4d
LA
17936 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
17937 * the same mask and op1. */
17938 if ((ctx->insn_flags & ASE_DSPR2) && (op1 == OPC_MULT_G_2E)) {
17939 op2 = MASK_ADDUH_QB(ctx->opcode);
461c08df 17940 switch (op2) {
099e5b4d
LA
17941 case OPC_ADDUH_QB:
17942 case OPC_ADDUH_R_QB:
17943 case OPC_ADDQH_PH:
17944 case OPC_ADDQH_R_PH:
17945 case OPC_ADDQH_W:
17946 case OPC_ADDQH_R_W:
17947 case OPC_SUBUH_QB:
17948 case OPC_SUBUH_R_QB:
17949 case OPC_SUBQH_PH:
17950 case OPC_SUBQH_R_PH:
17951 case OPC_SUBQH_W:
17952 case OPC_SUBQH_R_W:
461c08df
JL
17953 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
17954 break;
099e5b4d
LA
17955 case OPC_MUL_PH:
17956 case OPC_MUL_S_PH:
17957 case OPC_MULQ_S_W:
17958 case OPC_MULQ_RS_W:
17959 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
1cb6686c 17960 break;
461c08df 17961 default:
099e5b4d 17962 MIPS_INVAL("MASK ADDUH.QB");
9c708c7f 17963 generate_exception_end(ctx, EXCP_RI);
461c08df
JL
17964 break;
17965 }
099e5b4d
LA
17966 } else if (ctx->insn_flags & INSN_LOONGSON2E) {
17967 gen_loongson_integer(ctx, op1, rd, rs, rt);
17968 } else {
9c708c7f 17969 generate_exception_end(ctx, EXCP_RI);
099e5b4d
LA
17970 }
17971 break;
17972 case OPC_LX_DSP:
17973 op2 = MASK_LX(ctx->opcode);
17974 switch (op2) {
17975#if defined(TARGET_MIPS64)
17976 case OPC_LDX:
17977#endif
17978 case OPC_LBUX:
17979 case OPC_LHX:
17980 case OPC_LWX:
17981 gen_mipsdsp_ld(ctx, op2, rd, rs, rt);
17982 break;
17983 default: /* Invalid */
17984 MIPS_INVAL("MASK LX");
9c708c7f 17985 generate_exception_end(ctx, EXCP_RI);
099e5b4d
LA
17986 break;
17987 }
17988 break;
17989 case OPC_ABSQ_S_PH_DSP:
17990 op2 = MASK_ABSQ_S_PH(ctx->opcode);
17991 switch (op2) {
17992 case OPC_ABSQ_S_QB:
17993 case OPC_ABSQ_S_PH:
17994 case OPC_ABSQ_S_W:
17995 case OPC_PRECEQ_W_PHL:
17996 case OPC_PRECEQ_W_PHR:
17997 case OPC_PRECEQU_PH_QBL:
17998 case OPC_PRECEQU_PH_QBR:
17999 case OPC_PRECEQU_PH_QBLA:
18000 case OPC_PRECEQU_PH_QBRA:
18001 case OPC_PRECEU_PH_QBL:
18002 case OPC_PRECEU_PH_QBR:
18003 case OPC_PRECEU_PH_QBLA:
18004 case OPC_PRECEU_PH_QBRA:
18005 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
18006 break;
18007 case OPC_BITREV:
18008 case OPC_REPL_QB:
18009 case OPC_REPLV_QB:
18010 case OPC_REPL_PH:
18011 case OPC_REPLV_PH:
18012 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
18013 break;
18014 default:
18015 MIPS_INVAL("MASK ABSQ_S.PH");
9c708c7f 18016 generate_exception_end(ctx, EXCP_RI);
099e5b4d
LA
18017 break;
18018 }
18019 break;
18020 case OPC_ADDU_QB_DSP:
18021 op2 = MASK_ADDU_QB(ctx->opcode);
18022 switch (op2) {
18023 case OPC_ADDQ_PH:
18024 case OPC_ADDQ_S_PH:
18025 case OPC_ADDQ_S_W:
18026 case OPC_ADDU_QB:
18027 case OPC_ADDU_S_QB:
18028 case OPC_ADDU_PH:
18029 case OPC_ADDU_S_PH:
18030 case OPC_SUBQ_PH:
18031 case OPC_SUBQ_S_PH:
18032 case OPC_SUBQ_S_W:
18033 case OPC_SUBU_QB:
18034 case OPC_SUBU_S_QB:
18035 case OPC_SUBU_PH:
18036 case OPC_SUBU_S_PH:
18037 case OPC_ADDSC:
18038 case OPC_ADDWC:
18039 case OPC_MODSUB:
18040 case OPC_RADDU_W_QB:
18041 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
18042 break;
18043 case OPC_MULEU_S_PH_QBL:
18044 case OPC_MULEU_S_PH_QBR:
18045 case OPC_MULQ_RS_PH:
18046 case OPC_MULEQ_S_W_PHL:
18047 case OPC_MULEQ_S_W_PHR:
18048 case OPC_MULQ_S_PH:
18049 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
18050 break;
18051 default: /* Invalid */
18052 MIPS_INVAL("MASK ADDU.QB");
9c708c7f 18053 generate_exception_end(ctx, EXCP_RI);
461c08df 18054 break;
461c08df 18055
099e5b4d
LA
18056 }
18057 break;
18058 case OPC_CMPU_EQ_QB_DSP:
18059 op2 = MASK_CMPU_EQ_QB(ctx->opcode);
18060 switch (op2) {
18061 case OPC_PRECR_SRA_PH_W:
18062 case OPC_PRECR_SRA_R_PH_W:
18063 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
461c08df 18064 break;
099e5b4d
LA
18065 case OPC_PRECR_QB_PH:
18066 case OPC_PRECRQ_QB_PH:
18067 case OPC_PRECRQ_PH_W:
18068 case OPC_PRECRQ_RS_PH_W:
18069 case OPC_PRECRQU_S_QB_PH:
18070 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
461c08df 18071 break;
099e5b4d
LA
18072 case OPC_CMPU_EQ_QB:
18073 case OPC_CMPU_LT_QB:
18074 case OPC_CMPU_LE_QB:
18075 case OPC_CMP_EQ_PH:
18076 case OPC_CMP_LT_PH:
18077 case OPC_CMP_LE_PH:
18078 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
77c5fa8b 18079 break;
099e5b4d
LA
18080 case OPC_CMPGU_EQ_QB:
18081 case OPC_CMPGU_LT_QB:
18082 case OPC_CMPGU_LE_QB:
18083 case OPC_CMPGDU_EQ_QB:
18084 case OPC_CMPGDU_LT_QB:
18085 case OPC_CMPGDU_LE_QB:
18086 case OPC_PICK_QB:
18087 case OPC_PICK_PH:
18088 case OPC_PACKRL_PH:
18089 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
18090 break;
18091 default: /* Invalid */
18092 MIPS_INVAL("MASK CMPU.EQ.QB");
9c708c7f 18093 generate_exception_end(ctx, EXCP_RI);
099e5b4d
LA
18094 break;
18095 }
18096 break;
18097 case OPC_SHLL_QB_DSP:
18098 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
18099 break;
18100 case OPC_DPA_W_PH_DSP:
18101 op2 = MASK_DPA_W_PH(ctx->opcode);
18102 switch (op2) {
18103 case OPC_DPAU_H_QBL:
18104 case OPC_DPAU_H_QBR:
18105 case OPC_DPSU_H_QBL:
18106 case OPC_DPSU_H_QBR:
18107 case OPC_DPA_W_PH:
18108 case OPC_DPAX_W_PH:
18109 case OPC_DPAQ_S_W_PH:
18110 case OPC_DPAQX_S_W_PH:
18111 case OPC_DPAQX_SA_W_PH:
18112 case OPC_DPS_W_PH:
18113 case OPC_DPSX_W_PH:
18114 case OPC_DPSQ_S_W_PH:
18115 case OPC_DPSQX_S_W_PH:
18116 case OPC_DPSQX_SA_W_PH:
18117 case OPC_MULSAQ_S_W_PH:
18118 case OPC_DPAQ_SA_L_W:
18119 case OPC_DPSQ_SA_L_W:
18120 case OPC_MAQ_S_W_PHL:
18121 case OPC_MAQ_S_W_PHR:
18122 case OPC_MAQ_SA_W_PHL:
18123 case OPC_MAQ_SA_W_PHR:
18124 case OPC_MULSA_W_PH:
18125 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
18126 break;
18127 default: /* Invalid */
18128 MIPS_INVAL("MASK DPAW.PH");
9c708c7f 18129 generate_exception_end(ctx, EXCP_RI);
099e5b4d
LA
18130 break;
18131 }
18132 break;
18133 case OPC_INSV_DSP:
18134 op2 = MASK_INSV(ctx->opcode);
18135 switch (op2) {
18136 case OPC_INSV:
18137 check_dsp(ctx);
18138 {
18139 TCGv t0, t1;
18140
18141 if (rt == 0) {
099e5b4d
LA
18142 break;
18143 }
18144
18145 t0 = tcg_temp_new();
18146 t1 = tcg_temp_new();
18147
18148 gen_load_gpr(t0, rt);
18149 gen_load_gpr(t1, rs);
18150
18151 gen_helper_insv(cpu_gpr[rt], cpu_env, t1, t0);
18152
18153 tcg_temp_free(t0);
18154 tcg_temp_free(t1);
a22260ae
JL
18155 break;
18156 }
099e5b4d
LA
18157 default: /* Invalid */
18158 MIPS_INVAL("MASK INSV");
9c708c7f 18159 generate_exception_end(ctx, EXCP_RI);
099e5b4d
LA
18160 break;
18161 }
18162 break;
18163 case OPC_APPEND_DSP:
18164 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
18165 break;
18166 case OPC_EXTR_W_DSP:
18167 op2 = MASK_EXTR_W(ctx->opcode);
18168 switch (op2) {
18169 case OPC_EXTR_W:
18170 case OPC_EXTR_R_W:
18171 case OPC_EXTR_RS_W:
18172 case OPC_EXTR_S_H:
18173 case OPC_EXTRV_S_H:
18174 case OPC_EXTRV_W:
18175 case OPC_EXTRV_R_W:
18176 case OPC_EXTRV_RS_W:
18177 case OPC_EXTP:
18178 case OPC_EXTPV:
18179 case OPC_EXTPDP:
18180 case OPC_EXTPDPV:
18181 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
18182 break;
18183 case OPC_RDDSP:
18184 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 1);
18185 break;
18186 case OPC_SHILO:
18187 case OPC_SHILOV:
18188 case OPC_MTHLIP:
18189 case OPC_WRDSP:
18190 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
18191 break;
18192 default: /* Invalid */
18193 MIPS_INVAL("MASK EXTR.W");
9c708c7f 18194 generate_exception_end(ctx, EXCP_RI);
099e5b4d
LA
18195 break;
18196 }
18197 break;
099e5b4d 18198#if defined(TARGET_MIPS64)
c2e19f3c
AM
18199 case OPC_DDIV_G_2E:
18200 case OPC_DDIVU_G_2E:
18201 case OPC_DMULT_G_2E:
18202 case OPC_DMULTU_G_2E:
18203 case OPC_DMOD_G_2E:
18204 case OPC_DMODU_G_2E:
fac5a073
LA
18205 check_insn(ctx, INSN_LOONGSON2E);
18206 gen_loongson_integer(ctx, op1, rd, rs, rt);
099e5b4d 18207 break;
099e5b4d
LA
18208 case OPC_ABSQ_S_QH_DSP:
18209 op2 = MASK_ABSQ_S_QH(ctx->opcode);
18210 switch (op2) {
18211 case OPC_PRECEQ_L_PWL:
18212 case OPC_PRECEQ_L_PWR:
18213 case OPC_PRECEQ_PW_QHL:
18214 case OPC_PRECEQ_PW_QHR:
18215 case OPC_PRECEQ_PW_QHLA:
18216 case OPC_PRECEQ_PW_QHRA:
18217 case OPC_PRECEQU_QH_OBL:
18218 case OPC_PRECEQU_QH_OBR:
18219 case OPC_PRECEQU_QH_OBLA:
18220 case OPC_PRECEQU_QH_OBRA:
18221 case OPC_PRECEU_QH_OBL:
18222 case OPC_PRECEU_QH_OBR:
18223 case OPC_PRECEU_QH_OBLA:
18224 case OPC_PRECEU_QH_OBRA:
18225 case OPC_ABSQ_S_OB:
18226 case OPC_ABSQ_S_PW:
18227 case OPC_ABSQ_S_QH:
18228 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
18229 break;
18230 case OPC_REPL_OB:
18231 case OPC_REPL_PW:
18232 case OPC_REPL_QH:
18233 case OPC_REPLV_OB:
18234 case OPC_REPLV_PW:
18235 case OPC_REPLV_QH:
18236 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
18237 break;
18238 default: /* Invalid */
18239 MIPS_INVAL("MASK ABSQ_S.QH");
9c708c7f 18240 generate_exception_end(ctx, EXCP_RI);
099e5b4d
LA
18241 break;
18242 }
18243 break;
18244 case OPC_ADDU_OB_DSP:
18245 op2 = MASK_ADDU_OB(ctx->opcode);
18246 switch (op2) {
18247 case OPC_RADDU_L_OB:
18248 case OPC_SUBQ_PW:
18249 case OPC_SUBQ_S_PW:
18250 case OPC_SUBQ_QH:
18251 case OPC_SUBQ_S_QH:
18252 case OPC_SUBU_OB:
18253 case OPC_SUBU_S_OB:
18254 case OPC_SUBU_QH:
18255 case OPC_SUBU_S_QH:
18256 case OPC_SUBUH_OB:
18257 case OPC_SUBUH_R_OB:
18258 case OPC_ADDQ_PW:
18259 case OPC_ADDQ_S_PW:
18260 case OPC_ADDQ_QH:
18261 case OPC_ADDQ_S_QH:
18262 case OPC_ADDU_OB:
18263 case OPC_ADDU_S_OB:
18264 case OPC_ADDU_QH:
18265 case OPC_ADDU_S_QH:
18266 case OPC_ADDUH_OB:
18267 case OPC_ADDUH_R_OB:
18268 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
a22260ae 18269 break;
099e5b4d
LA
18270 case OPC_MULEQ_S_PW_QHL:
18271 case OPC_MULEQ_S_PW_QHR:
18272 case OPC_MULEU_S_QH_OBL:
18273 case OPC_MULEU_S_QH_OBR:
18274 case OPC_MULQ_RS_QH:
18275 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
1cb6686c 18276 break;
099e5b4d
LA
18277 default: /* Invalid */
18278 MIPS_INVAL("MASK ADDU.OB");
9c708c7f 18279 generate_exception_end(ctx, EXCP_RI);
26690560 18280 break;
099e5b4d
LA
18281 }
18282 break;
18283 case OPC_CMPU_EQ_OB_DSP:
18284 op2 = MASK_CMPU_EQ_OB(ctx->opcode);
18285 switch (op2) {
18286 case OPC_PRECR_SRA_QH_PW:
18287 case OPC_PRECR_SRA_R_QH_PW:
18288 /* Return value is rt. */
18289 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
b53371ed 18290 break;
099e5b4d
LA
18291 case OPC_PRECR_OB_QH:
18292 case OPC_PRECRQ_OB_QH:
18293 case OPC_PRECRQ_PW_L:
18294 case OPC_PRECRQ_QH_PW:
18295 case OPC_PRECRQ_RS_QH_PW:
18296 case OPC_PRECRQU_S_OB_QH:
18297 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
4368b29a 18298 break;
099e5b4d
LA
18299 case OPC_CMPU_EQ_OB:
18300 case OPC_CMPU_LT_OB:
18301 case OPC_CMPU_LE_OB:
18302 case OPC_CMP_EQ_QH:
18303 case OPC_CMP_LT_QH:
18304 case OPC_CMP_LE_QH:
18305 case OPC_CMP_EQ_PW:
18306 case OPC_CMP_LT_PW:
18307 case OPC_CMP_LE_PW:
18308 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
7a387fff 18309 break;
099e5b4d
LA
18310 case OPC_CMPGDU_EQ_OB:
18311 case OPC_CMPGDU_LT_OB:
18312 case OPC_CMPGDU_LE_OB:
18313 case OPC_CMPGU_EQ_OB:
18314 case OPC_CMPGU_LT_OB:
18315 case OPC_CMPGU_LE_OB:
18316 case OPC_PACKRL_PW:
18317 case OPC_PICK_OB:
18318 case OPC_PICK_PW:
18319 case OPC_PICK_QH:
18320 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
c6d6dd7c 18321 break;
099e5b4d
LA
18322 default: /* Invalid */
18323 MIPS_INVAL("MASK CMPU_EQ.OB");
9c708c7f 18324 generate_exception_end(ctx, EXCP_RI);
161f85e6 18325 break;
099e5b4d
LA
18326 }
18327 break;
18328 case OPC_DAPPEND_DSP:
18329 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
18330 break;
18331 case OPC_DEXTR_W_DSP:
18332 op2 = MASK_DEXTR_W(ctx->opcode);
18333 switch (op2) {
18334 case OPC_DEXTP:
18335 case OPC_DEXTPDP:
18336 case OPC_DEXTPDPV:
18337 case OPC_DEXTPV:
18338 case OPC_DEXTR_L:
18339 case OPC_DEXTR_R_L:
18340 case OPC_DEXTR_RS_L:
18341 case OPC_DEXTR_W:
18342 case OPC_DEXTR_R_W:
18343 case OPC_DEXTR_RS_W:
18344 case OPC_DEXTR_S_H:
18345 case OPC_DEXTRV_L:
18346 case OPC_DEXTRV_R_L:
18347 case OPC_DEXTRV_RS_L:
18348 case OPC_DEXTRV_S_H:
18349 case OPC_DEXTRV_W:
18350 case OPC_DEXTRV_R_W:
18351 case OPC_DEXTRV_RS_W:
18352 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
461c08df 18353 break;
099e5b4d
LA
18354 case OPC_DMTHLIP:
18355 case OPC_DSHILO:
18356 case OPC_DSHILOV:
18357 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
461c08df 18358 break;
099e5b4d
LA
18359 default: /* Invalid */
18360 MIPS_INVAL("MASK EXTR.W");
9c708c7f 18361 generate_exception_end(ctx, EXCP_RI);
461c08df 18362 break;
099e5b4d
LA
18363 }
18364 break;
18365 case OPC_DPAQ_W_QH_DSP:
18366 op2 = MASK_DPAQ_W_QH(ctx->opcode);
18367 switch (op2) {
18368 case OPC_DPAU_H_OBL:
18369 case OPC_DPAU_H_OBR:
18370 case OPC_DPSU_H_OBL:
18371 case OPC_DPSU_H_OBR:
18372 case OPC_DPA_W_QH:
18373 case OPC_DPAQ_S_W_QH:
18374 case OPC_DPS_W_QH:
18375 case OPC_DPSQ_S_W_QH:
18376 case OPC_MULSAQ_S_W_QH:
18377 case OPC_DPAQ_SA_L_PW:
18378 case OPC_DPSQ_SA_L_PW:
18379 case OPC_MULSAQ_S_L_PW:
18380 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
18381 break;
18382 case OPC_MAQ_S_W_QHLL:
18383 case OPC_MAQ_S_W_QHLR:
18384 case OPC_MAQ_S_W_QHRL:
18385 case OPC_MAQ_S_W_QHRR:
18386 case OPC_MAQ_SA_W_QHLL:
18387 case OPC_MAQ_SA_W_QHLR:
18388 case OPC_MAQ_SA_W_QHRL:
18389 case OPC_MAQ_SA_W_QHRR:
18390 case OPC_MAQ_S_L_PWL:
18391 case OPC_MAQ_S_L_PWR:
18392 case OPC_DMADD:
18393 case OPC_DMADDU:
18394 case OPC_DMSUB:
18395 case OPC_DMSUBU:
18396 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
26690560 18397 break;
099e5b4d
LA
18398 default: /* Invalid */
18399 MIPS_INVAL("MASK DPAQ.W.QH");
9c708c7f 18400 generate_exception_end(ctx, EXCP_RI);
b53371ed 18401 break;
099e5b4d
LA
18402 }
18403 break;
18404 case OPC_DINSV_DSP:
18405 op2 = MASK_INSV(ctx->opcode);
18406 switch (op2) {
18407 case OPC_DINSV:
18408 {
18409 TCGv t0, t1;
18410
18411 if (rt == 0) {
a22260ae
JL
18412 break;
18413 }
099e5b4d 18414 check_dsp(ctx);
1cb6686c 18415
099e5b4d
LA
18416 t0 = tcg_temp_new();
18417 t1 = tcg_temp_new();
1cb6686c 18418
099e5b4d
LA
18419 gen_load_gpr(t0, rt);
18420 gen_load_gpr(t1, rs);
1cb6686c 18421
099e5b4d 18422 gen_helper_dinsv(cpu_gpr[rt], cpu_env, t1, t0);
62eb3b9a 18423
099e5b4d
LA
18424 tcg_temp_free(t0);
18425 tcg_temp_free(t1);
77c5fa8b 18426 break;
099e5b4d 18427 }
7a387fff 18428 default: /* Invalid */
099e5b4d 18429 MIPS_INVAL("MASK DINSV");
9c708c7f 18430 generate_exception_end(ctx, EXCP_RI);
7a387fff
TS
18431 break;
18432 }
18433 break;
099e5b4d
LA
18434 case OPC_SHLL_OB_DSP:
18435 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
18436 break;
18437#endif
fac5a073
LA
18438 default: /* Invalid */
18439 MIPS_INVAL("special3_legacy");
9c708c7f 18440 generate_exception_end(ctx, EXCP_RI);
fac5a073
LA
18441 break;
18442 }
18443}
18444
18445static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx)
18446{
18447 int rs, rt, rd, sa;
18448 uint32_t op1, op2;
76964147 18449 int16_t imm;
fac5a073
LA
18450
18451 rs = (ctx->opcode >> 21) & 0x1f;
18452 rt = (ctx->opcode >> 16) & 0x1f;
18453 rd = (ctx->opcode >> 11) & 0x1f;
18454 sa = (ctx->opcode >> 6) & 0x1f;
76964147 18455 imm = sextract32(ctx->opcode, 7, 9);
fac5a073
LA
18456
18457 op1 = MASK_SPECIAL3(ctx->opcode);
76964147
JH
18458
18459 /*
18460 * EVA loads and stores overlap Loongson 2E instructions decoded by
18461 * decode_opc_special3_legacy(), so be careful to allow their decoding when
18462 * EVA is absent.
18463 */
18464 if (ctx->eva) {
18465 switch (op1) {
c2e19f3c
AM
18466 case OPC_LWLE:
18467 case OPC_LWRE:
76964147
JH
18468 check_insn_opc_removed(ctx, ISA_MIPS32R6);
18469 /* fall through */
c2e19f3c
AM
18470 case OPC_LBUE:
18471 case OPC_LHUE:
18472 case OPC_LBE:
18473 case OPC_LHE:
18474 case OPC_LLE:
18475 case OPC_LWE:
76964147
JH
18476 check_cp0_enabled(ctx);
18477 gen_ld(ctx, op1, rt, rs, imm);
18478 return;
c2e19f3c
AM
18479 case OPC_SWLE:
18480 case OPC_SWRE:
76964147
JH
18481 check_insn_opc_removed(ctx, ISA_MIPS32R6);
18482 /* fall through */
c2e19f3c
AM
18483 case OPC_SBE:
18484 case OPC_SHE:
76964147
JH
18485 case OPC_SWE:
18486 check_cp0_enabled(ctx);
18487 gen_st(ctx, op1, rt, rs, imm);
18488 return;
18489 case OPC_SCE:
18490 check_cp0_enabled(ctx);
18491 gen_st_cond(ctx, op1, rt, rs, imm);
18492 return;
18493 case OPC_CACHEE:
18494 check_cp0_enabled(ctx);
18495 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
18496 gen_cache_operation(ctx, rt, rs, imm);
18497 }
18498 /* Treat as NOP. */
18499 return;
18500 case OPC_PREFE:
18501 check_cp0_enabled(ctx);
18502 /* Treat as NOP. */
18503 return;
18504 }
18505 }
18506
fac5a073
LA
18507 switch (op1) {
18508 case OPC_EXT:
18509 case OPC_INS:
18510 check_insn(ctx, ISA_MIPS32R2);
18511 gen_bitops(ctx, op1, rt, rs, sa, rd);
18512 break;
18513 case OPC_BSHFL:
fac5a073 18514 op2 = MASK_BSHFL(ctx->opcode);
15eacb9b 18515 switch (op2) {
c2e19f3c
AM
18516 case OPC_ALIGN:
18517 case OPC_ALIGN_END:
15eacb9b
YK
18518 case OPC_BITSWAP:
18519 check_insn(ctx, ISA_MIPS32R6);
18520 decode_opc_special3_r6(env, ctx);
18521 break;
18522 default:
18523 check_insn(ctx, ISA_MIPS32R2);
18524 gen_bshfl(ctx, op2, rt, rd);
18525 break;
18526 }
fac5a073
LA
18527 break;
18528#if defined(TARGET_MIPS64)
c2e19f3c
AM
18529 case OPC_DEXTM:
18530 case OPC_DEXTU:
18531 case OPC_DEXT:
18532 case OPC_DINSM:
18533 case OPC_DINSU:
18534 case OPC_DINS:
fac5a073
LA
18535 check_insn(ctx, ISA_MIPS64R2);
18536 check_mips_64(ctx);
18537 gen_bitops(ctx, op1, rt, rs, sa, rd);
18538 break;
18539 case OPC_DBSHFL:
fac5a073 18540 op2 = MASK_DBSHFL(ctx->opcode);
15eacb9b 18541 switch (op2) {
c2e19f3c
AM
18542 case OPC_DALIGN:
18543 case OPC_DALIGN_END:
15eacb9b
YK
18544 case OPC_DBITSWAP:
18545 check_insn(ctx, ISA_MIPS32R6);
18546 decode_opc_special3_r6(env, ctx);
18547 break;
18548 default:
18549 check_insn(ctx, ISA_MIPS64R2);
18550 check_mips_64(ctx);
18551 op2 = MASK_DBSHFL(ctx->opcode);
18552 gen_bshfl(ctx, op2, rt, rd);
18553 break;
18554 }
fac5a073
LA
18555 break;
18556#endif
18557 case OPC_RDHWR:
b00c7218 18558 gen_rdhwr(ctx, rt, rd, extract32(ctx->opcode, 6, 3));
fac5a073
LA
18559 break;
18560 case OPC_FORK:
18561 check_insn(ctx, ASE_MT);
18562 {
18563 TCGv t0 = tcg_temp_new();
18564 TCGv t1 = tcg_temp_new();
18565
18566 gen_load_gpr(t0, rt);
18567 gen_load_gpr(t1, rs);
18568 gen_helper_fork(t0, t1);
18569 tcg_temp_free(t0);
18570 tcg_temp_free(t1);
18571 }
18572 break;
18573 case OPC_YIELD:
18574 check_insn(ctx, ASE_MT);
18575 {
18576 TCGv t0 = tcg_temp_new();
18577
fac5a073
LA
18578 gen_load_gpr(t0, rs);
18579 gen_helper_yield(t0, cpu_env, t0);
18580 gen_store_gpr(t0, rd);
18581 tcg_temp_free(t0);
18582 }
18583 break;
10dc65db
LA
18584 default:
18585 if (ctx->insn_flags & ISA_MIPS32R6) {
18586 decode_opc_special3_r6(env, ctx);
18587 } else {
18588 decode_opc_special3_legacy(env, ctx);
18589 }
099e5b4d
LA
18590 }
18591}
18592
863f264d
YK
18593/* MIPS SIMD Architecture (MSA) */
18594static inline int check_msa_access(DisasContext *ctx)
18595{
18596 if (unlikely((ctx->hflags & MIPS_HFLAG_FPU) &&
18597 !(ctx->hflags & MIPS_HFLAG_F64))) {
9c708c7f 18598 generate_exception_end(ctx, EXCP_RI);
863f264d
YK
18599 return 0;
18600 }
18601
18602 if (unlikely(!(ctx->hflags & MIPS_HFLAG_MSA))) {
18603 if (ctx->insn_flags & ASE_MSA) {
9c708c7f 18604 generate_exception_end(ctx, EXCP_MSADIS);
863f264d
YK
18605 return 0;
18606 } else {
9c708c7f 18607 generate_exception_end(ctx, EXCP_RI);
863f264d
YK
18608 return 0;
18609 }
18610 }
18611 return 1;
18612}
18613
5692c6e1
YK
18614static void gen_check_zero_element(TCGv tresult, uint8_t df, uint8_t wt)
18615{
18616 /* generates tcg ops to check if any element is 0 */
18617 /* Note this function only works with MSA_WRLEN = 128 */
18618 uint64_t eval_zero_or_big = 0;
18619 uint64_t eval_big = 0;
18620 TCGv_i64 t0 = tcg_temp_new_i64();
18621 TCGv_i64 t1 = tcg_temp_new_i64();
18622 switch (df) {
18623 case DF_BYTE:
18624 eval_zero_or_big = 0x0101010101010101ULL;
18625 eval_big = 0x8080808080808080ULL;
18626 break;
18627 case DF_HALF:
18628 eval_zero_or_big = 0x0001000100010001ULL;
18629 eval_big = 0x8000800080008000ULL;
18630 break;
18631 case DF_WORD:
18632 eval_zero_or_big = 0x0000000100000001ULL;
18633 eval_big = 0x8000000080000000ULL;
18634 break;
18635 case DF_DOUBLE:
18636 eval_zero_or_big = 0x0000000000000001ULL;
18637 eval_big = 0x8000000000000000ULL;
18638 break;
18639 }
18640 tcg_gen_subi_i64(t0, msa_wr_d[wt<<1], eval_zero_or_big);
18641 tcg_gen_andc_i64(t0, t0, msa_wr_d[wt<<1]);
18642 tcg_gen_andi_i64(t0, t0, eval_big);
18643 tcg_gen_subi_i64(t1, msa_wr_d[(wt<<1)+1], eval_zero_or_big);
18644 tcg_gen_andc_i64(t1, t1, msa_wr_d[(wt<<1)+1]);
18645 tcg_gen_andi_i64(t1, t1, eval_big);
18646 tcg_gen_or_i64(t0, t0, t1);
18647 /* if all bits are zero then all elements are not zero */
18648 /* if some bit is non-zero then some element is zero */
18649 tcg_gen_setcondi_i64(TCG_COND_NE, t0, t0, 0);
18650 tcg_gen_trunc_i64_tl(tresult, t0);
18651 tcg_temp_free_i64(t0);
18652 tcg_temp_free_i64(t1);
18653}
18654
18655static void gen_msa_branch(CPUMIPSState *env, DisasContext *ctx, uint32_t op1)
18656{
18657 uint8_t df = (ctx->opcode >> 21) & 0x3;
18658 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
18659 int64_t s16 = (int16_t)ctx->opcode;
18660
18661 check_msa_access(ctx);
18662
075a1fe7 18663 if (ctx->hflags & MIPS_HFLAG_BMASK) {
9c708c7f 18664 generate_exception_end(ctx, EXCP_RI);
5692c6e1
YK
18665 return;
18666 }
18667 switch (op1) {
18668 case OPC_BZ_V:
18669 case OPC_BNZ_V:
18670 {
18671 TCGv_i64 t0 = tcg_temp_new_i64();
18672 tcg_gen_or_i64(t0, msa_wr_d[wt<<1], msa_wr_d[(wt<<1)+1]);
18673 tcg_gen_setcondi_i64((op1 == OPC_BZ_V) ?
18674 TCG_COND_EQ : TCG_COND_NE, t0, t0, 0);
18675 tcg_gen_trunc_i64_tl(bcond, t0);
18676 tcg_temp_free_i64(t0);
18677 }
18678 break;
18679 case OPC_BZ_B:
18680 case OPC_BZ_H:
18681 case OPC_BZ_W:
18682 case OPC_BZ_D:
18683 gen_check_zero_element(bcond, df, wt);
18684 break;
18685 case OPC_BNZ_B:
18686 case OPC_BNZ_H:
18687 case OPC_BNZ_W:
18688 case OPC_BNZ_D:
18689 gen_check_zero_element(bcond, df, wt);
18690 tcg_gen_setcondi_tl(TCG_COND_EQ, bcond, bcond, 0);
18691 break;
18692 }
18693
eeb3bba8 18694 ctx->btarget = ctx->base.pc_next + (s16 << 2) + 4;
5692c6e1
YK
18695
18696 ctx->hflags |= MIPS_HFLAG_BC;
18697 ctx->hflags |= MIPS_HFLAG_BDS32;
18698}
18699
4c789546
YK
18700static void gen_msa_i8(CPUMIPSState *env, DisasContext *ctx)
18701{
18702#define MASK_MSA_I8(op) (MASK_MSA_MINOR(op) | (op & (0x03 << 24)))
18703 uint8_t i8 = (ctx->opcode >> 16) & 0xff;
18704 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18705 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18706
18707 TCGv_i32 twd = tcg_const_i32(wd);
18708 TCGv_i32 tws = tcg_const_i32(ws);
18709 TCGv_i32 ti8 = tcg_const_i32(i8);
18710
18711 switch (MASK_MSA_I8(ctx->opcode)) {
18712 case OPC_ANDI_B:
18713 gen_helper_msa_andi_b(cpu_env, twd, tws, ti8);
18714 break;
18715 case OPC_ORI_B:
18716 gen_helper_msa_ori_b(cpu_env, twd, tws, ti8);
18717 break;
18718 case OPC_NORI_B:
18719 gen_helper_msa_nori_b(cpu_env, twd, tws, ti8);
18720 break;
18721 case OPC_XORI_B:
18722 gen_helper_msa_xori_b(cpu_env, twd, tws, ti8);
18723 break;
18724 case OPC_BMNZI_B:
18725 gen_helper_msa_bmnzi_b(cpu_env, twd, tws, ti8);
18726 break;
18727 case OPC_BMZI_B:
18728 gen_helper_msa_bmzi_b(cpu_env, twd, tws, ti8);
18729 break;
18730 case OPC_BSELI_B:
18731 gen_helper_msa_bseli_b(cpu_env, twd, tws, ti8);
18732 break;
18733 case OPC_SHF_B:
18734 case OPC_SHF_H:
18735 case OPC_SHF_W:
18736 {
18737 uint8_t df = (ctx->opcode >> 24) & 0x3;
18738 if (df == DF_DOUBLE) {
9c708c7f 18739 generate_exception_end(ctx, EXCP_RI);
4c789546
YK
18740 } else {
18741 TCGv_i32 tdf = tcg_const_i32(df);
18742 gen_helper_msa_shf_df(cpu_env, tdf, twd, tws, ti8);
18743 tcg_temp_free_i32(tdf);
18744 }
18745 }
18746 break;
18747 default:
18748 MIPS_INVAL("MSA instruction");
9c708c7f 18749 generate_exception_end(ctx, EXCP_RI);
4c789546
YK
18750 break;
18751 }
18752
18753 tcg_temp_free_i32(twd);
18754 tcg_temp_free_i32(tws);
18755 tcg_temp_free_i32(ti8);
18756}
18757
80e71591
YK
18758static void gen_msa_i5(CPUMIPSState *env, DisasContext *ctx)
18759{
18760#define MASK_MSA_I5(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
18761 uint8_t df = (ctx->opcode >> 21) & 0x3;
18762 int8_t s5 = (int8_t) sextract32(ctx->opcode, 16, 5);
18763 uint8_t u5 = (ctx->opcode >> 16) & 0x1f;
18764 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18765 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18766
18767 TCGv_i32 tdf = tcg_const_i32(df);
18768 TCGv_i32 twd = tcg_const_i32(wd);
18769 TCGv_i32 tws = tcg_const_i32(ws);
18770 TCGv_i32 timm = tcg_temp_new_i32();
18771 tcg_gen_movi_i32(timm, u5);
18772
18773 switch (MASK_MSA_I5(ctx->opcode)) {
18774 case OPC_ADDVI_df:
18775 gen_helper_msa_addvi_df(cpu_env, tdf, twd, tws, timm);
18776 break;
18777 case OPC_SUBVI_df:
18778 gen_helper_msa_subvi_df(cpu_env, tdf, twd, tws, timm);
18779 break;
18780 case OPC_MAXI_S_df:
18781 tcg_gen_movi_i32(timm, s5);
18782 gen_helper_msa_maxi_s_df(cpu_env, tdf, twd, tws, timm);
18783 break;
18784 case OPC_MAXI_U_df:
18785 gen_helper_msa_maxi_u_df(cpu_env, tdf, twd, tws, timm);
18786 break;
18787 case OPC_MINI_S_df:
18788 tcg_gen_movi_i32(timm, s5);
18789 gen_helper_msa_mini_s_df(cpu_env, tdf, twd, tws, timm);
18790 break;
18791 case OPC_MINI_U_df:
18792 gen_helper_msa_mini_u_df(cpu_env, tdf, twd, tws, timm);
18793 break;
18794 case OPC_CEQI_df:
18795 tcg_gen_movi_i32(timm, s5);
18796 gen_helper_msa_ceqi_df(cpu_env, tdf, twd, tws, timm);
18797 break;
18798 case OPC_CLTI_S_df:
18799 tcg_gen_movi_i32(timm, s5);
18800 gen_helper_msa_clti_s_df(cpu_env, tdf, twd, tws, timm);
18801 break;
18802 case OPC_CLTI_U_df:
18803 gen_helper_msa_clti_u_df(cpu_env, tdf, twd, tws, timm);
18804 break;
18805 case OPC_CLEI_S_df:
18806 tcg_gen_movi_i32(timm, s5);
18807 gen_helper_msa_clei_s_df(cpu_env, tdf, twd, tws, timm);
18808 break;
18809 case OPC_CLEI_U_df:
18810 gen_helper_msa_clei_u_df(cpu_env, tdf, twd, tws, timm);
18811 break;
18812 case OPC_LDI_df:
18813 {
18814 int32_t s10 = sextract32(ctx->opcode, 11, 10);
18815 tcg_gen_movi_i32(timm, s10);
18816 gen_helper_msa_ldi_df(cpu_env, tdf, twd, timm);
18817 }
18818 break;
18819 default:
18820 MIPS_INVAL("MSA instruction");
9c708c7f 18821 generate_exception_end(ctx, EXCP_RI);
80e71591
YK
18822 break;
18823 }
18824
18825 tcg_temp_free_i32(tdf);
18826 tcg_temp_free_i32(twd);
18827 tcg_temp_free_i32(tws);
18828 tcg_temp_free_i32(timm);
18829}
18830
d4cf28de
YK
18831static void gen_msa_bit(CPUMIPSState *env, DisasContext *ctx)
18832{
18833#define MASK_MSA_BIT(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
18834 uint8_t dfm = (ctx->opcode >> 16) & 0x7f;
18835 uint32_t df = 0, m = 0;
18836 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18837 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18838
18839 TCGv_i32 tdf;
18840 TCGv_i32 tm;
18841 TCGv_i32 twd;
18842 TCGv_i32 tws;
18843
18844 if ((dfm & 0x40) == 0x00) {
18845 m = dfm & 0x3f;
18846 df = DF_DOUBLE;
18847 } else if ((dfm & 0x60) == 0x40) {
18848 m = dfm & 0x1f;
18849 df = DF_WORD;
18850 } else if ((dfm & 0x70) == 0x60) {
18851 m = dfm & 0x0f;
18852 df = DF_HALF;
18853 } else if ((dfm & 0x78) == 0x70) {
18854 m = dfm & 0x7;
18855 df = DF_BYTE;
18856 } else {
9c708c7f 18857 generate_exception_end(ctx, EXCP_RI);
d4cf28de
YK
18858 return;
18859 }
18860
18861 tdf = tcg_const_i32(df);
18862 tm = tcg_const_i32(m);
18863 twd = tcg_const_i32(wd);
18864 tws = tcg_const_i32(ws);
18865
18866 switch (MASK_MSA_BIT(ctx->opcode)) {
18867 case OPC_SLLI_df:
18868 gen_helper_msa_slli_df(cpu_env, tdf, twd, tws, tm);
18869 break;
18870 case OPC_SRAI_df:
18871 gen_helper_msa_srai_df(cpu_env, tdf, twd, tws, tm);
18872 break;
18873 case OPC_SRLI_df:
18874 gen_helper_msa_srli_df(cpu_env, tdf, twd, tws, tm);
18875 break;
18876 case OPC_BCLRI_df:
18877 gen_helper_msa_bclri_df(cpu_env, tdf, twd, tws, tm);
18878 break;
18879 case OPC_BSETI_df:
18880 gen_helper_msa_bseti_df(cpu_env, tdf, twd, tws, tm);
18881 break;
18882 case OPC_BNEGI_df:
18883 gen_helper_msa_bnegi_df(cpu_env, tdf, twd, tws, tm);
18884 break;
18885 case OPC_BINSLI_df:
18886 gen_helper_msa_binsli_df(cpu_env, tdf, twd, tws, tm);
18887 break;
18888 case OPC_BINSRI_df:
18889 gen_helper_msa_binsri_df(cpu_env, tdf, twd, tws, tm);
18890 break;
18891 case OPC_SAT_S_df:
18892 gen_helper_msa_sat_s_df(cpu_env, tdf, twd, tws, tm);
18893 break;
18894 case OPC_SAT_U_df:
18895 gen_helper_msa_sat_u_df(cpu_env, tdf, twd, tws, tm);
18896 break;
18897 case OPC_SRARI_df:
18898 gen_helper_msa_srari_df(cpu_env, tdf, twd, tws, tm);
18899 break;
18900 case OPC_SRLRI_df:
18901 gen_helper_msa_srlri_df(cpu_env, tdf, twd, tws, tm);
18902 break;
18903 default:
18904 MIPS_INVAL("MSA instruction");
9c708c7f 18905 generate_exception_end(ctx, EXCP_RI);
d4cf28de
YK
18906 break;
18907 }
18908
18909 tcg_temp_free_i32(tdf);
18910 tcg_temp_free_i32(tm);
18911 tcg_temp_free_i32(twd);
18912 tcg_temp_free_i32(tws);
18913}
18914
28f99f08
YK
18915static void gen_msa_3r(CPUMIPSState *env, DisasContext *ctx)
18916{
18917#define MASK_MSA_3R(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
18918 uint8_t df = (ctx->opcode >> 21) & 0x3;
18919 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
18920 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18921 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18922
18923 TCGv_i32 tdf = tcg_const_i32(df);
18924 TCGv_i32 twd = tcg_const_i32(wd);
18925 TCGv_i32 tws = tcg_const_i32(ws);
18926 TCGv_i32 twt = tcg_const_i32(wt);
18927
18928 switch (MASK_MSA_3R(ctx->opcode)) {
18929 case OPC_SLL_df:
18930 gen_helper_msa_sll_df(cpu_env, tdf, twd, tws, twt);
18931 break;
18932 case OPC_ADDV_df:
18933 gen_helper_msa_addv_df(cpu_env, tdf, twd, tws, twt);
18934 break;
18935 case OPC_CEQ_df:
18936 gen_helper_msa_ceq_df(cpu_env, tdf, twd, tws, twt);
18937 break;
18938 case OPC_ADD_A_df:
18939 gen_helper_msa_add_a_df(cpu_env, tdf, twd, tws, twt);
18940 break;
18941 case OPC_SUBS_S_df:
18942 gen_helper_msa_subs_s_df(cpu_env, tdf, twd, tws, twt);
18943 break;
18944 case OPC_MULV_df:
18945 gen_helper_msa_mulv_df(cpu_env, tdf, twd, tws, twt);
18946 break;
18947 case OPC_SLD_df:
18948 gen_helper_msa_sld_df(cpu_env, tdf, twd, tws, twt);
18949 break;
18950 case OPC_VSHF_df:
18951 gen_helper_msa_vshf_df(cpu_env, tdf, twd, tws, twt);
18952 break;
18953 case OPC_SRA_df:
18954 gen_helper_msa_sra_df(cpu_env, tdf, twd, tws, twt);
18955 break;
18956 case OPC_SUBV_df:
18957 gen_helper_msa_subv_df(cpu_env, tdf, twd, tws, twt);
18958 break;
18959 case OPC_ADDS_A_df:
18960 gen_helper_msa_adds_a_df(cpu_env, tdf, twd, tws, twt);
18961 break;
18962 case OPC_SUBS_U_df:
18963 gen_helper_msa_subs_u_df(cpu_env, tdf, twd, tws, twt);
18964 break;
18965 case OPC_MADDV_df:
18966 gen_helper_msa_maddv_df(cpu_env, tdf, twd, tws, twt);
18967 break;
18968 case OPC_SPLAT_df:
18969 gen_helper_msa_splat_df(cpu_env, tdf, twd, tws, twt);
18970 break;
18971 case OPC_SRAR_df:
18972 gen_helper_msa_srar_df(cpu_env, tdf, twd, tws, twt);
18973 break;
18974 case OPC_SRL_df:
18975 gen_helper_msa_srl_df(cpu_env, tdf, twd, tws, twt);
18976 break;
18977 case OPC_MAX_S_df:
18978 gen_helper_msa_max_s_df(cpu_env, tdf, twd, tws, twt);
18979 break;
18980 case OPC_CLT_S_df:
18981 gen_helper_msa_clt_s_df(cpu_env, tdf, twd, tws, twt);
18982 break;
18983 case OPC_ADDS_S_df:
18984 gen_helper_msa_adds_s_df(cpu_env, tdf, twd, tws, twt);
18985 break;
18986 case OPC_SUBSUS_U_df:
18987 gen_helper_msa_subsus_u_df(cpu_env, tdf, twd, tws, twt);
18988 break;
18989 case OPC_MSUBV_df:
18990 gen_helper_msa_msubv_df(cpu_env, tdf, twd, tws, twt);
18991 break;
18992 case OPC_PCKEV_df:
18993 gen_helper_msa_pckev_df(cpu_env, tdf, twd, tws, twt);
18994 break;
18995 case OPC_SRLR_df:
18996 gen_helper_msa_srlr_df(cpu_env, tdf, twd, tws, twt);
18997 break;
18998 case OPC_BCLR_df:
18999 gen_helper_msa_bclr_df(cpu_env, tdf, twd, tws, twt);
19000 break;
19001 case OPC_MAX_U_df:
19002 gen_helper_msa_max_u_df(cpu_env, tdf, twd, tws, twt);
19003 break;
19004 case OPC_CLT_U_df:
19005 gen_helper_msa_clt_u_df(cpu_env, tdf, twd, tws, twt);
19006 break;
19007 case OPC_ADDS_U_df:
19008 gen_helper_msa_adds_u_df(cpu_env, tdf, twd, tws, twt);
19009 break;
19010 case OPC_SUBSUU_S_df:
19011 gen_helper_msa_subsuu_s_df(cpu_env, tdf, twd, tws, twt);
19012 break;
19013 case OPC_PCKOD_df:
19014 gen_helper_msa_pckod_df(cpu_env, tdf, twd, tws, twt);
19015 break;
19016 case OPC_BSET_df:
19017 gen_helper_msa_bset_df(cpu_env, tdf, twd, tws, twt);
19018 break;
19019 case OPC_MIN_S_df:
19020 gen_helper_msa_min_s_df(cpu_env, tdf, twd, tws, twt);
19021 break;
19022 case OPC_CLE_S_df:
19023 gen_helper_msa_cle_s_df(cpu_env, tdf, twd, tws, twt);
19024 break;
19025 case OPC_AVE_S_df:
19026 gen_helper_msa_ave_s_df(cpu_env, tdf, twd, tws, twt);
19027 break;
19028 case OPC_ASUB_S_df:
19029 gen_helper_msa_asub_s_df(cpu_env, tdf, twd, tws, twt);
19030 break;
19031 case OPC_DIV_S_df:
19032 gen_helper_msa_div_s_df(cpu_env, tdf, twd, tws, twt);
19033 break;
19034 case OPC_ILVL_df:
19035 gen_helper_msa_ilvl_df(cpu_env, tdf, twd, tws, twt);
19036 break;
19037 case OPC_BNEG_df:
19038 gen_helper_msa_bneg_df(cpu_env, tdf, twd, tws, twt);
19039 break;
19040 case OPC_MIN_U_df:
19041 gen_helper_msa_min_u_df(cpu_env, tdf, twd, tws, twt);
19042 break;
19043 case OPC_CLE_U_df:
19044 gen_helper_msa_cle_u_df(cpu_env, tdf, twd, tws, twt);
19045 break;
19046 case OPC_AVE_U_df:
19047 gen_helper_msa_ave_u_df(cpu_env, tdf, twd, tws, twt);
19048 break;
19049 case OPC_ASUB_U_df:
19050 gen_helper_msa_asub_u_df(cpu_env, tdf, twd, tws, twt);
19051 break;
19052 case OPC_DIV_U_df:
19053 gen_helper_msa_div_u_df(cpu_env, tdf, twd, tws, twt);
19054 break;
19055 case OPC_ILVR_df:
19056 gen_helper_msa_ilvr_df(cpu_env, tdf, twd, tws, twt);
19057 break;
19058 case OPC_BINSL_df:
19059 gen_helper_msa_binsl_df(cpu_env, tdf, twd, tws, twt);
19060 break;
19061 case OPC_MAX_A_df:
19062 gen_helper_msa_max_a_df(cpu_env, tdf, twd, tws, twt);
19063 break;
19064 case OPC_AVER_S_df:
19065 gen_helper_msa_aver_s_df(cpu_env, tdf, twd, tws, twt);
19066 break;
19067 case OPC_MOD_S_df:
19068 gen_helper_msa_mod_s_df(cpu_env, tdf, twd, tws, twt);
19069 break;
19070 case OPC_ILVEV_df:
19071 gen_helper_msa_ilvev_df(cpu_env, tdf, twd, tws, twt);
19072 break;
19073 case OPC_BINSR_df:
19074 gen_helper_msa_binsr_df(cpu_env, tdf, twd, tws, twt);
19075 break;
19076 case OPC_MIN_A_df:
19077 gen_helper_msa_min_a_df(cpu_env, tdf, twd, tws, twt);
19078 break;
19079 case OPC_AVER_U_df:
19080 gen_helper_msa_aver_u_df(cpu_env, tdf, twd, tws, twt);
19081 break;
19082 case OPC_MOD_U_df:
19083 gen_helper_msa_mod_u_df(cpu_env, tdf, twd, tws, twt);
19084 break;
19085 case OPC_ILVOD_df:
19086 gen_helper_msa_ilvod_df(cpu_env, tdf, twd, tws, twt);
19087 break;
19088
19089 case OPC_DOTP_S_df:
19090 case OPC_DOTP_U_df:
19091 case OPC_DPADD_S_df:
19092 case OPC_DPADD_U_df:
19093 case OPC_DPSUB_S_df:
19094 case OPC_HADD_S_df:
19095 case OPC_DPSUB_U_df:
19096 case OPC_HADD_U_df:
19097 case OPC_HSUB_S_df:
19098 case OPC_HSUB_U_df:
19099 if (df == DF_BYTE) {
9c708c7f
PD
19100 generate_exception_end(ctx, EXCP_RI);
19101 break;
28f99f08
YK
19102 }
19103 switch (MASK_MSA_3R(ctx->opcode)) {
19104 case OPC_DOTP_S_df:
19105 gen_helper_msa_dotp_s_df(cpu_env, tdf, twd, tws, twt);
19106 break;
19107 case OPC_DOTP_U_df:
19108 gen_helper_msa_dotp_u_df(cpu_env, tdf, twd, tws, twt);
19109 break;
19110 case OPC_DPADD_S_df:
19111 gen_helper_msa_dpadd_s_df(cpu_env, tdf, twd, tws, twt);
19112 break;
19113 case OPC_DPADD_U_df:
19114 gen_helper_msa_dpadd_u_df(cpu_env, tdf, twd, tws, twt);
19115 break;
19116 case OPC_DPSUB_S_df:
19117 gen_helper_msa_dpsub_s_df(cpu_env, tdf, twd, tws, twt);
19118 break;
19119 case OPC_HADD_S_df:
19120 gen_helper_msa_hadd_s_df(cpu_env, tdf, twd, tws, twt);
19121 break;
19122 case OPC_DPSUB_U_df:
19123 gen_helper_msa_dpsub_u_df(cpu_env, tdf, twd, tws, twt);
19124 break;
19125 case OPC_HADD_U_df:
19126 gen_helper_msa_hadd_u_df(cpu_env, tdf, twd, tws, twt);
19127 break;
19128 case OPC_HSUB_S_df:
19129 gen_helper_msa_hsub_s_df(cpu_env, tdf, twd, tws, twt);
19130 break;
19131 case OPC_HSUB_U_df:
19132 gen_helper_msa_hsub_u_df(cpu_env, tdf, twd, tws, twt);
19133 break;
19134 }
19135 break;
19136 default:
19137 MIPS_INVAL("MSA instruction");
9c708c7f 19138 generate_exception_end(ctx, EXCP_RI);
28f99f08
YK
19139 break;
19140 }
19141 tcg_temp_free_i32(twd);
19142 tcg_temp_free_i32(tws);
19143 tcg_temp_free_i32(twt);
19144 tcg_temp_free_i32(tdf);
19145}
19146
1e608ec1
YK
19147static void gen_msa_elm_3e(CPUMIPSState *env, DisasContext *ctx)
19148{
19149#define MASK_MSA_ELM_DF3E(op) (MASK_MSA_MINOR(op) | (op & (0x3FF << 16)))
19150 uint8_t source = (ctx->opcode >> 11) & 0x1f;
19151 uint8_t dest = (ctx->opcode >> 6) & 0x1f;
19152 TCGv telm = tcg_temp_new();
19153 TCGv_i32 tsr = tcg_const_i32(source);
19154 TCGv_i32 tdt = tcg_const_i32(dest);
19155
19156 switch (MASK_MSA_ELM_DF3E(ctx->opcode)) {
19157 case OPC_CTCMSA:
19158 gen_load_gpr(telm, source);
19159 gen_helper_msa_ctcmsa(cpu_env, telm, tdt);
19160 break;
19161 case OPC_CFCMSA:
19162 gen_helper_msa_cfcmsa(telm, cpu_env, tsr);
19163 gen_store_gpr(telm, dest);
19164 break;
19165 case OPC_MOVE_V:
19166 gen_helper_msa_move_v(cpu_env, tdt, tsr);
19167 break;
19168 default:
19169 MIPS_INVAL("MSA instruction");
9c708c7f 19170 generate_exception_end(ctx, EXCP_RI);
1e608ec1
YK
19171 break;
19172 }
19173
19174 tcg_temp_free(telm);
19175 tcg_temp_free_i32(tdt);
19176 tcg_temp_free_i32(tsr);
19177}
19178
19179static void gen_msa_elm_df(CPUMIPSState *env, DisasContext *ctx, uint32_t df,
19180 uint32_t n)
19181{
19182#define MASK_MSA_ELM(op) (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
19183 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
19184 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
19185
19186 TCGv_i32 tws = tcg_const_i32(ws);
19187 TCGv_i32 twd = tcg_const_i32(wd);
19188 TCGv_i32 tn = tcg_const_i32(n);
19189 TCGv_i32 tdf = tcg_const_i32(df);
19190
19191 switch (MASK_MSA_ELM(ctx->opcode)) {
19192 case OPC_SLDI_df:
19193 gen_helper_msa_sldi_df(cpu_env, tdf, twd, tws, tn);
19194 break;
19195 case OPC_SPLATI_df:
19196 gen_helper_msa_splati_df(cpu_env, tdf, twd, tws, tn);
19197 break;
19198 case OPC_INSVE_df:
19199 gen_helper_msa_insve_df(cpu_env, tdf, twd, tws, tn);
19200 break;
19201 case OPC_COPY_S_df:
19202 case OPC_COPY_U_df:
19203 case OPC_INSERT_df:
19204#if !defined(TARGET_MIPS64)
19205 /* Double format valid only for MIPS64 */
19206 if (df == DF_DOUBLE) {
9c708c7f 19207 generate_exception_end(ctx, EXCP_RI);
1e608ec1
YK
19208 break;
19209 }
19210#endif
19211 switch (MASK_MSA_ELM(ctx->opcode)) {
19212 case OPC_COPY_S_df:
cab48881
MD
19213 if (likely(wd != 0)) {
19214 gen_helper_msa_copy_s_df(cpu_env, tdf, twd, tws, tn);
19215 }
1e608ec1
YK
19216 break;
19217 case OPC_COPY_U_df:
cab48881
MD
19218 if (likely(wd != 0)) {
19219 gen_helper_msa_copy_u_df(cpu_env, tdf, twd, tws, tn);
19220 }
1e608ec1
YK
19221 break;
19222 case OPC_INSERT_df:
19223 gen_helper_msa_insert_df(cpu_env, tdf, twd, tws, tn);
19224 break;
19225 }
19226 break;
19227 default:
19228 MIPS_INVAL("MSA instruction");
9c708c7f 19229 generate_exception_end(ctx, EXCP_RI);
1e608ec1
YK
19230 }
19231 tcg_temp_free_i32(twd);
19232 tcg_temp_free_i32(tws);
19233 tcg_temp_free_i32(tn);
19234 tcg_temp_free_i32(tdf);
19235}
19236
19237static void gen_msa_elm(CPUMIPSState *env, DisasContext *ctx)
19238{
19239 uint8_t dfn = (ctx->opcode >> 16) & 0x3f;
19240 uint32_t df = 0, n = 0;
19241
19242 if ((dfn & 0x30) == 0x00) {
19243 n = dfn & 0x0f;
19244 df = DF_BYTE;
19245 } else if ((dfn & 0x38) == 0x20) {
19246 n = dfn & 0x07;
19247 df = DF_HALF;
19248 } else if ((dfn & 0x3c) == 0x30) {
19249 n = dfn & 0x03;
19250 df = DF_WORD;
19251 } else if ((dfn & 0x3e) == 0x38) {
19252 n = dfn & 0x01;
19253 df = DF_DOUBLE;
19254 } else if (dfn == 0x3E) {
19255 /* CTCMSA, CFCMSA, MOVE.V */
19256 gen_msa_elm_3e(env, ctx);
19257 return;
19258 } else {
9c708c7f 19259 generate_exception_end(ctx, EXCP_RI);
1e608ec1
YK
19260 return;
19261 }
19262
19263 gen_msa_elm_df(env, ctx, df, n);
19264}
19265
7d05b9c8
YK
19266static void gen_msa_3rf(CPUMIPSState *env, DisasContext *ctx)
19267{
19268#define MASK_MSA_3RF(op) (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
19269 uint8_t df = (ctx->opcode >> 21) & 0x1;
19270 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
19271 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
19272 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
19273
19274 TCGv_i32 twd = tcg_const_i32(wd);
19275 TCGv_i32 tws = tcg_const_i32(ws);
19276 TCGv_i32 twt = tcg_const_i32(wt);
19277 TCGv_i32 tdf = tcg_temp_new_i32();
19278
19279 /* adjust df value for floating-point instruction */
19280 tcg_gen_movi_i32(tdf, df + 2);
19281
19282 switch (MASK_MSA_3RF(ctx->opcode)) {
19283 case OPC_FCAF_df:
19284 gen_helper_msa_fcaf_df(cpu_env, tdf, twd, tws, twt);
19285 break;
19286 case OPC_FADD_df:
19287 gen_helper_msa_fadd_df(cpu_env, tdf, twd, tws, twt);
19288 break;
19289 case OPC_FCUN_df:
19290 gen_helper_msa_fcun_df(cpu_env, tdf, twd, tws, twt);
19291 break;
19292 case OPC_FSUB_df:
19293 gen_helper_msa_fsub_df(cpu_env, tdf, twd, tws, twt);
19294 break;
19295 case OPC_FCOR_df:
19296 gen_helper_msa_fcor_df(cpu_env, tdf, twd, tws, twt);
19297 break;
19298 case OPC_FCEQ_df:
19299 gen_helper_msa_fceq_df(cpu_env, tdf, twd, tws, twt);
19300 break;
19301 case OPC_FMUL_df:
19302 gen_helper_msa_fmul_df(cpu_env, tdf, twd, tws, twt);
19303 break;
19304 case OPC_FCUNE_df:
19305 gen_helper_msa_fcune_df(cpu_env, tdf, twd, tws, twt);
19306 break;
19307 case OPC_FCUEQ_df:
19308 gen_helper_msa_fcueq_df(cpu_env, tdf, twd, tws, twt);
19309 break;
19310 case OPC_FDIV_df:
19311 gen_helper_msa_fdiv_df(cpu_env, tdf, twd, tws, twt);
19312 break;
19313 case OPC_FCNE_df:
19314 gen_helper_msa_fcne_df(cpu_env, tdf, twd, tws, twt);
19315 break;
19316 case OPC_FCLT_df:
19317 gen_helper_msa_fclt_df(cpu_env, tdf, twd, tws, twt);
19318 break;
19319 case OPC_FMADD_df:
19320 gen_helper_msa_fmadd_df(cpu_env, tdf, twd, tws, twt);
19321 break;
19322 case OPC_MUL_Q_df:
19323 tcg_gen_movi_i32(tdf, df + 1);
19324 gen_helper_msa_mul_q_df(cpu_env, tdf, twd, tws, twt);
19325 break;
19326 case OPC_FCULT_df:
19327 gen_helper_msa_fcult_df(cpu_env, tdf, twd, tws, twt);
19328 break;
19329 case OPC_FMSUB_df:
19330 gen_helper_msa_fmsub_df(cpu_env, tdf, twd, tws, twt);
19331 break;
19332 case OPC_MADD_Q_df:
19333 tcg_gen_movi_i32(tdf, df + 1);
19334 gen_helper_msa_madd_q_df(cpu_env, tdf, twd, tws, twt);
19335 break;
19336 case OPC_FCLE_df:
19337 gen_helper_msa_fcle_df(cpu_env, tdf, twd, tws, twt);
19338 break;
19339 case OPC_MSUB_Q_df:
19340 tcg_gen_movi_i32(tdf, df + 1);
19341 gen_helper_msa_msub_q_df(cpu_env, tdf, twd, tws, twt);
19342 break;
19343 case OPC_FCULE_df:
19344 gen_helper_msa_fcule_df(cpu_env, tdf, twd, tws, twt);
19345 break;
19346 case OPC_FEXP2_df:
19347 gen_helper_msa_fexp2_df(cpu_env, tdf, twd, tws, twt);
19348 break;
19349 case OPC_FSAF_df:
19350 gen_helper_msa_fsaf_df(cpu_env, tdf, twd, tws, twt);
19351 break;
19352 case OPC_FEXDO_df:
19353 gen_helper_msa_fexdo_df(cpu_env, tdf, twd, tws, twt);
19354 break;
19355 case OPC_FSUN_df:
19356 gen_helper_msa_fsun_df(cpu_env, tdf, twd, tws, twt);
19357 break;
19358 case OPC_FSOR_df:
19359 gen_helper_msa_fsor_df(cpu_env, tdf, twd, tws, twt);
19360 break;
19361 case OPC_FSEQ_df:
19362 gen_helper_msa_fseq_df(cpu_env, tdf, twd, tws, twt);
19363 break;
19364 case OPC_FTQ_df:
19365 gen_helper_msa_ftq_df(cpu_env, tdf, twd, tws, twt);
19366 break;
19367 case OPC_FSUNE_df:
19368 gen_helper_msa_fsune_df(cpu_env, tdf, twd, tws, twt);
19369 break;
19370 case OPC_FSUEQ_df:
19371 gen_helper_msa_fsueq_df(cpu_env, tdf, twd, tws, twt);
19372 break;
19373 case OPC_FSNE_df:
19374 gen_helper_msa_fsne_df(cpu_env, tdf, twd, tws, twt);
19375 break;
19376 case OPC_FSLT_df:
19377 gen_helper_msa_fslt_df(cpu_env, tdf, twd, tws, twt);
19378 break;
19379 case OPC_FMIN_df:
19380 gen_helper_msa_fmin_df(cpu_env, tdf, twd, tws, twt);
19381 break;
19382 case OPC_MULR_Q_df:
19383 tcg_gen_movi_i32(tdf, df + 1);
19384 gen_helper_msa_mulr_q_df(cpu_env, tdf, twd, tws, twt);
19385 break;
19386 case OPC_FSULT_df:
19387 gen_helper_msa_fsult_df(cpu_env, tdf, twd, tws, twt);
19388 break;
19389 case OPC_FMIN_A_df:
19390 gen_helper_msa_fmin_a_df(cpu_env, tdf, twd, tws, twt);
19391 break;
19392 case OPC_MADDR_Q_df:
19393 tcg_gen_movi_i32(tdf, df + 1);
19394 gen_helper_msa_maddr_q_df(cpu_env, tdf, twd, tws, twt);
19395 break;
19396 case OPC_FSLE_df:
19397 gen_helper_msa_fsle_df(cpu_env, tdf, twd, tws, twt);
19398 break;
19399 case OPC_FMAX_df:
19400 gen_helper_msa_fmax_df(cpu_env, tdf, twd, tws, twt);
19401 break;
19402 case OPC_MSUBR_Q_df:
19403 tcg_gen_movi_i32(tdf, df + 1);
19404 gen_helper_msa_msubr_q_df(cpu_env, tdf, twd, tws, twt);
19405 break;
19406 case OPC_FSULE_df:
19407 gen_helper_msa_fsule_df(cpu_env, tdf, twd, tws, twt);
19408 break;
19409 case OPC_FMAX_A_df:
19410 gen_helper_msa_fmax_a_df(cpu_env, tdf, twd, tws, twt);
19411 break;
19412 default:
19413 MIPS_INVAL("MSA instruction");
9c708c7f 19414 generate_exception_end(ctx, EXCP_RI);
7d05b9c8
YK
19415 break;
19416 }
19417
19418 tcg_temp_free_i32(twd);
19419 tcg_temp_free_i32(tws);
19420 tcg_temp_free_i32(twt);
19421 tcg_temp_free_i32(tdf);
19422}
19423
cbe50b9a
YK
19424static void gen_msa_2r(CPUMIPSState *env, DisasContext *ctx)
19425{
19426#define MASK_MSA_2R(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
19427 (op & (0x7 << 18)))
19428 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
19429 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
19430 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
19431 uint8_t df = (ctx->opcode >> 16) & 0x3;
19432 TCGv_i32 twd = tcg_const_i32(wd);
19433 TCGv_i32 tws = tcg_const_i32(ws);
19434 TCGv_i32 twt = tcg_const_i32(wt);
19435 TCGv_i32 tdf = tcg_const_i32(df);
19436
19437 switch (MASK_MSA_2R(ctx->opcode)) {
19438 case OPC_FILL_df:
19439#if !defined(TARGET_MIPS64)
19440 /* Double format valid only for MIPS64 */
19441 if (df == DF_DOUBLE) {
9c708c7f 19442 generate_exception_end(ctx, EXCP_RI);
cbe50b9a
YK
19443 break;
19444 }
19445#endif
19446 gen_helper_msa_fill_df(cpu_env, tdf, twd, tws); /* trs */
19447 break;
19448 case OPC_PCNT_df:
19449 gen_helper_msa_pcnt_df(cpu_env, tdf, twd, tws);
19450 break;
19451 case OPC_NLOC_df:
19452 gen_helper_msa_nloc_df(cpu_env, tdf, twd, tws);
19453 break;
19454 case OPC_NLZC_df:
19455 gen_helper_msa_nlzc_df(cpu_env, tdf, twd, tws);
19456 break;
19457 default:
19458 MIPS_INVAL("MSA instruction");
9c708c7f 19459 generate_exception_end(ctx, EXCP_RI);
cbe50b9a
YK
19460 break;
19461 }
19462
19463 tcg_temp_free_i32(twd);
19464 tcg_temp_free_i32(tws);
19465 tcg_temp_free_i32(twt);
19466 tcg_temp_free_i32(tdf);
19467}
19468
3bdeb688
YK
19469static void gen_msa_2rf(CPUMIPSState *env, DisasContext *ctx)
19470{
19471#define MASK_MSA_2RF(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
19472 (op & (0xf << 17)))
19473 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
19474 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
19475 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
19476 uint8_t df = (ctx->opcode >> 16) & 0x1;
19477 TCGv_i32 twd = tcg_const_i32(wd);
19478 TCGv_i32 tws = tcg_const_i32(ws);
19479 TCGv_i32 twt = tcg_const_i32(wt);
19480 /* adjust df value for floating-point instruction */
19481 TCGv_i32 tdf = tcg_const_i32(df + 2);
19482
19483 switch (MASK_MSA_2RF(ctx->opcode)) {
19484 case OPC_FCLASS_df:
19485 gen_helper_msa_fclass_df(cpu_env, tdf, twd, tws);
19486 break;
19487 case OPC_FTRUNC_S_df:
19488 gen_helper_msa_ftrunc_s_df(cpu_env, tdf, twd, tws);
19489 break;
19490 case OPC_FTRUNC_U_df:
19491 gen_helper_msa_ftrunc_u_df(cpu_env, tdf, twd, tws);
19492 break;
19493 case OPC_FSQRT_df:
19494 gen_helper_msa_fsqrt_df(cpu_env, tdf, twd, tws);
19495 break;
19496 case OPC_FRSQRT_df:
19497 gen_helper_msa_frsqrt_df(cpu_env, tdf, twd, tws);
19498 break;
19499 case OPC_FRCP_df:
19500 gen_helper_msa_frcp_df(cpu_env, tdf, twd, tws);
19501 break;
19502 case OPC_FRINT_df:
19503 gen_helper_msa_frint_df(cpu_env, tdf, twd, tws);
19504 break;
19505 case OPC_FLOG2_df:
19506 gen_helper_msa_flog2_df(cpu_env, tdf, twd, tws);
19507 break;
19508 case OPC_FEXUPL_df:
19509 gen_helper_msa_fexupl_df(cpu_env, tdf, twd, tws);
19510 break;
19511 case OPC_FEXUPR_df:
19512 gen_helper_msa_fexupr_df(cpu_env, tdf, twd, tws);
19513 break;
19514 case OPC_FFQL_df:
19515 gen_helper_msa_ffql_df(cpu_env, tdf, twd, tws);
19516 break;
19517 case OPC_FFQR_df:
19518 gen_helper_msa_ffqr_df(cpu_env, tdf, twd, tws);
19519 break;
19520 case OPC_FTINT_S_df:
19521 gen_helper_msa_ftint_s_df(cpu_env, tdf, twd, tws);
19522 break;
19523 case OPC_FTINT_U_df:
19524 gen_helper_msa_ftint_u_df(cpu_env, tdf, twd, tws);
19525 break;
19526 case OPC_FFINT_S_df:
19527 gen_helper_msa_ffint_s_df(cpu_env, tdf, twd, tws);
19528 break;
19529 case OPC_FFINT_U_df:
19530 gen_helper_msa_ffint_u_df(cpu_env, tdf, twd, tws);
19531 break;
19532 }
19533
19534 tcg_temp_free_i32(twd);
19535 tcg_temp_free_i32(tws);
19536 tcg_temp_free_i32(twt);
19537 tcg_temp_free_i32(tdf);
19538}
19539
cbe50b9a
YK
19540static void gen_msa_vec_v(CPUMIPSState *env, DisasContext *ctx)
19541{
19542#define MASK_MSA_VEC(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)))
19543 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
19544 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
19545 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
19546 TCGv_i32 twd = tcg_const_i32(wd);
19547 TCGv_i32 tws = tcg_const_i32(ws);
19548 TCGv_i32 twt = tcg_const_i32(wt);
19549
19550 switch (MASK_MSA_VEC(ctx->opcode)) {
19551 case OPC_AND_V:
19552 gen_helper_msa_and_v(cpu_env, twd, tws, twt);
19553 break;
19554 case OPC_OR_V:
19555 gen_helper_msa_or_v(cpu_env, twd, tws, twt);
19556 break;
19557 case OPC_NOR_V:
19558 gen_helper_msa_nor_v(cpu_env, twd, tws, twt);
19559 break;
19560 case OPC_XOR_V:
19561 gen_helper_msa_xor_v(cpu_env, twd, tws, twt);
19562 break;
19563 case OPC_BMNZ_V:
19564 gen_helper_msa_bmnz_v(cpu_env, twd, tws, twt);
19565 break;
19566 case OPC_BMZ_V:
19567 gen_helper_msa_bmz_v(cpu_env, twd, tws, twt);
19568 break;
19569 case OPC_BSEL_V:
19570 gen_helper_msa_bsel_v(cpu_env, twd, tws, twt);
19571 break;
19572 default:
19573 MIPS_INVAL("MSA instruction");
9c708c7f 19574 generate_exception_end(ctx, EXCP_RI);
cbe50b9a
YK
19575 break;
19576 }
19577
19578 tcg_temp_free_i32(twd);
19579 tcg_temp_free_i32(tws);
19580 tcg_temp_free_i32(twt);
19581}
19582
19583static void gen_msa_vec(CPUMIPSState *env, DisasContext *ctx)
19584{
19585 switch (MASK_MSA_VEC(ctx->opcode)) {
19586 case OPC_AND_V:
19587 case OPC_OR_V:
19588 case OPC_NOR_V:
19589 case OPC_XOR_V:
19590 case OPC_BMNZ_V:
19591 case OPC_BMZ_V:
19592 case OPC_BSEL_V:
19593 gen_msa_vec_v(env, ctx);
19594 break;
19595 case OPC_MSA_2R:
19596 gen_msa_2r(env, ctx);
19597 break;
3bdeb688
YK
19598 case OPC_MSA_2RF:
19599 gen_msa_2rf(env, ctx);
19600 break;
cbe50b9a
YK
19601 default:
19602 MIPS_INVAL("MSA instruction");
9c708c7f 19603 generate_exception_end(ctx, EXCP_RI);
cbe50b9a
YK
19604 break;
19605 }
19606}
19607
4c789546
YK
19608static void gen_msa(CPUMIPSState *env, DisasContext *ctx)
19609{
19610 uint32_t opcode = ctx->opcode;
19611 check_insn(ctx, ASE_MSA);
19612 check_msa_access(ctx);
19613
19614 switch (MASK_MSA_MINOR(opcode)) {
19615 case OPC_MSA_I8_00:
19616 case OPC_MSA_I8_01:
19617 case OPC_MSA_I8_02:
19618 gen_msa_i8(env, ctx);
19619 break;
80e71591
YK
19620 case OPC_MSA_I5_06:
19621 case OPC_MSA_I5_07:
19622 gen_msa_i5(env, ctx);
19623 break;
d4cf28de
YK
19624 case OPC_MSA_BIT_09:
19625 case OPC_MSA_BIT_0A:
19626 gen_msa_bit(env, ctx);
19627 break;
28f99f08
YK
19628 case OPC_MSA_3R_0D:
19629 case OPC_MSA_3R_0E:
19630 case OPC_MSA_3R_0F:
19631 case OPC_MSA_3R_10:
19632 case OPC_MSA_3R_11:
19633 case OPC_MSA_3R_12:
19634 case OPC_MSA_3R_13:
19635 case OPC_MSA_3R_14:
19636 case OPC_MSA_3R_15:
19637 gen_msa_3r(env, ctx);
19638 break;
1e608ec1
YK
19639 case OPC_MSA_ELM:
19640 gen_msa_elm(env, ctx);
19641 break;
7d05b9c8
YK
19642 case OPC_MSA_3RF_1A:
19643 case OPC_MSA_3RF_1B:
19644 case OPC_MSA_3RF_1C:
19645 gen_msa_3rf(env, ctx);
19646 break;
cbe50b9a
YK
19647 case OPC_MSA_VEC:
19648 gen_msa_vec(env, ctx);
19649 break;
f7685877
YK
19650 case OPC_LD_B:
19651 case OPC_LD_H:
19652 case OPC_LD_W:
19653 case OPC_LD_D:
19654 case OPC_ST_B:
19655 case OPC_ST_H:
19656 case OPC_ST_W:
19657 case OPC_ST_D:
19658 {
19659 int32_t s10 = sextract32(ctx->opcode, 16, 10);
19660 uint8_t rs = (ctx->opcode >> 11) & 0x1f;
19661 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
19662 uint8_t df = (ctx->opcode >> 0) & 0x3;
19663
f7685877 19664 TCGv_i32 twd = tcg_const_i32(wd);
adc370a4
YK
19665 TCGv taddr = tcg_temp_new();
19666 gen_base_offset_addr(ctx, taddr, rs, s10 << df);
f7685877
YK
19667
19668 switch (MASK_MSA_MINOR(opcode)) {
19669 case OPC_LD_B:
adc370a4
YK
19670 gen_helper_msa_ld_b(cpu_env, twd, taddr);
19671 break;
f7685877 19672 case OPC_LD_H:
adc370a4
YK
19673 gen_helper_msa_ld_h(cpu_env, twd, taddr);
19674 break;
f7685877 19675 case OPC_LD_W:
adc370a4
YK
19676 gen_helper_msa_ld_w(cpu_env, twd, taddr);
19677 break;
f7685877 19678 case OPC_LD_D:
adc370a4 19679 gen_helper_msa_ld_d(cpu_env, twd, taddr);
f7685877
YK
19680 break;
19681 case OPC_ST_B:
adc370a4
YK
19682 gen_helper_msa_st_b(cpu_env, twd, taddr);
19683 break;
f7685877 19684 case OPC_ST_H:
adc370a4
YK
19685 gen_helper_msa_st_h(cpu_env, twd, taddr);
19686 break;
f7685877 19687 case OPC_ST_W:
adc370a4
YK
19688 gen_helper_msa_st_w(cpu_env, twd, taddr);
19689 break;
f7685877 19690 case OPC_ST_D:
adc370a4 19691 gen_helper_msa_st_d(cpu_env, twd, taddr);
f7685877
YK
19692 break;
19693 }
19694
19695 tcg_temp_free_i32(twd);
adc370a4 19696 tcg_temp_free(taddr);
f7685877
YK
19697 }
19698 break;
4c789546
YK
19699 default:
19700 MIPS_INVAL("MSA instruction");
9c708c7f 19701 generate_exception_end(ctx, EXCP_RI);
4c789546
YK
19702 break;
19703 }
19704
19705}
19706
d2bfa6e6 19707static void decode_opc(CPUMIPSState *env, DisasContext *ctx)
099e5b4d
LA
19708{
19709 int32_t offset;
19710 int rs, rt, rd, sa;
19711 uint32_t op, op1;
19712 int16_t imm;
19713
19714 /* make sure instructions are on a word boundary */
eeb3bba8
EC
19715 if (ctx->base.pc_next & 0x3) {
19716 env->CP0_BadVAddr = ctx->base.pc_next;
aea14095 19717 generate_exception_err(ctx, EXCP_AdEL, EXCP_INST_NOTAVAIL);
099e5b4d
LA
19718 return;
19719 }
19720
19721 /* Handle blikely not taken case */
19722 if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
42a268c2 19723 TCGLabel *l1 = gen_new_label();
099e5b4d 19724
099e5b4d
LA
19725 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
19726 tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
eeb3bba8 19727 gen_goto_tb(ctx, 1, ctx->base.pc_next + 4);
099e5b4d
LA
19728 gen_set_label(l1);
19729 }
19730
099e5b4d
LA
19731 op = MASK_OP_MAJOR(ctx->opcode);
19732 rs = (ctx->opcode >> 21) & 0x1f;
19733 rt = (ctx->opcode >> 16) & 0x1f;
19734 rd = (ctx->opcode >> 11) & 0x1f;
19735 sa = (ctx->opcode >> 6) & 0x1f;
19736 imm = (int16_t)ctx->opcode;
19737 switch (op) {
19738 case OPC_SPECIAL:
19739 decode_opc_special(env, ctx);
19740 break;
19741 case OPC_SPECIAL2:
4267d3e6 19742 decode_opc_special2_legacy(env, ctx);
099e5b4d
LA
19743 break;
19744 case OPC_SPECIAL3:
19745 decode_opc_special3(env, ctx);
19746 break;
7a387fff
TS
19747 case OPC_REGIMM:
19748 op1 = MASK_REGIMM(ctx->opcode);
19749 switch (op1) {
fecd2646
LA
19750 case OPC_BLTZL: /* REGIMM branches */
19751 case OPC_BGEZL:
19752 case OPC_BLTZALL:
19753 case OPC_BGEZALL:
d9224450 19754 check_insn(ctx, ISA_MIPS2);
fecd2646 19755 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d9224450 19756 /* Fallthrough */
fecd2646
LA
19757 case OPC_BLTZ:
19758 case OPC_BGEZ:
b231c103 19759 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
0aefa333 19760 break;
fecd2646
LA
19761 case OPC_BLTZAL:
19762 case OPC_BGEZAL:
0aefa333
YK
19763 if (ctx->insn_flags & ISA_MIPS32R6) {
19764 if (rs == 0) {
19765 /* OPC_NAL, OPC_BAL */
b231c103 19766 gen_compute_branch(ctx, op1, 4, 0, -1, imm << 2, 4);
0aefa333 19767 } else {
9c708c7f 19768 generate_exception_end(ctx, EXCP_RI);
0aefa333
YK
19769 }
19770 } else {
b231c103 19771 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
0aefa333 19772 }
c9602061 19773 break;
c2e19f3c
AM
19774 case OPC_TGEI: /* REGIMM traps */
19775 case OPC_TGEIU:
19776 case OPC_TLTI:
19777 case OPC_TLTIU:
19778 case OPC_TEQI:
19779
7a387fff 19780 case OPC_TNEI:
d9224450 19781 check_insn(ctx, ISA_MIPS2);
fecd2646 19782 check_insn_opc_removed(ctx, ISA_MIPS32R6);
7a387fff
TS
19783 gen_trap(ctx, op1, rs, -1, imm);
19784 break;
bb238210
YK
19785 case OPC_SIGRIE:
19786 check_insn(ctx, ISA_MIPS32R6);
19787 generate_exception_end(ctx, EXCP_RI);
19788 break;
7a387fff 19789 case OPC_SYNCI:
d75c135e 19790 check_insn(ctx, ISA_MIPS32R2);
a83bddd6
DZ
19791 /* Break the TB to be able to sync copied instructions
19792 immediately */
eeb3bba8 19793 ctx->base.is_jmp = DISAS_STOP;
6af0bf9c 19794 break;
e45a93e2
JL
19795 case OPC_BPOSGE32: /* MIPS DSP branch */
19796#if defined(TARGET_MIPS64)
19797 case OPC_BPOSGE64:
19798#endif
19799 check_dsp(ctx);
b231c103 19800 gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2, 4);
e45a93e2 19801 break;
d4ea6acd
LA
19802#if defined(TARGET_MIPS64)
19803 case OPC_DAHI:
19804 check_insn(ctx, ISA_MIPS32R6);
19805 check_mips_64(ctx);
19806 if (rs != 0) {
19807 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 32);
19808 }
d4ea6acd
LA
19809 break;
19810 case OPC_DATI:
19811 check_insn(ctx, ISA_MIPS32R6);
19812 check_mips_64(ctx);
19813 if (rs != 0) {
19814 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 48);
19815 }
d4ea6acd
LA
19816 break;
19817#endif
6af0bf9c 19818 default: /* Invalid */
923617a3 19819 MIPS_INVAL("regimm");
9c708c7f 19820 generate_exception_end(ctx, EXCP_RI);
6af0bf9c
FB
19821 break;
19822 }
19823 break;
7a387fff 19824 case OPC_CP0:
387a8fe5 19825 check_cp0_enabled(ctx);
7a387fff 19826 op1 = MASK_CP0(ctx->opcode);
6af0bf9c 19827 switch (op1) {
7a387fff
TS
19828 case OPC_MFC0:
19829 case OPC_MTC0:
ead9360e
TS
19830 case OPC_MFTR:
19831 case OPC_MTTR:
5204ea79
LA
19832 case OPC_MFHC0:
19833 case OPC_MTHC0:
d26bc211 19834#if defined(TARGET_MIPS64)
7a387fff
TS
19835 case OPC_DMFC0:
19836 case OPC_DMTC0:
19837#endif
f1aa6320 19838#ifndef CONFIG_USER_ONLY
932e71cd 19839 gen_cp0(env, ctx, op1, rt, rd);
0eaef5aa 19840#endif /* !CONFIG_USER_ONLY */
7a387fff 19841 break;
c38a1d52
AR
19842 case OPC_C0:
19843 case OPC_C0_1:
19844 case OPC_C0_2:
19845 case OPC_C0_3:
19846 case OPC_C0_4:
19847 case OPC_C0_5:
19848 case OPC_C0_6:
19849 case OPC_C0_7:
19850 case OPC_C0_8:
19851 case OPC_C0_9:
19852 case OPC_C0_A:
19853 case OPC_C0_B:
19854 case OPC_C0_C:
19855 case OPC_C0_D:
19856 case OPC_C0_E:
19857 case OPC_C0_F:
f1aa6320 19858#ifndef CONFIG_USER_ONLY
932e71cd 19859 gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
0eaef5aa 19860#endif /* !CONFIG_USER_ONLY */
7a387fff
TS
19861 break;
19862 case OPC_MFMC0:
8706c382 19863#ifndef CONFIG_USER_ONLY
932e71cd 19864 {
099e5b4d 19865 uint32_t op2;
35fbce2c 19866 TCGv t0 = tcg_temp_new();
6c5c1e20 19867
0eaef5aa 19868 op2 = MASK_MFMC0(ctx->opcode);
6c5c1e20
TS
19869 switch (op2) {
19870 case OPC_DMT:
d75c135e 19871 check_insn(ctx, ASE_MT);
9ed5726c 19872 gen_helper_dmt(t0);
35fbce2c 19873 gen_store_gpr(t0, rt);
6c5c1e20
TS
19874 break;
19875 case OPC_EMT:
d75c135e 19876 check_insn(ctx, ASE_MT);
9ed5726c 19877 gen_helper_emt(t0);
35fbce2c 19878 gen_store_gpr(t0, rt);
da80682b 19879 break;
6c5c1e20 19880 case OPC_DVPE:
d75c135e 19881 check_insn(ctx, ASE_MT);
895c2d04 19882 gen_helper_dvpe(t0, cpu_env);
35fbce2c 19883 gen_store_gpr(t0, rt);
6c5c1e20
TS
19884 break;
19885 case OPC_EVPE:
d75c135e 19886 check_insn(ctx, ASE_MT);
895c2d04 19887 gen_helper_evpe(t0, cpu_env);
35fbce2c 19888 gen_store_gpr(t0, rt);
6c5c1e20 19889 break;
01bc435b
YK
19890 case OPC_DVP:
19891 check_insn(ctx, ISA_MIPS32R6);
19892 if (ctx->vp) {
19893 gen_helper_dvp(t0, cpu_env);
19894 gen_store_gpr(t0, rt);
19895 }
19896 break;
19897 case OPC_EVP:
19898 check_insn(ctx, ISA_MIPS32R6);
19899 if (ctx->vp) {
19900 gen_helper_evp(t0, cpu_env);
19901 gen_store_gpr(t0, rt);
19902 }
19903 break;
6c5c1e20 19904 case OPC_DI:
d75c135e 19905 check_insn(ctx, ISA_MIPS32R2);
867abc7e 19906 save_cpu_state(ctx, 1);
895c2d04 19907 gen_helper_di(t0, cpu_env);
35fbce2c 19908 gen_store_gpr(t0, rt);
d2bfa6e6
MR
19909 /* Stop translation as we may have switched
19910 the execution mode. */
eeb3bba8 19911 ctx->base.is_jmp = DISAS_STOP;
6c5c1e20
TS
19912 break;
19913 case OPC_EI:
d75c135e 19914 check_insn(ctx, ISA_MIPS32R2);
867abc7e 19915 save_cpu_state(ctx, 1);
895c2d04 19916 gen_helper_ei(t0, cpu_env);
35fbce2c 19917 gen_store_gpr(t0, rt);
b28425ba
EC
19918 /* DISAS_STOP isn't sufficient, we need to ensure we break
19919 out of translated code to check for pending interrupts */
eeb3bba8
EC
19920 gen_save_pc(ctx->base.pc_next + 4);
19921 ctx->base.is_jmp = DISAS_EXIT;
6c5c1e20
TS
19922 break;
19923 default: /* Invalid */
19924 MIPS_INVAL("mfmc0");
9c708c7f 19925 generate_exception_end(ctx, EXCP_RI);
6c5c1e20
TS
19926 break;
19927 }
6c5c1e20 19928 tcg_temp_free(t0);
7a387fff 19929 }
0eaef5aa 19930#endif /* !CONFIG_USER_ONLY */
6af0bf9c 19931 break;
7a387fff 19932 case OPC_RDPGPR:
d75c135e 19933 check_insn(ctx, ISA_MIPS32R2);
be24bb4f 19934 gen_load_srsgpr(rt, rd);
ead9360e 19935 break;
7a387fff 19936 case OPC_WRPGPR:
d75c135e 19937 check_insn(ctx, ISA_MIPS32R2);
be24bb4f 19938 gen_store_srsgpr(rt, rd);
38121543 19939 break;
6af0bf9c 19940 default:
923617a3 19941 MIPS_INVAL("cp0");
9c708c7f 19942 generate_exception_end(ctx, EXCP_RI);
6af0bf9c
FB
19943 break;
19944 }
19945 break;
31837be3
YK
19946 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC, OPC_ADDI */
19947 if (ctx->insn_flags & ISA_MIPS32R6) {
19948 /* OPC_BOVC, OPC_BEQZALC, OPC_BEQC */
19949 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19950 } else {
19951 /* OPC_ADDI */
19952 /* Arithmetic with immediate opcode */
19953 gen_arith_imm(ctx, op, rt, rs, imm);
19954 }
19955 break;
324d9e32 19956 case OPC_ADDIU:
d75c135e 19957 gen_arith_imm(ctx, op, rt, rs, imm);
7a387fff 19958 break;
324d9e32
AJ
19959 case OPC_SLTI: /* Set on less than with immediate opcode */
19960 case OPC_SLTIU:
d75c135e 19961 gen_slt_imm(ctx, op, rt, rs, imm);
324d9e32
AJ
19962 break;
19963 case OPC_ANDI: /* Arithmetic with immediate opcode */
d4ea6acd 19964 case OPC_LUI: /* OPC_AUI */
324d9e32
AJ
19965 case OPC_ORI:
19966 case OPC_XORI:
d75c135e 19967 gen_logic_imm(ctx, op, rt, rs, imm);
324d9e32 19968 break;
c2e19f3c
AM
19969 case OPC_J: /* Jump */
19970 case OPC_JAL:
7a387fff 19971 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
b231c103 19972 gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
c9602061 19973 break;
31837be3
YK
19974 /* Branch */
19975 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC, OPC_BLEZL */
19976 if (ctx->insn_flags & ISA_MIPS32R6) {
19977 if (rt == 0) {
9c708c7f 19978 generate_exception_end(ctx, EXCP_RI);
31837be3
YK
19979 break;
19980 }
19981 /* OPC_BLEZC, OPC_BGEZC, OPC_BGEC */
19982 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19983 } else {
19984 /* OPC_BLEZL */
b231c103 19985 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
31837be3
YK
19986 }
19987 break;
19988 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC, OPC_BGTZL */
19989 if (ctx->insn_flags & ISA_MIPS32R6) {
19990 if (rt == 0) {
9c708c7f 19991 generate_exception_end(ctx, EXCP_RI);
31837be3
YK
19992 break;
19993 }
19994 /* OPC_BGTZC, OPC_BLTZC, OPC_BLTC */
19995 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19996 } else {
19997 /* OPC_BGTZL */
b231c103 19998 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
31837be3
YK
19999 }
20000 break;
20001 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC, OPC_BLEZ */
20002 if (rt == 0) {
20003 /* OPC_BLEZ */
b231c103 20004 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
31837be3
YK
20005 } else {
20006 check_insn(ctx, ISA_MIPS32R6);
20007 /* OPC_BLEZALC, OPC_BGEZALC, OPC_BGEUC */
20008 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
20009 }
20010 break;
20011 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC, OPC_BGTZ */
20012 if (rt == 0) {
20013 /* OPC_BGTZ */
b231c103 20014 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
31837be3
YK
20015 } else {
20016 check_insn(ctx, ISA_MIPS32R6);
20017 /* OPC_BGTZALC, OPC_BLTZALC, OPC_BLTUC */
20018 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
20019 }
20020 break;
20021 case OPC_BEQL:
20022 case OPC_BNEL:
d9224450 20023 check_insn(ctx, ISA_MIPS2);
fecd2646 20024 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d9224450 20025 /* Fallthrough */
31837be3
YK
20026 case OPC_BEQ:
20027 case OPC_BNE:
b231c103 20028 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
c9602061 20029 break;
d9224450
MR
20030 case OPC_LL: /* Load and stores */
20031 check_insn(ctx, ISA_MIPS2);
20032 /* Fallthrough */
20033 case OPC_LWL:
fecd2646
LA
20034 case OPC_LWR:
20035 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d9224450 20036 /* Fallthrough */
c2e19f3c
AM
20037 case OPC_LB:
20038 case OPC_LH:
20039 case OPC_LW:
20040 case OPC_LWPC:
20041 case OPC_LBU:
20042 case OPC_LHU:
d75c135e 20043 gen_ld(ctx, op, rt, rs, imm);
5c13fdfd 20044 break;
fecd2646 20045 case OPC_SWL:
7a387fff 20046 case OPC_SWR:
fecd2646 20047 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b6f3b233 20048 /* fall through */
c2e19f3c
AM
20049 case OPC_SB:
20050 case OPC_SH:
fecd2646 20051 case OPC_SW:
5c13fdfd 20052 gen_st(ctx, op, rt, rs, imm);
7a387fff 20053 break;
d66c7132 20054 case OPC_SC:
d9224450 20055 check_insn(ctx, ISA_MIPS2);
4368b29a 20056 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d66c7132
AJ
20057 gen_st_cond(ctx, op, rt, rs, imm);
20058 break;
7a387fff 20059 case OPC_CACHE:
bf7910c6 20060 check_insn_opc_removed(ctx, ISA_MIPS32R6);
2e15497c 20061 check_cp0_enabled(ctx);
d75c135e 20062 check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
0d74a222
LA
20063 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
20064 gen_cache_operation(ctx, rt, rs, imm);
20065 }
ead9360e 20066 /* Treat as NOP. */
34ae7b51 20067 break;
7a387fff 20068 case OPC_PREF:
bf7910c6 20069 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d75c135e 20070 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
ead9360e 20071 /* Treat as NOP. */
6af0bf9c 20072 break;
4ad40f36 20073
923617a3 20074 /* Floating point (COP1). */
7a387fff
TS
20075 case OPC_LWC1:
20076 case OPC_LDC1:
20077 case OPC_SWC1:
20078 case OPC_SDC1:
5ab5c041 20079 gen_cop1_ldst(ctx, op, rt, rs, imm);
6ea83fed
FB
20080 break;
20081
7a387fff 20082 case OPC_CP1:
5692c6e1
YK
20083 op1 = MASK_CP1(ctx->opcode);
20084
20085 switch (op1) {
20086 case OPC_MFHC1:
20087 case OPC_MTHC1:
5e755519 20088 check_cp1_enabled(ctx);
5692c6e1
YK
20089 check_insn(ctx, ISA_MIPS32R2);
20090 case OPC_MFC1:
20091 case OPC_CFC1:
20092 case OPC_MTC1:
20093 case OPC_CTC1:
20094 check_cp1_enabled(ctx);
20095 gen_cp1(ctx, op1, rt, rd);
20096 break;
d26bc211 20097#if defined(TARGET_MIPS64)
5692c6e1
YK
20098 case OPC_DMFC1:
20099 case OPC_DMTC1:
20100 check_cp1_enabled(ctx);
20101 check_insn(ctx, ISA_MIPS3);
d9224450 20102 check_mips_64(ctx);
5692c6e1
YK
20103 gen_cp1(ctx, op1, rt, rd);
20104 break;
e189e748 20105#endif
5692c6e1
YK
20106 case OPC_BC1EQZ: /* OPC_BC1ANY2 */
20107 check_cp1_enabled(ctx);
20108 if (ctx->insn_flags & ISA_MIPS32R6) {
20109 /* OPC_BC1EQZ */
31837be3 20110 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
65935f07 20111 rt, imm << 2, 4);
5692c6e1
YK
20112 } else {
20113 /* OPC_BC1ANY2 */
b8aa4598 20114 check_cop1x(ctx);
d75c135e 20115 check_insn(ctx, ASE_MIPS3D);
d75c135e 20116 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
5a5012ec 20117 (rt >> 2) & 0x7, imm << 2);
5692c6e1
YK
20118 }
20119 break;
20120 case OPC_BC1NEZ:
20121 check_cp1_enabled(ctx);
20122 check_insn(ctx, ISA_MIPS32R6);
20123 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
65935f07 20124 rt, imm << 2, 4);
5692c6e1
YK
20125 break;
20126 case OPC_BC1ANY4:
20127 check_cp1_enabled(ctx);
20128 check_insn_opc_removed(ctx, ISA_MIPS32R6);
20129 check_cop1x(ctx);
20130 check_insn(ctx, ASE_MIPS3D);
20131 /* fall through */
20132 case OPC_BC1:
20133 check_cp1_enabled(ctx);
20134 check_insn_opc_removed(ctx, ISA_MIPS32R6);
20135 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
20136 (rt >> 2) & 0x7, imm << 2);
20137 break;
20138 case OPC_PS_FMT:
e29c9628 20139 check_ps(ctx);
b6f3b233 20140 /* fall through */
5692c6e1
YK
20141 case OPC_S_FMT:
20142 case OPC_D_FMT:
20143 check_cp1_enabled(ctx);
20144 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
20145 (imm >> 8) & 0x7);
20146 break;
20147 case OPC_W_FMT:
20148 case OPC_L_FMT:
20149 {
20150 int r6_op = ctx->opcode & FOP(0x3f, 0x1f);
20151 check_cp1_enabled(ctx);
20152 if (ctx->insn_flags & ISA_MIPS32R6) {
20153 switch (r6_op) {
20154 case R6_OPC_CMP_AF_S:
20155 case R6_OPC_CMP_UN_S:
20156 case R6_OPC_CMP_EQ_S:
20157 case R6_OPC_CMP_UEQ_S:
20158 case R6_OPC_CMP_LT_S:
20159 case R6_OPC_CMP_ULT_S:
20160 case R6_OPC_CMP_LE_S:
20161 case R6_OPC_CMP_ULE_S:
20162 case R6_OPC_CMP_SAF_S:
20163 case R6_OPC_CMP_SUN_S:
20164 case R6_OPC_CMP_SEQ_S:
20165 case R6_OPC_CMP_SEUQ_S:
20166 case R6_OPC_CMP_SLT_S:
20167 case R6_OPC_CMP_SULT_S:
20168 case R6_OPC_CMP_SLE_S:
20169 case R6_OPC_CMP_SULE_S:
20170 case R6_OPC_CMP_OR_S:
20171 case R6_OPC_CMP_UNE_S:
20172 case R6_OPC_CMP_NE_S:
20173 case R6_OPC_CMP_SOR_S:
20174 case R6_OPC_CMP_SUNE_S:
20175 case R6_OPC_CMP_SNE_S:
20176 gen_r6_cmp_s(ctx, ctx->opcode & 0x1f, rt, rd, sa);
20177 break;
20178 case R6_OPC_CMP_AF_D:
20179 case R6_OPC_CMP_UN_D:
20180 case R6_OPC_CMP_EQ_D:
20181 case R6_OPC_CMP_UEQ_D:
20182 case R6_OPC_CMP_LT_D:
20183 case R6_OPC_CMP_ULT_D:
20184 case R6_OPC_CMP_LE_D:
20185 case R6_OPC_CMP_ULE_D:
20186 case R6_OPC_CMP_SAF_D:
20187 case R6_OPC_CMP_SUN_D:
20188 case R6_OPC_CMP_SEQ_D:
20189 case R6_OPC_CMP_SEUQ_D:
20190 case R6_OPC_CMP_SLT_D:
20191 case R6_OPC_CMP_SULT_D:
20192 case R6_OPC_CMP_SLE_D:
20193 case R6_OPC_CMP_SULE_D:
20194 case R6_OPC_CMP_OR_D:
20195 case R6_OPC_CMP_UNE_D:
20196 case R6_OPC_CMP_NE_D:
20197 case R6_OPC_CMP_SOR_D:
20198 case R6_OPC_CMP_SUNE_D:
20199 case R6_OPC_CMP_SNE_D:
20200 gen_r6_cmp_d(ctx, ctx->opcode & 0x1f, rt, rd, sa);
20201 break;
20202 default:
d2bfa6e6
MR
20203 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f),
20204 rt, rd, sa, (imm >> 8) & 0x7);
20205
5692c6e1 20206 break;
3f493883 20207 }
5692c6e1
YK
20208 } else {
20209 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
20210 (imm >> 8) & 0x7);
36d23958 20211 }
5692c6e1
YK
20212 break;
20213 }
20214 case OPC_BZ_V:
20215 case OPC_BNZ_V:
20216 case OPC_BZ_B:
20217 case OPC_BZ_H:
20218 case OPC_BZ_W:
20219 case OPC_BZ_D:
20220 case OPC_BNZ_B:
20221 case OPC_BNZ_H:
20222 case OPC_BNZ_W:
20223 case OPC_BNZ_D:
20224 check_insn(ctx, ASE_MSA);
20225 gen_msa_branch(env, ctx, op1);
20226 break;
20227 default:
20228 MIPS_INVAL("cp1");
9c708c7f 20229 generate_exception_end(ctx, EXCP_RI);
5692c6e1 20230 break;
6ea83fed 20231 }
4ad40f36
FB
20232 break;
20233
31837be3
YK
20234 /* Compact branches [R6] and COP2 [non-R6] */
20235 case OPC_BC: /* OPC_LWC2 */
20236 case OPC_BALC: /* OPC_SWC2 */
20237 if (ctx->insn_flags & ISA_MIPS32R6) {
20238 /* OPC_BC, OPC_BALC */
20239 gen_compute_compact_branch(ctx, op, 0, 0,
20240 sextract32(ctx->opcode << 2, 0, 28));
20241 } else {
20242 /* OPC_LWC2, OPC_SWC2 */
20243 /* COP2: Not implemented. */
20244 generate_exception_err(ctx, EXCP_CpU, 2);
20245 }
20246 break;
20247 case OPC_BEQZC: /* OPC_JIC, OPC_LDC2 */
20248 case OPC_BNEZC: /* OPC_JIALC, OPC_SDC2 */
20249 if (ctx->insn_flags & ISA_MIPS32R6) {
20250 if (rs != 0) {
20251 /* OPC_BEQZC, OPC_BNEZC */
20252 gen_compute_compact_branch(ctx, op, rs, 0,
20253 sextract32(ctx->opcode << 2, 0, 23));
20254 } else {
20255 /* OPC_JIC, OPC_JIALC */
20256 gen_compute_compact_branch(ctx, op, 0, rt, imm);
20257 }
20258 } else {
20259 /* OPC_LWC2, OPC_SWC2 */
20260 /* COP2: Not implemented. */
20261 generate_exception_err(ctx, EXCP_CpU, 2);
20262 }
4ad40f36 20263 break;
bd277fa1 20264 case OPC_CP2:
d75c135e 20265 check_insn(ctx, INSN_LOONGSON2F);
bd277fa1
RH
20266 /* Note that these instructions use different fields. */
20267 gen_loongson_multimedia(ctx, sa, rd, rt);
20268 break;
4ad40f36 20269
7a387fff 20270 case OPC_CP3:
fecd2646 20271 check_insn_opc_removed(ctx, ISA_MIPS32R6);
5ab5c041 20272 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
5e755519 20273 check_cp1_enabled(ctx);
36d23958
TS
20274 op1 = MASK_CP3(ctx->opcode);
20275 switch (op1) {
d9224450
MR
20276 case OPC_LUXC1:
20277 case OPC_SUXC1:
20278 check_insn(ctx, ISA_MIPS5 | ISA_MIPS32R2);
20279 /* Fallthrough */
5a5012ec
TS
20280 case OPC_LWXC1:
20281 case OPC_LDXC1:
5a5012ec
TS
20282 case OPC_SWXC1:
20283 case OPC_SDXC1:
d9224450 20284 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
93b12ccc 20285 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
5a5012ec 20286 break;
e0c84da7 20287 case OPC_PREFX:
d9224450 20288 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
ead9360e 20289 /* Treat as NOP. */
e0c84da7 20290 break;
5a5012ec 20291 case OPC_ALNV_PS:
d9224450
MR
20292 check_insn(ctx, ISA_MIPS5 | ISA_MIPS32R2);
20293 /* Fallthrough */
5a5012ec
TS
20294 case OPC_MADD_S:
20295 case OPC_MADD_D:
20296 case OPC_MADD_PS:
20297 case OPC_MSUB_S:
20298 case OPC_MSUB_D:
20299 case OPC_MSUB_PS:
20300 case OPC_NMADD_S:
20301 case OPC_NMADD_D:
20302 case OPC_NMADD_PS:
20303 case OPC_NMSUB_S:
20304 case OPC_NMSUB_D:
20305 case OPC_NMSUB_PS:
d9224450 20306 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
5a5012ec
TS
20307 gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
20308 break;
36d23958 20309 default:
923617a3 20310 MIPS_INVAL("cp3");
9c708c7f 20311 generate_exception_end(ctx, EXCP_RI);
36d23958
TS
20312 break;
20313 }
20314 } else {
e397ee33 20315 generate_exception_err(ctx, EXCP_CpU, 1);
7a387fff 20316 }
4ad40f36
FB
20317 break;
20318
d26bc211 20319#if defined(TARGET_MIPS64)
7a387fff 20320 /* MIPS64 opcodes */
c2e19f3c
AM
20321 case OPC_LDL:
20322 case OPC_LDR:
bf7910c6 20323 case OPC_LLD:
fecd2646 20324 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b6f3b233 20325 /* fall through */
fecd2646 20326 case OPC_LWU:
7a387fff 20327 case OPC_LD:
d75c135e 20328 check_insn(ctx, ISA_MIPS3);
5c13fdfd 20329 check_mips_64(ctx);
d75c135e 20330 gen_ld(ctx, op, rt, rs, imm);
5c13fdfd 20331 break;
c2e19f3c
AM
20332 case OPC_SDL:
20333 case OPC_SDR:
fecd2646 20334 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b6f3b233 20335 /* fall through */
7a387fff 20336 case OPC_SD:
d75c135e 20337 check_insn(ctx, ISA_MIPS3);
e189e748 20338 check_mips_64(ctx);
5c13fdfd 20339 gen_st(ctx, op, rt, rs, imm);
7a387fff 20340 break;
d66c7132 20341 case OPC_SCD:
bf7910c6 20342 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d75c135e 20343 check_insn(ctx, ISA_MIPS3);
d66c7132
AJ
20344 check_mips_64(ctx);
20345 gen_st_cond(ctx, op, rt, rs, imm);
20346 break;
31837be3
YK
20347 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC, OPC_DADDI */
20348 if (ctx->insn_flags & ISA_MIPS32R6) {
20349 /* OPC_BNVC, OPC_BNEZALC, OPC_BNEC */
20350 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
20351 } else {
20352 /* OPC_DADDI */
20353 check_insn(ctx, ISA_MIPS3);
20354 check_mips_64(ctx);
20355 gen_arith_imm(ctx, op, rt, rs, imm);
20356 }
20357 break;
324d9e32 20358 case OPC_DADDIU:
d75c135e 20359 check_insn(ctx, ISA_MIPS3);
e189e748 20360 check_mips_64(ctx);
d75c135e 20361 gen_arith_imm(ctx, op, rt, rs, imm);
7a387fff 20362 break;
31837be3
YK
20363#else
20364 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
20365 if (ctx->insn_flags & ISA_MIPS32R6) {
20366 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
20367 } else {
20368 MIPS_INVAL("major opcode");
9c708c7f 20369 generate_exception_end(ctx, EXCP_RI);
31837be3
YK
20370 }
20371 break;
6af0bf9c 20372#endif
d4ea6acd
LA
20373 case OPC_DAUI: /* OPC_JALX */
20374 if (ctx->insn_flags & ISA_MIPS32R6) {
20375#if defined(TARGET_MIPS64)
20376 /* OPC_DAUI */
20377 check_mips_64(ctx);
db77d852
LA
20378 if (rs == 0) {
20379 generate_exception(ctx, EXCP_RI);
20380 } else if (rt != 0) {
d4ea6acd
LA
20381 TCGv t0 = tcg_temp_new();
20382 gen_load_gpr(t0, rs);
20383 tcg_gen_addi_tl(cpu_gpr[rt], t0, imm << 16);
20384 tcg_temp_free(t0);
20385 }
d4ea6acd 20386#else
9c708c7f 20387 generate_exception_end(ctx, EXCP_RI);
d4ea6acd
LA
20388 MIPS_INVAL("major opcode");
20389#endif
20390 } else {
20391 /* OPC_JALX */
20392 check_insn(ctx, ASE_MIPS16 | ASE_MICROMIPS);
20393 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
b231c103 20394 gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
d4ea6acd 20395 }
364d4831 20396 break;
4c789546 20397 case OPC_MSA: /* OPC_MDMX */
7a387fff 20398 /* MDMX: Not implemented. */
4c789546 20399 gen_msa(env, ctx);
d4ea6acd
LA
20400 break;
20401 case OPC_PCREL:
20402 check_insn(ctx, ISA_MIPS32R6);
eeb3bba8 20403 gen_pcrel(ctx, ctx->opcode, ctx->base.pc_next, rs);
d4ea6acd 20404 break;
6af0bf9c 20405 default: /* Invalid */
923617a3 20406 MIPS_INVAL("major opcode");
9c708c7f 20407 generate_exception_end(ctx, EXCP_RI);
6af0bf9c
FB
20408 break;
20409 }
6af0bf9c
FB
20410}
20411
18f440ed 20412static void mips_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
6af0bf9c 20413{
18f440ed 20414 DisasContext *ctx = container_of(dcbase, DisasContext, base);
9c489ea6 20415 CPUMIPSState *env = cs->env_ptr;
12be9258 20416
18f440ed 20417 ctx->page_start = ctx->base.pc_first & TARGET_PAGE_MASK;
12be9258
EC
20418 ctx->saved_pc = -1;
20419 ctx->insn_flags = env->insn_flags;
20420 ctx->CP0_Config1 = env->CP0_Config1;
20421 ctx->btarget = 0;
20422 ctx->kscrexist = (env->CP0_Config4 >> CP0C4_KScrExist) & 0xff;
20423 ctx->rxi = (env->CP0_Config3 >> CP0C3_RXI) & 1;
20424 ctx->ie = (env->CP0_Config4 >> CP0C4_IE) & 3;
20425 ctx->bi = (env->CP0_Config3 >> CP0C3_BI) & 1;
20426 ctx->bp = (env->CP0_Config3 >> CP0C3_BP) & 1;
20427 ctx->PAMask = env->PAMask;
20428 ctx->mvh = (env->CP0_Config5 >> CP0C5_MVH) & 1;
20429 ctx->eva = (env->CP0_Config5 >> CP0C5_EVA) & 1;
20430 ctx->sc = (env->CP0_Config3 >> CP0C3_SC) & 1;
20431 ctx->CP0_LLAddr_shift = env->CP0_LLAddr_shift;
20432 ctx->cmgcr = (env->CP0_Config3 >> CP0C3_CMGCR) & 1;
4ad40f36 20433 /* Restore delay slot state from the tb context. */
12be9258
EC
20434 ctx->hflags = (uint32_t)ctx->base.tb->flags; /* FIXME: maybe use 64 bits? */
20435 ctx->ulri = (env->CP0_Config3 >> CP0C3_ULRI) & 1;
20436 ctx->ps = ((env->active_fpu.fcr0 >> FCR0_PS) & 1) ||
e29c9628 20437 (env->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F));
12be9258
EC
20438 ctx->vp = (env->CP0_Config5 >> CP0C5_VP) & 1;
20439 ctx->mrp = (env->CP0_Config5 >> CP0C5_MRP) & 1;
20440 ctx->nan2008 = (env->active_fpu.fcr31 >> FCR31_NAN2008) & 1;
20441 ctx->abs2008 = (env->active_fpu.fcr31 >> FCR31_ABS2008) & 1;
20442 restore_cpu_state(env, ctx);
932e71cd 20443#ifdef CONFIG_USER_ONLY
12be9258 20444 ctx->mem_idx = MIPS_HFLAG_UM;
932e71cd 20445#else
12be9258 20446 ctx->mem_idx = hflags_mmu_index(ctx->hflags);
932e71cd 20447#endif
12be9258
EC
20448 ctx->default_tcg_memop_mask = (ctx->insn_flags & ISA_MIPS32R6) ?
20449 MO_UNALN : MO_ALIGN;
190ce7fb 20450
18f440ed
EC
20451 LOG_DISAS("\ntb %p idx %d hflags %04x\n", ctx->base.tb, ctx->mem_idx,
20452 ctx->hflags);
20453}
12be9258 20454
18f440ed
EC
20455static void mips_tr_tb_start(DisasContextBase *dcbase, CPUState *cs)
20456{
20457}
b933066a 20458
18f440ed
EC
20459static void mips_tr_insn_start(DisasContextBase *dcbase, CPUState *cs)
20460{
20461 DisasContext *ctx = container_of(dcbase, DisasContext, base);
c9602061 20462
18f440ed
EC
20463 tcg_gen_insn_start(ctx->base.pc_next, ctx->hflags & MIPS_HFLAG_BMASK,
20464 ctx->btarget);
20465}
31837be3 20466
18f440ed
EC
20467static bool mips_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cs,
20468 const CPUBreakpoint *bp)
20469{
20470 DisasContext *ctx = container_of(dcbase, DisasContext, base);
c9602061 20471
18f440ed
EC
20472 save_cpu_state(ctx, 1);
20473 ctx->base.is_jmp = DISAS_NORETURN;
20474 gen_helper_raise_exception_debug(cpu_env);
20475 /* The address covered by the breakpoint must be included in
20476 [tb->pc, tb->pc + tb->size) in order to for it to be
20477 properly cleared -- thus we increment the PC here so that
20478 the logic setting tb->size below does the right thing. */
20479 ctx->base.pc_next += 4;
20480 return true;
20481}
4ad40f36 20482
18f440ed
EC
20483static void mips_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
20484{
20485 CPUMIPSState *env = cs->env_ptr;
20486 DisasContext *ctx = container_of(dcbase, DisasContext, base);
20487 int insn_bytes;
20488 int is_slot;
4ad40f36 20489
18f440ed
EC
20490 is_slot = ctx->hflags & MIPS_HFLAG_BMASK;
20491 if (!(ctx->hflags & MIPS_HFLAG_M16)) {
20492 ctx->opcode = cpu_ldl_code(env, ctx->base.pc_next);
20493 insn_bytes = 4;
20494 decode_opc(env, ctx);
20495 } else if (ctx->insn_flags & ASE_MICROMIPS) {
20496 ctx->opcode = cpu_lduw_code(env, ctx->base.pc_next);
20497 insn_bytes = decode_micromips_opc(env, ctx);
20498 } else if (ctx->insn_flags & ASE_MIPS16) {
20499 ctx->opcode = cpu_lduw_code(env, ctx->base.pc_next);
20500 insn_bytes = decode_mips16_opc(env, ctx);
20501 } else {
20502 generate_exception_end(ctx, EXCP_RI);
20503 g_assert(ctx->base.is_jmp == DISAS_NORETURN);
20504 return;
20505 }
faf7aaa9 20506
18f440ed
EC
20507 if (ctx->hflags & MIPS_HFLAG_BMASK) {
20508 if (!(ctx->hflags & (MIPS_HFLAG_BDS16 | MIPS_HFLAG_BDS32 |
20509 MIPS_HFLAG_FBNSLOT))) {
20510 /* force to generate branch as there is neither delay nor
20511 forbidden slot */
20512 is_slot = 1;
20513 }
20514 if ((ctx->hflags & MIPS_HFLAG_M16) &&
20515 (ctx->hflags & MIPS_HFLAG_FBNSLOT)) {
20516 /* Force to generate branch as microMIPS R6 doesn't restrict
20517 branches in the forbidden slot. */
20518 is_slot = 1;
eeb3bba8 20519 }
18f440ed
EC
20520 }
20521 if (is_slot) {
20522 gen_branch(ctx, insn_bytes);
20523 }
20524 ctx->base.pc_next += insn_bytes;
1b530a6d 20525
18f440ed
EC
20526 if (ctx->base.is_jmp != DISAS_NEXT) {
20527 return;
6af0bf9c 20528 }
18f440ed
EC
20529 /* Execute a branch and its delay slot as a single instruction.
20530 This is what GDB expects and is consistent with what the
20531 hardware does (e.g. if a delay slot instruction faults, the
20532 reported PC is the PC of the branch). */
20533 if (ctx->base.singlestep_enabled &&
20534 (ctx->hflags & MIPS_HFLAG_BMASK) == 0) {
20535 ctx->base.is_jmp = DISAS_TOO_MANY;
20536 }
20537 if (ctx->base.pc_next - ctx->page_start >= TARGET_PAGE_SIZE) {
20538 ctx->base.is_jmp = DISAS_TOO_MANY;
ed2803da 20539 }
18f440ed
EC
20540}
20541
20542static void mips_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
20543{
20544 DisasContext *ctx = container_of(dcbase, DisasContext, base);
20545
12be9258
EC
20546 if (ctx->base.singlestep_enabled && ctx->base.is_jmp != DISAS_NORETURN) {
20547 save_cpu_state(ctx, ctx->base.is_jmp != DISAS_EXIT);
9c708c7f 20548 gen_helper_raise_exception_debug(cpu_env);
16c00cb2 20549 } else {
12be9258 20550 switch (ctx->base.is_jmp) {
b28425ba 20551 case DISAS_STOP:
12be9258 20552 gen_save_pc(ctx->base.pc_next);
cd314a7d 20553 tcg_gen_lookup_and_goto_ptr();
df1561e2 20554 break;
b28425ba 20555 case DISAS_NEXT:
18f440ed 20556 case DISAS_TOO_MANY:
12be9258
EC
20557 save_cpu_state(ctx, 0);
20558 gen_goto_tb(ctx, 0, ctx->base.pc_next);
16c00cb2 20559 break;
b28425ba 20560 case DISAS_EXIT:
07ea28b4 20561 tcg_gen_exit_tb(NULL, 0);
16c00cb2 20562 break;
b28425ba 20563 case DISAS_NORETURN:
5a5012ec 20564 break;
18f440ed
EC
20565 default:
20566 g_assert_not_reached();
6958549d 20567 }
6af0bf9c 20568 }
18f440ed
EC
20569}
20570
20571static void mips_tr_disas_log(const DisasContextBase *dcbase, CPUState *cs)
20572{
20573 qemu_log("IN: %s\n", lookup_symbol(dcbase->pc_first));
20574 log_target_disas(cs, dcbase->pc_first, dcbase->tb->size);
20575}
20576
20577static const TranslatorOps mips_tr_ops = {
20578 .init_disas_context = mips_tr_init_disas_context,
20579 .tb_start = mips_tr_tb_start,
20580 .insn_start = mips_tr_insn_start,
20581 .breakpoint_check = mips_tr_breakpoint_check,
20582 .translate_insn = mips_tr_translate_insn,
20583 .tb_stop = mips_tr_tb_stop,
20584 .disas_log = mips_tr_disas_log,
20585};
20586
20587void gen_intermediate_code(CPUState *cs, struct TranslationBlock *tb)
20588{
20589 DisasContext ctx;
20590
20591 translator_loop(&mips_tr_ops, &ctx.base, cs, tb);
6af0bf9c
FB
20592}
20593
7db13fae 20594static void fpu_dump_state(CPUMIPSState *env, FILE *f, fprintf_function fpu_fprintf,
8706c382 20595 int flags)
6ea83fed
FB
20596{
20597 int i;
5e755519 20598 int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
5a5012ec 20599
2a5612e6
SW
20600#define printfpr(fp) \
20601 do { \
20602 if (is_fpu64) \
20603 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
20604 " fd:%13g fs:%13g psu: %13g\n", \
20605 (fp)->w[FP_ENDIAN_IDX], (fp)->d, \
20606 (double)(fp)->fd, \
20607 (double)(fp)->fs[FP_ENDIAN_IDX], \
20608 (double)(fp)->fs[!FP_ENDIAN_IDX]); \
20609 else { \
20610 fpr_t tmp; \
20611 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
20612 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
20613 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
20614 " fd:%13g fs:%13g psu:%13g\n", \
20615 tmp.w[FP_ENDIAN_IDX], tmp.d, \
20616 (double)tmp.fd, \
20617 (double)tmp.fs[FP_ENDIAN_IDX], \
20618 (double)tmp.fs[!FP_ENDIAN_IDX]); \
20619 } \
6ea83fed
FB
20620 } while(0)
20621
5a5012ec 20622
9a78eead
SW
20623 fpu_fprintf(f, "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%02x\n",
20624 env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64,
f01be154 20625 get_float_exception_flags(&env->active_fpu.fp_status));
5a5012ec
TS
20626 for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
20627 fpu_fprintf(f, "%3s: ", fregnames[i]);
f01be154 20628 printfpr(&env->active_fpu.fpr[i]);
6ea83fed
FB
20629 }
20630
20631#undef printfpr
20632}
20633
878096ee
AF
20634void mips_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
20635 int flags)
6af0bf9c 20636{
878096ee
AF
20637 MIPSCPU *cpu = MIPS_CPU(cs);
20638 CPUMIPSState *env = &cpu->env;
6af0bf9c 20639 int i;
3b46e624 20640
a7200c9f
SW
20641 cpu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
20642 " LO=0x" TARGET_FMT_lx " ds %04x "
20643 TARGET_FMT_lx " " TARGET_FMT_ld "\n",
3d5be870
TS
20644 env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
20645 env->hflags, env->btarget, env->bcond);
6af0bf9c
FB
20646 for (i = 0; i < 32; i++) {
20647 if ((i & 3) == 0)
20648 cpu_fprintf(f, "GPR%02d:", i);
b5dc7732 20649 cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
6af0bf9c
FB
20650 if ((i & 3) == 3)
20651 cpu_fprintf(f, "\n");
20652 }
568b600d 20653
3594c774 20654 cpu_fprintf(f, "CP0 Status 0x%08x Cause 0x%08x EPC 0x" TARGET_FMT_lx "\n",
5e755519 20655 env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
284b731a
LA
20656 cpu_fprintf(f, " Config0 0x%08x Config1 0x%08x LLAddr 0x%016"
20657 PRIx64 "\n",
5499b6ff 20658 env->CP0_Config0, env->CP0_Config1, env->lladdr);
27e1fb13
MR
20659 cpu_fprintf(f, " Config2 0x%08x Config3 0x%08x\n",
20660 env->CP0_Config2, env->CP0_Config3);
20661 cpu_fprintf(f, " Config4 0x%08x Config5 0x%08x\n",
20662 env->CP0_Config4, env->CP0_Config5);
1cc5af69 20663 if ((flags & CPU_DUMP_FPU) && (env->hflags & MIPS_HFLAG_FPU)) {
7a387fff 20664 fpu_dump_state(env, f, cpu_fprintf, flags);
1cc5af69 20665 }
6af0bf9c
FB
20666}
20667
78ce64f4 20668void mips_tcg_init(void)
39454628 20669{
f01be154 20670 int i;
39454628 20671
f764718d 20672 cpu_gpr[0] = NULL;
bb928dbe 20673 for (i = 1; i < 32; i++)
e1ccc054 20674 cpu_gpr[i] = tcg_global_mem_new(cpu_env,
7db13fae 20675 offsetof(CPUMIPSState, active_tc.gpr[i]),
4b2eb8d2 20676 regnames[i]);
d73ee8a2 20677
863f264d
YK
20678 for (i = 0; i < 32; i++) {
20679 int off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[0]);
20680 msa_wr_d[i * 2] =
e1ccc054 20681 tcg_global_mem_new_i64(cpu_env, off, msaregnames[i * 2]);
cb269f27
YK
20682 /* The scalar floating-point unit (FPU) registers are mapped on
20683 * the MSA vector registers. */
20684 fpu_f64[i] = msa_wr_d[i * 2];
863f264d
YK
20685 off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[1]);
20686 msa_wr_d[i * 2 + 1] =
e1ccc054 20687 tcg_global_mem_new_i64(cpu_env, off, msaregnames[i * 2 + 1]);
863f264d
YK
20688 }
20689
e1ccc054 20690 cpu_PC = tcg_global_mem_new(cpu_env,
7db13fae 20691 offsetof(CPUMIPSState, active_tc.PC), "PC");
4b2eb8d2 20692 for (i = 0; i < MIPS_DSP_ACC; i++) {
e1ccc054 20693 cpu_HI[i] = tcg_global_mem_new(cpu_env,
7db13fae 20694 offsetof(CPUMIPSState, active_tc.HI[i]),
4b2eb8d2 20695 regnames_HI[i]);
e1ccc054 20696 cpu_LO[i] = tcg_global_mem_new(cpu_env,
7db13fae 20697 offsetof(CPUMIPSState, active_tc.LO[i]),
4b2eb8d2 20698 regnames_LO[i]);
4b2eb8d2 20699 }
e1ccc054 20700 cpu_dspctrl = tcg_global_mem_new(cpu_env,
7db13fae 20701 offsetof(CPUMIPSState, active_tc.DSPControl),
4b2eb8d2 20702 "DSPControl");
e1ccc054 20703 bcond = tcg_global_mem_new(cpu_env,
7db13fae 20704 offsetof(CPUMIPSState, bcond), "bcond");
e1ccc054 20705 btarget = tcg_global_mem_new(cpu_env,
7db13fae 20706 offsetof(CPUMIPSState, btarget), "btarget");
e1ccc054 20707 hflags = tcg_global_mem_new_i32(cpu_env,
7db13fae 20708 offsetof(CPUMIPSState, hflags), "hflags");
41db4607 20709
e1ccc054 20710 fpu_fcr0 = tcg_global_mem_new_i32(cpu_env,
7db13fae 20711 offsetof(CPUMIPSState, active_fpu.fcr0),
a7812ae4 20712 "fcr0");
e1ccc054 20713 fpu_fcr31 = tcg_global_mem_new_i32(cpu_env,
7db13fae 20714 offsetof(CPUMIPSState, active_fpu.fcr31),
a7812ae4 20715 "fcr31");
39454628
TS
20716}
20717
5b27a92d 20718#include "translate_init.inc.c"
aaed909a 20719
27e38392
PMD
20720void cpu_mips_realize_env(CPUMIPSState *env)
20721{
20722 env->exception_base = (int32_t)0xBFC00000;
20723
20724#ifndef CONFIG_USER_ONLY
20725 mmu_init(env, env->cpu_model);
20726#endif
20727 fpu_init(env, env->cpu_model);
20728 mvp_init(env, env->cpu_model);
20729}
20730
a7519f2b 20731bool cpu_supports_cps_smp(const char *cpu_type)
bff384a4 20732{
a7519f2b
IM
20733 const MIPSCPUClass *mcc = MIPS_CPU_CLASS(object_class_by_name(cpu_type));
20734 return (mcc->cpu_def->CP0_Config3 & (1 << CP0C3_CMGCR)) != 0;
bff384a4
LA
20735}
20736
a7519f2b 20737bool cpu_supports_isa(const char *cpu_type, unsigned int isa)
bed9e5ce 20738{
a7519f2b
IM
20739 const MIPSCPUClass *mcc = MIPS_CPU_CLASS(object_class_by_name(cpu_type));
20740 return (mcc->cpu_def->insn_flags & isa) != 0;
bed9e5ce
PB
20741}
20742
89777fd1
LA
20743void cpu_set_exception_base(int vp_index, target_ulong address)
20744{
20745 MIPSCPU *vp = MIPS_CPU(qemu_get_cpu(vp_index));
20746 vp->env.exception_base = address;
20747}
20748
1bba0dc9 20749void cpu_state_reset(CPUMIPSState *env)
6ae81775 20750{
55e5c285
AF
20751 MIPSCPU *cpu = mips_env_get_cpu(env);
20752 CPUState *cs = CPU(cpu);
6ae81775 20753
51cc2e78
BS
20754 /* Reset registers to their default values */
20755 env->CP0_PRid = env->cpu_model->CP0_PRid;
20756 env->CP0_Config0 = env->cpu_model->CP0_Config0;
20757#ifdef TARGET_WORDS_BIGENDIAN
20758 env->CP0_Config0 |= (1 << CP0C0_BE);
20759#endif
20760 env->CP0_Config1 = env->cpu_model->CP0_Config1;
20761 env->CP0_Config2 = env->cpu_model->CP0_Config2;
20762 env->CP0_Config3 = env->cpu_model->CP0_Config3;
b4160af1
PJ
20763 env->CP0_Config4 = env->cpu_model->CP0_Config4;
20764 env->CP0_Config4_rw_bitmask = env->cpu_model->CP0_Config4_rw_bitmask;
b4dd99a3
PJ
20765 env->CP0_Config5 = env->cpu_model->CP0_Config5;
20766 env->CP0_Config5_rw_bitmask = env->cpu_model->CP0_Config5_rw_bitmask;
51cc2e78
BS
20767 env->CP0_Config6 = env->cpu_model->CP0_Config6;
20768 env->CP0_Config7 = env->cpu_model->CP0_Config7;
2a6e32dd
AJ
20769 env->CP0_LLAddr_rw_bitmask = env->cpu_model->CP0_LLAddr_rw_bitmask
20770 << env->cpu_model->CP0_LLAddr_shift;
20771 env->CP0_LLAddr_shift = env->cpu_model->CP0_LLAddr_shift;
51cc2e78
BS
20772 env->SYNCI_Step = env->cpu_model->SYNCI_Step;
20773 env->CCRes = env->cpu_model->CCRes;
20774 env->CP0_Status_rw_bitmask = env->cpu_model->CP0_Status_rw_bitmask;
20775 env->CP0_TCStatus_rw_bitmask = env->cpu_model->CP0_TCStatus_rw_bitmask;
20776 env->CP0_SRSCtl = env->cpu_model->CP0_SRSCtl;
20777 env->current_tc = 0;
20778 env->SEGBITS = env->cpu_model->SEGBITS;
20779 env->SEGMask = (target_ulong)((1ULL << env->cpu_model->SEGBITS) - 1);
20780#if defined(TARGET_MIPS64)
20781 if (env->cpu_model->insn_flags & ISA_MIPS3) {
20782 env->SEGMask |= 3ULL << 62;
20783 }
20784#endif
20785 env->PABITS = env->cpu_model->PABITS;
51cc2e78
BS
20786 env->CP0_SRSConf0_rw_bitmask = env->cpu_model->CP0_SRSConf0_rw_bitmask;
20787 env->CP0_SRSConf0 = env->cpu_model->CP0_SRSConf0;
20788 env->CP0_SRSConf1_rw_bitmask = env->cpu_model->CP0_SRSConf1_rw_bitmask;
20789 env->CP0_SRSConf1 = env->cpu_model->CP0_SRSConf1;
20790 env->CP0_SRSConf2_rw_bitmask = env->cpu_model->CP0_SRSConf2_rw_bitmask;
20791 env->CP0_SRSConf2 = env->cpu_model->CP0_SRSConf2;
20792 env->CP0_SRSConf3_rw_bitmask = env->cpu_model->CP0_SRSConf3_rw_bitmask;
20793 env->CP0_SRSConf3 = env->cpu_model->CP0_SRSConf3;
20794 env->CP0_SRSConf4_rw_bitmask = env->cpu_model->CP0_SRSConf4_rw_bitmask;
20795 env->CP0_SRSConf4 = env->cpu_model->CP0_SRSConf4;
7207c7f9
LA
20796 env->CP0_PageGrain_rw_bitmask = env->cpu_model->CP0_PageGrain_rw_bitmask;
20797 env->CP0_PageGrain = env->cpu_model->CP0_PageGrain;
74dbf824 20798 env->CP0_EBaseWG_rw_bitmask = env->cpu_model->CP0_EBaseWG_rw_bitmask;
f1cb0951 20799 env->active_fpu.fcr0 = env->cpu_model->CP1_fcr0;
599bc5e8 20800 env->active_fpu.fcr31_rw_bitmask = env->cpu_model->CP1_fcr31_rw_bitmask;
ba5c79f2 20801 env->active_fpu.fcr31 = env->cpu_model->CP1_fcr31;
863f264d 20802 env->msair = env->cpu_model->MSAIR;
51cc2e78
BS
20803 env->insn_flags = env->cpu_model->insn_flags;
20804
0eaef5aa 20805#if defined(CONFIG_USER_ONLY)
03e6e501 20806 env->CP0_Status = (MIPS_HFLAG_UM << CP0St_KSU);
68473f15
RH
20807# ifdef TARGET_MIPS64
20808 /* Enable 64-bit register mode. */
20809 env->CP0_Status |= (1 << CP0St_PX);
20810# endif
20811# ifdef TARGET_ABI_MIPSN64
20812 /* Enable 64-bit address mode. */
20813 env->CP0_Status |= (1 << CP0St_UX);
20814# endif
94159135
MI
20815 /* Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
20816 hardware registers. */
20817 env->CP0_HWREna |= 0x0000000F;
91a75935 20818 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
03e6e501 20819 env->CP0_Status |= (1 << CP0St_CU1);
91a75935 20820 }
6f0af304
PJ
20821 if (env->CP0_Config3 & (1 << CP0C3_DSPP)) {
20822 env->CP0_Status |= (1 << CP0St_MX);
853c3240 20823 }
4d66261f
PJ
20824# if defined(TARGET_MIPS64)
20825 /* For MIPS64, init FR bit to 1 if FPU unit is there and bit is writable. */
20826 if ((env->CP0_Config1 & (1 << CP0C1_FP)) &&
20827 (env->CP0_Status_rw_bitmask & (1 << CP0St_FR))) {
68473f15
RH
20828 env->CP0_Status |= (1 << CP0St_FR);
20829 }
4d66261f 20830# endif
932e71cd
AJ
20831#else
20832 if (env->hflags & MIPS_HFLAG_BMASK) {
20833 /* If the exception was raised from a delay slot,
20834 come back to the jump. */
c3577479
MR
20835 env->CP0_ErrorEPC = (env->active_tc.PC
20836 - (env->hflags & MIPS_HFLAG_B16 ? 2 : 4));
aa328add 20837 } else {
932e71cd
AJ
20838 env->CP0_ErrorEPC = env->active_tc.PC;
20839 }
89777fd1 20840 env->active_tc.PC = env->exception_base;
51cc2e78
BS
20841 env->CP0_Random = env->tlb->nb_tlb - 1;
20842 env->tlb->tlb_in_use = env->tlb->nb_tlb;
932e71cd 20843 env->CP0_Wired = 0;
01bc435b 20844 env->CP0_GlobalNumber = (cs->cpu_index & 0xFF) << CP0GN_VPId;
0a2672b7 20845 env->CP0_EBase = (cs->cpu_index & 0x3FF);
d3d93c6c 20846 if (mips_um_ksegs_enabled()) {
0a2672b7
JH
20847 env->CP0_EBase |= 0x40000000;
20848 } else {
74dbf824 20849 env->CP0_EBase |= (int32_t)0x80000000;
0a2672b7 20850 }
c870e3f5
YK
20851 if (env->CP0_Config3 & (1 << CP0C3_CMGCR)) {
20852 env->CP0_CMGCRBase = 0x1fbf8000 >> 4;
20853 }
a0c80608
PB
20854 env->CP0_EntryHi_ASID_mask = (env->CP0_Config4 & (1 << CP0C4_AE)) ?
20855 0x3ff : 0xff;
932e71cd
AJ
20856 env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
20857 /* vectored interrupts not implemented, timer on int 7,
20858 no performance counters. */
20859 env->CP0_IntCtl = 0xe0000000;
20860 {
20861 int i;
20862
20863 for (i = 0; i < 7; i++) {
20864 env->CP0_WatchLo[i] = 0;
20865 env->CP0_WatchHi[i] = 0x80000000;
fd88b6ab 20866 }
932e71cd
AJ
20867 env->CP0_WatchLo[7] = 0;
20868 env->CP0_WatchHi[7] = 0;
fd88b6ab 20869 }
932e71cd
AJ
20870 /* Count register increments in debug mode, EJTAG version 1 */
20871 env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
9e56e756 20872
4b69c7e2
JH
20873 cpu_mips_store_count(env, 1);
20874
9e56e756
EI
20875 if (env->CP0_Config3 & (1 << CP0C3_MT)) {
20876 int i;
20877
20878 /* Only TC0 on VPE 0 starts as active. */
20879 for (i = 0; i < ARRAY_SIZE(env->tcs); i++) {
55e5c285 20880 env->tcs[i].CP0_TCBind = cs->cpu_index << CP0TCBd_CurVPE;
9e56e756
EI
20881 env->tcs[i].CP0_TCHalt = 1;
20882 }
20883 env->active_tc.CP0_TCHalt = 1;
259186a7 20884 cs->halted = 1;
9e56e756 20885
55e5c285 20886 if (cs->cpu_index == 0) {
9e56e756
EI
20887 /* VPE0 starts up enabled. */
20888 env->mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
20889 env->CP0_VPEConf0 |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
20890
20891 /* TC0 starts up unhalted. */
259186a7 20892 cs->halted = 0;
9e56e756
EI
20893 env->active_tc.CP0_TCHalt = 0;
20894 env->tcs[0].CP0_TCHalt = 0;
20895 /* With thread 0 active. */
20896 env->active_tc.CP0_TCStatus = (1 << CP0TCSt_A);
20897 env->tcs[0].CP0_TCStatus = (1 << CP0TCSt_A);
20898 }
20899 }
cec56a73
JH
20900
20901 /*
20902 * Configure default legacy segmentation control. We use this regardless of
20903 * whether segmentation control is presented to the guest.
20904 */
20905 /* KSeg3 (seg0 0xE0000000..0xFFFFFFFF) */
20906 env->CP0_SegCtl0 = (CP0SC_AM_MK << CP0SC_AM);
20907 /* KSeg2 (seg1 0xC0000000..0xDFFFFFFF) */
20908 env->CP0_SegCtl0 |= ((CP0SC_AM_MSK << CP0SC_AM)) << 16;
20909 /* KSeg1 (seg2 0xA0000000..0x9FFFFFFF) */
20910 env->CP0_SegCtl1 = (0 << CP0SC_PA) | (CP0SC_AM_UK << CP0SC_AM) |
20911 (2 << CP0SC_C);
20912 /* KSeg0 (seg3 0x80000000..0x9FFFFFFF) */
20913 env->CP0_SegCtl1 |= ((0 << CP0SC_PA) | (CP0SC_AM_UK << CP0SC_AM) |
20914 (3 << CP0SC_C)) << 16;
20915 /* USeg (seg4 0x40000000..0x7FFFFFFF) */
20916 env->CP0_SegCtl2 = (2 << CP0SC_PA) | (CP0SC_AM_MUSK << CP0SC_AM) |
20917 (1 << CP0SC_EU) | (2 << CP0SC_C);
20918 /* USeg (seg5 0x00000000..0x3FFFFFFF) */
20919 env->CP0_SegCtl2 |= ((0 << CP0SC_PA) | (CP0SC_AM_MUSK << CP0SC_AM) |
20920 (1 << CP0SC_EU) | (2 << CP0SC_C)) << 16;
20921 /* XKPhys (note, SegCtl2.XR = 0, so XAM won't be used) */
20922 env->CP0_SegCtl1 |= (CP0SC_AM_UK << CP0SC1_XAM);
51cc2e78 20923#endif
ddc584bd
LA
20924 if ((env->insn_flags & ISA_MIPS32R6) &&
20925 (env->active_fpu.fcr0 & (1 << FCR0_F64))) {
20926 /* Status.FR = 0 mode in 64-bit FPU not allowed in R6 */
20927 env->CP0_Status |= (1 << CP0St_FR);
20928 }
20929
0305d194
YK
20930 if (env->CP0_Config3 & (1 << CP0C3_ISA)) {
20931 /* microMIPS on reset when Config3.ISA == {1, 3} */
20932 env->hflags |= MIPS_HFLAG_M16;
20933 }
20934
863f264d
YK
20935 /* MSA */
20936 if (env->CP0_Config3 & (1 << CP0C3_MSAP)) {
20937 msa_reset(env);
20938 }
20939
03e6e501 20940 compute_hflags(env);
599bc5e8 20941 restore_fp_status(env);
e117f526 20942 restore_pamask(env);
27103424 20943 cs->exception_index = EXCP_NONE;
3b3c1694
LA
20944
20945 if (semihosting_get_argc()) {
20946 /* UHI interface can be used to obtain argc and argv */
20947 env->active_tc.gpr[4] = -1;
20948 }
6af0bf9c 20949}
d2856f1a 20950
bad729e2
RH
20951void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb,
20952 target_ulong *data)
d2856f1a 20953{
bad729e2 20954 env->active_tc.PC = data[0];
d2856f1a 20955 env->hflags &= ~MIPS_HFLAG_BMASK;
bad729e2 20956 env->hflags |= data[1];
4636401d
AJ
20957 switch (env->hflags & MIPS_HFLAG_BMASK_BASE) {
20958 case MIPS_HFLAG_BR:
20959 break;
20960 case MIPS_HFLAG_BC:
20961 case MIPS_HFLAG_BL:
20962 case MIPS_HFLAG_B:
bad729e2 20963 env->btarget = data[2];
4636401d
AJ
20964 break;
20965 }
d2856f1a 20966}