]> git.ipfire.org Git - thirdparty/qemu.git/blame - target/mips/translate.c
target/mips: Add CP0 BadInstrX register
[thirdparty/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;
25beba9b
SM
5331 case 3:
5332 CP0_CHECK(ctx->bi);
5333 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrX));
5334 tcg_gen_andi_tl(arg, arg, ~0xffff);
5335 rn = "BadInstrX";
5336 break;
5337 default:
f31b035a 5338 goto cp0_unimplemented;
aea14095 5339 }
873eb012
TS
5340 break;
5341 case 9:
7a387fff
TS
5342 switch (sel) {
5343 case 0:
2e70f6ef 5344 /* Mark as an IO operation because we read the time. */
eeb3bba8 5345 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
2e70f6ef 5346 gen_io_start();
bd79255d 5347 }
895c2d04 5348 gen_helper_mfc0_count(arg, cpu_env);
eeb3bba8 5349 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
2e70f6ef 5350 gen_io_end();
2e70f6ef 5351 }
55807224 5352 /* Break the TB to be able to take timer interrupts immediately
b28425ba
EC
5353 after reading count. DISAS_STOP isn't sufficient, we need to
5354 ensure we break completely out of translated code. */
eeb3bba8
EC
5355 gen_save_pc(ctx->base.pc_next + 4);
5356 ctx->base.is_jmp = DISAS_EXIT;
2423f660
TS
5357 rn = "Count";
5358 break;
5359 /* 6,7 are implementation dependent */
7a387fff 5360 default:
f31b035a 5361 goto cp0_unimplemented;
2423f660 5362 }
873eb012
TS
5363 break;
5364 case 10:
7a387fff
TS
5365 switch (sel) {
5366 case 0:
7db13fae 5367 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
d9bea114 5368 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
5369 rn = "EntryHi";
5370 break;
7a387fff 5371 default:
f31b035a 5372 goto cp0_unimplemented;
1579a72e 5373 }
873eb012
TS
5374 break;
5375 case 11:
7a387fff
TS
5376 switch (sel) {
5377 case 0:
7db13fae 5378 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
2423f660
TS
5379 rn = "Compare";
5380 break;
5381 /* 6,7 are implementation dependent */
7a387fff 5382 default:
f31b035a 5383 goto cp0_unimplemented;
2423f660 5384 }
873eb012
TS
5385 break;
5386 case 12:
7a387fff
TS
5387 switch (sel) {
5388 case 0:
7db13fae 5389 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
2423f660
TS
5390 rn = "Status";
5391 break;
7a387fff 5392 case 1:
d75c135e 5393 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5394 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
2423f660
TS
5395 rn = "IntCtl";
5396 break;
7a387fff 5397 case 2:
d75c135e 5398 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5399 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
2423f660
TS
5400 rn = "SRSCtl";
5401 break;
7a387fff 5402 case 3:
d75c135e 5403 check_insn(ctx, ISA_MIPS32R2);
7db13fae 5404 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
2423f660 5405 rn = "SRSMap";
fd88b6ab 5406 break;
7a387fff 5407 default:
f31b035a 5408 goto cp0_unimplemented;
7a387fff 5409 }
873eb012
TS
5410 break;
5411 case 13:
7a387fff
TS
5412 switch (sel) {
5413 case 0:
7db13fae 5414 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
2423f660
TS
5415 rn = "Cause";
5416 break;
7a387fff 5417 default:
f31b035a 5418 goto cp0_unimplemented;
7a387fff 5419 }
873eb012
TS
5420 break;
5421 case 14:
7a387fff
TS
5422 switch (sel) {
5423 case 0:
7db13fae 5424 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
d9bea114 5425 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
5426 rn = "EPC";
5427 break;
7a387fff 5428 default:
f31b035a 5429 goto cp0_unimplemented;
1579a72e 5430 }
873eb012
TS
5431 break;
5432 case 15:
7a387fff
TS
5433 switch (sel) {
5434 case 0:
7db13fae 5435 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
2423f660
TS
5436 rn = "PRid";
5437 break;
7a387fff 5438 case 1:
d75c135e 5439 check_insn(ctx, ISA_MIPS32R2);
74dbf824
JH
5440 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EBase));
5441 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
5442 rn = "EBase";
5443 break;
c870e3f5
YK
5444 case 3:
5445 check_insn(ctx, ISA_MIPS32R2);
5446 CP0_CHECK(ctx->cmgcr);
5447 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase));
5448 tcg_gen_ext32s_tl(arg, arg);
5449 rn = "CMGCRBase";
5450 break;
7a387fff 5451 default:
f31b035a 5452 goto cp0_unimplemented;
7a387fff 5453 }
873eb012
TS
5454 break;
5455 case 16:
5456 switch (sel) {
5457 case 0:
7db13fae 5458 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
873eb012
TS
5459 rn = "Config";
5460 break;
5461 case 1:
7db13fae 5462 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
873eb012
TS
5463 rn = "Config1";
5464 break;
7a387fff 5465 case 2:
7db13fae 5466 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
7a387fff
TS
5467 rn = "Config2";
5468 break;
5469 case 3:
7db13fae 5470 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
7a387fff
TS
5471 rn = "Config3";
5472 break;
b4160af1
PJ
5473 case 4:
5474 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
5475 rn = "Config4";
5476 break;
b4dd99a3
PJ
5477 case 5:
5478 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
5479 rn = "Config5";
5480 break;
e397ee33
TS
5481 /* 6,7 are implementation dependent */
5482 case 6:
7db13fae 5483 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
e397ee33
TS
5484 rn = "Config6";
5485 break;
5486 case 7:
7db13fae 5487 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
e397ee33
TS
5488 rn = "Config7";
5489 break;
873eb012 5490 default:
f31b035a 5491 goto cp0_unimplemented;
873eb012
TS
5492 }
5493 break;
5494 case 17:
7a387fff
TS
5495 switch (sel) {
5496 case 0:
895c2d04 5497 gen_helper_mfc0_lladdr(arg, cpu_env);
2423f660
TS
5498 rn = "LLAddr";
5499 break;
f6d4dd81
YK
5500 case 1:
5501 CP0_CHECK(ctx->mrp);
5502 gen_helper_mfc0_maar(arg, cpu_env);
5503 rn = "MAAR";
5504 break;
5505 case 2:
5506 CP0_CHECK(ctx->mrp);
5507 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI));
5508 rn = "MAARI";
5509 break;
7a387fff 5510 default:
f31b035a 5511 goto cp0_unimplemented;
7a387fff 5512 }
873eb012
TS
5513 break;
5514 case 18:
7a387fff 5515 switch (sel) {
c2e19f3c
AM
5516 case 0:
5517 case 1:
5518 case 2:
5519 case 3:
5520 case 4:
5521 case 5:
5522 case 6:
5523 case 7:
895c2d04 5524 gen_helper_1e0i(mfc0_watchlo, arg, sel);
2423f660
TS
5525 rn = "WatchLo";
5526 break;
7a387fff 5527 default:
f31b035a 5528 goto cp0_unimplemented;
7a387fff 5529 }
873eb012
TS
5530 break;
5531 case 19:
7a387fff 5532 switch (sel) {
c2e19f3c
AM
5533 case 0:
5534 case 1:
5535 case 2:
5536 case 3:
5537 case 4:
5538 case 5:
5539 case 6:
5540 case 7:
895c2d04 5541 gen_helper_1e0i(mfc0_watchhi, arg, sel);
2423f660
TS
5542 rn = "WatchHi";
5543 break;
7a387fff 5544 default:
f31b035a 5545 goto cp0_unimplemented;
7a387fff 5546 }
873eb012 5547 break;
8c0fdd85 5548 case 20:
7a387fff
TS
5549 switch (sel) {
5550 case 0:
d26bc211 5551#if defined(TARGET_MIPS64)
d75c135e 5552 check_insn(ctx, ISA_MIPS3);
7db13fae 5553 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
d9bea114 5554 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
5555 rn = "XContext";
5556 break;
703eaf37 5557#endif
7a387fff 5558 default:
f31b035a 5559 goto cp0_unimplemented;
7a387fff 5560 }
8c0fdd85
TS
5561 break;
5562 case 21:
7a387fff 5563 /* Officially reserved, but sel 0 is used for R1x000 framemask */
f31b035a 5564 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
7a387fff
TS
5565 switch (sel) {
5566 case 0:
7db13fae 5567 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
2423f660
TS
5568 rn = "Framemask";
5569 break;
7a387fff 5570 default:
f31b035a 5571 goto cp0_unimplemented;
7a387fff 5572 }
8c0fdd85
TS
5573 break;
5574 case 22:
d9bea114 5575 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
5576 rn = "'Diagnostic"; /* implementation dependent */
5577 break;
873eb012 5578 case 23:
7a387fff
TS
5579 switch (sel) {
5580 case 0:
895c2d04 5581 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
2423f660
TS
5582 rn = "Debug";
5583 break;
7a387fff 5584 case 1:
d9bea114 5585// gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
2423f660 5586 rn = "TraceControl";
3570d7f6 5587 goto cp0_unimplemented;
7a387fff 5588 case 2:
d9bea114 5589// gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
2423f660 5590 rn = "TraceControl2";
3570d7f6 5591 goto cp0_unimplemented;
7a387fff 5592 case 3:
d9bea114 5593// gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
2423f660 5594 rn = "UserTraceData";
3570d7f6 5595 goto cp0_unimplemented;
7a387fff 5596 case 4:
d9bea114 5597// gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
2423f660 5598 rn = "TraceBPC";
3570d7f6 5599 goto cp0_unimplemented;
7a387fff 5600 default:
f31b035a 5601 goto cp0_unimplemented;
7a387fff 5602 }
873eb012
TS
5603 break;
5604 case 24:
7a387fff
TS
5605 switch (sel) {
5606 case 0:
f0b3f3ae 5607 /* EJTAG support */
7db13fae 5608 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
d9bea114 5609 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
5610 rn = "DEPC";
5611 break;
7a387fff 5612 default:
f31b035a 5613 goto cp0_unimplemented;
7a387fff 5614 }
873eb012 5615 break;
8c0fdd85 5616 case 25:
7a387fff
TS
5617 switch (sel) {
5618 case 0:
7db13fae 5619 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
2423f660 5620 rn = "Performance0";
7a387fff
TS
5621 break;
5622 case 1:
d9bea114 5623// gen_helper_mfc0_performance1(arg);
2423f660 5624 rn = "Performance1";
3570d7f6 5625 goto cp0_unimplemented;
7a387fff 5626 case 2:
d9bea114 5627// gen_helper_mfc0_performance2(arg);
2423f660 5628 rn = "Performance2";
3570d7f6 5629 goto cp0_unimplemented;
7a387fff 5630 case 3:
d9bea114 5631// gen_helper_mfc0_performance3(arg);
2423f660 5632 rn = "Performance3";
3570d7f6 5633 goto cp0_unimplemented;
7a387fff 5634 case 4:
d9bea114 5635// gen_helper_mfc0_performance4(arg);
2423f660 5636 rn = "Performance4";
3570d7f6 5637 goto cp0_unimplemented;
7a387fff 5638 case 5:
d9bea114 5639// gen_helper_mfc0_performance5(arg);
2423f660 5640 rn = "Performance5";
3570d7f6 5641 goto cp0_unimplemented;
7a387fff 5642 case 6:
d9bea114 5643// gen_helper_mfc0_performance6(arg);
2423f660 5644 rn = "Performance6";
3570d7f6 5645 goto cp0_unimplemented;
7a387fff 5646 case 7:
d9bea114 5647// gen_helper_mfc0_performance7(arg);
2423f660 5648 rn = "Performance7";
3570d7f6 5649 goto cp0_unimplemented;
7a387fff 5650 default:
f31b035a 5651 goto cp0_unimplemented;
7a387fff 5652 }
8c0fdd85
TS
5653 break;
5654 case 26:
0d74a222
LA
5655 switch (sel) {
5656 case 0:
5657 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl));
5658 rn = "ErrCtl";
5659 break;
5660 default:
5661 goto cp0_unimplemented;
5662 }
da80682b 5663 break;
8c0fdd85 5664 case 27:
7a387fff 5665 switch (sel) {
c2e19f3c
AM
5666 case 0:
5667 case 1:
5668 case 2:
5669 case 3:
d9bea114 5670 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
5671 rn = "CacheErr";
5672 break;
7a387fff 5673 default:
f31b035a 5674 goto cp0_unimplemented;
7a387fff 5675 }
8c0fdd85 5676 break;
873eb012
TS
5677 case 28:
5678 switch (sel) {
5679 case 0:
7a387fff
TS
5680 case 2:
5681 case 4:
5682 case 6:
284b731a
LA
5683 {
5684 TCGv_i64 tmp = tcg_temp_new_i64();
5685 tcg_gen_ld_i64(tmp, cpu_env, offsetof(CPUMIPSState, CP0_TagLo));
5686 gen_move_low32(arg, tmp);
5687 tcg_temp_free_i64(tmp);
5688 }
873eb012
TS
5689 rn = "TagLo";
5690 break;
5691 case 1:
7a387fff
TS
5692 case 3:
5693 case 5:
5694 case 7:
7db13fae 5695 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
873eb012
TS
5696 rn = "DataLo";
5697 break;
5698 default:
f31b035a 5699 goto cp0_unimplemented;
873eb012
TS
5700 }
5701 break;
8c0fdd85 5702 case 29:
7a387fff
TS
5703 switch (sel) {
5704 case 0:
5705 case 2:
5706 case 4:
5707 case 6:
7db13fae 5708 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
7a387fff
TS
5709 rn = "TagHi";
5710 break;
5711 case 1:
5712 case 3:
5713 case 5:
5714 case 7:
7db13fae 5715 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
7a387fff
TS
5716 rn = "DataHi";
5717 break;
5718 default:
f31b035a 5719 goto cp0_unimplemented;
7a387fff 5720 }
8c0fdd85 5721 break;
873eb012 5722 case 30:
7a387fff
TS
5723 switch (sel) {
5724 case 0:
7db13fae 5725 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
d9bea114 5726 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
5727 rn = "ErrorEPC";
5728 break;
7a387fff 5729 default:
f31b035a 5730 goto cp0_unimplemented;
7a387fff 5731 }
873eb012
TS
5732 break;
5733 case 31:
7a387fff
TS
5734 switch (sel) {
5735 case 0:
f0b3f3ae 5736 /* EJTAG support */
7db13fae 5737 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
5738 rn = "DESAVE";
5739 break;
c2e19f3c
AM
5740 case 2:
5741 case 3:
5742 case 4:
5743 case 5:
5744 case 6:
5745 case 7:
f31b035a
LA
5746 CP0_CHECK(ctx->kscrexist & (1 << sel));
5747 tcg_gen_ld_tl(arg, cpu_env,
5748 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
5749 tcg_gen_ext32s_tl(arg, arg);
5750 rn = "KScratch";
e98c0d17 5751 break;
7a387fff 5752 default:
f31b035a 5753 goto cp0_unimplemented;
7a387fff 5754 }
873eb012
TS
5755 break;
5756 default:
f31b035a 5757 goto cp0_unimplemented;
873eb012 5758 }
b44a7fb1 5759 trace_mips_translate_c0("mfc0", rn, reg, sel);
873eb012
TS
5760 return;
5761
f31b035a 5762cp0_unimplemented:
965447ee 5763 qemu_log_mask(LOG_UNIMP, "mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
f31b035a 5764 gen_mfc0_unimplemented(ctx, arg);
873eb012
TS
5765}
5766
d75c135e 5767static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
8c0fdd85 5768{
7a387fff
TS
5769 const char *rn = "invalid";
5770
e189e748 5771 if (sel != 0)
d75c135e 5772 check_insn(ctx, ISA_MIPS32);
e189e748 5773
eeb3bba8 5774 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
2e70f6ef 5775 gen_io_start();
bd79255d 5776 }
2e70f6ef 5777
8c0fdd85
TS
5778 switch (reg) {
5779 case 0:
7a387fff
TS
5780 switch (sel) {
5781 case 0:
895c2d04 5782 gen_helper_mtc0_index(cpu_env, arg);
7a387fff
TS
5783 rn = "Index";
5784 break;
5785 case 1:
f31b035a 5786 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5787 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
7a387fff 5788 rn = "MVPControl";
ead9360e 5789 break;
7a387fff 5790 case 2:
f31b035a 5791 CP0_CHECK(ctx->insn_flags & ASE_MT);
ead9360e 5792 /* ignored */
7a387fff 5793 rn = "MVPConf0";
ead9360e 5794 break;
7a387fff 5795 case 3:
f31b035a 5796 CP0_CHECK(ctx->insn_flags & ASE_MT);
ead9360e 5797 /* ignored */
7a387fff 5798 rn = "MVPConf1";
ead9360e 5799 break;
01bc435b
YK
5800 case 4:
5801 CP0_CHECK(ctx->vp);
5802 /* ignored */
5803 rn = "VPControl";
5804 break;
7a387fff 5805 default:
f31b035a 5806 goto cp0_unimplemented;
7a387fff 5807 }
8c0fdd85
TS
5808 break;
5809 case 1:
7a387fff
TS
5810 switch (sel) {
5811 case 0:
2423f660 5812 /* ignored */
7a387fff 5813 rn = "Random";
2423f660 5814 break;
7a387fff 5815 case 1:
f31b035a 5816 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5817 gen_helper_mtc0_vpecontrol(cpu_env, arg);
7a387fff 5818 rn = "VPEControl";
ead9360e 5819 break;
7a387fff 5820 case 2:
f31b035a 5821 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5822 gen_helper_mtc0_vpeconf0(cpu_env, arg);
7a387fff 5823 rn = "VPEConf0";
ead9360e 5824 break;
7a387fff 5825 case 3:
f31b035a 5826 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5827 gen_helper_mtc0_vpeconf1(cpu_env, arg);
7a387fff 5828 rn = "VPEConf1";
ead9360e 5829 break;
7a387fff 5830 case 4:
f31b035a 5831 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5832 gen_helper_mtc0_yqmask(cpu_env, arg);
7a387fff 5833 rn = "YQMask";
ead9360e 5834 break;
7a387fff 5835 case 5:
f31b035a 5836 CP0_CHECK(ctx->insn_flags & ASE_MT);
d54a299b
LA
5837 tcg_gen_st_tl(arg, cpu_env,
5838 offsetof(CPUMIPSState, CP0_VPESchedule));
7a387fff 5839 rn = "VPESchedule";
ead9360e 5840 break;
7a387fff 5841 case 6:
f31b035a 5842 CP0_CHECK(ctx->insn_flags & ASE_MT);
d54a299b
LA
5843 tcg_gen_st_tl(arg, cpu_env,
5844 offsetof(CPUMIPSState, CP0_VPEScheFBack));
7a387fff 5845 rn = "VPEScheFBack";
ead9360e 5846 break;
7a387fff 5847 case 7:
f31b035a 5848 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5849 gen_helper_mtc0_vpeopt(cpu_env, arg);
7a387fff 5850 rn = "VPEOpt";
ead9360e 5851 break;
7a387fff 5852 default:
f31b035a 5853 goto cp0_unimplemented;
7a387fff 5854 }
8c0fdd85
TS
5855 break;
5856 case 2:
7a387fff
TS
5857 switch (sel) {
5858 case 0:
895c2d04 5859 gen_helper_mtc0_entrylo0(cpu_env, arg);
2423f660
TS
5860 rn = "EntryLo0";
5861 break;
7a387fff 5862 case 1:
f31b035a 5863 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5864 gen_helper_mtc0_tcstatus(cpu_env, arg);
2423f660 5865 rn = "TCStatus";
ead9360e 5866 break;
7a387fff 5867 case 2:
f31b035a 5868 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5869 gen_helper_mtc0_tcbind(cpu_env, arg);
2423f660 5870 rn = "TCBind";
ead9360e 5871 break;
7a387fff 5872 case 3:
f31b035a 5873 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5874 gen_helper_mtc0_tcrestart(cpu_env, arg);
2423f660 5875 rn = "TCRestart";
ead9360e 5876 break;
7a387fff 5877 case 4:
f31b035a 5878 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5879 gen_helper_mtc0_tchalt(cpu_env, arg);
2423f660 5880 rn = "TCHalt";
ead9360e 5881 break;
7a387fff 5882 case 5:
f31b035a 5883 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5884 gen_helper_mtc0_tccontext(cpu_env, arg);
2423f660 5885 rn = "TCContext";
ead9360e 5886 break;
7a387fff 5887 case 6:
f31b035a 5888 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5889 gen_helper_mtc0_tcschedule(cpu_env, arg);
2423f660 5890 rn = "TCSchedule";
ead9360e 5891 break;
7a387fff 5892 case 7:
f31b035a 5893 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 5894 gen_helper_mtc0_tcschefback(cpu_env, arg);
2423f660 5895 rn = "TCScheFBack";
ead9360e 5896 break;
7a387fff 5897 default:
f31b035a 5898 goto cp0_unimplemented;
7a387fff 5899 }
8c0fdd85
TS
5900 break;
5901 case 3:
7a387fff
TS
5902 switch (sel) {
5903 case 0:
895c2d04 5904 gen_helper_mtc0_entrylo1(cpu_env, arg);
2423f660
TS
5905 rn = "EntryLo1";
5906 break;
01bc435b
YK
5907 case 1:
5908 CP0_CHECK(ctx->vp);
5909 /* ignored */
5910 rn = "GlobalNumber";
5911 break;
7a387fff 5912 default:
f31b035a 5913 goto cp0_unimplemented;
876d4b07 5914 }
8c0fdd85
TS
5915 break;
5916 case 4:
7a387fff
TS
5917 switch (sel) {
5918 case 0:
895c2d04 5919 gen_helper_mtc0_context(cpu_env, arg);
2423f660
TS
5920 rn = "Context";
5921 break;
7a387fff 5922 case 1:
895c2d04 5923// gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
2423f660 5924 rn = "ContextConfig";
f31b035a 5925 goto cp0_unimplemented;
d279279e 5926 case 2:
f31b035a
LA
5927 CP0_CHECK(ctx->ulri);
5928 tcg_gen_st_tl(arg, cpu_env,
5929 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
5930 rn = "UserLocal";
d279279e 5931 break;
7a387fff 5932 default:
f31b035a 5933 goto cp0_unimplemented;
876d4b07 5934 }
8c0fdd85
TS
5935 break;
5936 case 5:
7a387fff
TS
5937 switch (sel) {
5938 case 0:
895c2d04 5939 gen_helper_mtc0_pagemask(cpu_env, arg);
2423f660
TS
5940 rn = "PageMask";
5941 break;
7a387fff 5942 case 1:
d75c135e 5943 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5944 gen_helper_mtc0_pagegrain(cpu_env, arg);
2423f660 5945 rn = "PageGrain";
eeb3bba8 5946 ctx->base.is_jmp = DISAS_STOP;
2423f660 5947 break;
cec56a73
JH
5948 case 2:
5949 CP0_CHECK(ctx->sc);
5950 gen_helper_mtc0_segctl0(cpu_env, arg);
5951 rn = "SegCtl0";
5952 break;
5953 case 3:
5954 CP0_CHECK(ctx->sc);
5955 gen_helper_mtc0_segctl1(cpu_env, arg);
5956 rn = "SegCtl1";
5957 break;
5958 case 4:
5959 CP0_CHECK(ctx->sc);
5960 gen_helper_mtc0_segctl2(cpu_env, arg);
5961 rn = "SegCtl2";
5962 break;
7a387fff 5963 default:
f31b035a 5964 goto cp0_unimplemented;
876d4b07 5965 }
8c0fdd85
TS
5966 break;
5967 case 6:
7a387fff
TS
5968 switch (sel) {
5969 case 0:
895c2d04 5970 gen_helper_mtc0_wired(cpu_env, arg);
2423f660
TS
5971 rn = "Wired";
5972 break;
7a387fff 5973 case 1:
d75c135e 5974 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5975 gen_helper_mtc0_srsconf0(cpu_env, arg);
2423f660 5976 rn = "SRSConf0";
ead9360e 5977 break;
7a387fff 5978 case 2:
d75c135e 5979 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5980 gen_helper_mtc0_srsconf1(cpu_env, arg);
2423f660 5981 rn = "SRSConf1";
ead9360e 5982 break;
7a387fff 5983 case 3:
d75c135e 5984 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5985 gen_helper_mtc0_srsconf2(cpu_env, arg);
2423f660 5986 rn = "SRSConf2";
ead9360e 5987 break;
7a387fff 5988 case 4:
d75c135e 5989 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5990 gen_helper_mtc0_srsconf3(cpu_env, arg);
2423f660 5991 rn = "SRSConf3";
ead9360e 5992 break;
7a387fff 5993 case 5:
d75c135e 5994 check_insn(ctx, ISA_MIPS32R2);
895c2d04 5995 gen_helper_mtc0_srsconf4(cpu_env, arg);
2423f660 5996 rn = "SRSConf4";
ead9360e 5997 break;
7a387fff 5998 default:
f31b035a 5999 goto cp0_unimplemented;
876d4b07 6000 }
8c0fdd85
TS
6001 break;
6002 case 7:
7a387fff
TS
6003 switch (sel) {
6004 case 0:
d75c135e 6005 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6006 gen_helper_mtc0_hwrena(cpu_env, arg);
eeb3bba8 6007 ctx->base.is_jmp = DISAS_STOP;
2423f660
TS
6008 rn = "HWREna";
6009 break;
7a387fff 6010 default:
f31b035a 6011 goto cp0_unimplemented;
876d4b07 6012 }
8c0fdd85
TS
6013 break;
6014 case 8:
aea14095
LA
6015 switch (sel) {
6016 case 0:
6017 /* ignored */
6018 rn = "BadVAddr";
6019 break;
6020 case 1:
6021 /* ignored */
6022 rn = "BadInstr";
6023 break;
6024 case 2:
6025 /* ignored */
6026 rn = "BadInstrP";
6027 break;
25beba9b
SM
6028 case 3:
6029 /* ignored */
6030 rn = "BadInstrX";
6031 break;
aea14095 6032 default:
f31b035a 6033 goto cp0_unimplemented;
aea14095 6034 }
8c0fdd85
TS
6035 break;
6036 case 9:
7a387fff
TS
6037 switch (sel) {
6038 case 0:
895c2d04 6039 gen_helper_mtc0_count(cpu_env, arg);
2423f660
TS
6040 rn = "Count";
6041 break;
876d4b07 6042 /* 6,7 are implementation dependent */
7a387fff 6043 default:
f31b035a 6044 goto cp0_unimplemented;
876d4b07 6045 }
8c0fdd85
TS
6046 break;
6047 case 10:
7a387fff
TS
6048 switch (sel) {
6049 case 0:
895c2d04 6050 gen_helper_mtc0_entryhi(cpu_env, arg);
2423f660
TS
6051 rn = "EntryHi";
6052 break;
7a387fff 6053 default:
f31b035a 6054 goto cp0_unimplemented;
876d4b07 6055 }
8c0fdd85
TS
6056 break;
6057 case 11:
7a387fff
TS
6058 switch (sel) {
6059 case 0:
895c2d04 6060 gen_helper_mtc0_compare(cpu_env, arg);
2423f660
TS
6061 rn = "Compare";
6062 break;
6063 /* 6,7 are implementation dependent */
7a387fff 6064 default:
f31b035a 6065 goto cp0_unimplemented;
876d4b07 6066 }
8c0fdd85
TS
6067 break;
6068 case 12:
7a387fff
TS
6069 switch (sel) {
6070 case 0:
867abc7e 6071 save_cpu_state(ctx, 1);
895c2d04 6072 gen_helper_mtc0_status(cpu_env, arg);
b28425ba 6073 /* DISAS_STOP isn't good enough here, hflags may have changed. */
eeb3bba8
EC
6074 gen_save_pc(ctx->base.pc_next + 4);
6075 ctx->base.is_jmp = DISAS_EXIT;
2423f660
TS
6076 rn = "Status";
6077 break;
7a387fff 6078 case 1:
d75c135e 6079 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6080 gen_helper_mtc0_intctl(cpu_env, arg);
8487327a 6081 /* Stop translation as we may have switched the execution mode */
eeb3bba8 6082 ctx->base.is_jmp = DISAS_STOP;
2423f660
TS
6083 rn = "IntCtl";
6084 break;
7a387fff 6085 case 2:
d75c135e 6086 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6087 gen_helper_mtc0_srsctl(cpu_env, arg);
8487327a 6088 /* Stop translation as we may have switched the execution mode */
eeb3bba8 6089 ctx->base.is_jmp = DISAS_STOP;
2423f660
TS
6090 rn = "SRSCtl";
6091 break;
7a387fff 6092 case 3:
d75c135e 6093 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6094 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
8487327a 6095 /* Stop translation as we may have switched the execution mode */
eeb3bba8 6096 ctx->base.is_jmp = DISAS_STOP;
2423f660 6097 rn = "SRSMap";
fd88b6ab 6098 break;
7a387fff 6099 default:
f31b035a 6100 goto cp0_unimplemented;
876d4b07 6101 }
8c0fdd85
TS
6102 break;
6103 case 13:
7a387fff
TS
6104 switch (sel) {
6105 case 0:
867abc7e 6106 save_cpu_state(ctx, 1);
895c2d04 6107 gen_helper_mtc0_cause(cpu_env, arg);
b28425ba
EC
6108 /* Stop translation as we may have triggered an interrupt.
6109 * DISAS_STOP isn't sufficient, we need to ensure we break out of
6110 * translated code to check for pending interrupts. */
eeb3bba8
EC
6111 gen_save_pc(ctx->base.pc_next + 4);
6112 ctx->base.is_jmp = DISAS_EXIT;
2423f660
TS
6113 rn = "Cause";
6114 break;
7a387fff 6115 default:
f31b035a 6116 goto cp0_unimplemented;
876d4b07 6117 }
8c0fdd85
TS
6118 break;
6119 case 14:
7a387fff
TS
6120 switch (sel) {
6121 case 0:
d54a299b 6122 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
2423f660
TS
6123 rn = "EPC";
6124 break;
7a387fff 6125 default:
f31b035a 6126 goto cp0_unimplemented;
876d4b07 6127 }
8c0fdd85
TS
6128 break;
6129 case 15:
7a387fff
TS
6130 switch (sel) {
6131 case 0:
2423f660
TS
6132 /* ignored */
6133 rn = "PRid";
6134 break;
7a387fff 6135 case 1:
d75c135e 6136 check_insn(ctx, ISA_MIPS32R2);
895c2d04 6137 gen_helper_mtc0_ebase(cpu_env, arg);
2423f660
TS
6138 rn = "EBase";
6139 break;
7a387fff 6140 default:
f31b035a 6141 goto cp0_unimplemented;
1579a72e 6142 }
8c0fdd85
TS
6143 break;
6144 case 16:
6145 switch (sel) {
6146 case 0:
895c2d04 6147 gen_helper_mtc0_config0(cpu_env, arg);
7a387fff 6148 rn = "Config";
2423f660 6149 /* Stop translation as we may have switched the execution mode */
eeb3bba8 6150 ctx->base.is_jmp = DISAS_STOP;
7a387fff
TS
6151 break;
6152 case 1:
e397ee33 6153 /* ignored, read only */
7a387fff
TS
6154 rn = "Config1";
6155 break;
6156 case 2:
895c2d04 6157 gen_helper_mtc0_config2(cpu_env, arg);
7a387fff 6158 rn = "Config2";
2423f660 6159 /* Stop translation as we may have switched the execution mode */
eeb3bba8 6160 ctx->base.is_jmp = DISAS_STOP;
8c0fdd85 6161 break;
7a387fff 6162 case 3:
90f12d73 6163 gen_helper_mtc0_config3(cpu_env, arg);
7a387fff 6164 rn = "Config3";
90f12d73 6165 /* Stop translation as we may have switched the execution mode */
eeb3bba8 6166 ctx->base.is_jmp = DISAS_STOP;
7a387fff 6167 break;
b4160af1
PJ
6168 case 4:
6169 gen_helper_mtc0_config4(cpu_env, arg);
6170 rn = "Config4";
eeb3bba8 6171 ctx->base.is_jmp = DISAS_STOP;
b4160af1 6172 break;
b4dd99a3
PJ
6173 case 5:
6174 gen_helper_mtc0_config5(cpu_env, arg);
6175 rn = "Config5";
6176 /* Stop translation as we may have switched the execution mode */
eeb3bba8 6177 ctx->base.is_jmp = DISAS_STOP;
b4dd99a3 6178 break;
e397ee33
TS
6179 /* 6,7 are implementation dependent */
6180 case 6:
6181 /* ignored */
6182 rn = "Config6";
6183 break;
6184 case 7:
6185 /* ignored */
6186 rn = "Config7";
6187 break;
8c0fdd85
TS
6188 default:
6189 rn = "Invalid config selector";
f31b035a 6190 goto cp0_unimplemented;
8c0fdd85
TS
6191 }
6192 break;
6193 case 17:
7a387fff
TS
6194 switch (sel) {
6195 case 0:
895c2d04 6196 gen_helper_mtc0_lladdr(cpu_env, arg);
2423f660
TS
6197 rn = "LLAddr";
6198 break;
f6d4dd81
YK
6199 case 1:
6200 CP0_CHECK(ctx->mrp);
6201 gen_helper_mtc0_maar(cpu_env, arg);
6202 rn = "MAAR";
6203 break;
6204 case 2:
6205 CP0_CHECK(ctx->mrp);
6206 gen_helper_mtc0_maari(cpu_env, arg);
6207 rn = "MAARI";
6208 break;
7a387fff 6209 default:
f31b035a 6210 goto cp0_unimplemented;
7a387fff 6211 }
8c0fdd85
TS
6212 break;
6213 case 18:
7a387fff 6214 switch (sel) {
c2e19f3c
AM
6215 case 0:
6216 case 1:
6217 case 2:
6218 case 3:
6219 case 4:
6220 case 5:
6221 case 6:
6222 case 7:
895c2d04 6223 gen_helper_0e1i(mtc0_watchlo, arg, sel);
2423f660
TS
6224 rn = "WatchLo";
6225 break;
7a387fff 6226 default:
f31b035a 6227 goto cp0_unimplemented;
7a387fff 6228 }
8c0fdd85
TS
6229 break;
6230 case 19:
7a387fff 6231 switch (sel) {
c2e19f3c
AM
6232 case 0:
6233 case 1:
6234 case 2:
6235 case 3:
6236 case 4:
6237 case 5:
6238 case 6:
6239 case 7:
895c2d04 6240 gen_helper_0e1i(mtc0_watchhi, arg, sel);
2423f660
TS
6241 rn = "WatchHi";
6242 break;
7a387fff 6243 default:
f31b035a 6244 goto cp0_unimplemented;
7a387fff 6245 }
8c0fdd85
TS
6246 break;
6247 case 20:
7a387fff
TS
6248 switch (sel) {
6249 case 0:
d26bc211 6250#if defined(TARGET_MIPS64)
d75c135e 6251 check_insn(ctx, ISA_MIPS3);
895c2d04 6252 gen_helper_mtc0_xcontext(cpu_env, arg);
2423f660
TS
6253 rn = "XContext";
6254 break;
703eaf37 6255#endif
7a387fff 6256 default:
f31b035a 6257 goto cp0_unimplemented;
7a387fff 6258 }
8c0fdd85
TS
6259 break;
6260 case 21:
7a387fff 6261 /* Officially reserved, but sel 0 is used for R1x000 framemask */
f31b035a 6262 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
7a387fff
TS
6263 switch (sel) {
6264 case 0:
895c2d04 6265 gen_helper_mtc0_framemask(cpu_env, arg);
2423f660
TS
6266 rn = "Framemask";
6267 break;
7a387fff 6268 default:
f31b035a 6269 goto cp0_unimplemented;
7a387fff
TS
6270 }
6271 break;
8c0fdd85 6272 case 22:
7a387fff
TS
6273 /* ignored */
6274 rn = "Diagnostic"; /* implementation dependent */
2423f660 6275 break;
8c0fdd85 6276 case 23:
7a387fff
TS
6277 switch (sel) {
6278 case 0:
895c2d04 6279 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
b28425ba 6280 /* DISAS_STOP isn't good enough here, hflags may have changed. */
eeb3bba8
EC
6281 gen_save_pc(ctx->base.pc_next + 4);
6282 ctx->base.is_jmp = DISAS_EXIT;
2423f660
TS
6283 rn = "Debug";
6284 break;
7a387fff 6285 case 1:
895c2d04 6286// gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
2423f660 6287 rn = "TraceControl";
8487327a 6288 /* Stop translation as we may have switched the execution mode */
eeb3bba8 6289 ctx->base.is_jmp = DISAS_STOP;
3570d7f6 6290 goto cp0_unimplemented;
7a387fff 6291 case 2:
895c2d04 6292// gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
2423f660 6293 rn = "TraceControl2";
8487327a 6294 /* Stop translation as we may have switched the execution mode */
eeb3bba8 6295 ctx->base.is_jmp = DISAS_STOP;
3570d7f6 6296 goto cp0_unimplemented;
7a387fff 6297 case 3:
8487327a 6298 /* Stop translation as we may have switched the execution mode */
eeb3bba8 6299 ctx->base.is_jmp = DISAS_STOP;
895c2d04 6300// gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
2423f660 6301 rn = "UserTraceData";
8487327a 6302 /* Stop translation as we may have switched the execution mode */
eeb3bba8 6303 ctx->base.is_jmp = DISAS_STOP;
3570d7f6 6304 goto cp0_unimplemented;
7a387fff 6305 case 4:
895c2d04 6306// gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
8487327a 6307 /* Stop translation as we may have switched the execution mode */
eeb3bba8 6308 ctx->base.is_jmp = DISAS_STOP;
2423f660 6309 rn = "TraceBPC";
3570d7f6 6310 goto cp0_unimplemented;
7a387fff 6311 default:
f31b035a 6312 goto cp0_unimplemented;
7a387fff 6313 }
8c0fdd85
TS
6314 break;
6315 case 24:
7a387fff
TS
6316 switch (sel) {
6317 case 0:
f1aa6320 6318 /* EJTAG support */
d54a299b 6319 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
2423f660
TS
6320 rn = "DEPC";
6321 break;
7a387fff 6322 default:
f31b035a 6323 goto cp0_unimplemented;
7a387fff 6324 }
8c0fdd85
TS
6325 break;
6326 case 25:
7a387fff
TS
6327 switch (sel) {
6328 case 0:
895c2d04 6329 gen_helper_mtc0_performance0(cpu_env, arg);
2423f660
TS
6330 rn = "Performance0";
6331 break;
7a387fff 6332 case 1:
d9bea114 6333// gen_helper_mtc0_performance1(arg);
2423f660 6334 rn = "Performance1";
3570d7f6 6335 goto cp0_unimplemented;
7a387fff 6336 case 2:
d9bea114 6337// gen_helper_mtc0_performance2(arg);
2423f660 6338 rn = "Performance2";
3570d7f6 6339 goto cp0_unimplemented;
7a387fff 6340 case 3:
d9bea114 6341// gen_helper_mtc0_performance3(arg);
2423f660 6342 rn = "Performance3";
3570d7f6 6343 goto cp0_unimplemented;
7a387fff 6344 case 4:
d9bea114 6345// gen_helper_mtc0_performance4(arg);
2423f660 6346 rn = "Performance4";
3570d7f6 6347 goto cp0_unimplemented;
7a387fff 6348 case 5:
d9bea114 6349// gen_helper_mtc0_performance5(arg);
2423f660 6350 rn = "Performance5";
3570d7f6 6351 goto cp0_unimplemented;
7a387fff 6352 case 6:
d9bea114 6353// gen_helper_mtc0_performance6(arg);
2423f660 6354 rn = "Performance6";
3570d7f6 6355 goto cp0_unimplemented;
7a387fff 6356 case 7:
d9bea114 6357// gen_helper_mtc0_performance7(arg);
2423f660 6358 rn = "Performance7";
3570d7f6 6359 goto cp0_unimplemented;
7a387fff 6360 default:
f31b035a 6361 goto cp0_unimplemented;
7a387fff 6362 }
8c0fdd85
TS
6363 break;
6364 case 26:
0d74a222
LA
6365 switch (sel) {
6366 case 0:
6367 gen_helper_mtc0_errctl(cpu_env, arg);
eeb3bba8 6368 ctx->base.is_jmp = DISAS_STOP;
0d74a222
LA
6369 rn = "ErrCtl";
6370 break;
6371 default:
6372 goto cp0_unimplemented;
6373 }
2423f660 6374 break;
8c0fdd85 6375 case 27:
7a387fff 6376 switch (sel) {
c2e19f3c
AM
6377 case 0:
6378 case 1:
6379 case 2:
6380 case 3:
2423f660
TS
6381 /* ignored */
6382 rn = "CacheErr";
6383 break;
7a387fff 6384 default:
f31b035a 6385 goto cp0_unimplemented;
7a387fff 6386 }
8c0fdd85
TS
6387 break;
6388 case 28:
6389 switch (sel) {
6390 case 0:
7a387fff
TS
6391 case 2:
6392 case 4:
6393 case 6:
895c2d04 6394 gen_helper_mtc0_taglo(cpu_env, arg);
8c0fdd85
TS
6395 rn = "TagLo";
6396 break;
7a387fff
TS
6397 case 1:
6398 case 3:
6399 case 5:
6400 case 7:
895c2d04 6401 gen_helper_mtc0_datalo(cpu_env, arg);
7a387fff
TS
6402 rn = "DataLo";
6403 break;
8c0fdd85 6404 default:
f31b035a 6405 goto cp0_unimplemented;
8c0fdd85
TS
6406 }
6407 break;
6408 case 29:
7a387fff
TS
6409 switch (sel) {
6410 case 0:
6411 case 2:
6412 case 4:
6413 case 6:
895c2d04 6414 gen_helper_mtc0_taghi(cpu_env, arg);
7a387fff
TS
6415 rn = "TagHi";
6416 break;
6417 case 1:
6418 case 3:
6419 case 5:
6420 case 7:
895c2d04 6421 gen_helper_mtc0_datahi(cpu_env, arg);
7a387fff
TS
6422 rn = "DataHi";
6423 break;
6424 default:
6425 rn = "invalid sel";
f31b035a 6426 goto cp0_unimplemented;
7a387fff 6427 }
8c0fdd85
TS
6428 break;
6429 case 30:
7a387fff
TS
6430 switch (sel) {
6431 case 0:
d54a299b 6432 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
2423f660
TS
6433 rn = "ErrorEPC";
6434 break;
7a387fff 6435 default:
f31b035a 6436 goto cp0_unimplemented;
7a387fff 6437 }
8c0fdd85
TS
6438 break;
6439 case 31:
7a387fff
TS
6440 switch (sel) {
6441 case 0:
f1aa6320 6442 /* EJTAG support */
7db13fae 6443 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
6444 rn = "DESAVE";
6445 break;
c2e19f3c
AM
6446 case 2:
6447 case 3:
6448 case 4:
6449 case 5:
6450 case 6:
6451 case 7:
f31b035a
LA
6452 CP0_CHECK(ctx->kscrexist & (1 << sel));
6453 tcg_gen_st_tl(arg, cpu_env,
6454 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
6455 rn = "KScratch";
e98c0d17 6456 break;
7a387fff 6457 default:
f31b035a 6458 goto cp0_unimplemented;
7a387fff 6459 }
8c0fdd85
TS
6460 break;
6461 default:
f31b035a 6462 goto cp0_unimplemented;
8c0fdd85 6463 }
b44a7fb1
PMD
6464 trace_mips_translate_c0("mtc0", rn, reg, sel);
6465
bf20dc07 6466 /* For simplicity assume that all writes can cause interrupts. */
eeb3bba8 6467 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
2e70f6ef 6468 gen_io_end();
b28425ba 6469 /* DISAS_STOP isn't sufficient, we need to ensure we break out of
b74cddcb 6470 * translated code to check for pending interrupts. */
eeb3bba8
EC
6471 gen_save_pc(ctx->base.pc_next + 4);
6472 ctx->base.is_jmp = DISAS_EXIT;
2e70f6ef 6473 }
8c0fdd85
TS
6474 return;
6475
f31b035a 6476cp0_unimplemented:
965447ee 6477 qemu_log_mask(LOG_UNIMP, "mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
8c0fdd85
TS
6478}
6479
d26bc211 6480#if defined(TARGET_MIPS64)
d75c135e 6481static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
9c2149c8
TS
6482{
6483 const char *rn = "invalid";
6484
e189e748 6485 if (sel != 0)
d75c135e 6486 check_insn(ctx, ISA_MIPS64);
e189e748 6487
9c2149c8
TS
6488 switch (reg) {
6489 case 0:
6490 switch (sel) {
6491 case 0:
7db13fae 6492 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
9c2149c8
TS
6493 rn = "Index";
6494 break;
6495 case 1:
f31b035a 6496 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6497 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
9c2149c8 6498 rn = "MVPControl";
ead9360e 6499 break;
9c2149c8 6500 case 2:
f31b035a 6501 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6502 gen_helper_mfc0_mvpconf0(arg, cpu_env);
9c2149c8 6503 rn = "MVPConf0";
ead9360e 6504 break;
9c2149c8 6505 case 3:
f31b035a 6506 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6507 gen_helper_mfc0_mvpconf1(arg, cpu_env);
9c2149c8 6508 rn = "MVPConf1";
ead9360e 6509 break;
01bc435b
YK
6510 case 4:
6511 CP0_CHECK(ctx->vp);
6512 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl));
6513 rn = "VPControl";
6514 break;
9c2149c8 6515 default:
f31b035a 6516 goto cp0_unimplemented;
9c2149c8
TS
6517 }
6518 break;
6519 case 1:
6520 switch (sel) {
6521 case 0:
f31b035a 6522 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
895c2d04 6523 gen_helper_mfc0_random(arg, cpu_env);
9c2149c8 6524 rn = "Random";
2423f660 6525 break;
9c2149c8 6526 case 1:
f31b035a 6527 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6528 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
9c2149c8 6529 rn = "VPEControl";
ead9360e 6530 break;
9c2149c8 6531 case 2:
f31b035a 6532 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6533 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
9c2149c8 6534 rn = "VPEConf0";
ead9360e 6535 break;
9c2149c8 6536 case 3:
f31b035a 6537 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6538 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
9c2149c8 6539 rn = "VPEConf1";
ead9360e 6540 break;
9c2149c8 6541 case 4:
f31b035a 6542 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6543 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_YQMask));
9c2149c8 6544 rn = "YQMask";
ead9360e 6545 break;
9c2149c8 6546 case 5:
f31b035a 6547 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6548 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
9c2149c8 6549 rn = "VPESchedule";
ead9360e 6550 break;
9c2149c8 6551 case 6:
f31b035a 6552 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6553 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
9c2149c8 6554 rn = "VPEScheFBack";
ead9360e 6555 break;
9c2149c8 6556 case 7:
f31b035a 6557 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 6558 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
9c2149c8 6559 rn = "VPEOpt";
ead9360e 6560 break;
9c2149c8 6561 default:
f31b035a 6562 goto cp0_unimplemented;
9c2149c8
TS
6563 }
6564 break;
6565 case 2:
6566 switch (sel) {
6567 case 0:
7db13fae 6568 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
2423f660
TS
6569 rn = "EntryLo0";
6570 break;
9c2149c8 6571 case 1:
f31b035a 6572 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6573 gen_helper_mfc0_tcstatus(arg, cpu_env);
2423f660 6574 rn = "TCStatus";
ead9360e 6575 break;
9c2149c8 6576 case 2:
f31b035a 6577 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6578 gen_helper_mfc0_tcbind(arg, cpu_env);
2423f660 6579 rn = "TCBind";
ead9360e 6580 break;
9c2149c8 6581 case 3:
f31b035a 6582 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6583 gen_helper_dmfc0_tcrestart(arg, cpu_env);
2423f660 6584 rn = "TCRestart";
ead9360e 6585 break;
9c2149c8 6586 case 4:
f31b035a 6587 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6588 gen_helper_dmfc0_tchalt(arg, cpu_env);
2423f660 6589 rn = "TCHalt";
ead9360e 6590 break;
9c2149c8 6591 case 5:
f31b035a 6592 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6593 gen_helper_dmfc0_tccontext(arg, cpu_env);
2423f660 6594 rn = "TCContext";
ead9360e 6595 break;
9c2149c8 6596 case 6:
f31b035a 6597 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6598 gen_helper_dmfc0_tcschedule(arg, cpu_env);
2423f660 6599 rn = "TCSchedule";
ead9360e 6600 break;
9c2149c8 6601 case 7:
f31b035a 6602 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 6603 gen_helper_dmfc0_tcschefback(arg, cpu_env);
2423f660 6604 rn = "TCScheFBack";
ead9360e 6605 break;
9c2149c8 6606 default:
f31b035a 6607 goto cp0_unimplemented;
9c2149c8
TS
6608 }
6609 break;
6610 case 3:
6611 switch (sel) {
6612 case 0:
7db13fae 6613 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
2423f660
TS
6614 rn = "EntryLo1";
6615 break;
01bc435b
YK
6616 case 1:
6617 CP0_CHECK(ctx->vp);
6618 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber));
6619 rn = "GlobalNumber";
6620 break;
9c2149c8 6621 default:
f31b035a 6622 goto cp0_unimplemented;
1579a72e 6623 }
9c2149c8
TS
6624 break;
6625 case 4:
6626 switch (sel) {
6627 case 0:
7db13fae 6628 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
2423f660
TS
6629 rn = "Context";
6630 break;
9c2149c8 6631 case 1:
d9bea114 6632// gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
2423f660 6633 rn = "ContextConfig";
f31b035a 6634 goto cp0_unimplemented;
d279279e 6635 case 2:
f31b035a
LA
6636 CP0_CHECK(ctx->ulri);
6637 tcg_gen_ld_tl(arg, cpu_env,
6638 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
6639 rn = "UserLocal";
d279279e 6640 break;
9c2149c8 6641 default:
f31b035a 6642 goto cp0_unimplemented;
876d4b07 6643 }
9c2149c8
TS
6644 break;
6645 case 5:
6646 switch (sel) {
6647 case 0:
7db13fae 6648 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
2423f660
TS
6649 rn = "PageMask";
6650 break;
9c2149c8 6651 case 1:
d75c135e 6652 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6653 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
2423f660
TS
6654 rn = "PageGrain";
6655 break;
cec56a73
JH
6656 case 2:
6657 CP0_CHECK(ctx->sc);
6658 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl0));
6659 rn = "SegCtl0";
6660 break;
6661 case 3:
6662 CP0_CHECK(ctx->sc);
6663 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl1));
6664 rn = "SegCtl1";
6665 break;
6666 case 4:
6667 CP0_CHECK(ctx->sc);
6668 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl2));
6669 rn = "SegCtl2";
6670 break;
9c2149c8 6671 default:
f31b035a 6672 goto cp0_unimplemented;
876d4b07 6673 }
9c2149c8
TS
6674 break;
6675 case 6:
6676 switch (sel) {
6677 case 0:
7db13fae 6678 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
2423f660
TS
6679 rn = "Wired";
6680 break;
9c2149c8 6681 case 1:
d75c135e 6682 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6683 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
2423f660 6684 rn = "SRSConf0";
ead9360e 6685 break;
9c2149c8 6686 case 2:
d75c135e 6687 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6688 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
2423f660 6689 rn = "SRSConf1";
ead9360e 6690 break;
9c2149c8 6691 case 3:
d75c135e 6692 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6693 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
2423f660 6694 rn = "SRSConf2";
ead9360e 6695 break;
9c2149c8 6696 case 4:
d75c135e 6697 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6698 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
2423f660 6699 rn = "SRSConf3";
ead9360e 6700 break;
9c2149c8 6701 case 5:
d75c135e 6702 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6703 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
2423f660 6704 rn = "SRSConf4";
ead9360e 6705 break;
9c2149c8 6706 default:
f31b035a 6707 goto cp0_unimplemented;
876d4b07 6708 }
9c2149c8
TS
6709 break;
6710 case 7:
6711 switch (sel) {
6712 case 0:
d75c135e 6713 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6714 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
2423f660
TS
6715 rn = "HWREna";
6716 break;
9c2149c8 6717 default:
f31b035a 6718 goto cp0_unimplemented;
876d4b07 6719 }
9c2149c8
TS
6720 break;
6721 case 8:
6722 switch (sel) {
6723 case 0:
7db13fae 6724 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
f0b3f3ae 6725 rn = "BadVAddr";
2423f660 6726 break;
aea14095 6727 case 1:
f31b035a
LA
6728 CP0_CHECK(ctx->bi);
6729 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
6730 rn = "BadInstr";
aea14095
LA
6731 break;
6732 case 2:
f31b035a
LA
6733 CP0_CHECK(ctx->bp);
6734 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
6735 rn = "BadInstrP";
aea14095 6736 break;
25beba9b
SM
6737 case 3:
6738 CP0_CHECK(ctx->bi);
6739 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrX));
6740 tcg_gen_andi_tl(arg, arg, ~0xffff);
6741 rn = "BadInstrX";
6742 break;
9c2149c8 6743 default:
f31b035a 6744 goto cp0_unimplemented;
876d4b07 6745 }
9c2149c8
TS
6746 break;
6747 case 9:
6748 switch (sel) {
6749 case 0:
2e70f6ef 6750 /* Mark as an IO operation because we read the time. */
eeb3bba8 6751 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
2e70f6ef 6752 gen_io_start();
bd79255d 6753 }
895c2d04 6754 gen_helper_mfc0_count(arg, cpu_env);
eeb3bba8 6755 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
2e70f6ef 6756 gen_io_end();
2e70f6ef 6757 }
55807224 6758 /* Break the TB to be able to take timer interrupts immediately
b28425ba
EC
6759 after reading count. DISAS_STOP isn't sufficient, we need to
6760 ensure we break completely out of translated code. */
eeb3bba8
EC
6761 gen_save_pc(ctx->base.pc_next + 4);
6762 ctx->base.is_jmp = DISAS_EXIT;
2423f660
TS
6763 rn = "Count";
6764 break;
6765 /* 6,7 are implementation dependent */
9c2149c8 6766 default:
f31b035a 6767 goto cp0_unimplemented;
876d4b07 6768 }
9c2149c8
TS
6769 break;
6770 case 10:
6771 switch (sel) {
6772 case 0:
7db13fae 6773 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
2423f660
TS
6774 rn = "EntryHi";
6775 break;
9c2149c8 6776 default:
f31b035a 6777 goto cp0_unimplemented;
876d4b07 6778 }
9c2149c8
TS
6779 break;
6780 case 11:
6781 switch (sel) {
6782 case 0:
7db13fae 6783 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
2423f660
TS
6784 rn = "Compare";
6785 break;
876d4b07 6786 /* 6,7 are implementation dependent */
9c2149c8 6787 default:
f31b035a 6788 goto cp0_unimplemented;
876d4b07 6789 }
9c2149c8
TS
6790 break;
6791 case 12:
6792 switch (sel) {
6793 case 0:
7db13fae 6794 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
2423f660
TS
6795 rn = "Status";
6796 break;
9c2149c8 6797 case 1:
d75c135e 6798 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6799 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
2423f660
TS
6800 rn = "IntCtl";
6801 break;
9c2149c8 6802 case 2:
d75c135e 6803 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6804 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
2423f660
TS
6805 rn = "SRSCtl";
6806 break;
9c2149c8 6807 case 3:
d75c135e 6808 check_insn(ctx, ISA_MIPS32R2);
7db13fae 6809 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
2423f660
TS
6810 rn = "SRSMap";
6811 break;
9c2149c8 6812 default:
f31b035a 6813 goto cp0_unimplemented;
876d4b07 6814 }
9c2149c8
TS
6815 break;
6816 case 13:
6817 switch (sel) {
6818 case 0:
7db13fae 6819 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
2423f660
TS
6820 rn = "Cause";
6821 break;
9c2149c8 6822 default:
f31b035a 6823 goto cp0_unimplemented;
876d4b07 6824 }
9c2149c8
TS
6825 break;
6826 case 14:
6827 switch (sel) {
6828 case 0:
7db13fae 6829 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
2423f660
TS
6830 rn = "EPC";
6831 break;
9c2149c8 6832 default:
f31b035a 6833 goto cp0_unimplemented;
876d4b07 6834 }
9c2149c8
TS
6835 break;
6836 case 15:
6837 switch (sel) {
6838 case 0:
7db13fae 6839 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
2423f660
TS
6840 rn = "PRid";
6841 break;
9c2149c8 6842 case 1:
d75c135e 6843 check_insn(ctx, ISA_MIPS32R2);
74dbf824 6844 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EBase));
2423f660
TS
6845 rn = "EBase";
6846 break;
c870e3f5
YK
6847 case 3:
6848 check_insn(ctx, ISA_MIPS32R2);
6849 CP0_CHECK(ctx->cmgcr);
6850 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase));
6851 rn = "CMGCRBase";
6852 break;
9c2149c8 6853 default:
f31b035a 6854 goto cp0_unimplemented;
876d4b07 6855 }
9c2149c8
TS
6856 break;
6857 case 16:
6858 switch (sel) {
6859 case 0:
7db13fae 6860 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
9c2149c8
TS
6861 rn = "Config";
6862 break;
6863 case 1:
7db13fae 6864 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
9c2149c8
TS
6865 rn = "Config1";
6866 break;
6867 case 2:
7db13fae 6868 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
9c2149c8
TS
6869 rn = "Config2";
6870 break;
6871 case 3:
7db13fae 6872 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
9c2149c8
TS
6873 rn = "Config3";
6874 break;
faf1f68b
LA
6875 case 4:
6876 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
6877 rn = "Config4";
6878 break;
6879 case 5:
6880 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
6881 rn = "Config5";
6882 break;
9c2149c8 6883 /* 6,7 are implementation dependent */
f0b3f3ae 6884 case 6:
7db13fae 6885 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
f0b3f3ae
TS
6886 rn = "Config6";
6887 break;
6888 case 7:
7db13fae 6889 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
f0b3f3ae
TS
6890 rn = "Config7";
6891 break;
9c2149c8 6892 default:
f31b035a 6893 goto cp0_unimplemented;
9c2149c8
TS
6894 }
6895 break;
6896 case 17:
6897 switch (sel) {
6898 case 0:
895c2d04 6899 gen_helper_dmfc0_lladdr(arg, cpu_env);
2423f660
TS
6900 rn = "LLAddr";
6901 break;
f6d4dd81
YK
6902 case 1:
6903 CP0_CHECK(ctx->mrp);
6904 gen_helper_dmfc0_maar(arg, cpu_env);
6905 rn = "MAAR";
6906 break;
6907 case 2:
6908 CP0_CHECK(ctx->mrp);
6909 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI));
6910 rn = "MAARI";
6911 break;
9c2149c8 6912 default:
f31b035a 6913 goto cp0_unimplemented;
9c2149c8
TS
6914 }
6915 break;
6916 case 18:
6917 switch (sel) {
c2e19f3c
AM
6918 case 0:
6919 case 1:
6920 case 2:
6921 case 3:
6922 case 4:
6923 case 5:
6924 case 6:
6925 case 7:
895c2d04 6926 gen_helper_1e0i(dmfc0_watchlo, arg, sel);
2423f660
TS
6927 rn = "WatchLo";
6928 break;
9c2149c8 6929 default:
f31b035a 6930 goto cp0_unimplemented;
9c2149c8
TS
6931 }
6932 break;
6933 case 19:
6934 switch (sel) {
c2e19f3c
AM
6935 case 0:
6936 case 1:
6937 case 2:
6938 case 3:
6939 case 4:
6940 case 5:
6941 case 6:
6942 case 7:
895c2d04 6943 gen_helper_1e0i(mfc0_watchhi, arg, sel);
2423f660
TS
6944 rn = "WatchHi";
6945 break;
9c2149c8 6946 default:
f31b035a 6947 goto cp0_unimplemented;
9c2149c8
TS
6948 }
6949 break;
6950 case 20:
6951 switch (sel) {
6952 case 0:
d75c135e 6953 check_insn(ctx, ISA_MIPS3);
7db13fae 6954 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
2423f660
TS
6955 rn = "XContext";
6956 break;
9c2149c8 6957 default:
f31b035a 6958 goto cp0_unimplemented;
9c2149c8
TS
6959 }
6960 break;
6961 case 21:
6962 /* Officially reserved, but sel 0 is used for R1x000 framemask */
f31b035a 6963 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
9c2149c8
TS
6964 switch (sel) {
6965 case 0:
7db13fae 6966 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
2423f660
TS
6967 rn = "Framemask";
6968 break;
9c2149c8 6969 default:
f31b035a 6970 goto cp0_unimplemented;
9c2149c8
TS
6971 }
6972 break;
6973 case 22:
d9bea114 6974 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
6975 rn = "'Diagnostic"; /* implementation dependent */
6976 break;
9c2149c8
TS
6977 case 23:
6978 switch (sel) {
6979 case 0:
895c2d04 6980 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
2423f660
TS
6981 rn = "Debug";
6982 break;
9c2149c8 6983 case 1:
895c2d04 6984// gen_helper_dmfc0_tracecontrol(arg, cpu_env); /* PDtrace support */
2423f660 6985 rn = "TraceControl";
3570d7f6 6986 goto cp0_unimplemented;
9c2149c8 6987 case 2:
895c2d04 6988// gen_helper_dmfc0_tracecontrol2(arg, cpu_env); /* PDtrace support */
2423f660 6989 rn = "TraceControl2";
3570d7f6 6990 goto cp0_unimplemented;
9c2149c8 6991 case 3:
895c2d04 6992// gen_helper_dmfc0_usertracedata(arg, cpu_env); /* PDtrace support */
2423f660 6993 rn = "UserTraceData";
3570d7f6 6994 goto cp0_unimplemented;
9c2149c8 6995 case 4:
895c2d04 6996// gen_helper_dmfc0_tracebpc(arg, cpu_env); /* PDtrace support */
2423f660 6997 rn = "TraceBPC";
3570d7f6 6998 goto cp0_unimplemented;
9c2149c8 6999 default:
f31b035a 7000 goto cp0_unimplemented;
9c2149c8
TS
7001 }
7002 break;
7003 case 24:
7004 switch (sel) {
7005 case 0:
f0b3f3ae 7006 /* EJTAG support */
7db13fae 7007 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
2423f660
TS
7008 rn = "DEPC";
7009 break;
9c2149c8 7010 default:
f31b035a 7011 goto cp0_unimplemented;
9c2149c8
TS
7012 }
7013 break;
7014 case 25:
7015 switch (sel) {
7016 case 0:
7db13fae 7017 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
2423f660 7018 rn = "Performance0";
9c2149c8
TS
7019 break;
7020 case 1:
d9bea114 7021// gen_helper_dmfc0_performance1(arg);
2423f660 7022 rn = "Performance1";
3570d7f6 7023 goto cp0_unimplemented;
9c2149c8 7024 case 2:
d9bea114 7025// gen_helper_dmfc0_performance2(arg);
2423f660 7026 rn = "Performance2";
3570d7f6 7027 goto cp0_unimplemented;
9c2149c8 7028 case 3:
d9bea114 7029// gen_helper_dmfc0_performance3(arg);
2423f660 7030 rn = "Performance3";
3570d7f6 7031 goto cp0_unimplemented;
9c2149c8 7032 case 4:
d9bea114 7033// gen_helper_dmfc0_performance4(arg);
2423f660 7034 rn = "Performance4";
3570d7f6 7035 goto cp0_unimplemented;
9c2149c8 7036 case 5:
d9bea114 7037// gen_helper_dmfc0_performance5(arg);
2423f660 7038 rn = "Performance5";
3570d7f6 7039 goto cp0_unimplemented;
9c2149c8 7040 case 6:
d9bea114 7041// gen_helper_dmfc0_performance6(arg);
2423f660 7042 rn = "Performance6";
3570d7f6 7043 goto cp0_unimplemented;
9c2149c8 7044 case 7:
d9bea114 7045// gen_helper_dmfc0_performance7(arg);
2423f660 7046 rn = "Performance7";
3570d7f6 7047 goto cp0_unimplemented;
9c2149c8 7048 default:
f31b035a 7049 goto cp0_unimplemented;
9c2149c8
TS
7050 }
7051 break;
7052 case 26:
0d74a222
LA
7053 switch (sel) {
7054 case 0:
7055 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl));
7056 rn = "ErrCtl";
7057 break;
7058 default:
7059 goto cp0_unimplemented;
7060 }
da80682b 7061 break;
9c2149c8
TS
7062 case 27:
7063 switch (sel) {
7064 /* ignored */
c2e19f3c
AM
7065 case 0:
7066 case 1:
7067 case 2:
7068 case 3:
d9bea114 7069 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
7070 rn = "CacheErr";
7071 break;
9c2149c8 7072 default:
f31b035a 7073 goto cp0_unimplemented;
9c2149c8
TS
7074 }
7075 break;
7076 case 28:
7077 switch (sel) {
7078 case 0:
7079 case 2:
7080 case 4:
7081 case 6:
7db13fae 7082 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
9c2149c8
TS
7083 rn = "TagLo";
7084 break;
7085 case 1:
7086 case 3:
7087 case 5:
7088 case 7:
7db13fae 7089 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
9c2149c8
TS
7090 rn = "DataLo";
7091 break;
7092 default:
f31b035a 7093 goto cp0_unimplemented;
9c2149c8
TS
7094 }
7095 break;
7096 case 29:
7097 switch (sel) {
7098 case 0:
7099 case 2:
7100 case 4:
7101 case 6:
7db13fae 7102 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
9c2149c8
TS
7103 rn = "TagHi";
7104 break;
7105 case 1:
7106 case 3:
7107 case 5:
7108 case 7:
7db13fae 7109 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
9c2149c8
TS
7110 rn = "DataHi";
7111 break;
7112 default:
f31b035a 7113 goto cp0_unimplemented;
9c2149c8
TS
7114 }
7115 break;
7116 case 30:
7117 switch (sel) {
7118 case 0:
7db13fae 7119 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
2423f660
TS
7120 rn = "ErrorEPC";
7121 break;
9c2149c8 7122 default:
f31b035a 7123 goto cp0_unimplemented;
9c2149c8
TS
7124 }
7125 break;
7126 case 31:
7127 switch (sel) {
7128 case 0:
f0b3f3ae 7129 /* EJTAG support */
7db13fae 7130 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
7131 rn = "DESAVE";
7132 break;
c2e19f3c
AM
7133 case 2:
7134 case 3:
7135 case 4:
7136 case 5:
7137 case 6:
7138 case 7:
f31b035a
LA
7139 CP0_CHECK(ctx->kscrexist & (1 << sel));
7140 tcg_gen_ld_tl(arg, cpu_env,
7141 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
7142 rn = "KScratch";
e98c0d17 7143 break;
9c2149c8 7144 default:
f31b035a 7145 goto cp0_unimplemented;
9c2149c8
TS
7146 }
7147 break;
7148 default:
f31b035a 7149 goto cp0_unimplemented;
9c2149c8 7150 }
b44a7fb1 7151 trace_mips_translate_c0("dmfc0", rn, reg, sel);
9c2149c8
TS
7152 return;
7153
f31b035a 7154cp0_unimplemented:
965447ee 7155 qemu_log_mask(LOG_UNIMP, "dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
f31b035a 7156 gen_mfc0_unimplemented(ctx, arg);
9c2149c8
TS
7157}
7158
d75c135e 7159static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
9c2149c8
TS
7160{
7161 const char *rn = "invalid";
7162
e189e748 7163 if (sel != 0)
d75c135e 7164 check_insn(ctx, ISA_MIPS64);
e189e748 7165
eeb3bba8 7166 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
2e70f6ef 7167 gen_io_start();
bd79255d 7168 }
2e70f6ef 7169
9c2149c8
TS
7170 switch (reg) {
7171 case 0:
7172 switch (sel) {
7173 case 0:
895c2d04 7174 gen_helper_mtc0_index(cpu_env, arg);
9c2149c8
TS
7175 rn = "Index";
7176 break;
7177 case 1:
f31b035a 7178 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7179 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
9c2149c8 7180 rn = "MVPControl";
ead9360e 7181 break;
9c2149c8 7182 case 2:
f31b035a 7183 CP0_CHECK(ctx->insn_flags & ASE_MT);
ead9360e 7184 /* ignored */
9c2149c8 7185 rn = "MVPConf0";
ead9360e 7186 break;
9c2149c8 7187 case 3:
f31b035a 7188 CP0_CHECK(ctx->insn_flags & ASE_MT);
ead9360e 7189 /* ignored */
9c2149c8 7190 rn = "MVPConf1";
ead9360e 7191 break;
01bc435b
YK
7192 case 4:
7193 CP0_CHECK(ctx->vp);
7194 /* ignored */
7195 rn = "VPControl";
7196 break;
9c2149c8 7197 default:
f31b035a 7198 goto cp0_unimplemented;
9c2149c8
TS
7199 }
7200 break;
7201 case 1:
7202 switch (sel) {
7203 case 0:
2423f660 7204 /* ignored */
9c2149c8 7205 rn = "Random";
2423f660 7206 break;
9c2149c8 7207 case 1:
f31b035a 7208 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7209 gen_helper_mtc0_vpecontrol(cpu_env, arg);
9c2149c8 7210 rn = "VPEControl";
ead9360e 7211 break;
9c2149c8 7212 case 2:
f31b035a 7213 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7214 gen_helper_mtc0_vpeconf0(cpu_env, arg);
9c2149c8 7215 rn = "VPEConf0";
ead9360e 7216 break;
9c2149c8 7217 case 3:
f31b035a 7218 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7219 gen_helper_mtc0_vpeconf1(cpu_env, arg);
9c2149c8 7220 rn = "VPEConf1";
ead9360e 7221 break;
9c2149c8 7222 case 4:
f31b035a 7223 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7224 gen_helper_mtc0_yqmask(cpu_env, arg);
9c2149c8 7225 rn = "YQMask";
ead9360e 7226 break;
9c2149c8 7227 case 5:
f31b035a 7228 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 7229 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
9c2149c8 7230 rn = "VPESchedule";
ead9360e 7231 break;
9c2149c8 7232 case 6:
f31b035a 7233 CP0_CHECK(ctx->insn_flags & ASE_MT);
7db13fae 7234 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
9c2149c8 7235 rn = "VPEScheFBack";
ead9360e 7236 break;
9c2149c8 7237 case 7:
f31b035a 7238 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7239 gen_helper_mtc0_vpeopt(cpu_env, arg);
9c2149c8 7240 rn = "VPEOpt";
ead9360e 7241 break;
9c2149c8 7242 default:
f31b035a 7243 goto cp0_unimplemented;
9c2149c8
TS
7244 }
7245 break;
7246 case 2:
7247 switch (sel) {
7248 case 0:
7207c7f9 7249 gen_helper_dmtc0_entrylo0(cpu_env, arg);
2423f660
TS
7250 rn = "EntryLo0";
7251 break;
9c2149c8 7252 case 1:
f31b035a 7253 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7254 gen_helper_mtc0_tcstatus(cpu_env, arg);
2423f660 7255 rn = "TCStatus";
ead9360e 7256 break;
9c2149c8 7257 case 2:
f31b035a 7258 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7259 gen_helper_mtc0_tcbind(cpu_env, arg);
2423f660 7260 rn = "TCBind";
ead9360e 7261 break;
9c2149c8 7262 case 3:
f31b035a 7263 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7264 gen_helper_mtc0_tcrestart(cpu_env, arg);
2423f660 7265 rn = "TCRestart";
ead9360e 7266 break;
9c2149c8 7267 case 4:
f31b035a 7268 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7269 gen_helper_mtc0_tchalt(cpu_env, arg);
2423f660 7270 rn = "TCHalt";
ead9360e 7271 break;
9c2149c8 7272 case 5:
f31b035a 7273 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7274 gen_helper_mtc0_tccontext(cpu_env, arg);
2423f660 7275 rn = "TCContext";
ead9360e 7276 break;
9c2149c8 7277 case 6:
f31b035a 7278 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7279 gen_helper_mtc0_tcschedule(cpu_env, arg);
2423f660 7280 rn = "TCSchedule";
ead9360e 7281 break;
9c2149c8 7282 case 7:
f31b035a 7283 CP0_CHECK(ctx->insn_flags & ASE_MT);
895c2d04 7284 gen_helper_mtc0_tcschefback(cpu_env, arg);
2423f660 7285 rn = "TCScheFBack";
ead9360e 7286 break;
9c2149c8 7287 default:
f31b035a 7288 goto cp0_unimplemented;
9c2149c8
TS
7289 }
7290 break;
7291 case 3:
7292 switch (sel) {
7293 case 0:
7207c7f9 7294 gen_helper_dmtc0_entrylo1(cpu_env, arg);
2423f660
TS
7295 rn = "EntryLo1";
7296 break;
01bc435b
YK
7297 case 1:
7298 CP0_CHECK(ctx->vp);
7299 /* ignored */
7300 rn = "GlobalNumber";
7301 break;
9c2149c8 7302 default:
f31b035a 7303 goto cp0_unimplemented;
876d4b07 7304 }
9c2149c8
TS
7305 break;
7306 case 4:
7307 switch (sel) {
7308 case 0:
895c2d04 7309 gen_helper_mtc0_context(cpu_env, arg);
2423f660
TS
7310 rn = "Context";
7311 break;
9c2149c8 7312 case 1:
895c2d04 7313// gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
2423f660 7314 rn = "ContextConfig";
f31b035a 7315 goto cp0_unimplemented;
d279279e 7316 case 2:
f31b035a
LA
7317 CP0_CHECK(ctx->ulri);
7318 tcg_gen_st_tl(arg, cpu_env,
7319 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
7320 rn = "UserLocal";
d279279e 7321 break;
9c2149c8 7322 default:
f31b035a 7323 goto cp0_unimplemented;
876d4b07 7324 }
9c2149c8
TS
7325 break;
7326 case 5:
7327 switch (sel) {
7328 case 0:
895c2d04 7329 gen_helper_mtc0_pagemask(cpu_env, arg);
2423f660
TS
7330 rn = "PageMask";
7331 break;
9c2149c8 7332 case 1:
d75c135e 7333 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7334 gen_helper_mtc0_pagegrain(cpu_env, arg);
2423f660
TS
7335 rn = "PageGrain";
7336 break;
cec56a73
JH
7337 case 2:
7338 CP0_CHECK(ctx->sc);
7339 gen_helper_mtc0_segctl0(cpu_env, arg);
7340 rn = "SegCtl0";
7341 break;
7342 case 3:
7343 CP0_CHECK(ctx->sc);
7344 gen_helper_mtc0_segctl1(cpu_env, arg);
7345 rn = "SegCtl1";
7346 break;
7347 case 4:
7348 CP0_CHECK(ctx->sc);
7349 gen_helper_mtc0_segctl2(cpu_env, arg);
7350 rn = "SegCtl2";
7351 break;
9c2149c8 7352 default:
f31b035a 7353 goto cp0_unimplemented;
876d4b07 7354 }
9c2149c8
TS
7355 break;
7356 case 6:
7357 switch (sel) {
7358 case 0:
895c2d04 7359 gen_helper_mtc0_wired(cpu_env, arg);
2423f660
TS
7360 rn = "Wired";
7361 break;
9c2149c8 7362 case 1:
d75c135e 7363 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7364 gen_helper_mtc0_srsconf0(cpu_env, arg);
2423f660 7365 rn = "SRSConf0";
ead9360e 7366 break;
9c2149c8 7367 case 2:
d75c135e 7368 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7369 gen_helper_mtc0_srsconf1(cpu_env, arg);
2423f660 7370 rn = "SRSConf1";
ead9360e 7371 break;
9c2149c8 7372 case 3:
d75c135e 7373 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7374 gen_helper_mtc0_srsconf2(cpu_env, arg);
2423f660 7375 rn = "SRSConf2";
ead9360e 7376 break;
9c2149c8 7377 case 4:
d75c135e 7378 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7379 gen_helper_mtc0_srsconf3(cpu_env, arg);
2423f660 7380 rn = "SRSConf3";
ead9360e 7381 break;
9c2149c8 7382 case 5:
d75c135e 7383 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7384 gen_helper_mtc0_srsconf4(cpu_env, arg);
2423f660 7385 rn = "SRSConf4";
ead9360e 7386 break;
9c2149c8 7387 default:
f31b035a 7388 goto cp0_unimplemented;
876d4b07 7389 }
9c2149c8
TS
7390 break;
7391 case 7:
7392 switch (sel) {
7393 case 0:
d75c135e 7394 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7395 gen_helper_mtc0_hwrena(cpu_env, arg);
eeb3bba8 7396 ctx->base.is_jmp = DISAS_STOP;
2423f660
TS
7397 rn = "HWREna";
7398 break;
9c2149c8 7399 default:
f31b035a 7400 goto cp0_unimplemented;
876d4b07 7401 }
9c2149c8
TS
7402 break;
7403 case 8:
aea14095
LA
7404 switch (sel) {
7405 case 0:
7406 /* ignored */
7407 rn = "BadVAddr";
7408 break;
7409 case 1:
7410 /* ignored */
7411 rn = "BadInstr";
7412 break;
7413 case 2:
7414 /* ignored */
7415 rn = "BadInstrP";
7416 break;
25beba9b
SM
7417 case 3:
7418 /* ignored */
7419 rn = "BadInstrX";
7420 break;
aea14095 7421 default:
f31b035a 7422 goto cp0_unimplemented;
aea14095 7423 }
9c2149c8
TS
7424 break;
7425 case 9:
7426 switch (sel) {
7427 case 0:
895c2d04 7428 gen_helper_mtc0_count(cpu_env, arg);
2423f660
TS
7429 rn = "Count";
7430 break;
876d4b07 7431 /* 6,7 are implementation dependent */
9c2149c8 7432 default:
f31b035a 7433 goto cp0_unimplemented;
876d4b07
TS
7434 }
7435 /* Stop translation as we may have switched the execution mode */
eeb3bba8 7436 ctx->base.is_jmp = DISAS_STOP;
9c2149c8
TS
7437 break;
7438 case 10:
7439 switch (sel) {
7440 case 0:
895c2d04 7441 gen_helper_mtc0_entryhi(cpu_env, arg);
2423f660
TS
7442 rn = "EntryHi";
7443 break;
9c2149c8 7444 default:
f31b035a 7445 goto cp0_unimplemented;
876d4b07 7446 }
9c2149c8
TS
7447 break;
7448 case 11:
7449 switch (sel) {
7450 case 0:
895c2d04 7451 gen_helper_mtc0_compare(cpu_env, arg);
2423f660
TS
7452 rn = "Compare";
7453 break;
876d4b07 7454 /* 6,7 are implementation dependent */
9c2149c8 7455 default:
f31b035a 7456 goto cp0_unimplemented;
876d4b07 7457 }
de9a95f0 7458 /* Stop translation as we may have switched the execution mode */
eeb3bba8 7459 ctx->base.is_jmp = DISAS_STOP;
9c2149c8
TS
7460 break;
7461 case 12:
7462 switch (sel) {
7463 case 0:
867abc7e 7464 save_cpu_state(ctx, 1);
895c2d04 7465 gen_helper_mtc0_status(cpu_env, arg);
b28425ba 7466 /* DISAS_STOP isn't good enough here, hflags may have changed. */
eeb3bba8
EC
7467 gen_save_pc(ctx->base.pc_next + 4);
7468 ctx->base.is_jmp = DISAS_EXIT;
2423f660
TS
7469 rn = "Status";
7470 break;
9c2149c8 7471 case 1:
d75c135e 7472 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7473 gen_helper_mtc0_intctl(cpu_env, arg);
8487327a 7474 /* Stop translation as we may have switched the execution mode */
eeb3bba8 7475 ctx->base.is_jmp = DISAS_STOP;
2423f660
TS
7476 rn = "IntCtl";
7477 break;
9c2149c8 7478 case 2:
d75c135e 7479 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7480 gen_helper_mtc0_srsctl(cpu_env, arg);
8487327a 7481 /* Stop translation as we may have switched the execution mode */
eeb3bba8 7482 ctx->base.is_jmp = DISAS_STOP;
2423f660
TS
7483 rn = "SRSCtl";
7484 break;
9c2149c8 7485 case 3:
d75c135e 7486 check_insn(ctx, ISA_MIPS32R2);
7db13fae 7487 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
8487327a 7488 /* Stop translation as we may have switched the execution mode */
eeb3bba8 7489 ctx->base.is_jmp = DISAS_STOP;
2423f660
TS
7490 rn = "SRSMap";
7491 break;
7492 default:
f31b035a 7493 goto cp0_unimplemented;
876d4b07 7494 }
9c2149c8
TS
7495 break;
7496 case 13:
7497 switch (sel) {
7498 case 0:
867abc7e 7499 save_cpu_state(ctx, 1);
895c2d04 7500 gen_helper_mtc0_cause(cpu_env, arg);
b28425ba
EC
7501 /* Stop translation as we may have triggered an interrupt.
7502 * DISAS_STOP isn't sufficient, we need to ensure we break out of
7503 * translated code to check for pending interrupts. */
eeb3bba8
EC
7504 gen_save_pc(ctx->base.pc_next + 4);
7505 ctx->base.is_jmp = DISAS_EXIT;
2423f660
TS
7506 rn = "Cause";
7507 break;
9c2149c8 7508 default:
f31b035a 7509 goto cp0_unimplemented;
876d4b07 7510 }
9c2149c8
TS
7511 break;
7512 case 14:
7513 switch (sel) {
7514 case 0:
7db13fae 7515 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
2423f660
TS
7516 rn = "EPC";
7517 break;
9c2149c8 7518 default:
f31b035a 7519 goto cp0_unimplemented;
876d4b07 7520 }
9c2149c8
TS
7521 break;
7522 case 15:
7523 switch (sel) {
7524 case 0:
2423f660
TS
7525 /* ignored */
7526 rn = "PRid";
7527 break;
9c2149c8 7528 case 1:
d75c135e 7529 check_insn(ctx, ISA_MIPS32R2);
895c2d04 7530 gen_helper_mtc0_ebase(cpu_env, arg);
2423f660
TS
7531 rn = "EBase";
7532 break;
9c2149c8 7533 default:
f31b035a 7534 goto cp0_unimplemented;
876d4b07 7535 }
9c2149c8
TS
7536 break;
7537 case 16:
7538 switch (sel) {
7539 case 0:
895c2d04 7540 gen_helper_mtc0_config0(cpu_env, arg);
9c2149c8 7541 rn = "Config";
2423f660 7542 /* Stop translation as we may have switched the execution mode */
eeb3bba8 7543 ctx->base.is_jmp = DISAS_STOP;
9c2149c8
TS
7544 break;
7545 case 1:
1fc7bf6e 7546 /* ignored, read only */
9c2149c8
TS
7547 rn = "Config1";
7548 break;
7549 case 2:
895c2d04 7550 gen_helper_mtc0_config2(cpu_env, arg);
9c2149c8 7551 rn = "Config2";
2423f660 7552 /* Stop translation as we may have switched the execution mode */
eeb3bba8 7553 ctx->base.is_jmp = DISAS_STOP;
9c2149c8
TS
7554 break;
7555 case 3:
90f12d73 7556 gen_helper_mtc0_config3(cpu_env, arg);
9c2149c8 7557 rn = "Config3";
90f12d73 7558 /* Stop translation as we may have switched the execution mode */
eeb3bba8 7559 ctx->base.is_jmp = DISAS_STOP;
9c2149c8 7560 break;
faf1f68b
LA
7561 case 4:
7562 /* currently ignored */
7563 rn = "Config4";
7564 break;
7565 case 5:
7566 gen_helper_mtc0_config5(cpu_env, arg);
7567 rn = "Config5";
7568 /* Stop translation as we may have switched the execution mode */
eeb3bba8 7569 ctx->base.is_jmp = DISAS_STOP;
faf1f68b 7570 break;
9c2149c8
TS
7571 /* 6,7 are implementation dependent */
7572 default:
7573 rn = "Invalid config selector";
f31b035a 7574 goto cp0_unimplemented;
9c2149c8 7575 }
9c2149c8
TS
7576 break;
7577 case 17:
7578 switch (sel) {
7579 case 0:
895c2d04 7580 gen_helper_mtc0_lladdr(cpu_env, arg);
2423f660
TS
7581 rn = "LLAddr";
7582 break;
f6d4dd81
YK
7583 case 1:
7584 CP0_CHECK(ctx->mrp);
7585 gen_helper_mtc0_maar(cpu_env, arg);
7586 rn = "MAAR";
7587 break;
7588 case 2:
7589 CP0_CHECK(ctx->mrp);
7590 gen_helper_mtc0_maari(cpu_env, arg);
7591 rn = "MAARI";
7592 break;
9c2149c8 7593 default:
f31b035a 7594 goto cp0_unimplemented;
9c2149c8
TS
7595 }
7596 break;
7597 case 18:
7598 switch (sel) {
c2e19f3c
AM
7599 case 0:
7600 case 1:
7601 case 2:
7602 case 3:
7603 case 4:
7604 case 5:
7605 case 6:
7606 case 7:
895c2d04 7607 gen_helper_0e1i(mtc0_watchlo, arg, sel);
2423f660
TS
7608 rn = "WatchLo";
7609 break;
9c2149c8 7610 default:
f31b035a 7611 goto cp0_unimplemented;
9c2149c8
TS
7612 }
7613 break;
7614 case 19:
7615 switch (sel) {
c2e19f3c
AM
7616 case 0:
7617 case 1:
7618 case 2:
7619 case 3:
7620 case 4:
7621 case 5:
7622 case 6:
7623 case 7:
895c2d04 7624 gen_helper_0e1i(mtc0_watchhi, arg, sel);
2423f660
TS
7625 rn = "WatchHi";
7626 break;
9c2149c8 7627 default:
f31b035a 7628 goto cp0_unimplemented;
9c2149c8
TS
7629 }
7630 break;
7631 case 20:
7632 switch (sel) {
7633 case 0:
d75c135e 7634 check_insn(ctx, ISA_MIPS3);
895c2d04 7635 gen_helper_mtc0_xcontext(cpu_env, arg);
2423f660
TS
7636 rn = "XContext";
7637 break;
9c2149c8 7638 default:
f31b035a 7639 goto cp0_unimplemented;
9c2149c8
TS
7640 }
7641 break;
7642 case 21:
7643 /* Officially reserved, but sel 0 is used for R1x000 framemask */
f31b035a 7644 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
9c2149c8
TS
7645 switch (sel) {
7646 case 0:
895c2d04 7647 gen_helper_mtc0_framemask(cpu_env, arg);
2423f660
TS
7648 rn = "Framemask";
7649 break;
9c2149c8 7650 default:
f31b035a 7651 goto cp0_unimplemented;
9c2149c8
TS
7652 }
7653 break;
7654 case 22:
7655 /* ignored */
7656 rn = "Diagnostic"; /* implementation dependent */
876d4b07 7657 break;
9c2149c8
TS
7658 case 23:
7659 switch (sel) {
7660 case 0:
895c2d04 7661 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
b28425ba 7662 /* DISAS_STOP isn't good enough here, hflags may have changed. */
eeb3bba8
EC
7663 gen_save_pc(ctx->base.pc_next + 4);
7664 ctx->base.is_jmp = DISAS_EXIT;
2423f660
TS
7665 rn = "Debug";
7666 break;
9c2149c8 7667 case 1:
895c2d04 7668// gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
8487327a 7669 /* Stop translation as we may have switched the execution mode */
eeb3bba8 7670 ctx->base.is_jmp = DISAS_STOP;
2423f660 7671 rn = "TraceControl";
3570d7f6 7672 goto cp0_unimplemented;
9c2149c8 7673 case 2:
895c2d04 7674// gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
8487327a 7675 /* Stop translation as we may have switched the execution mode */
eeb3bba8 7676 ctx->base.is_jmp = DISAS_STOP;
2423f660 7677 rn = "TraceControl2";
3570d7f6 7678 goto cp0_unimplemented;
9c2149c8 7679 case 3:
895c2d04 7680// gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
8487327a 7681 /* Stop translation as we may have switched the execution mode */
eeb3bba8 7682 ctx->base.is_jmp = DISAS_STOP;
2423f660 7683 rn = "UserTraceData";
3570d7f6 7684 goto cp0_unimplemented;
9c2149c8 7685 case 4:
895c2d04 7686// gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
8487327a 7687 /* Stop translation as we may have switched the execution mode */
eeb3bba8 7688 ctx->base.is_jmp = DISAS_STOP;
2423f660 7689 rn = "TraceBPC";
3570d7f6 7690 goto cp0_unimplemented;
9c2149c8 7691 default:
f31b035a 7692 goto cp0_unimplemented;
9c2149c8 7693 }
9c2149c8
TS
7694 break;
7695 case 24:
7696 switch (sel) {
7697 case 0:
f1aa6320 7698 /* EJTAG support */
7db13fae 7699 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
2423f660
TS
7700 rn = "DEPC";
7701 break;
9c2149c8 7702 default:
f31b035a 7703 goto cp0_unimplemented;
9c2149c8
TS
7704 }
7705 break;
7706 case 25:
7707 switch (sel) {
7708 case 0:
895c2d04 7709 gen_helper_mtc0_performance0(cpu_env, arg);
2423f660
TS
7710 rn = "Performance0";
7711 break;
9c2149c8 7712 case 1:
895c2d04 7713// gen_helper_mtc0_performance1(cpu_env, arg);
2423f660 7714 rn = "Performance1";
3570d7f6 7715 goto cp0_unimplemented;
9c2149c8 7716 case 2:
895c2d04 7717// gen_helper_mtc0_performance2(cpu_env, arg);
2423f660 7718 rn = "Performance2";
3570d7f6 7719 goto cp0_unimplemented;
9c2149c8 7720 case 3:
895c2d04 7721// gen_helper_mtc0_performance3(cpu_env, arg);
2423f660 7722 rn = "Performance3";
3570d7f6 7723 goto cp0_unimplemented;
9c2149c8 7724 case 4:
895c2d04 7725// gen_helper_mtc0_performance4(cpu_env, arg);
2423f660 7726 rn = "Performance4";
3570d7f6 7727 goto cp0_unimplemented;
9c2149c8 7728 case 5:
895c2d04 7729// gen_helper_mtc0_performance5(cpu_env, arg);
2423f660 7730 rn = "Performance5";
3570d7f6 7731 goto cp0_unimplemented;
9c2149c8 7732 case 6:
895c2d04 7733// gen_helper_mtc0_performance6(cpu_env, arg);
2423f660 7734 rn = "Performance6";
3570d7f6 7735 goto cp0_unimplemented;
9c2149c8 7736 case 7:
895c2d04 7737// gen_helper_mtc0_performance7(cpu_env, arg);
2423f660 7738 rn = "Performance7";
3570d7f6 7739 goto cp0_unimplemented;
9c2149c8 7740 default:
f31b035a 7741 goto cp0_unimplemented;
9c2149c8 7742 }
876d4b07 7743 break;
9c2149c8 7744 case 26:
0d74a222
LA
7745 switch (sel) {
7746 case 0:
7747 gen_helper_mtc0_errctl(cpu_env, arg);
eeb3bba8 7748 ctx->base.is_jmp = DISAS_STOP;
0d74a222
LA
7749 rn = "ErrCtl";
7750 break;
7751 default:
7752 goto cp0_unimplemented;
7753 }
876d4b07 7754 break;
9c2149c8
TS
7755 case 27:
7756 switch (sel) {
c2e19f3c
AM
7757 case 0:
7758 case 1:
7759 case 2:
7760 case 3:
2423f660
TS
7761 /* ignored */
7762 rn = "CacheErr";
7763 break;
9c2149c8 7764 default:
f31b035a 7765 goto cp0_unimplemented;
9c2149c8 7766 }
876d4b07 7767 break;
9c2149c8
TS
7768 case 28:
7769 switch (sel) {
7770 case 0:
7771 case 2:
7772 case 4:
7773 case 6:
895c2d04 7774 gen_helper_mtc0_taglo(cpu_env, arg);
9c2149c8
TS
7775 rn = "TagLo";
7776 break;
7777 case 1:
7778 case 3:
7779 case 5:
7780 case 7:
895c2d04 7781 gen_helper_mtc0_datalo(cpu_env, arg);
9c2149c8
TS
7782 rn = "DataLo";
7783 break;
7784 default:
f31b035a 7785 goto cp0_unimplemented;
9c2149c8
TS
7786 }
7787 break;
7788 case 29:
7789 switch (sel) {
7790 case 0:
7791 case 2:
7792 case 4:
7793 case 6:
895c2d04 7794 gen_helper_mtc0_taghi(cpu_env, arg);
9c2149c8
TS
7795 rn = "TagHi";
7796 break;
7797 case 1:
7798 case 3:
7799 case 5:
7800 case 7:
895c2d04 7801 gen_helper_mtc0_datahi(cpu_env, arg);
9c2149c8
TS
7802 rn = "DataHi";
7803 break;
7804 default:
7805 rn = "invalid sel";
f31b035a 7806 goto cp0_unimplemented;
9c2149c8 7807 }
876d4b07 7808 break;
9c2149c8
TS
7809 case 30:
7810 switch (sel) {
7811 case 0:
7db13fae 7812 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
2423f660
TS
7813 rn = "ErrorEPC";
7814 break;
9c2149c8 7815 default:
f31b035a 7816 goto cp0_unimplemented;
9c2149c8
TS
7817 }
7818 break;
7819 case 31:
7820 switch (sel) {
7821 case 0:
f1aa6320 7822 /* EJTAG support */
7db13fae 7823 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
7824 rn = "DESAVE";
7825 break;
c2e19f3c
AM
7826 case 2:
7827 case 3:
7828 case 4:
7829 case 5:
7830 case 6:
7831 case 7:
f31b035a
LA
7832 CP0_CHECK(ctx->kscrexist & (1 << sel));
7833 tcg_gen_st_tl(arg, cpu_env,
7834 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
7835 rn = "KScratch";
e98c0d17 7836 break;
9c2149c8 7837 default:
f31b035a 7838 goto cp0_unimplemented;
9c2149c8 7839 }
9c2149c8
TS
7840 break;
7841 default:
f31b035a 7842 goto cp0_unimplemented;
9c2149c8 7843 }
b44a7fb1
PMD
7844 trace_mips_translate_c0("dmtc0", rn, reg, sel);
7845
bf20dc07 7846 /* For simplicity assume that all writes can cause interrupts. */
eeb3bba8 7847 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
2e70f6ef 7848 gen_io_end();
b28425ba 7849 /* DISAS_STOP isn't sufficient, we need to ensure we break out of
b74cddcb 7850 * translated code to check for pending interrupts. */
eeb3bba8
EC
7851 gen_save_pc(ctx->base.pc_next + 4);
7852 ctx->base.is_jmp = DISAS_EXIT;
2e70f6ef 7853 }
9c2149c8
TS
7854 return;
7855
f31b035a 7856cp0_unimplemented:
965447ee 7857 qemu_log_mask(LOG_UNIMP, "dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
9c2149c8 7858}
d26bc211 7859#endif /* TARGET_MIPS64 */
9c2149c8 7860
7db13fae 7861static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
ead9360e
TS
7862 int u, int sel, int h)
7863{
7864 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
a7812ae4 7865 TCGv t0 = tcg_temp_local_new();
ead9360e
TS
7866
7867 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
b5dc7732
TS
7868 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
7869 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
1a3fd9c3 7870 tcg_gen_movi_tl(t0, -1);
ead9360e
TS
7871 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
7872 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
1a3fd9c3 7873 tcg_gen_movi_tl(t0, -1);
ead9360e
TS
7874 else if (u == 0) {
7875 switch (rt) {
5a25ce94
EI
7876 case 1:
7877 switch (sel) {
7878 case 1:
895c2d04 7879 gen_helper_mftc0_vpecontrol(t0, cpu_env);
5a25ce94
EI
7880 break;
7881 case 2:
895c2d04 7882 gen_helper_mftc0_vpeconf0(t0, cpu_env);
5a25ce94
EI
7883 break;
7884 default:
7885 goto die;
7886 break;
7887 }
7888 break;
ead9360e
TS
7889 case 2:
7890 switch (sel) {
7891 case 1:
895c2d04 7892 gen_helper_mftc0_tcstatus(t0, cpu_env);
ead9360e
TS
7893 break;
7894 case 2:
895c2d04 7895 gen_helper_mftc0_tcbind(t0, cpu_env);
ead9360e
TS
7896 break;
7897 case 3:
895c2d04 7898 gen_helper_mftc0_tcrestart(t0, cpu_env);
ead9360e
TS
7899 break;
7900 case 4:
895c2d04 7901 gen_helper_mftc0_tchalt(t0, cpu_env);
ead9360e
TS
7902 break;
7903 case 5:
895c2d04 7904 gen_helper_mftc0_tccontext(t0, cpu_env);
ead9360e
TS
7905 break;
7906 case 6:
895c2d04 7907 gen_helper_mftc0_tcschedule(t0, cpu_env);
ead9360e
TS
7908 break;
7909 case 7:
895c2d04 7910 gen_helper_mftc0_tcschefback(t0, cpu_env);
ead9360e
TS
7911 break;
7912 default:
d75c135e 7913 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
7914 break;
7915 }
7916 break;
7917 case 10:
7918 switch (sel) {
7919 case 0:
895c2d04 7920 gen_helper_mftc0_entryhi(t0, cpu_env);
ead9360e
TS
7921 break;
7922 default:
d75c135e 7923 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
7924 break;
7925 }
7926 case 12:
7927 switch (sel) {
7928 case 0:
895c2d04 7929 gen_helper_mftc0_status(t0, cpu_env);
ead9360e
TS
7930 break;
7931 default:
d75c135e 7932 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
7933 break;
7934 }
5a25ce94
EI
7935 case 13:
7936 switch (sel) {
7937 case 0:
895c2d04 7938 gen_helper_mftc0_cause(t0, cpu_env);
5a25ce94
EI
7939 break;
7940 default:
7941 goto die;
7942 break;
7943 }
7944 break;
7945 case 14:
7946 switch (sel) {
7947 case 0:
895c2d04 7948 gen_helper_mftc0_epc(t0, cpu_env);
5a25ce94
EI
7949 break;
7950 default:
7951 goto die;
7952 break;
7953 }
7954 break;
7955 case 15:
7956 switch (sel) {
7957 case 1:
895c2d04 7958 gen_helper_mftc0_ebase(t0, cpu_env);
5a25ce94
EI
7959 break;
7960 default:
7961 goto die;
7962 break;
7963 }
7964 break;
7965 case 16:
7966 switch (sel) {
c2e19f3c
AM
7967 case 0:
7968 case 1:
7969 case 2:
7970 case 3:
7971 case 4:
7972 case 5:
7973 case 6:
7974 case 7:
895c2d04 7975 gen_helper_mftc0_configx(t0, cpu_env, tcg_const_tl(sel));
5a25ce94
EI
7976 break;
7977 default:
7978 goto die;
7979 break;
7980 }
7981 break;
ead9360e
TS
7982 case 23:
7983 switch (sel) {
7984 case 0:
895c2d04 7985 gen_helper_mftc0_debug(t0, cpu_env);
ead9360e
TS
7986 break;
7987 default:
d75c135e 7988 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
7989 break;
7990 }
7991 break;
7992 default:
d75c135e 7993 gen_mfc0(ctx, t0, rt, sel);
ead9360e
TS
7994 }
7995 } else switch (sel) {
7996 /* GPR registers. */
7997 case 0:
895c2d04 7998 gen_helper_1e0i(mftgpr, t0, rt);
ead9360e
TS
7999 break;
8000 /* Auxiliary CPU registers */
8001 case 1:
8002 switch (rt) {
8003 case 0:
895c2d04 8004 gen_helper_1e0i(mftlo, t0, 0);
ead9360e
TS
8005 break;
8006 case 1:
895c2d04 8007 gen_helper_1e0i(mfthi, t0, 0);
ead9360e
TS
8008 break;
8009 case 2:
895c2d04 8010 gen_helper_1e0i(mftacx, t0, 0);
ead9360e
TS
8011 break;
8012 case 4:
895c2d04 8013 gen_helper_1e0i(mftlo, t0, 1);
ead9360e
TS
8014 break;
8015 case 5:
895c2d04 8016 gen_helper_1e0i(mfthi, t0, 1);
ead9360e
TS
8017 break;
8018 case 6:
895c2d04 8019 gen_helper_1e0i(mftacx, t0, 1);
ead9360e
TS
8020 break;
8021 case 8:
895c2d04 8022 gen_helper_1e0i(mftlo, t0, 2);
ead9360e
TS
8023 break;
8024 case 9:
895c2d04 8025 gen_helper_1e0i(mfthi, t0, 2);
ead9360e
TS
8026 break;
8027 case 10:
895c2d04 8028 gen_helper_1e0i(mftacx, t0, 2);
ead9360e
TS
8029 break;
8030 case 12:
895c2d04 8031 gen_helper_1e0i(mftlo, t0, 3);
ead9360e
TS
8032 break;
8033 case 13:
895c2d04 8034 gen_helper_1e0i(mfthi, t0, 3);
ead9360e
TS
8035 break;
8036 case 14:
895c2d04 8037 gen_helper_1e0i(mftacx, t0, 3);
ead9360e
TS
8038 break;
8039 case 16:
895c2d04 8040 gen_helper_mftdsp(t0, cpu_env);
ead9360e
TS
8041 break;
8042 default:
8043 goto die;
8044 }
8045 break;
8046 /* Floating point (COP1). */
8047 case 2:
8048 /* XXX: For now we support only a single FPU context. */
8049 if (h == 0) {
a7812ae4 8050 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8051
7c979afd 8052 gen_load_fpr32(ctx, fp0, rt);
b6d96bed 8053 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 8054 tcg_temp_free_i32(fp0);
ead9360e 8055 } else {
a7812ae4 8056 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8057
7f6613ce 8058 gen_load_fpr32h(ctx, fp0, rt);
b6d96bed 8059 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 8060 tcg_temp_free_i32(fp0);
ead9360e
TS
8061 }
8062 break;
8063 case 3:
8064 /* XXX: For now we support only a single FPU context. */
895c2d04 8065 gen_helper_1e0i(cfc1, t0, rt);
ead9360e
TS
8066 break;
8067 /* COP2: Not implemented. */
8068 case 4:
8069 case 5:
8070 /* fall through */
8071 default:
8072 goto die;
8073 }
b44a7fb1 8074 trace_mips_translate_tr("mftr", rt, u, sel, h);
1a3fd9c3
TS
8075 gen_store_gpr(t0, rd);
8076 tcg_temp_free(t0);
ead9360e
TS
8077 return;
8078
8079die:
1a3fd9c3 8080 tcg_temp_free(t0);
d12d51d5 8081 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
9c708c7f 8082 generate_exception_end(ctx, EXCP_RI);
ead9360e
TS
8083}
8084
7db13fae 8085static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
ead9360e
TS
8086 int u, int sel, int h)
8087{
8088 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
a7812ae4 8089 TCGv t0 = tcg_temp_local_new();
ead9360e 8090
1a3fd9c3 8091 gen_load_gpr(t0, rt);
ead9360e 8092 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
b5dc7732
TS
8093 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
8094 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
ead9360e
TS
8095 /* NOP */ ;
8096 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
8097 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
8098 /* NOP */ ;
8099 else if (u == 0) {
8100 switch (rd) {
5a25ce94
EI
8101 case 1:
8102 switch (sel) {
8103 case 1:
895c2d04 8104 gen_helper_mttc0_vpecontrol(cpu_env, t0);
5a25ce94
EI
8105 break;
8106 case 2:
895c2d04 8107 gen_helper_mttc0_vpeconf0(cpu_env, t0);
5a25ce94
EI
8108 break;
8109 default:
8110 goto die;
8111 break;
8112 }
8113 break;
ead9360e
TS
8114 case 2:
8115 switch (sel) {
8116 case 1:
895c2d04 8117 gen_helper_mttc0_tcstatus(cpu_env, t0);
ead9360e
TS
8118 break;
8119 case 2:
895c2d04 8120 gen_helper_mttc0_tcbind(cpu_env, t0);
ead9360e
TS
8121 break;
8122 case 3:
895c2d04 8123 gen_helper_mttc0_tcrestart(cpu_env, t0);
ead9360e
TS
8124 break;
8125 case 4:
895c2d04 8126 gen_helper_mttc0_tchalt(cpu_env, t0);
ead9360e
TS
8127 break;
8128 case 5:
895c2d04 8129 gen_helper_mttc0_tccontext(cpu_env, t0);
ead9360e
TS
8130 break;
8131 case 6:
895c2d04 8132 gen_helper_mttc0_tcschedule(cpu_env, t0);
ead9360e
TS
8133 break;
8134 case 7:
895c2d04 8135 gen_helper_mttc0_tcschefback(cpu_env, t0);
ead9360e
TS
8136 break;
8137 default:
d75c135e 8138 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
8139 break;
8140 }
8141 break;
8142 case 10:
8143 switch (sel) {
8144 case 0:
895c2d04 8145 gen_helper_mttc0_entryhi(cpu_env, t0);
ead9360e
TS
8146 break;
8147 default:
d75c135e 8148 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
8149 break;
8150 }
8151 case 12:
8152 switch (sel) {
8153 case 0:
895c2d04 8154 gen_helper_mttc0_status(cpu_env, t0);
ead9360e
TS
8155 break;
8156 default:
d75c135e 8157 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
8158 break;
8159 }
5a25ce94
EI
8160 case 13:
8161 switch (sel) {
8162 case 0:
895c2d04 8163 gen_helper_mttc0_cause(cpu_env, t0);
5a25ce94
EI
8164 break;
8165 default:
8166 goto die;
8167 break;
8168 }
8169 break;
8170 case 15:
8171 switch (sel) {
8172 case 1:
895c2d04 8173 gen_helper_mttc0_ebase(cpu_env, t0);
5a25ce94
EI
8174 break;
8175 default:
8176 goto die;
8177 break;
8178 }
8179 break;
ead9360e
TS
8180 case 23:
8181 switch (sel) {
8182 case 0:
895c2d04 8183 gen_helper_mttc0_debug(cpu_env, t0);
ead9360e
TS
8184 break;
8185 default:
d75c135e 8186 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
8187 break;
8188 }
8189 break;
8190 default:
d75c135e 8191 gen_mtc0(ctx, t0, rd, sel);
ead9360e
TS
8192 }
8193 } else switch (sel) {
8194 /* GPR registers. */
8195 case 0:
895c2d04 8196 gen_helper_0e1i(mttgpr, t0, rd);
ead9360e
TS
8197 break;
8198 /* Auxiliary CPU registers */
8199 case 1:
8200 switch (rd) {
8201 case 0:
895c2d04 8202 gen_helper_0e1i(mttlo, t0, 0);
ead9360e
TS
8203 break;
8204 case 1:
895c2d04 8205 gen_helper_0e1i(mtthi, t0, 0);
ead9360e
TS
8206 break;
8207 case 2:
895c2d04 8208 gen_helper_0e1i(mttacx, t0, 0);
ead9360e
TS
8209 break;
8210 case 4:
895c2d04 8211 gen_helper_0e1i(mttlo, t0, 1);
ead9360e
TS
8212 break;
8213 case 5:
895c2d04 8214 gen_helper_0e1i(mtthi, t0, 1);
ead9360e
TS
8215 break;
8216 case 6:
895c2d04 8217 gen_helper_0e1i(mttacx, t0, 1);
ead9360e
TS
8218 break;
8219 case 8:
895c2d04 8220 gen_helper_0e1i(mttlo, t0, 2);
ead9360e
TS
8221 break;
8222 case 9:
895c2d04 8223 gen_helper_0e1i(mtthi, t0, 2);
ead9360e
TS
8224 break;
8225 case 10:
895c2d04 8226 gen_helper_0e1i(mttacx, t0, 2);
ead9360e
TS
8227 break;
8228 case 12:
895c2d04 8229 gen_helper_0e1i(mttlo, t0, 3);
ead9360e
TS
8230 break;
8231 case 13:
895c2d04 8232 gen_helper_0e1i(mtthi, t0, 3);
ead9360e
TS
8233 break;
8234 case 14:
895c2d04 8235 gen_helper_0e1i(mttacx, t0, 3);
ead9360e
TS
8236 break;
8237 case 16:
895c2d04 8238 gen_helper_mttdsp(cpu_env, t0);
ead9360e
TS
8239 break;
8240 default:
8241 goto die;
8242 }
8243 break;
8244 /* Floating point (COP1). */
8245 case 2:
8246 /* XXX: For now we support only a single FPU context. */
8247 if (h == 0) {
a7812ae4 8248 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8249
8250 tcg_gen_trunc_tl_i32(fp0, t0);
7c979afd 8251 gen_store_fpr32(ctx, fp0, rd);
a7812ae4 8252 tcg_temp_free_i32(fp0);
ead9360e 8253 } else {
a7812ae4 8254 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8255
8256 tcg_gen_trunc_tl_i32(fp0, t0);
7f6613ce 8257 gen_store_fpr32h(ctx, fp0, rd);
a7812ae4 8258 tcg_temp_free_i32(fp0);
ead9360e
TS
8259 }
8260 break;
8261 case 3:
8262 /* XXX: For now we support only a single FPU context. */
736d120a
PJ
8263 {
8264 TCGv_i32 fs_tmp = tcg_const_i32(rd);
8265
8266 gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
8267 tcg_temp_free_i32(fs_tmp);
8268 }
4cf8a45f 8269 /* Stop translation as we may have changed hflags */
eeb3bba8 8270 ctx->base.is_jmp = DISAS_STOP;
ead9360e
TS
8271 break;
8272 /* COP2: Not implemented. */
8273 case 4:
8274 case 5:
8275 /* fall through */
8276 default:
8277 goto die;
8278 }
b44a7fb1 8279 trace_mips_translate_tr("mttr", rd, u, sel, h);
1a3fd9c3 8280 tcg_temp_free(t0);
ead9360e
TS
8281 return;
8282
8283die:
1a3fd9c3 8284 tcg_temp_free(t0);
d12d51d5 8285 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
9c708c7f 8286 generate_exception_end(ctx, EXCP_RI);
ead9360e
TS
8287}
8288
7db13fae 8289static void gen_cp0 (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
6af0bf9c 8290{
287c4b84 8291 const char *opn = "ldst";
6af0bf9c 8292
2e15497c 8293 check_cp0_enabled(ctx);
6af0bf9c
FB
8294 switch (opc) {
8295 case OPC_MFC0:
8296 if (rt == 0) {
ead9360e 8297 /* Treat as NOP. */
6af0bf9c
FB
8298 return;
8299 }
d75c135e 8300 gen_mfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
6af0bf9c
FB
8301 opn = "mfc0";
8302 break;
8303 case OPC_MTC0:
1a3fd9c3 8304 {
1fc7bf6e 8305 TCGv t0 = tcg_temp_new();
1a3fd9c3
TS
8306
8307 gen_load_gpr(t0, rt);
d75c135e 8308 gen_mtc0(ctx, t0, rd, ctx->opcode & 0x7);
1a3fd9c3
TS
8309 tcg_temp_free(t0);
8310 }
6af0bf9c
FB
8311 opn = "mtc0";
8312 break;
d26bc211 8313#if defined(TARGET_MIPS64)
9c2149c8 8314 case OPC_DMFC0:
d75c135e 8315 check_insn(ctx, ISA_MIPS3);
9c2149c8 8316 if (rt == 0) {
ead9360e 8317 /* Treat as NOP. */
9c2149c8
TS
8318 return;
8319 }
d75c135e 8320 gen_dmfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
9c2149c8
TS
8321 opn = "dmfc0";
8322 break;
8323 case OPC_DMTC0:
d75c135e 8324 check_insn(ctx, ISA_MIPS3);
1a3fd9c3 8325 {
1fc7bf6e 8326 TCGv t0 = tcg_temp_new();
1a3fd9c3
TS
8327
8328 gen_load_gpr(t0, rt);
d75c135e 8329 gen_dmtc0(ctx, t0, rd, ctx->opcode & 0x7);
1a3fd9c3
TS
8330 tcg_temp_free(t0);
8331 }
9c2149c8
TS
8332 opn = "dmtc0";
8333 break;
534ce69f 8334#endif
5204ea79
LA
8335 case OPC_MFHC0:
8336 check_mvh(ctx);
8337 if (rt == 0) {
8338 /* Treat as NOP. */
8339 return;
8340 }
8341 gen_mfhc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
8342 opn = "mfhc0";
8343 break;
8344 case OPC_MTHC0:
8345 check_mvh(ctx);
8346 {
8347 TCGv t0 = tcg_temp_new();
8348 gen_load_gpr(t0, rt);
8349 gen_mthc0(ctx, t0, rd, ctx->opcode & 0x7);
8350 tcg_temp_free(t0);
8351 }
8352 opn = "mthc0";
8353 break;
ead9360e 8354 case OPC_MFTR:
d75c135e 8355 check_insn(ctx, ASE_MT);
ead9360e
TS
8356 if (rd == 0) {
8357 /* Treat as NOP. */
8358 return;
8359 }
6c5c1e20 8360 gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
ead9360e 8361 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
ead9360e
TS
8362 opn = "mftr";
8363 break;
8364 case OPC_MTTR:
d75c135e 8365 check_insn(ctx, ASE_MT);
6c5c1e20 8366 gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
ead9360e
TS
8367 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
8368 opn = "mttr";
8369 break;
6af0bf9c 8370 case OPC_TLBWI:
6af0bf9c 8371 opn = "tlbwi";
c01fccd2 8372 if (!env->tlb->helper_tlbwi)
29929e34 8373 goto die;
895c2d04 8374 gen_helper_tlbwi(cpu_env);
6af0bf9c 8375 break;
9456c2fb
LA
8376 case OPC_TLBINV:
8377 opn = "tlbinv";
8378 if (ctx->ie >= 2) {
8379 if (!env->tlb->helper_tlbinv) {
8380 goto die;
8381 }
8382 gen_helper_tlbinv(cpu_env);
8383 } /* treat as nop if TLBINV not supported */
8384 break;
8385 case OPC_TLBINVF:
8386 opn = "tlbinvf";
8387 if (ctx->ie >= 2) {
8388 if (!env->tlb->helper_tlbinvf) {
8389 goto die;
8390 }
8391 gen_helper_tlbinvf(cpu_env);
8392 } /* treat as nop if TLBINV not supported */
8393 break;
6af0bf9c 8394 case OPC_TLBWR:
6af0bf9c 8395 opn = "tlbwr";
c01fccd2 8396 if (!env->tlb->helper_tlbwr)
29929e34 8397 goto die;
895c2d04 8398 gen_helper_tlbwr(cpu_env);
6af0bf9c
FB
8399 break;
8400 case OPC_TLBP:
6af0bf9c 8401 opn = "tlbp";
c01fccd2 8402 if (!env->tlb->helper_tlbp)
29929e34 8403 goto die;
895c2d04 8404 gen_helper_tlbp(cpu_env);
6af0bf9c
FB
8405 break;
8406 case OPC_TLBR:
6af0bf9c 8407 opn = "tlbr";
c01fccd2 8408 if (!env->tlb->helper_tlbr)
29929e34 8409 goto die;
895c2d04 8410 gen_helper_tlbr(cpu_env);
6af0bf9c 8411 break;
ce9782f4 8412 case OPC_ERET: /* OPC_ERETNC */
339cd2a8
LA
8413 if ((ctx->insn_flags & ISA_MIPS32R6) &&
8414 (ctx->hflags & MIPS_HFLAG_BMASK)) {
339cd2a8 8415 goto die;
ce9782f4
LA
8416 } else {
8417 int bit_shift = (ctx->hflags & MIPS_HFLAG_M16) ? 16 : 6;
8418 if (ctx->opcode & (1 << bit_shift)) {
8419 /* OPC_ERETNC */
8420 opn = "eretnc";
8421 check_insn(ctx, ISA_MIPS32R5);
8422 gen_helper_eretnc(cpu_env);
8423 } else {
8424 /* OPC_ERET */
8425 opn = "eret";
8426 check_insn(ctx, ISA_MIPS2);
8427 gen_helper_eret(cpu_env);
8428 }
eeb3bba8 8429 ctx->base.is_jmp = DISAS_EXIT;
339cd2a8 8430 }
6af0bf9c
FB
8431 break;
8432 case OPC_DERET:
8433 opn = "deret";
d75c135e 8434 check_insn(ctx, ISA_MIPS32);
339cd2a8
LA
8435 if ((ctx->insn_flags & ISA_MIPS32R6) &&
8436 (ctx->hflags & MIPS_HFLAG_BMASK)) {
339cd2a8
LA
8437 goto die;
8438 }
6af0bf9c 8439 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
923617a3 8440 MIPS_INVAL(opn);
9c708c7f 8441 generate_exception_end(ctx, EXCP_RI);
6af0bf9c 8442 } else {
895c2d04 8443 gen_helper_deret(cpu_env);
eeb3bba8 8444 ctx->base.is_jmp = DISAS_EXIT;
6af0bf9c
FB
8445 }
8446 break;
4ad40f36
FB
8447 case OPC_WAIT:
8448 opn = "wait";
d75c135e 8449 check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
339cd2a8
LA
8450 if ((ctx->insn_flags & ISA_MIPS32R6) &&
8451 (ctx->hflags & MIPS_HFLAG_BMASK)) {
339cd2a8
LA
8452 goto die;
8453 }
4ad40f36 8454 /* If we get an exception, we want to restart at next instruction */
eeb3bba8 8455 ctx->base.pc_next += 4;
4ad40f36 8456 save_cpu_state(ctx, 1);
eeb3bba8 8457 ctx->base.pc_next -= 4;
895c2d04 8458 gen_helper_wait(cpu_env);
eeb3bba8 8459 ctx->base.is_jmp = DISAS_NORETURN;
4ad40f36 8460 break;
6af0bf9c 8461 default:
29929e34 8462 die:
923617a3 8463 MIPS_INVAL(opn);
9c708c7f 8464 generate_exception_end(ctx, EXCP_RI);
6af0bf9c
FB
8465 return;
8466 }
2abf314d 8467 (void)opn; /* avoid a compiler warning */
6af0bf9c 8468}
f1aa6320 8469#endif /* !CONFIG_USER_ONLY */
6af0bf9c 8470
6ea83fed 8471/* CP1 Branches (before delay slot) */
d75c135e
AJ
8472static void gen_compute_branch1(DisasContext *ctx, uint32_t op,
8473 int32_t cc, int32_t offset)
6ea83fed
FB
8474{
8475 target_ulong btarget;
a7812ae4 8476 TCGv_i32 t0 = tcg_temp_new_i32();
6ea83fed 8477
339cd2a8 8478 if ((ctx->insn_flags & ISA_MIPS32R6) && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9c708c7f 8479 generate_exception_end(ctx, EXCP_RI);
339cd2a8
LA
8480 goto out;
8481 }
8482
e189e748 8483 if (cc != 0)
d75c135e 8484 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
e189e748 8485
eeb3bba8 8486 btarget = ctx->base.pc_next + 4 + offset;
6ea83fed 8487
7a387fff
TS
8488 switch (op) {
8489 case OPC_BC1F:
d94536f4
AJ
8490 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8491 tcg_gen_not_i32(t0, t0);
8492 tcg_gen_andi_i32(t0, t0, 1);
8493 tcg_gen_extu_i32_tl(bcond, t0);
6ea83fed 8494 goto not_likely;
7a387fff 8495 case OPC_BC1FL:
d94536f4
AJ
8496 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8497 tcg_gen_not_i32(t0, t0);
8498 tcg_gen_andi_i32(t0, t0, 1);
8499 tcg_gen_extu_i32_tl(bcond, t0);
6ea83fed 8500 goto likely;
7a387fff 8501 case OPC_BC1T:
d94536f4
AJ
8502 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8503 tcg_gen_andi_i32(t0, t0, 1);
8504 tcg_gen_extu_i32_tl(bcond, t0);
5a5012ec 8505 goto not_likely;
7a387fff 8506 case OPC_BC1TL:
d94536f4
AJ
8507 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8508 tcg_gen_andi_i32(t0, t0, 1);
8509 tcg_gen_extu_i32_tl(bcond, t0);
6ea83fed
FB
8510 likely:
8511 ctx->hflags |= MIPS_HFLAG_BL;
8512 break;
5a5012ec 8513 case OPC_BC1FANY2:
a16336e4 8514 {
d94536f4
AJ
8515 TCGv_i32 t1 = tcg_temp_new_i32();
8516 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8517 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
d7f66b52 8518 tcg_gen_nand_i32(t0, t0, t1);
d94536f4 8519 tcg_temp_free_i32(t1);
d94536f4
AJ
8520 tcg_gen_andi_i32(t0, t0, 1);
8521 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 8522 }
5a5012ec
TS
8523 goto not_likely;
8524 case OPC_BC1TANY2:
a16336e4 8525 {
d94536f4
AJ
8526 TCGv_i32 t1 = tcg_temp_new_i32();
8527 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8528 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
8529 tcg_gen_or_i32(t0, t0, t1);
8530 tcg_temp_free_i32(t1);
8531 tcg_gen_andi_i32(t0, t0, 1);
8532 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 8533 }
5a5012ec
TS
8534 goto not_likely;
8535 case OPC_BC1FANY4:
a16336e4 8536 {
d94536f4
AJ
8537 TCGv_i32 t1 = tcg_temp_new_i32();
8538 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8539 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
d7f66b52 8540 tcg_gen_and_i32(t0, t0, t1);
d94536f4 8541 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
d7f66b52 8542 tcg_gen_and_i32(t0, t0, t1);
d94536f4 8543 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
d7f66b52 8544 tcg_gen_nand_i32(t0, t0, t1);
d94536f4 8545 tcg_temp_free_i32(t1);
d94536f4
AJ
8546 tcg_gen_andi_i32(t0, t0, 1);
8547 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 8548 }
5a5012ec
TS
8549 goto not_likely;
8550 case OPC_BC1TANY4:
a16336e4 8551 {
d94536f4
AJ
8552 TCGv_i32 t1 = tcg_temp_new_i32();
8553 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8554 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
8555 tcg_gen_or_i32(t0, t0, t1);
8556 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
8557 tcg_gen_or_i32(t0, t0, t1);
8558 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
8559 tcg_gen_or_i32(t0, t0, t1);
8560 tcg_temp_free_i32(t1);
8561 tcg_gen_andi_i32(t0, t0, 1);
8562 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 8563 }
5a5012ec
TS
8564 not_likely:
8565 ctx->hflags |= MIPS_HFLAG_BC;
5a5012ec
TS
8566 break;
8567 default:
9d68ac14 8568 MIPS_INVAL("cp1 cond branch");
9c708c7f 8569 generate_exception_end(ctx, EXCP_RI);
6c5c1e20 8570 goto out;
6ea83fed 8571 }
6ea83fed 8572 ctx->btarget = btarget;
b231c103 8573 ctx->hflags |= MIPS_HFLAG_BDS32;
6c5c1e20 8574 out:
a7812ae4 8575 tcg_temp_free_i32(t0);
6ea83fed
FB
8576}
8577
31837be3
YK
8578/* R6 CP1 Branches */
8579static void gen_compute_branch1_r6(DisasContext *ctx, uint32_t op,
65935f07
YK
8580 int32_t ft, int32_t offset,
8581 int delayslot_size)
31837be3
YK
8582{
8583 target_ulong btarget;
31837be3
YK
8584 TCGv_i64 t0 = tcg_temp_new_i64();
8585
8586 if (ctx->hflags & MIPS_HFLAG_BMASK) {
8587#ifdef MIPS_DEBUG_DISAS
339cd2a8 8588 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
eeb3bba8 8589 "\n", ctx->base.pc_next);
31837be3 8590#endif
9c708c7f 8591 generate_exception_end(ctx, EXCP_RI);
31837be3
YK
8592 goto out;
8593 }
8594
8595 gen_load_fpr64(ctx, t0, ft);
8596 tcg_gen_andi_i64(t0, t0, 1);
8597
eeb3bba8 8598 btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
31837be3
YK
8599
8600 switch (op) {
8601 case OPC_BC1EQZ:
8602 tcg_gen_xori_i64(t0, t0, 1);
31837be3
YK
8603 ctx->hflags |= MIPS_HFLAG_BC;
8604 break;
8605 case OPC_BC1NEZ:
8606 /* t0 already set */
31837be3
YK
8607 ctx->hflags |= MIPS_HFLAG_BC;
8608 break;
8609 default:
9d68ac14 8610 MIPS_INVAL("cp1 cond branch");
9c708c7f 8611 generate_exception_end(ctx, EXCP_RI);
31837be3
YK
8612 goto out;
8613 }
8614
8615 tcg_gen_trunc_i64_tl(bcond, t0);
8616
31837be3 8617 ctx->btarget = btarget;
65935f07
YK
8618
8619 switch (delayslot_size) {
8620 case 2:
8621 ctx->hflags |= MIPS_HFLAG_BDS16;
8622 break;
8623 case 4:
8624 ctx->hflags |= MIPS_HFLAG_BDS32;
8625 break;
8626 }
31837be3
YK
8627
8628out:
8629 tcg_temp_free_i64(t0);
8630}
8631
6af0bf9c 8632/* Coprocessor 1 (FPU) */
5a5012ec 8633
5a5012ec
TS
8634#define FOP(func, fmt) (((fmt) << 21) | (func))
8635
bf4120ad
NF
8636enum fopcode {
8637 OPC_ADD_S = FOP(0, FMT_S),
8638 OPC_SUB_S = FOP(1, FMT_S),
8639 OPC_MUL_S = FOP(2, FMT_S),
8640 OPC_DIV_S = FOP(3, FMT_S),
8641 OPC_SQRT_S = FOP(4, FMT_S),
8642 OPC_ABS_S = FOP(5, FMT_S),
8643 OPC_MOV_S = FOP(6, FMT_S),
8644 OPC_NEG_S = FOP(7, FMT_S),
8645 OPC_ROUND_L_S = FOP(8, FMT_S),
8646 OPC_TRUNC_L_S = FOP(9, FMT_S),
8647 OPC_CEIL_L_S = FOP(10, FMT_S),
8648 OPC_FLOOR_L_S = FOP(11, FMT_S),
8649 OPC_ROUND_W_S = FOP(12, FMT_S),
8650 OPC_TRUNC_W_S = FOP(13, FMT_S),
8651 OPC_CEIL_W_S = FOP(14, FMT_S),
8652 OPC_FLOOR_W_S = FOP(15, FMT_S),
e7f16abb 8653 OPC_SEL_S = FOP(16, FMT_S),
bf4120ad
NF
8654 OPC_MOVCF_S = FOP(17, FMT_S),
8655 OPC_MOVZ_S = FOP(18, FMT_S),
8656 OPC_MOVN_S = FOP(19, FMT_S),
e7f16abb 8657 OPC_SELEQZ_S = FOP(20, FMT_S),
bf4120ad
NF
8658 OPC_RECIP_S = FOP(21, FMT_S),
8659 OPC_RSQRT_S = FOP(22, FMT_S),
e7f16abb
LA
8660 OPC_SELNEZ_S = FOP(23, FMT_S),
8661 OPC_MADDF_S = FOP(24, FMT_S),
8662 OPC_MSUBF_S = FOP(25, FMT_S),
8663 OPC_RINT_S = FOP(26, FMT_S),
8664 OPC_CLASS_S = FOP(27, FMT_S),
8665 OPC_MIN_S = FOP(28, FMT_S),
bf4120ad 8666 OPC_RECIP2_S = FOP(28, FMT_S),
e7f16abb 8667 OPC_MINA_S = FOP(29, FMT_S),
bf4120ad 8668 OPC_RECIP1_S = FOP(29, FMT_S),
e7f16abb 8669 OPC_MAX_S = FOP(30, FMT_S),
bf4120ad 8670 OPC_RSQRT1_S = FOP(30, FMT_S),
e7f16abb 8671 OPC_MAXA_S = FOP(31, FMT_S),
bf4120ad
NF
8672 OPC_RSQRT2_S = FOP(31, FMT_S),
8673 OPC_CVT_D_S = FOP(33, FMT_S),
8674 OPC_CVT_W_S = FOP(36, FMT_S),
8675 OPC_CVT_L_S = FOP(37, FMT_S),
8676 OPC_CVT_PS_S = FOP(38, FMT_S),
8677 OPC_CMP_F_S = FOP (48, FMT_S),
8678 OPC_CMP_UN_S = FOP (49, FMT_S),
8679 OPC_CMP_EQ_S = FOP (50, FMT_S),
8680 OPC_CMP_UEQ_S = FOP (51, FMT_S),
8681 OPC_CMP_OLT_S = FOP (52, FMT_S),
8682 OPC_CMP_ULT_S = FOP (53, FMT_S),
8683 OPC_CMP_OLE_S = FOP (54, FMT_S),
8684 OPC_CMP_ULE_S = FOP (55, FMT_S),
8685 OPC_CMP_SF_S = FOP (56, FMT_S),
8686 OPC_CMP_NGLE_S = FOP (57, FMT_S),
8687 OPC_CMP_SEQ_S = FOP (58, FMT_S),
8688 OPC_CMP_NGL_S = FOP (59, FMT_S),
8689 OPC_CMP_LT_S = FOP (60, FMT_S),
8690 OPC_CMP_NGE_S = FOP (61, FMT_S),
8691 OPC_CMP_LE_S = FOP (62, FMT_S),
8692 OPC_CMP_NGT_S = FOP (63, FMT_S),
8693
8694 OPC_ADD_D = FOP(0, FMT_D),
8695 OPC_SUB_D = FOP(1, FMT_D),
8696 OPC_MUL_D = FOP(2, FMT_D),
8697 OPC_DIV_D = FOP(3, FMT_D),
8698 OPC_SQRT_D = FOP(4, FMT_D),
8699 OPC_ABS_D = FOP(5, FMT_D),
8700 OPC_MOV_D = FOP(6, FMT_D),
8701 OPC_NEG_D = FOP(7, FMT_D),
8702 OPC_ROUND_L_D = FOP(8, FMT_D),
8703 OPC_TRUNC_L_D = FOP(9, FMT_D),
8704 OPC_CEIL_L_D = FOP(10, FMT_D),
8705 OPC_FLOOR_L_D = FOP(11, FMT_D),
8706 OPC_ROUND_W_D = FOP(12, FMT_D),
8707 OPC_TRUNC_W_D = FOP(13, FMT_D),
8708 OPC_CEIL_W_D = FOP(14, FMT_D),
8709 OPC_FLOOR_W_D = FOP(15, FMT_D),
e7f16abb 8710 OPC_SEL_D = FOP(16, FMT_D),
bf4120ad
NF
8711 OPC_MOVCF_D = FOP(17, FMT_D),
8712 OPC_MOVZ_D = FOP(18, FMT_D),
8713 OPC_MOVN_D = FOP(19, FMT_D),
e7f16abb 8714 OPC_SELEQZ_D = FOP(20, FMT_D),
bf4120ad
NF
8715 OPC_RECIP_D = FOP(21, FMT_D),
8716 OPC_RSQRT_D = FOP(22, FMT_D),
e7f16abb
LA
8717 OPC_SELNEZ_D = FOP(23, FMT_D),
8718 OPC_MADDF_D = FOP(24, FMT_D),
8719 OPC_MSUBF_D = FOP(25, FMT_D),
8720 OPC_RINT_D = FOP(26, FMT_D),
8721 OPC_CLASS_D = FOP(27, FMT_D),
8722 OPC_MIN_D = FOP(28, FMT_D),
bf4120ad 8723 OPC_RECIP2_D = FOP(28, FMT_D),
e7f16abb 8724 OPC_MINA_D = FOP(29, FMT_D),
bf4120ad 8725 OPC_RECIP1_D = FOP(29, FMT_D),
e7f16abb 8726 OPC_MAX_D = FOP(30, FMT_D),
bf4120ad 8727 OPC_RSQRT1_D = FOP(30, FMT_D),
e7f16abb 8728 OPC_MAXA_D = FOP(31, FMT_D),
bf4120ad
NF
8729 OPC_RSQRT2_D = FOP(31, FMT_D),
8730 OPC_CVT_S_D = FOP(32, FMT_D),
8731 OPC_CVT_W_D = FOP(36, FMT_D),
8732 OPC_CVT_L_D = FOP(37, FMT_D),
8733 OPC_CMP_F_D = FOP (48, FMT_D),
8734 OPC_CMP_UN_D = FOP (49, FMT_D),
8735 OPC_CMP_EQ_D = FOP (50, FMT_D),
8736 OPC_CMP_UEQ_D = FOP (51, FMT_D),
8737 OPC_CMP_OLT_D = FOP (52, FMT_D),
8738 OPC_CMP_ULT_D = FOP (53, FMT_D),
8739 OPC_CMP_OLE_D = FOP (54, FMT_D),
8740 OPC_CMP_ULE_D = FOP (55, FMT_D),
8741 OPC_CMP_SF_D = FOP (56, FMT_D),
8742 OPC_CMP_NGLE_D = FOP (57, FMT_D),
8743 OPC_CMP_SEQ_D = FOP (58, FMT_D),
8744 OPC_CMP_NGL_D = FOP (59, FMT_D),
8745 OPC_CMP_LT_D = FOP (60, FMT_D),
8746 OPC_CMP_NGE_D = FOP (61, FMT_D),
8747 OPC_CMP_LE_D = FOP (62, FMT_D),
8748 OPC_CMP_NGT_D = FOP (63, FMT_D),
8749
8750 OPC_CVT_S_W = FOP(32, FMT_W),
8751 OPC_CVT_D_W = FOP(33, FMT_W),
8752 OPC_CVT_S_L = FOP(32, FMT_L),
8753 OPC_CVT_D_L = FOP(33, FMT_L),
8754 OPC_CVT_PS_PW = FOP(38, FMT_W),
8755
8756 OPC_ADD_PS = FOP(0, FMT_PS),
8757 OPC_SUB_PS = FOP(1, FMT_PS),
8758 OPC_MUL_PS = FOP(2, FMT_PS),
8759 OPC_DIV_PS = FOP(3, FMT_PS),
8760 OPC_ABS_PS = FOP(5, FMT_PS),
8761 OPC_MOV_PS = FOP(6, FMT_PS),
8762 OPC_NEG_PS = FOP(7, FMT_PS),
8763 OPC_MOVCF_PS = FOP(17, FMT_PS),
8764 OPC_MOVZ_PS = FOP(18, FMT_PS),
8765 OPC_MOVN_PS = FOP(19, FMT_PS),
8766 OPC_ADDR_PS = FOP(24, FMT_PS),
8767 OPC_MULR_PS = FOP(26, FMT_PS),
8768 OPC_RECIP2_PS = FOP(28, FMT_PS),
8769 OPC_RECIP1_PS = FOP(29, FMT_PS),
8770 OPC_RSQRT1_PS = FOP(30, FMT_PS),
8771 OPC_RSQRT2_PS = FOP(31, FMT_PS),
8772
8773 OPC_CVT_S_PU = FOP(32, FMT_PS),
8774 OPC_CVT_PW_PS = FOP(36, FMT_PS),
8775 OPC_CVT_S_PL = FOP(40, FMT_PS),
8776 OPC_PLL_PS = FOP(44, FMT_PS),
8777 OPC_PLU_PS = FOP(45, FMT_PS),
8778 OPC_PUL_PS = FOP(46, FMT_PS),
8779 OPC_PUU_PS = FOP(47, FMT_PS),
8780 OPC_CMP_F_PS = FOP (48, FMT_PS),
8781 OPC_CMP_UN_PS = FOP (49, FMT_PS),
8782 OPC_CMP_EQ_PS = FOP (50, FMT_PS),
8783 OPC_CMP_UEQ_PS = FOP (51, FMT_PS),
8784 OPC_CMP_OLT_PS = FOP (52, FMT_PS),
8785 OPC_CMP_ULT_PS = FOP (53, FMT_PS),
8786 OPC_CMP_OLE_PS = FOP (54, FMT_PS),
8787 OPC_CMP_ULE_PS = FOP (55, FMT_PS),
8788 OPC_CMP_SF_PS = FOP (56, FMT_PS),
8789 OPC_CMP_NGLE_PS = FOP (57, FMT_PS),
8790 OPC_CMP_SEQ_PS = FOP (58, FMT_PS),
8791 OPC_CMP_NGL_PS = FOP (59, FMT_PS),
8792 OPC_CMP_LT_PS = FOP (60, FMT_PS),
8793 OPC_CMP_NGE_PS = FOP (61, FMT_PS),
8794 OPC_CMP_LE_PS = FOP (62, FMT_PS),
8795 OPC_CMP_NGT_PS = FOP (63, FMT_PS),
8796};
8797
3f493883
YK
8798enum r6_f_cmp_op {
8799 R6_OPC_CMP_AF_S = FOP(0, FMT_W),
8800 R6_OPC_CMP_UN_S = FOP(1, FMT_W),
8801 R6_OPC_CMP_EQ_S = FOP(2, FMT_W),
8802 R6_OPC_CMP_UEQ_S = FOP(3, FMT_W),
8803 R6_OPC_CMP_LT_S = FOP(4, FMT_W),
8804 R6_OPC_CMP_ULT_S = FOP(5, FMT_W),
8805 R6_OPC_CMP_LE_S = FOP(6, FMT_W),
8806 R6_OPC_CMP_ULE_S = FOP(7, FMT_W),
8807 R6_OPC_CMP_SAF_S = FOP(8, FMT_W),
8808 R6_OPC_CMP_SUN_S = FOP(9, FMT_W),
8809 R6_OPC_CMP_SEQ_S = FOP(10, FMT_W),
8810 R6_OPC_CMP_SEUQ_S = FOP(11, FMT_W),
8811 R6_OPC_CMP_SLT_S = FOP(12, FMT_W),
8812 R6_OPC_CMP_SULT_S = FOP(13, FMT_W),
8813 R6_OPC_CMP_SLE_S = FOP(14, FMT_W),
8814 R6_OPC_CMP_SULE_S = FOP(15, FMT_W),
8815 R6_OPC_CMP_OR_S = FOP(17, FMT_W),
8816 R6_OPC_CMP_UNE_S = FOP(18, FMT_W),
8817 R6_OPC_CMP_NE_S = FOP(19, FMT_W),
8818 R6_OPC_CMP_SOR_S = FOP(25, FMT_W),
8819 R6_OPC_CMP_SUNE_S = FOP(26, FMT_W),
8820 R6_OPC_CMP_SNE_S = FOP(27, FMT_W),
8821
8822 R6_OPC_CMP_AF_D = FOP(0, FMT_L),
8823 R6_OPC_CMP_UN_D = FOP(1, FMT_L),
8824 R6_OPC_CMP_EQ_D = FOP(2, FMT_L),
8825 R6_OPC_CMP_UEQ_D = FOP(3, FMT_L),
8826 R6_OPC_CMP_LT_D = FOP(4, FMT_L),
8827 R6_OPC_CMP_ULT_D = FOP(5, FMT_L),
8828 R6_OPC_CMP_LE_D = FOP(6, FMT_L),
8829 R6_OPC_CMP_ULE_D = FOP(7, FMT_L),
8830 R6_OPC_CMP_SAF_D = FOP(8, FMT_L),
8831 R6_OPC_CMP_SUN_D = FOP(9, FMT_L),
8832 R6_OPC_CMP_SEQ_D = FOP(10, FMT_L),
8833 R6_OPC_CMP_SEUQ_D = FOP(11, FMT_L),
8834 R6_OPC_CMP_SLT_D = FOP(12, FMT_L),
8835 R6_OPC_CMP_SULT_D = FOP(13, FMT_L),
8836 R6_OPC_CMP_SLE_D = FOP(14, FMT_L),
8837 R6_OPC_CMP_SULE_D = FOP(15, FMT_L),
8838 R6_OPC_CMP_OR_D = FOP(17, FMT_L),
8839 R6_OPC_CMP_UNE_D = FOP(18, FMT_L),
8840 R6_OPC_CMP_NE_D = FOP(19, FMT_L),
8841 R6_OPC_CMP_SOR_D = FOP(25, FMT_L),
8842 R6_OPC_CMP_SUNE_D = FOP(26, FMT_L),
8843 R6_OPC_CMP_SNE_D = FOP(27, FMT_L),
8844};
7a387fff 8845static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
6ea83fed 8846{
72c3a3ee 8847 TCGv t0 = tcg_temp_new();
6ea83fed
FB
8848
8849 switch (opc) {
8850 case OPC_MFC1:
b6d96bed 8851 {
a7812ae4 8852 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8853
7c979afd 8854 gen_load_fpr32(ctx, fp0, fs);
b6d96bed 8855 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 8856 tcg_temp_free_i32(fp0);
6958549d 8857 }
6c5c1e20 8858 gen_store_gpr(t0, rt);
6ea83fed
FB
8859 break;
8860 case OPC_MTC1:
6c5c1e20 8861 gen_load_gpr(t0, rt);
b6d96bed 8862 {
a7812ae4 8863 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8864
8865 tcg_gen_trunc_tl_i32(fp0, t0);
7c979afd 8866 gen_store_fpr32(ctx, fp0, fs);
a7812ae4 8867 tcg_temp_free_i32(fp0);
6958549d 8868 }
6ea83fed
FB
8869 break;
8870 case OPC_CFC1:
895c2d04 8871 gen_helper_1e0i(cfc1, t0, fs);
6c5c1e20 8872 gen_store_gpr(t0, rt);
6ea83fed
FB
8873 break;
8874 case OPC_CTC1:
6c5c1e20 8875 gen_load_gpr(t0, rt);
9c708c7f 8876 save_cpu_state(ctx, 0);
736d120a
PJ
8877 {
8878 TCGv_i32 fs_tmp = tcg_const_i32(fs);
8879
8880 gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
8881 tcg_temp_free_i32(fs_tmp);
8882 }
4cf8a45f 8883 /* Stop translation as we may have changed hflags */
eeb3bba8 8884 ctx->base.is_jmp = DISAS_STOP;
6ea83fed 8885 break;
72c3a3ee 8886#if defined(TARGET_MIPS64)
9c2149c8 8887 case OPC_DMFC1:
72c3a3ee 8888 gen_load_fpr64(ctx, t0, fs);
6c5c1e20 8889 gen_store_gpr(t0, rt);
5a5012ec 8890 break;
9c2149c8 8891 case OPC_DMTC1:
6c5c1e20 8892 gen_load_gpr(t0, rt);
72c3a3ee 8893 gen_store_fpr64(ctx, t0, fs);
5a5012ec 8894 break;
72c3a3ee 8895#endif
5a5012ec 8896 case OPC_MFHC1:
b6d96bed 8897 {
a7812ae4 8898 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8899
7f6613ce 8900 gen_load_fpr32h(ctx, fp0, fs);
b6d96bed 8901 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 8902 tcg_temp_free_i32(fp0);
6958549d 8903 }
6c5c1e20 8904 gen_store_gpr(t0, rt);
5a5012ec
TS
8905 break;
8906 case OPC_MTHC1:
6c5c1e20 8907 gen_load_gpr(t0, rt);
b6d96bed 8908 {
a7812ae4 8909 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8910
8911 tcg_gen_trunc_tl_i32(fp0, t0);
7f6613ce 8912 gen_store_fpr32h(ctx, fp0, fs);
a7812ae4 8913 tcg_temp_free_i32(fp0);
6958549d 8914 }
5a5012ec 8915 break;
6ea83fed 8916 default:
9d68ac14 8917 MIPS_INVAL("cp1 move");
9c708c7f 8918 generate_exception_end(ctx, EXCP_RI);
6c5c1e20 8919 goto out;
6ea83fed 8920 }
6c5c1e20
TS
8921
8922 out:
8923 tcg_temp_free(t0);
6ea83fed
FB
8924}
8925
5a5012ec
TS
8926static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
8927{
42a268c2 8928 TCGLabel *l1;
e214b9bb 8929 TCGCond cond;
af58f9ca
AJ
8930 TCGv_i32 t0;
8931
8932 if (rd == 0) {
8933 /* Treat as NOP. */
8934 return;
8935 }
6ea83fed 8936
e214b9bb 8937 if (tf)
e214b9bb 8938 cond = TCG_COND_EQ;
27848470
TS
8939 else
8940 cond = TCG_COND_NE;
8941
af58f9ca
AJ
8942 l1 = gen_new_label();
8943 t0 = tcg_temp_new_i32();
fa31af0e 8944 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
af58f9ca 8945 tcg_gen_brcondi_i32(cond, t0, 0, l1);
a4e8338d 8946 tcg_temp_free_i32(t0);
af58f9ca
AJ
8947 if (rs == 0) {
8948 tcg_gen_movi_tl(cpu_gpr[rd], 0);
8949 } else {
8950 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
8951 }
e214b9bb 8952 gen_set_label(l1);
5a5012ec
TS
8953}
8954
7c979afd
LA
8955static inline void gen_movcf_s(DisasContext *ctx, int fs, int fd, int cc,
8956 int tf)
a16336e4 8957{
a16336e4 8958 int cond;
cbc37b28 8959 TCGv_i32 t0 = tcg_temp_new_i32();
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);
7c979afd
LA
8969 gen_load_fpr32(ctx, t0, fs);
8970 gen_store_fpr32(ctx, t0, fd);
a16336e4 8971 gen_set_label(l1);
cbc37b28 8972 tcg_temp_free_i32(t0);
5a5012ec 8973}
a16336e4 8974
b6d96bed 8975static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
a16336e4 8976{
a16336e4 8977 int cond;
cbc37b28
AJ
8978 TCGv_i32 t0 = tcg_temp_new_i32();
8979 TCGv_i64 fp0;
42a268c2 8980 TCGLabel *l1 = gen_new_label();
a16336e4 8981
a16336e4
TS
8982 if (tf)
8983 cond = TCG_COND_EQ;
8984 else
8985 cond = TCG_COND_NE;
8986
fa31af0e 8987 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
cbc37b28 8988 tcg_gen_brcondi_i32(cond, t0, 0, l1);
a4e8338d 8989 tcg_temp_free_i32(t0);
11f94258 8990 fp0 = tcg_temp_new_i64();
9bf3eb2c 8991 gen_load_fpr64(ctx, fp0, fs);
9bf3eb2c 8992 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8993 tcg_temp_free_i64(fp0);
cbc37b28 8994 gen_set_label(l1);
a16336e4
TS
8995}
8996
7f6613ce
PJ
8997static inline void gen_movcf_ps(DisasContext *ctx, int fs, int fd,
8998 int cc, int tf)
a16336e4
TS
8999{
9000 int cond;
cbc37b28 9001 TCGv_i32 t0 = tcg_temp_new_i32();
42a268c2
RH
9002 TCGLabel *l1 = gen_new_label();
9003 TCGLabel *l2 = gen_new_label();
a16336e4
TS
9004
9005 if (tf)
9006 cond = TCG_COND_EQ;
9007 else
9008 cond = TCG_COND_NE;
9009
fa31af0e 9010 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
cbc37b28 9011 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7c979afd
LA
9012 gen_load_fpr32(ctx, t0, fs);
9013 gen_store_fpr32(ctx, t0, fd);
a16336e4 9014 gen_set_label(l1);
9bf3eb2c 9015
fa31af0e 9016 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc+1));
cbc37b28 9017 tcg_gen_brcondi_i32(cond, t0, 0, l2);
7f6613ce
PJ
9018 gen_load_fpr32h(ctx, t0, fs);
9019 gen_store_fpr32h(ctx, t0, fd);
52a0e9eb 9020 tcg_temp_free_i32(t0);
a16336e4 9021 gen_set_label(l2);
a16336e4
TS
9022}
9023
e7f16abb
LA
9024static void gen_sel_s(DisasContext *ctx, enum fopcode op1, int fd, int ft,
9025 int fs)
9026{
9027 TCGv_i32 t1 = tcg_const_i32(0);
9028 TCGv_i32 fp0 = tcg_temp_new_i32();
9029 TCGv_i32 fp1 = tcg_temp_new_i32();
9030 TCGv_i32 fp2 = tcg_temp_new_i32();
7c979afd
LA
9031 gen_load_fpr32(ctx, fp0, fd);
9032 gen_load_fpr32(ctx, fp1, ft);
9033 gen_load_fpr32(ctx, fp2, fs);
e7f16abb
LA
9034
9035 switch (op1) {
9036 case OPC_SEL_S:
9037 tcg_gen_andi_i32(fp0, fp0, 1);
9038 tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
9039 break;
9040 case OPC_SELEQZ_S:
9041 tcg_gen_andi_i32(fp1, fp1, 1);
9042 tcg_gen_movcond_i32(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
9043 break;
9044 case OPC_SELNEZ_S:
9045 tcg_gen_andi_i32(fp1, fp1, 1);
9046 tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
9047 break;
9048 default:
9049 MIPS_INVAL("gen_sel_s");
9c708c7f 9050 generate_exception_end(ctx, EXCP_RI);
e7f16abb
LA
9051 break;
9052 }
9053
7c979afd 9054 gen_store_fpr32(ctx, fp0, fd);
e7f16abb
LA
9055 tcg_temp_free_i32(fp2);
9056 tcg_temp_free_i32(fp1);
9057 tcg_temp_free_i32(fp0);
9058 tcg_temp_free_i32(t1);
9059}
9060
9061static void gen_sel_d(DisasContext *ctx, enum fopcode op1, int fd, int ft,
9062 int fs)
9063{
9064 TCGv_i64 t1 = tcg_const_i64(0);
9065 TCGv_i64 fp0 = tcg_temp_new_i64();
9066 TCGv_i64 fp1 = tcg_temp_new_i64();
9067 TCGv_i64 fp2 = tcg_temp_new_i64();
9068 gen_load_fpr64(ctx, fp0, fd);
9069 gen_load_fpr64(ctx, fp1, ft);
9070 gen_load_fpr64(ctx, fp2, fs);
9071
9072 switch (op1) {
9073 case OPC_SEL_D:
9074 tcg_gen_andi_i64(fp0, fp0, 1);
9075 tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
9076 break;
9077 case OPC_SELEQZ_D:
9078 tcg_gen_andi_i64(fp1, fp1, 1);
9079 tcg_gen_movcond_i64(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
9080 break;
9081 case OPC_SELNEZ_D:
9082 tcg_gen_andi_i64(fp1, fp1, 1);
9083 tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
9084 break;
9085 default:
9086 MIPS_INVAL("gen_sel_d");
9c708c7f 9087 generate_exception_end(ctx, EXCP_RI);
e7f16abb
LA
9088 break;
9089 }
9090
9091 gen_store_fpr64(ctx, fp0, fd);
9092 tcg_temp_free_i64(fp2);
9093 tcg_temp_free_i64(fp1);
9094 tcg_temp_free_i64(fp0);
9095 tcg_temp_free_i64(t1);
9096}
6ea83fed 9097
bf4120ad 9098static void gen_farith (DisasContext *ctx, enum fopcode op1,
5e755519 9099 int ft, int fs, int fd, int cc)
6ea83fed 9100{
7a387fff 9101 uint32_t func = ctx->opcode & 0x3f;
bf4120ad
NF
9102 switch (op1) {
9103 case OPC_ADD_S:
b6d96bed 9104 {
a7812ae4
PB
9105 TCGv_i32 fp0 = tcg_temp_new_i32();
9106 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 9107
7c979afd
LA
9108 gen_load_fpr32(ctx, fp0, fs);
9109 gen_load_fpr32(ctx, fp1, ft);
895c2d04 9110 gen_helper_float_add_s(fp0, cpu_env, fp0, fp1);
a7812ae4 9111 tcg_temp_free_i32(fp1);
7c979afd 9112 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9113 tcg_temp_free_i32(fp0);
b6d96bed 9114 }
5a5012ec 9115 break;
bf4120ad 9116 case OPC_SUB_S:
b6d96bed 9117 {
a7812ae4
PB
9118 TCGv_i32 fp0 = tcg_temp_new_i32();
9119 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 9120
7c979afd
LA
9121 gen_load_fpr32(ctx, fp0, fs);
9122 gen_load_fpr32(ctx, fp1, ft);
895c2d04 9123 gen_helper_float_sub_s(fp0, cpu_env, fp0, fp1);
a7812ae4 9124 tcg_temp_free_i32(fp1);
7c979afd 9125 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9126 tcg_temp_free_i32(fp0);
b6d96bed 9127 }
5a5012ec 9128 break;
bf4120ad 9129 case OPC_MUL_S:
b6d96bed 9130 {
a7812ae4
PB
9131 TCGv_i32 fp0 = tcg_temp_new_i32();
9132 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 9133
7c979afd
LA
9134 gen_load_fpr32(ctx, fp0, fs);
9135 gen_load_fpr32(ctx, fp1, ft);
895c2d04 9136 gen_helper_float_mul_s(fp0, cpu_env, fp0, fp1);
a7812ae4 9137 tcg_temp_free_i32(fp1);
7c979afd 9138 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9139 tcg_temp_free_i32(fp0);
b6d96bed 9140 }
5a5012ec 9141 break;
bf4120ad 9142 case OPC_DIV_S:
b6d96bed 9143 {
a7812ae4
PB
9144 TCGv_i32 fp0 = tcg_temp_new_i32();
9145 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 9146
7c979afd
LA
9147 gen_load_fpr32(ctx, fp0, fs);
9148 gen_load_fpr32(ctx, fp1, ft);
895c2d04 9149 gen_helper_float_div_s(fp0, cpu_env, fp0, fp1);
a7812ae4 9150 tcg_temp_free_i32(fp1);
7c979afd 9151 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9152 tcg_temp_free_i32(fp0);
b6d96bed 9153 }
5a5012ec 9154 break;
bf4120ad 9155 case OPC_SQRT_S:
b6d96bed 9156 {
a7812ae4 9157 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9158
7c979afd 9159 gen_load_fpr32(ctx, fp0, fs);
895c2d04 9160 gen_helper_float_sqrt_s(fp0, cpu_env, fp0);
7c979afd 9161 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9162 tcg_temp_free_i32(fp0);
b6d96bed 9163 }
5a5012ec 9164 break;
bf4120ad 9165 case OPC_ABS_S:
b6d96bed 9166 {
a7812ae4 9167 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9168
7c979afd 9169 gen_load_fpr32(ctx, fp0, fs);
6be77480
AM
9170 if (ctx->abs2008) {
9171 tcg_gen_andi_i32(fp0, fp0, 0x7fffffffUL);
9172 } else {
9173 gen_helper_float_abs_s(fp0, fp0);
9174 }
7c979afd 9175 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9176 tcg_temp_free_i32(fp0);
b6d96bed 9177 }
5a5012ec 9178 break;
bf4120ad 9179 case OPC_MOV_S:
b6d96bed 9180 {
a7812ae4 9181 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9182
7c979afd
LA
9183 gen_load_fpr32(ctx, fp0, fs);
9184 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9185 tcg_temp_free_i32(fp0);
b6d96bed 9186 }
5a5012ec 9187 break;
bf4120ad 9188 case OPC_NEG_S:
b6d96bed 9189 {
a7812ae4 9190 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9191
7c979afd 9192 gen_load_fpr32(ctx, fp0, fs);
6be77480
AM
9193 if (ctx->abs2008) {
9194 tcg_gen_xori_i32(fp0, fp0, 1UL << 31);
9195 } else {
9196 gen_helper_float_chs_s(fp0, fp0);
9197 }
7c979afd 9198 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9199 tcg_temp_free_i32(fp0);
b6d96bed 9200 }
5a5012ec 9201 break;
bf4120ad 9202 case OPC_ROUND_L_S:
5e755519 9203 check_cp1_64bitmode(ctx);
b6d96bed 9204 {
a7812ae4
PB
9205 TCGv_i32 fp32 = tcg_temp_new_i32();
9206 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 9207
7c979afd 9208 gen_load_fpr32(ctx, fp32, fs);
87552089
AM
9209 if (ctx->nan2008) {
9210 gen_helper_float_round_2008_l_s(fp64, cpu_env, fp32);
9211 } else {
9212 gen_helper_float_round_l_s(fp64, cpu_env, fp32);
9213 }
a7812ae4 9214 tcg_temp_free_i32(fp32);
b6d96bed 9215 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 9216 tcg_temp_free_i64(fp64);
b6d96bed 9217 }
5a5012ec 9218 break;
bf4120ad 9219 case OPC_TRUNC_L_S:
5e755519 9220 check_cp1_64bitmode(ctx);
b6d96bed 9221 {
a7812ae4
PB
9222 TCGv_i32 fp32 = tcg_temp_new_i32();
9223 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 9224
7c979afd 9225 gen_load_fpr32(ctx, fp32, fs);
87552089
AM
9226 if (ctx->nan2008) {
9227 gen_helper_float_trunc_2008_l_s(fp64, cpu_env, fp32);
9228 } else {
9229 gen_helper_float_trunc_l_s(fp64, cpu_env, fp32);
9230 }
a7812ae4 9231 tcg_temp_free_i32(fp32);
b6d96bed 9232 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 9233 tcg_temp_free_i64(fp64);
b6d96bed 9234 }
5a5012ec 9235 break;
bf4120ad 9236 case OPC_CEIL_L_S:
5e755519 9237 check_cp1_64bitmode(ctx);
b6d96bed 9238 {
a7812ae4
PB
9239 TCGv_i32 fp32 = tcg_temp_new_i32();
9240 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 9241
7c979afd 9242 gen_load_fpr32(ctx, fp32, fs);
87552089
AM
9243 if (ctx->nan2008) {
9244 gen_helper_float_ceil_2008_l_s(fp64, cpu_env, fp32);
9245 } else {
9246 gen_helper_float_ceil_l_s(fp64, cpu_env, fp32);
9247 }
a7812ae4 9248 tcg_temp_free_i32(fp32);
b6d96bed 9249 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 9250 tcg_temp_free_i64(fp64);
b6d96bed 9251 }
5a5012ec 9252 break;
bf4120ad 9253 case OPC_FLOOR_L_S:
5e755519 9254 check_cp1_64bitmode(ctx);
b6d96bed 9255 {
a7812ae4
PB
9256 TCGv_i32 fp32 = tcg_temp_new_i32();
9257 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 9258
7c979afd 9259 gen_load_fpr32(ctx, fp32, fs);
87552089
AM
9260 if (ctx->nan2008) {
9261 gen_helper_float_floor_2008_l_s(fp64, cpu_env, fp32);
9262 } else {
9263 gen_helper_float_floor_l_s(fp64, cpu_env, fp32);
9264 }
a7812ae4 9265 tcg_temp_free_i32(fp32);
b6d96bed 9266 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 9267 tcg_temp_free_i64(fp64);
b6d96bed 9268 }
5a5012ec 9269 break;
bf4120ad 9270 case OPC_ROUND_W_S:
b6d96bed 9271 {
a7812ae4 9272 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9273
7c979afd 9274 gen_load_fpr32(ctx, fp0, fs);
87552089
AM
9275 if (ctx->nan2008) {
9276 gen_helper_float_round_2008_w_s(fp0, cpu_env, fp0);
9277 } else {
9278 gen_helper_float_round_w_s(fp0, cpu_env, fp0);
9279 }
7c979afd 9280 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9281 tcg_temp_free_i32(fp0);
b6d96bed 9282 }
5a5012ec 9283 break;
bf4120ad 9284 case OPC_TRUNC_W_S:
b6d96bed 9285 {
a7812ae4 9286 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9287
7c979afd 9288 gen_load_fpr32(ctx, fp0, fs);
87552089
AM
9289 if (ctx->nan2008) {
9290 gen_helper_float_trunc_2008_w_s(fp0, cpu_env, fp0);
9291 } else {
9292 gen_helper_float_trunc_w_s(fp0, cpu_env, fp0);
9293 }
7c979afd 9294 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9295 tcg_temp_free_i32(fp0);
b6d96bed 9296 }
5a5012ec 9297 break;
bf4120ad 9298 case OPC_CEIL_W_S:
b6d96bed 9299 {
a7812ae4 9300 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9301
7c979afd 9302 gen_load_fpr32(ctx, fp0, fs);
87552089
AM
9303 if (ctx->nan2008) {
9304 gen_helper_float_ceil_2008_w_s(fp0, cpu_env, fp0);
9305 } else {
9306 gen_helper_float_ceil_w_s(fp0, cpu_env, fp0);
9307 }
7c979afd 9308 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9309 tcg_temp_free_i32(fp0);
b6d96bed 9310 }
5a5012ec 9311 break;
bf4120ad 9312 case OPC_FLOOR_W_S:
b6d96bed 9313 {
a7812ae4 9314 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9315
7c979afd 9316 gen_load_fpr32(ctx, fp0, fs);
87552089
AM
9317 if (ctx->nan2008) {
9318 gen_helper_float_floor_2008_w_s(fp0, cpu_env, fp0);
9319 } else {
9320 gen_helper_float_floor_w_s(fp0, cpu_env, fp0);
9321 }
7c979afd 9322 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9323 tcg_temp_free_i32(fp0);
b6d96bed 9324 }
5a5012ec 9325 break;
e7f16abb
LA
9326 case OPC_SEL_S:
9327 check_insn(ctx, ISA_MIPS32R6);
9328 gen_sel_s(ctx, op1, fd, ft, fs);
e7f16abb
LA
9329 break;
9330 case OPC_SELEQZ_S:
9331 check_insn(ctx, ISA_MIPS32R6);
9332 gen_sel_s(ctx, op1, fd, ft, fs);
e7f16abb
LA
9333 break;
9334 case OPC_SELNEZ_S:
9335 check_insn(ctx, ISA_MIPS32R6);
9336 gen_sel_s(ctx, op1, fd, ft, fs);
e7f16abb 9337 break;
bf4120ad 9338 case OPC_MOVCF_S:
fecd2646 9339 check_insn_opc_removed(ctx, ISA_MIPS32R6);
7c979afd 9340 gen_movcf_s(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
5a5012ec 9341 break;
bf4120ad 9342 case OPC_MOVZ_S:
fecd2646 9343 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a16336e4 9344 {
42a268c2 9345 TCGLabel *l1 = gen_new_label();
c9297f4d 9346 TCGv_i32 fp0;
a16336e4 9347
c9297f4d
AJ
9348 if (ft != 0) {
9349 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
9350 }
9351 fp0 = tcg_temp_new_i32();
7c979afd
LA
9352 gen_load_fpr32(ctx, fp0, fs);
9353 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9354 tcg_temp_free_i32(fp0);
a16336e4
TS
9355 gen_set_label(l1);
9356 }
5a5012ec 9357 break;
bf4120ad 9358 case OPC_MOVN_S:
fecd2646 9359 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a16336e4 9360 {
42a268c2 9361 TCGLabel *l1 = gen_new_label();
c9297f4d
AJ
9362 TCGv_i32 fp0;
9363
9364 if (ft != 0) {
9365 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
9366 fp0 = tcg_temp_new_i32();
7c979afd
LA
9367 gen_load_fpr32(ctx, fp0, fs);
9368 gen_store_fpr32(ctx, fp0, fd);
c9297f4d
AJ
9369 tcg_temp_free_i32(fp0);
9370 gen_set_label(l1);
9371 }
a16336e4 9372 }
5a5012ec 9373 break;
bf4120ad 9374 case OPC_RECIP_S:
b6d96bed 9375 {
a7812ae4 9376 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9377
7c979afd 9378 gen_load_fpr32(ctx, fp0, fs);
895c2d04 9379 gen_helper_float_recip_s(fp0, cpu_env, fp0);
7c979afd 9380 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9381 tcg_temp_free_i32(fp0);
b6d96bed 9382 }
57fa1fb3 9383 break;
bf4120ad 9384 case OPC_RSQRT_S:
b6d96bed 9385 {
a7812ae4 9386 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9387
7c979afd 9388 gen_load_fpr32(ctx, fp0, fs);
895c2d04 9389 gen_helper_float_rsqrt_s(fp0, cpu_env, fp0);
7c979afd 9390 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9391 tcg_temp_free_i32(fp0);
b6d96bed 9392 }
57fa1fb3 9393 break;
e7f16abb
LA
9394 case OPC_MADDF_S:
9395 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 9396 {
a7812ae4
PB
9397 TCGv_i32 fp0 = tcg_temp_new_i32();
9398 TCGv_i32 fp1 = tcg_temp_new_i32();
e7f16abb 9399 TCGv_i32 fp2 = tcg_temp_new_i32();
7c979afd
LA
9400 gen_load_fpr32(ctx, fp0, fs);
9401 gen_load_fpr32(ctx, fp1, ft);
9402 gen_load_fpr32(ctx, fp2, fd);
e7f16abb 9403 gen_helper_float_maddf_s(fp2, cpu_env, fp0, fp1, fp2);
7c979afd 9404 gen_store_fpr32(ctx, fp2, fd);
e7f16abb 9405 tcg_temp_free_i32(fp2);
a7812ae4 9406 tcg_temp_free_i32(fp1);
a7812ae4 9407 tcg_temp_free_i32(fp0);
b6d96bed 9408 }
57fa1fb3 9409 break;
e7f16abb
LA
9410 case OPC_MSUBF_S:
9411 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 9412 {
a7812ae4 9413 TCGv_i32 fp0 = tcg_temp_new_i32();
e7f16abb
LA
9414 TCGv_i32 fp1 = tcg_temp_new_i32();
9415 TCGv_i32 fp2 = tcg_temp_new_i32();
7c979afd
LA
9416 gen_load_fpr32(ctx, fp0, fs);
9417 gen_load_fpr32(ctx, fp1, ft);
9418 gen_load_fpr32(ctx, fp2, fd);
e7f16abb 9419 gen_helper_float_msubf_s(fp2, cpu_env, fp0, fp1, fp2);
7c979afd 9420 gen_store_fpr32(ctx, fp2, fd);
e7f16abb
LA
9421 tcg_temp_free_i32(fp2);
9422 tcg_temp_free_i32(fp1);
a7812ae4 9423 tcg_temp_free_i32(fp0);
b6d96bed 9424 }
57fa1fb3 9425 break;
e7f16abb
LA
9426 case OPC_RINT_S:
9427 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 9428 {
a7812ae4 9429 TCGv_i32 fp0 = tcg_temp_new_i32();
7c979afd 9430 gen_load_fpr32(ctx, fp0, fs);
e7f16abb 9431 gen_helper_float_rint_s(fp0, cpu_env, fp0);
7c979afd 9432 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9433 tcg_temp_free_i32(fp0);
b6d96bed 9434 }
57fa1fb3 9435 break;
e7f16abb
LA
9436 case OPC_CLASS_S:
9437 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 9438 {
e7f16abb 9439 TCGv_i32 fp0 = tcg_temp_new_i32();
7c979afd 9440 gen_load_fpr32(ctx, fp0, fs);
af39bc8c 9441 gen_helper_float_class_s(fp0, cpu_env, fp0);
7c979afd 9442 gen_store_fpr32(ctx, fp0, fd);
e7f16abb 9443 tcg_temp_free_i32(fp0);
e7f16abb
LA
9444 }
9445 break;
9446 case OPC_MIN_S: /* OPC_RECIP2_S */
9447 if (ctx->insn_flags & ISA_MIPS32R6) {
9448 /* OPC_MIN_S */
a7812ae4
PB
9449 TCGv_i32 fp0 = tcg_temp_new_i32();
9450 TCGv_i32 fp1 = tcg_temp_new_i32();
e7f16abb 9451 TCGv_i32 fp2 = tcg_temp_new_i32();
7c979afd
LA
9452 gen_load_fpr32(ctx, fp0, fs);
9453 gen_load_fpr32(ctx, fp1, ft);
e7f16abb 9454 gen_helper_float_min_s(fp2, cpu_env, fp0, fp1);
7c979afd 9455 gen_store_fpr32(ctx, fp2, fd);
e7f16abb
LA
9456 tcg_temp_free_i32(fp2);
9457 tcg_temp_free_i32(fp1);
9458 tcg_temp_free_i32(fp0);
e7f16abb
LA
9459 } else {
9460 /* OPC_RECIP2_S */
9461 check_cp1_64bitmode(ctx);
9462 {
9463 TCGv_i32 fp0 = tcg_temp_new_i32();
9464 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 9465
7c979afd
LA
9466 gen_load_fpr32(ctx, fp0, fs);
9467 gen_load_fpr32(ctx, fp1, ft);
e7f16abb
LA
9468 gen_helper_float_recip2_s(fp0, cpu_env, fp0, fp1);
9469 tcg_temp_free_i32(fp1);
7c979afd 9470 gen_store_fpr32(ctx, fp0, fd);
e7f16abb
LA
9471 tcg_temp_free_i32(fp0);
9472 }
e7f16abb
LA
9473 }
9474 break;
9475 case OPC_MINA_S: /* OPC_RECIP1_S */
9476 if (ctx->insn_flags & ISA_MIPS32R6) {
9477 /* OPC_MINA_S */
9478 TCGv_i32 fp0 = tcg_temp_new_i32();
9479 TCGv_i32 fp1 = tcg_temp_new_i32();
9480 TCGv_i32 fp2 = tcg_temp_new_i32();
7c979afd
LA
9481 gen_load_fpr32(ctx, fp0, fs);
9482 gen_load_fpr32(ctx, fp1, ft);
e7f16abb 9483 gen_helper_float_mina_s(fp2, cpu_env, fp0, fp1);
7c979afd 9484 gen_store_fpr32(ctx, fp2, fd);
e7f16abb
LA
9485 tcg_temp_free_i32(fp2);
9486 tcg_temp_free_i32(fp1);
9487 tcg_temp_free_i32(fp0);
e7f16abb
LA
9488 } else {
9489 /* OPC_RECIP1_S */
9490 check_cp1_64bitmode(ctx);
9491 {
9492 TCGv_i32 fp0 = tcg_temp_new_i32();
9493
7c979afd 9494 gen_load_fpr32(ctx, fp0, fs);
e7f16abb 9495 gen_helper_float_recip1_s(fp0, cpu_env, fp0);
7c979afd 9496 gen_store_fpr32(ctx, fp0, fd);
e7f16abb
LA
9497 tcg_temp_free_i32(fp0);
9498 }
e7f16abb
LA
9499 }
9500 break;
9501 case OPC_MAX_S: /* OPC_RSQRT1_S */
9502 if (ctx->insn_flags & ISA_MIPS32R6) {
9503 /* OPC_MAX_S */
9504 TCGv_i32 fp0 = tcg_temp_new_i32();
9505 TCGv_i32 fp1 = tcg_temp_new_i32();
7c979afd
LA
9506 gen_load_fpr32(ctx, fp0, fs);
9507 gen_load_fpr32(ctx, fp1, ft);
e7f16abb 9508 gen_helper_float_max_s(fp1, cpu_env, fp0, fp1);
7c979afd 9509 gen_store_fpr32(ctx, fp1, fd);
e7f16abb
LA
9510 tcg_temp_free_i32(fp1);
9511 tcg_temp_free_i32(fp0);
e7f16abb
LA
9512 } else {
9513 /* OPC_RSQRT1_S */
9514 check_cp1_64bitmode(ctx);
9515 {
9516 TCGv_i32 fp0 = tcg_temp_new_i32();
9517
7c979afd 9518 gen_load_fpr32(ctx, fp0, fs);
e7f16abb 9519 gen_helper_float_rsqrt1_s(fp0, cpu_env, fp0);
7c979afd 9520 gen_store_fpr32(ctx, fp0, fd);
e7f16abb
LA
9521 tcg_temp_free_i32(fp0);
9522 }
e7f16abb
LA
9523 }
9524 break;
9525 case OPC_MAXA_S: /* OPC_RSQRT2_S */
9526 if (ctx->insn_flags & ISA_MIPS32R6) {
9527 /* OPC_MAXA_S */
9528 TCGv_i32 fp0 = tcg_temp_new_i32();
9529 TCGv_i32 fp1 = tcg_temp_new_i32();
7c979afd
LA
9530 gen_load_fpr32(ctx, fp0, fs);
9531 gen_load_fpr32(ctx, fp1, ft);
e7f16abb 9532 gen_helper_float_maxa_s(fp1, cpu_env, fp0, fp1);
7c979afd 9533 gen_store_fpr32(ctx, fp1, fd);
a7812ae4 9534 tcg_temp_free_i32(fp1);
a7812ae4 9535 tcg_temp_free_i32(fp0);
e7f16abb
LA
9536 } else {
9537 /* OPC_RSQRT2_S */
9538 check_cp1_64bitmode(ctx);
9539 {
9540 TCGv_i32 fp0 = tcg_temp_new_i32();
9541 TCGv_i32 fp1 = tcg_temp_new_i32();
9542
7c979afd
LA
9543 gen_load_fpr32(ctx, fp0, fs);
9544 gen_load_fpr32(ctx, fp1, ft);
e7f16abb
LA
9545 gen_helper_float_rsqrt2_s(fp0, cpu_env, fp0, fp1);
9546 tcg_temp_free_i32(fp1);
7c979afd 9547 gen_store_fpr32(ctx, fp0, fd);
e7f16abb
LA
9548 tcg_temp_free_i32(fp0);
9549 }
b6d96bed 9550 }
57fa1fb3 9551 break;
bf4120ad 9552 case OPC_CVT_D_S:
5e755519 9553 check_cp1_registers(ctx, fd);
b6d96bed 9554 {
a7812ae4
PB
9555 TCGv_i32 fp32 = tcg_temp_new_i32();
9556 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 9557
7c979afd 9558 gen_load_fpr32(ctx, fp32, fs);
895c2d04 9559 gen_helper_float_cvtd_s(fp64, cpu_env, fp32);
a7812ae4 9560 tcg_temp_free_i32(fp32);
b6d96bed 9561 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 9562 tcg_temp_free_i64(fp64);
b6d96bed 9563 }
5a5012ec 9564 break;
bf4120ad 9565 case OPC_CVT_W_S:
b6d96bed 9566 {
a7812ae4 9567 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 9568
7c979afd 9569 gen_load_fpr32(ctx, fp0, fs);
87552089
AM
9570 if (ctx->nan2008) {
9571 gen_helper_float_cvt_2008_w_s(fp0, cpu_env, fp0);
9572 } else {
9573 gen_helper_float_cvt_w_s(fp0, cpu_env, fp0);
9574 }
7c979afd 9575 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 9576 tcg_temp_free_i32(fp0);
b6d96bed 9577 }
5a5012ec 9578 break;
bf4120ad 9579 case OPC_CVT_L_S:
5e755519 9580 check_cp1_64bitmode(ctx);
b6d96bed 9581 {
a7812ae4
PB
9582 TCGv_i32 fp32 = tcg_temp_new_i32();
9583 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 9584
7c979afd 9585 gen_load_fpr32(ctx, fp32, fs);
87552089
AM
9586 if (ctx->nan2008) {
9587 gen_helper_float_cvt_2008_l_s(fp64, cpu_env, fp32);
9588 } else {
9589 gen_helper_float_cvt_l_s(fp64, cpu_env, fp32);
9590 }
a7812ae4 9591 tcg_temp_free_i32(fp32);
b6d96bed 9592 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 9593 tcg_temp_free_i64(fp64);
b6d96bed 9594 }
5a5012ec 9595 break;
bf4120ad 9596 case OPC_CVT_PS_S:
e29c9628 9597 check_ps(ctx);
b6d96bed 9598 {
a7812ae4
PB
9599 TCGv_i64 fp64 = tcg_temp_new_i64();
9600 TCGv_i32 fp32_0 = tcg_temp_new_i32();
9601 TCGv_i32 fp32_1 = tcg_temp_new_i32();
b6d96bed 9602
7c979afd
LA
9603 gen_load_fpr32(ctx, fp32_0, fs);
9604 gen_load_fpr32(ctx, fp32_1, ft);
13d24f49 9605 tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0);
a7812ae4
PB
9606 tcg_temp_free_i32(fp32_1);
9607 tcg_temp_free_i32(fp32_0);
36aa55dc 9608 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 9609 tcg_temp_free_i64(fp64);
b6d96bed 9610 }
5a5012ec 9611 break;
bf4120ad
NF
9612 case OPC_CMP_F_S:
9613 case OPC_CMP_UN_S:
9614 case OPC_CMP_EQ_S:
9615 case OPC_CMP_UEQ_S:
9616 case OPC_CMP_OLT_S:
9617 case OPC_CMP_ULT_S:
9618 case OPC_CMP_OLE_S:
9619 case OPC_CMP_ULE_S:
9620 case OPC_CMP_SF_S:
9621 case OPC_CMP_NGLE_S:
9622 case OPC_CMP_SEQ_S:
9623 case OPC_CMP_NGL_S:
9624 case OPC_CMP_LT_S:
9625 case OPC_CMP_NGE_S:
9626 case OPC_CMP_LE_S:
9627 case OPC_CMP_NGT_S:
fecd2646 9628 check_insn_opc_removed(ctx, ISA_MIPS32R6);
8153667c
NF
9629 if (ctx->opcode & (1 << 6)) {
9630 gen_cmpabs_s(ctx, func-48, ft, fs, cc);
8153667c
NF
9631 } else {
9632 gen_cmp_s(ctx, func-48, ft, fs, cc);
5a1e8ffb 9633 }
5a5012ec 9634 break;
bf4120ad 9635 case OPC_ADD_D:
5e755519 9636 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 9637 {
a7812ae4
PB
9638 TCGv_i64 fp0 = tcg_temp_new_i64();
9639 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9640
9641 gen_load_fpr64(ctx, fp0, fs);
9642 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9643 gen_helper_float_add_d(fp0, cpu_env, fp0, fp1);
a7812ae4 9644 tcg_temp_free_i64(fp1);
b6d96bed 9645 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9646 tcg_temp_free_i64(fp0);
b6d96bed 9647 }
6ea83fed 9648 break;
bf4120ad 9649 case OPC_SUB_D:
5e755519 9650 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 9651 {
a7812ae4
PB
9652 TCGv_i64 fp0 = tcg_temp_new_i64();
9653 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9654
9655 gen_load_fpr64(ctx, fp0, fs);
9656 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9657 gen_helper_float_sub_d(fp0, cpu_env, fp0, fp1);
a7812ae4 9658 tcg_temp_free_i64(fp1);
b6d96bed 9659 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9660 tcg_temp_free_i64(fp0);
b6d96bed 9661 }
6ea83fed 9662 break;
bf4120ad 9663 case OPC_MUL_D:
5e755519 9664 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 9665 {
a7812ae4
PB
9666 TCGv_i64 fp0 = tcg_temp_new_i64();
9667 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9668
9669 gen_load_fpr64(ctx, fp0, fs);
9670 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9671 gen_helper_float_mul_d(fp0, cpu_env, fp0, fp1);
a7812ae4 9672 tcg_temp_free_i64(fp1);
b6d96bed 9673 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9674 tcg_temp_free_i64(fp0);
b6d96bed 9675 }
6ea83fed 9676 break;
bf4120ad 9677 case OPC_DIV_D:
5e755519 9678 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 9679 {
a7812ae4
PB
9680 TCGv_i64 fp0 = tcg_temp_new_i64();
9681 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
9682
9683 gen_load_fpr64(ctx, fp0, fs);
9684 gen_load_fpr64(ctx, fp1, ft);
895c2d04 9685 gen_helper_float_div_d(fp0, cpu_env, fp0, fp1);
a7812ae4 9686 tcg_temp_free_i64(fp1);
b6d96bed 9687 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9688 tcg_temp_free_i64(fp0);
b6d96bed 9689 }
6ea83fed 9690 break;
bf4120ad 9691 case OPC_SQRT_D:
5e755519 9692 check_cp1_registers(ctx, fs | fd);
b6d96bed 9693 {
a7812ae4 9694 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9695
9696 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9697 gen_helper_float_sqrt_d(fp0, cpu_env, fp0);
b6d96bed 9698 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9699 tcg_temp_free_i64(fp0);
b6d96bed 9700 }
6ea83fed 9701 break;
bf4120ad 9702 case OPC_ABS_D:
5e755519 9703 check_cp1_registers(ctx, fs | fd);
b6d96bed 9704 {
a7812ae4 9705 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9706
9707 gen_load_fpr64(ctx, fp0, fs);
6be77480
AM
9708 if (ctx->abs2008) {
9709 tcg_gen_andi_i64(fp0, fp0, 0x7fffffffffffffffULL);
9710 } else {
9711 gen_helper_float_abs_d(fp0, fp0);
9712 }
b6d96bed 9713 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9714 tcg_temp_free_i64(fp0);
b6d96bed 9715 }
6ea83fed 9716 break;
bf4120ad 9717 case OPC_MOV_D:
5e755519 9718 check_cp1_registers(ctx, fs | fd);
b6d96bed 9719 {
a7812ae4 9720 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9721
9722 gen_load_fpr64(ctx, fp0, fs);
9723 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9724 tcg_temp_free_i64(fp0);
b6d96bed 9725 }
6ea83fed 9726 break;
bf4120ad 9727 case OPC_NEG_D:
5e755519 9728 check_cp1_registers(ctx, fs | fd);
b6d96bed 9729 {
a7812ae4 9730 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9731
9732 gen_load_fpr64(ctx, fp0, fs);
6be77480
AM
9733 if (ctx->abs2008) {
9734 tcg_gen_xori_i64(fp0, fp0, 1ULL << 63);
9735 } else {
9736 gen_helper_float_chs_d(fp0, fp0);
9737 }
b6d96bed 9738 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9739 tcg_temp_free_i64(fp0);
b6d96bed 9740 }
6ea83fed 9741 break;
bf4120ad 9742 case OPC_ROUND_L_D:
5e755519 9743 check_cp1_64bitmode(ctx);
b6d96bed 9744 {
a7812ae4 9745 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9746
9747 gen_load_fpr64(ctx, fp0, fs);
87552089
AM
9748 if (ctx->nan2008) {
9749 gen_helper_float_round_2008_l_d(fp0, cpu_env, fp0);
9750 } else {
9751 gen_helper_float_round_l_d(fp0, cpu_env, fp0);
9752 }
b6d96bed 9753 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9754 tcg_temp_free_i64(fp0);
b6d96bed 9755 }
5a5012ec 9756 break;
bf4120ad 9757 case OPC_TRUNC_L_D:
5e755519 9758 check_cp1_64bitmode(ctx);
b6d96bed 9759 {
a7812ae4 9760 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9761
9762 gen_load_fpr64(ctx, fp0, fs);
87552089
AM
9763 if (ctx->nan2008) {
9764 gen_helper_float_trunc_2008_l_d(fp0, cpu_env, fp0);
9765 } else {
9766 gen_helper_float_trunc_l_d(fp0, cpu_env, fp0);
9767 }
b6d96bed 9768 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9769 tcg_temp_free_i64(fp0);
b6d96bed 9770 }
5a5012ec 9771 break;
bf4120ad 9772 case OPC_CEIL_L_D:
5e755519 9773 check_cp1_64bitmode(ctx);
b6d96bed 9774 {
a7812ae4 9775 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9776
9777 gen_load_fpr64(ctx, fp0, fs);
87552089
AM
9778 if (ctx->nan2008) {
9779 gen_helper_float_ceil_2008_l_d(fp0, cpu_env, fp0);
9780 } else {
9781 gen_helper_float_ceil_l_d(fp0, cpu_env, fp0);
9782 }
b6d96bed 9783 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9784 tcg_temp_free_i64(fp0);
b6d96bed 9785 }
5a5012ec 9786 break;
bf4120ad 9787 case OPC_FLOOR_L_D:
5e755519 9788 check_cp1_64bitmode(ctx);
b6d96bed 9789 {
a7812ae4 9790 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9791
9792 gen_load_fpr64(ctx, fp0, fs);
87552089
AM
9793 if (ctx->nan2008) {
9794 gen_helper_float_floor_2008_l_d(fp0, cpu_env, fp0);
9795 } else {
9796 gen_helper_float_floor_l_d(fp0, cpu_env, fp0);
9797 }
b6d96bed 9798 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9799 tcg_temp_free_i64(fp0);
b6d96bed 9800 }
5a5012ec 9801 break;
bf4120ad 9802 case OPC_ROUND_W_D:
5e755519 9803 check_cp1_registers(ctx, fs);
b6d96bed 9804 {
a7812ae4
PB
9805 TCGv_i32 fp32 = tcg_temp_new_i32();
9806 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
9807
9808 gen_load_fpr64(ctx, fp64, fs);
87552089
AM
9809 if (ctx->nan2008) {
9810 gen_helper_float_round_2008_w_d(fp32, cpu_env, fp64);
9811 } else {
9812 gen_helper_float_round_w_d(fp32, cpu_env, fp64);
9813 }
a7812ae4 9814 tcg_temp_free_i64(fp64);
7c979afd 9815 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 9816 tcg_temp_free_i32(fp32);
b6d96bed 9817 }
6ea83fed 9818 break;
bf4120ad 9819 case OPC_TRUNC_W_D:
5e755519 9820 check_cp1_registers(ctx, fs);
b6d96bed 9821 {
a7812ae4
PB
9822 TCGv_i32 fp32 = tcg_temp_new_i32();
9823 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
9824
9825 gen_load_fpr64(ctx, fp64, fs);
87552089
AM
9826 if (ctx->nan2008) {
9827 gen_helper_float_trunc_2008_w_d(fp32, cpu_env, fp64);
9828 } else {
9829 gen_helper_float_trunc_w_d(fp32, cpu_env, fp64);
9830 }
a7812ae4 9831 tcg_temp_free_i64(fp64);
7c979afd 9832 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 9833 tcg_temp_free_i32(fp32);
b6d96bed 9834 }
6ea83fed 9835 break;
bf4120ad 9836 case OPC_CEIL_W_D:
5e755519 9837 check_cp1_registers(ctx, fs);
b6d96bed 9838 {
a7812ae4
PB
9839 TCGv_i32 fp32 = tcg_temp_new_i32();
9840 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
9841
9842 gen_load_fpr64(ctx, fp64, fs);
87552089
AM
9843 if (ctx->nan2008) {
9844 gen_helper_float_ceil_2008_w_d(fp32, cpu_env, fp64);
9845 } else {
9846 gen_helper_float_ceil_w_d(fp32, cpu_env, fp64);
9847 }
a7812ae4 9848 tcg_temp_free_i64(fp64);
7c979afd 9849 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 9850 tcg_temp_free_i32(fp32);
b6d96bed 9851 }
6ea83fed 9852 break;
bf4120ad 9853 case OPC_FLOOR_W_D:
5e755519 9854 check_cp1_registers(ctx, fs);
b6d96bed 9855 {
a7812ae4
PB
9856 TCGv_i32 fp32 = tcg_temp_new_i32();
9857 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
9858
9859 gen_load_fpr64(ctx, fp64, fs);
87552089
AM
9860 if (ctx->nan2008) {
9861 gen_helper_float_floor_2008_w_d(fp32, cpu_env, fp64);
9862 } else {
9863 gen_helper_float_floor_w_d(fp32, cpu_env, fp64);
9864 }
a7812ae4 9865 tcg_temp_free_i64(fp64);
7c979afd 9866 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 9867 tcg_temp_free_i32(fp32);
b6d96bed 9868 }
6ea83fed 9869 break;
e7f16abb
LA
9870 case OPC_SEL_D:
9871 check_insn(ctx, ISA_MIPS32R6);
9872 gen_sel_d(ctx, op1, fd, ft, fs);
e7f16abb
LA
9873 break;
9874 case OPC_SELEQZ_D:
9875 check_insn(ctx, ISA_MIPS32R6);
9876 gen_sel_d(ctx, op1, fd, ft, fs);
e7f16abb
LA
9877 break;
9878 case OPC_SELNEZ_D:
9879 check_insn(ctx, ISA_MIPS32R6);
9880 gen_sel_d(ctx, op1, fd, ft, fs);
e7f16abb 9881 break;
bf4120ad 9882 case OPC_MOVCF_D:
fecd2646 9883 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b6d96bed 9884 gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
dd016883 9885 break;
bf4120ad 9886 case OPC_MOVZ_D:
fecd2646 9887 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a16336e4 9888 {
42a268c2 9889 TCGLabel *l1 = gen_new_label();
c9297f4d 9890 TCGv_i64 fp0;
a16336e4 9891
c9297f4d
AJ
9892 if (ft != 0) {
9893 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
9894 }
9895 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9896 gen_load_fpr64(ctx, fp0, fs);
9897 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9898 tcg_temp_free_i64(fp0);
a16336e4
TS
9899 gen_set_label(l1);
9900 }
5a5012ec 9901 break;
bf4120ad 9902 case OPC_MOVN_D:
fecd2646 9903 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a16336e4 9904 {
42a268c2 9905 TCGLabel *l1 = gen_new_label();
c9297f4d
AJ
9906 TCGv_i64 fp0;
9907
9908 if (ft != 0) {
9909 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
9910 fp0 = tcg_temp_new_i64();
9911 gen_load_fpr64(ctx, fp0, fs);
9912 gen_store_fpr64(ctx, fp0, fd);
9913 tcg_temp_free_i64(fp0);
9914 gen_set_label(l1);
9915 }
a16336e4 9916 }
6ea83fed 9917 break;
bf4120ad 9918 case OPC_RECIP_D:
ca6c7803 9919 check_cp1_registers(ctx, fs | fd);
b6d96bed 9920 {
a7812ae4 9921 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9922
9923 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9924 gen_helper_float_recip_d(fp0, cpu_env, fp0);
b6d96bed 9925 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9926 tcg_temp_free_i64(fp0);
b6d96bed 9927 }
57fa1fb3 9928 break;
bf4120ad 9929 case OPC_RSQRT_D:
ca6c7803 9930 check_cp1_registers(ctx, fs | fd);
b6d96bed 9931 {
a7812ae4 9932 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
9933
9934 gen_load_fpr64(ctx, fp0, fs);
895c2d04 9935 gen_helper_float_rsqrt_d(fp0, cpu_env, fp0);
b6d96bed 9936 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9937 tcg_temp_free_i64(fp0);
b6d96bed 9938 }
57fa1fb3 9939 break;
e7f16abb
LA
9940 case OPC_MADDF_D:
9941 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 9942 {
a7812ae4
PB
9943 TCGv_i64 fp0 = tcg_temp_new_i64();
9944 TCGv_i64 fp1 = tcg_temp_new_i64();
e7f16abb 9945 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
9946 gen_load_fpr64(ctx, fp0, fs);
9947 gen_load_fpr64(ctx, fp1, ft);
e7f16abb
LA
9948 gen_load_fpr64(ctx, fp2, fd);
9949 gen_helper_float_maddf_d(fp2, cpu_env, fp0, fp1, fp2);
9950 gen_store_fpr64(ctx, fp2, fd);
9951 tcg_temp_free_i64(fp2);
a7812ae4 9952 tcg_temp_free_i64(fp1);
a7812ae4 9953 tcg_temp_free_i64(fp0);
b6d96bed 9954 }
57fa1fb3 9955 break;
e7f16abb
LA
9956 case OPC_MSUBF_D:
9957 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 9958 {
a7812ae4 9959 TCGv_i64 fp0 = tcg_temp_new_i64();
e7f16abb
LA
9960 TCGv_i64 fp1 = tcg_temp_new_i64();
9961 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed 9962 gen_load_fpr64(ctx, fp0, fs);
e7f16abb
LA
9963 gen_load_fpr64(ctx, fp1, ft);
9964 gen_load_fpr64(ctx, fp2, fd);
9965 gen_helper_float_msubf_d(fp2, cpu_env, fp0, fp1, fp2);
9966 gen_store_fpr64(ctx, fp2, fd);
9967 tcg_temp_free_i64(fp2);
9968 tcg_temp_free_i64(fp1);
a7812ae4 9969 tcg_temp_free_i64(fp0);
b6d96bed 9970 }
57fa1fb3 9971 break;
e7f16abb
LA
9972 case OPC_RINT_D:
9973 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 9974 {
a7812ae4 9975 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 9976 gen_load_fpr64(ctx, fp0, fs);
e7f16abb 9977 gen_helper_float_rint_d(fp0, cpu_env, fp0);
b6d96bed 9978 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 9979 tcg_temp_free_i64(fp0);
b6d96bed 9980 }
57fa1fb3 9981 break;
e7f16abb
LA
9982 case OPC_CLASS_D:
9983 check_insn(ctx, ISA_MIPS32R6);
b6d96bed 9984 {
e7f16abb
LA
9985 TCGv_i64 fp0 = tcg_temp_new_i64();
9986 gen_load_fpr64(ctx, fp0, fs);
af39bc8c 9987 gen_helper_float_class_d(fp0, cpu_env, fp0);
e7f16abb
LA
9988 gen_store_fpr64(ctx, fp0, fd);
9989 tcg_temp_free_i64(fp0);
e7f16abb
LA
9990 }
9991 break;
9992 case OPC_MIN_D: /* OPC_RECIP2_D */
9993 if (ctx->insn_flags & ISA_MIPS32R6) {
9994 /* OPC_MIN_D */
a7812ae4
PB
9995 TCGv_i64 fp0 = tcg_temp_new_i64();
9996 TCGv_i64 fp1 = tcg_temp_new_i64();
e7f16abb
LA
9997 gen_load_fpr64(ctx, fp0, fs);
9998 gen_load_fpr64(ctx, fp1, ft);
9999 gen_helper_float_min_d(fp1, cpu_env, fp0, fp1);
10000 gen_store_fpr64(ctx, fp1, fd);
10001 tcg_temp_free_i64(fp1);
10002 tcg_temp_free_i64(fp0);
e7f16abb
LA
10003 } else {
10004 /* OPC_RECIP2_D */
10005 check_cp1_64bitmode(ctx);
10006 {
10007 TCGv_i64 fp0 = tcg_temp_new_i64();
10008 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed 10009
e7f16abb
LA
10010 gen_load_fpr64(ctx, fp0, fs);
10011 gen_load_fpr64(ctx, fp1, ft);
10012 gen_helper_float_recip2_d(fp0, cpu_env, fp0, fp1);
10013 tcg_temp_free_i64(fp1);
10014 gen_store_fpr64(ctx, fp0, fd);
10015 tcg_temp_free_i64(fp0);
10016 }
e7f16abb
LA
10017 }
10018 break;
10019 case OPC_MINA_D: /* OPC_RECIP1_D */
10020 if (ctx->insn_flags & ISA_MIPS32R6) {
10021 /* OPC_MINA_D */
10022 TCGv_i64 fp0 = tcg_temp_new_i64();
10023 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
10024 gen_load_fpr64(ctx, fp0, fs);
10025 gen_load_fpr64(ctx, fp1, ft);
e7f16abb
LA
10026 gen_helper_float_mina_d(fp1, cpu_env, fp0, fp1);
10027 gen_store_fpr64(ctx, fp1, fd);
10028 tcg_temp_free_i64(fp1);
10029 tcg_temp_free_i64(fp0);
e7f16abb
LA
10030 } else {
10031 /* OPC_RECIP1_D */
10032 check_cp1_64bitmode(ctx);
10033 {
10034 TCGv_i64 fp0 = tcg_temp_new_i64();
10035
10036 gen_load_fpr64(ctx, fp0, fs);
10037 gen_helper_float_recip1_d(fp0, cpu_env, fp0);
10038 gen_store_fpr64(ctx, fp0, fd);
10039 tcg_temp_free_i64(fp0);
10040 }
e7f16abb
LA
10041 }
10042 break;
10043 case OPC_MAX_D: /* OPC_RSQRT1_D */
10044 if (ctx->insn_flags & ISA_MIPS32R6) {
10045 /* OPC_MAX_D */
10046 TCGv_i64 fp0 = tcg_temp_new_i64();
10047 TCGv_i64 fp1 = tcg_temp_new_i64();
10048 gen_load_fpr64(ctx, fp0, fs);
10049 gen_load_fpr64(ctx, fp1, ft);
10050 gen_helper_float_max_d(fp1, cpu_env, fp0, fp1);
10051 gen_store_fpr64(ctx, fp1, fd);
a7812ae4 10052 tcg_temp_free_i64(fp1);
a7812ae4 10053 tcg_temp_free_i64(fp0);
e7f16abb
LA
10054 } else {
10055 /* OPC_RSQRT1_D */
10056 check_cp1_64bitmode(ctx);
10057 {
10058 TCGv_i64 fp0 = tcg_temp_new_i64();
10059
10060 gen_load_fpr64(ctx, fp0, fs);
10061 gen_helper_float_rsqrt1_d(fp0, cpu_env, fp0);
10062 gen_store_fpr64(ctx, fp0, fd);
10063 tcg_temp_free_i64(fp0);
10064 }
e7f16abb
LA
10065 }
10066 break;
10067 case OPC_MAXA_D: /* OPC_RSQRT2_D */
10068 if (ctx->insn_flags & ISA_MIPS32R6) {
10069 /* OPC_MAXA_D */
10070 TCGv_i64 fp0 = tcg_temp_new_i64();
10071 TCGv_i64 fp1 = tcg_temp_new_i64();
10072 gen_load_fpr64(ctx, fp0, fs);
10073 gen_load_fpr64(ctx, fp1, ft);
10074 gen_helper_float_maxa_d(fp1, cpu_env, fp0, fp1);
10075 gen_store_fpr64(ctx, fp1, fd);
10076 tcg_temp_free_i64(fp1);
10077 tcg_temp_free_i64(fp0);
e7f16abb
LA
10078 } else {
10079 /* OPC_RSQRT2_D */
10080 check_cp1_64bitmode(ctx);
10081 {
10082 TCGv_i64 fp0 = tcg_temp_new_i64();
10083 TCGv_i64 fp1 = tcg_temp_new_i64();
10084
10085 gen_load_fpr64(ctx, fp0, fs);
10086 gen_load_fpr64(ctx, fp1, ft);
10087 gen_helper_float_rsqrt2_d(fp0, cpu_env, fp0, fp1);
10088 tcg_temp_free_i64(fp1);
10089 gen_store_fpr64(ctx, fp0, fd);
10090 tcg_temp_free_i64(fp0);
10091 }
b6d96bed 10092 }
57fa1fb3 10093 break;
bf4120ad
NF
10094 case OPC_CMP_F_D:
10095 case OPC_CMP_UN_D:
10096 case OPC_CMP_EQ_D:
10097 case OPC_CMP_UEQ_D:
10098 case OPC_CMP_OLT_D:
10099 case OPC_CMP_ULT_D:
10100 case OPC_CMP_OLE_D:
10101 case OPC_CMP_ULE_D:
10102 case OPC_CMP_SF_D:
10103 case OPC_CMP_NGLE_D:
10104 case OPC_CMP_SEQ_D:
10105 case OPC_CMP_NGL_D:
10106 case OPC_CMP_LT_D:
10107 case OPC_CMP_NGE_D:
10108 case OPC_CMP_LE_D:
10109 case OPC_CMP_NGT_D:
fecd2646 10110 check_insn_opc_removed(ctx, ISA_MIPS32R6);
8153667c
NF
10111 if (ctx->opcode & (1 << 6)) {
10112 gen_cmpabs_d(ctx, func-48, ft, fs, cc);
8153667c
NF
10113 } else {
10114 gen_cmp_d(ctx, func-48, ft, fs, cc);
5a1e8ffb 10115 }
6ea83fed 10116 break;
bf4120ad 10117 case OPC_CVT_S_D:
5e755519 10118 check_cp1_registers(ctx, fs);
b6d96bed 10119 {
a7812ae4
PB
10120 TCGv_i32 fp32 = tcg_temp_new_i32();
10121 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
10122
10123 gen_load_fpr64(ctx, fp64, fs);
895c2d04 10124 gen_helper_float_cvts_d(fp32, cpu_env, fp64);
a7812ae4 10125 tcg_temp_free_i64(fp64);
7c979afd 10126 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 10127 tcg_temp_free_i32(fp32);
b6d96bed 10128 }
5a5012ec 10129 break;
bf4120ad 10130 case OPC_CVT_W_D:
5e755519 10131 check_cp1_registers(ctx, fs);
b6d96bed 10132 {
a7812ae4
PB
10133 TCGv_i32 fp32 = tcg_temp_new_i32();
10134 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
10135
10136 gen_load_fpr64(ctx, fp64, fs);
87552089
AM
10137 if (ctx->nan2008) {
10138 gen_helper_float_cvt_2008_w_d(fp32, cpu_env, fp64);
10139 } else {
10140 gen_helper_float_cvt_w_d(fp32, cpu_env, fp64);
10141 }
a7812ae4 10142 tcg_temp_free_i64(fp64);
7c979afd 10143 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 10144 tcg_temp_free_i32(fp32);
b6d96bed 10145 }
5a5012ec 10146 break;
bf4120ad 10147 case OPC_CVT_L_D:
5e755519 10148 check_cp1_64bitmode(ctx);
b6d96bed 10149 {
a7812ae4 10150 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
10151
10152 gen_load_fpr64(ctx, fp0, fs);
87552089
AM
10153 if (ctx->nan2008) {
10154 gen_helper_float_cvt_2008_l_d(fp0, cpu_env, fp0);
10155 } else {
10156 gen_helper_float_cvt_l_d(fp0, cpu_env, fp0);
10157 }
b6d96bed 10158 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10159 tcg_temp_free_i64(fp0);
b6d96bed 10160 }
5a5012ec 10161 break;
bf4120ad 10162 case OPC_CVT_S_W:
b6d96bed 10163 {
a7812ae4 10164 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 10165
7c979afd 10166 gen_load_fpr32(ctx, fp0, fs);
895c2d04 10167 gen_helper_float_cvts_w(fp0, cpu_env, fp0);
7c979afd 10168 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 10169 tcg_temp_free_i32(fp0);
b6d96bed 10170 }
6ea83fed 10171 break;
bf4120ad 10172 case OPC_CVT_D_W:
5e755519 10173 check_cp1_registers(ctx, fd);
b6d96bed 10174 {
a7812ae4
PB
10175 TCGv_i32 fp32 = tcg_temp_new_i32();
10176 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed 10177
7c979afd 10178 gen_load_fpr32(ctx, fp32, fs);
895c2d04 10179 gen_helper_float_cvtd_w(fp64, cpu_env, fp32);
a7812ae4 10180 tcg_temp_free_i32(fp32);
b6d96bed 10181 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 10182 tcg_temp_free_i64(fp64);
b6d96bed 10183 }
5a5012ec 10184 break;
bf4120ad 10185 case OPC_CVT_S_L:
5e755519 10186 check_cp1_64bitmode(ctx);
b6d96bed 10187 {
a7812ae4
PB
10188 TCGv_i32 fp32 = tcg_temp_new_i32();
10189 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
10190
10191 gen_load_fpr64(ctx, fp64, fs);
895c2d04 10192 gen_helper_float_cvts_l(fp32, cpu_env, fp64);
a7812ae4 10193 tcg_temp_free_i64(fp64);
7c979afd 10194 gen_store_fpr32(ctx, fp32, fd);
a7812ae4 10195 tcg_temp_free_i32(fp32);
b6d96bed 10196 }
5a5012ec 10197 break;
bf4120ad 10198 case OPC_CVT_D_L:
5e755519 10199 check_cp1_64bitmode(ctx);
b6d96bed 10200 {
a7812ae4 10201 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
10202
10203 gen_load_fpr64(ctx, fp0, fs);
895c2d04 10204 gen_helper_float_cvtd_l(fp0, cpu_env, fp0);
b6d96bed 10205 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10206 tcg_temp_free_i64(fp0);
b6d96bed 10207 }
5a5012ec 10208 break;
bf4120ad 10209 case OPC_CVT_PS_PW:
e29c9628 10210 check_ps(ctx);
b6d96bed 10211 {
a7812ae4 10212 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
10213
10214 gen_load_fpr64(ctx, fp0, fs);
895c2d04 10215 gen_helper_float_cvtps_pw(fp0, cpu_env, fp0);
b6d96bed 10216 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10217 tcg_temp_free_i64(fp0);
b6d96bed 10218 }
5a5012ec 10219 break;
bf4120ad 10220 case OPC_ADD_PS:
e29c9628 10221 check_ps(ctx);
b6d96bed 10222 {
a7812ae4
PB
10223 TCGv_i64 fp0 = tcg_temp_new_i64();
10224 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
10225
10226 gen_load_fpr64(ctx, fp0, fs);
10227 gen_load_fpr64(ctx, fp1, ft);
895c2d04 10228 gen_helper_float_add_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 10229 tcg_temp_free_i64(fp1);
b6d96bed 10230 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10231 tcg_temp_free_i64(fp0);
b6d96bed 10232 }
6ea83fed 10233 break;
bf4120ad 10234 case OPC_SUB_PS:
e29c9628 10235 check_ps(ctx);
b6d96bed 10236 {
a7812ae4
PB
10237 TCGv_i64 fp0 = tcg_temp_new_i64();
10238 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
10239
10240 gen_load_fpr64(ctx, fp0, fs);
10241 gen_load_fpr64(ctx, fp1, ft);
895c2d04 10242 gen_helper_float_sub_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 10243 tcg_temp_free_i64(fp1);
b6d96bed 10244 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10245 tcg_temp_free_i64(fp0);
b6d96bed 10246 }
6ea83fed 10247 break;
bf4120ad 10248 case OPC_MUL_PS:
e29c9628 10249 check_ps(ctx);
b6d96bed 10250 {
a7812ae4
PB
10251 TCGv_i64 fp0 = tcg_temp_new_i64();
10252 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
10253
10254 gen_load_fpr64(ctx, fp0, fs);
10255 gen_load_fpr64(ctx, fp1, ft);
895c2d04 10256 gen_helper_float_mul_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 10257 tcg_temp_free_i64(fp1);
b6d96bed 10258 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10259 tcg_temp_free_i64(fp0);
b6d96bed 10260 }
6ea83fed 10261 break;
bf4120ad 10262 case OPC_ABS_PS:
e29c9628 10263 check_ps(ctx);
b6d96bed 10264 {
a7812ae4 10265 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
10266
10267 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 10268 gen_helper_float_abs_ps(fp0, fp0);
b6d96bed 10269 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10270 tcg_temp_free_i64(fp0);
b6d96bed 10271 }
6ea83fed 10272 break;
bf4120ad 10273 case OPC_MOV_PS:
e29c9628 10274 check_ps(ctx);
b6d96bed 10275 {
a7812ae4 10276 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
10277
10278 gen_load_fpr64(ctx, fp0, fs);
10279 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10280 tcg_temp_free_i64(fp0);
b6d96bed 10281 }
6ea83fed 10282 break;
bf4120ad 10283 case OPC_NEG_PS:
e29c9628 10284 check_ps(ctx);
b6d96bed 10285 {
a7812ae4 10286 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
10287
10288 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 10289 gen_helper_float_chs_ps(fp0, fp0);
b6d96bed 10290 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10291 tcg_temp_free_i64(fp0);
b6d96bed 10292 }
6ea83fed 10293 break;
bf4120ad 10294 case OPC_MOVCF_PS:
e29c9628 10295 check_ps(ctx);
7f6613ce 10296 gen_movcf_ps(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
6ea83fed 10297 break;
bf4120ad 10298 case OPC_MOVZ_PS:
e29c9628 10299 check_ps(ctx);
a16336e4 10300 {
42a268c2 10301 TCGLabel *l1 = gen_new_label();
30a3848b 10302 TCGv_i64 fp0;
a16336e4 10303
c9297f4d
AJ
10304 if (ft != 0)
10305 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
10306 fp0 = tcg_temp_new_i64();
10307 gen_load_fpr64(ctx, fp0, fs);
10308 gen_store_fpr64(ctx, fp0, fd);
10309 tcg_temp_free_i64(fp0);
a16336e4
TS
10310 gen_set_label(l1);
10311 }
6ea83fed 10312 break;
bf4120ad 10313 case OPC_MOVN_PS:
e29c9628 10314 check_ps(ctx);
a16336e4 10315 {
42a268c2 10316 TCGLabel *l1 = gen_new_label();
30a3848b 10317 TCGv_i64 fp0;
c9297f4d
AJ
10318
10319 if (ft != 0) {
10320 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
10321 fp0 = tcg_temp_new_i64();
10322 gen_load_fpr64(ctx, fp0, fs);
10323 gen_store_fpr64(ctx, fp0, fd);
10324 tcg_temp_free_i64(fp0);
10325 gen_set_label(l1);
10326 }
a16336e4 10327 }
6ea83fed 10328 break;
bf4120ad 10329 case OPC_ADDR_PS:
e29c9628 10330 check_ps(ctx);
b6d96bed 10331 {
a7812ae4
PB
10332 TCGv_i64 fp0 = tcg_temp_new_i64();
10333 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
10334
10335 gen_load_fpr64(ctx, fp0, ft);
10336 gen_load_fpr64(ctx, fp1, fs);
895c2d04 10337 gen_helper_float_addr_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 10338 tcg_temp_free_i64(fp1);
b6d96bed 10339 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10340 tcg_temp_free_i64(fp0);
b6d96bed 10341 }
fbcc6828 10342 break;
bf4120ad 10343 case OPC_MULR_PS:
e29c9628 10344 check_ps(ctx);
b6d96bed 10345 {
a7812ae4
PB
10346 TCGv_i64 fp0 = tcg_temp_new_i64();
10347 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
10348
10349 gen_load_fpr64(ctx, fp0, ft);
10350 gen_load_fpr64(ctx, fp1, fs);
895c2d04 10351 gen_helper_float_mulr_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 10352 tcg_temp_free_i64(fp1);
b6d96bed 10353 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10354 tcg_temp_free_i64(fp0);
b6d96bed 10355 }
57fa1fb3 10356 break;
bf4120ad 10357 case OPC_RECIP2_PS:
e29c9628 10358 check_ps(ctx);
b6d96bed 10359 {
a7812ae4
PB
10360 TCGv_i64 fp0 = tcg_temp_new_i64();
10361 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
10362
10363 gen_load_fpr64(ctx, fp0, fs);
d22d7289 10364 gen_load_fpr64(ctx, fp1, ft);
895c2d04 10365 gen_helper_float_recip2_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 10366 tcg_temp_free_i64(fp1);
b6d96bed 10367 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10368 tcg_temp_free_i64(fp0);
b6d96bed 10369 }
57fa1fb3 10370 break;
bf4120ad 10371 case OPC_RECIP1_PS:
e29c9628 10372 check_ps(ctx);
b6d96bed 10373 {
a7812ae4 10374 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
10375
10376 gen_load_fpr64(ctx, fp0, fs);
895c2d04 10377 gen_helper_float_recip1_ps(fp0, cpu_env, fp0);
b6d96bed 10378 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10379 tcg_temp_free_i64(fp0);
b6d96bed 10380 }
57fa1fb3 10381 break;
bf4120ad 10382 case OPC_RSQRT1_PS:
e29c9628 10383 check_ps(ctx);
b6d96bed 10384 {
a7812ae4 10385 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
10386
10387 gen_load_fpr64(ctx, fp0, fs);
895c2d04 10388 gen_helper_float_rsqrt1_ps(fp0, cpu_env, fp0);
b6d96bed 10389 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10390 tcg_temp_free_i64(fp0);
b6d96bed 10391 }
57fa1fb3 10392 break;
bf4120ad 10393 case OPC_RSQRT2_PS:
e29c9628 10394 check_ps(ctx);
b6d96bed 10395 {
a7812ae4
PB
10396 TCGv_i64 fp0 = tcg_temp_new_i64();
10397 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
10398
10399 gen_load_fpr64(ctx, fp0, fs);
10400 gen_load_fpr64(ctx, fp1, ft);
895c2d04 10401 gen_helper_float_rsqrt2_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 10402 tcg_temp_free_i64(fp1);
b6d96bed 10403 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10404 tcg_temp_free_i64(fp0);
b6d96bed 10405 }
57fa1fb3 10406 break;
bf4120ad 10407 case OPC_CVT_S_PU:
5e755519 10408 check_cp1_64bitmode(ctx);
b6d96bed 10409 {
a7812ae4 10410 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 10411
7f6613ce 10412 gen_load_fpr32h(ctx, fp0, fs);
895c2d04 10413 gen_helper_float_cvts_pu(fp0, cpu_env, fp0);
7c979afd 10414 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 10415 tcg_temp_free_i32(fp0);
b6d96bed 10416 }
dd016883 10417 break;
bf4120ad 10418 case OPC_CVT_PW_PS:
e29c9628 10419 check_ps(ctx);
b6d96bed 10420 {
a7812ae4 10421 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
10422
10423 gen_load_fpr64(ctx, fp0, fs);
895c2d04 10424 gen_helper_float_cvtpw_ps(fp0, cpu_env, fp0);
b6d96bed 10425 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10426 tcg_temp_free_i64(fp0);
b6d96bed 10427 }
6ea83fed 10428 break;
bf4120ad 10429 case OPC_CVT_S_PL:
5e755519 10430 check_cp1_64bitmode(ctx);
b6d96bed 10431 {
a7812ae4 10432 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 10433
7c979afd 10434 gen_load_fpr32(ctx, fp0, fs);
895c2d04 10435 gen_helper_float_cvts_pl(fp0, cpu_env, fp0);
7c979afd 10436 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 10437 tcg_temp_free_i32(fp0);
b6d96bed 10438 }
6ea83fed 10439 break;
bf4120ad 10440 case OPC_PLL_PS:
e29c9628 10441 check_ps(ctx);
b6d96bed 10442 {
a7812ae4
PB
10443 TCGv_i32 fp0 = tcg_temp_new_i32();
10444 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 10445
7c979afd
LA
10446 gen_load_fpr32(ctx, fp0, fs);
10447 gen_load_fpr32(ctx, fp1, ft);
7f6613ce 10448 gen_store_fpr32h(ctx, fp0, fd);
7c979afd 10449 gen_store_fpr32(ctx, fp1, fd);
a7812ae4
PB
10450 tcg_temp_free_i32(fp0);
10451 tcg_temp_free_i32(fp1);
b6d96bed 10452 }
6ea83fed 10453 break;
bf4120ad 10454 case OPC_PLU_PS:
e29c9628 10455 check_ps(ctx);
b6d96bed 10456 {
a7812ae4
PB
10457 TCGv_i32 fp0 = tcg_temp_new_i32();
10458 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 10459
7c979afd 10460 gen_load_fpr32(ctx, fp0, fs);
7f6613ce 10461 gen_load_fpr32h(ctx, fp1, ft);
7c979afd 10462 gen_store_fpr32(ctx, fp1, fd);
7f6613ce 10463 gen_store_fpr32h(ctx, fp0, fd);
a7812ae4
PB
10464 tcg_temp_free_i32(fp0);
10465 tcg_temp_free_i32(fp1);
b6d96bed 10466 }
5a5012ec 10467 break;
bf4120ad 10468 case OPC_PUL_PS:
e29c9628 10469 check_ps(ctx);
b6d96bed 10470 {
a7812ae4
PB
10471 TCGv_i32 fp0 = tcg_temp_new_i32();
10472 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 10473
7f6613ce 10474 gen_load_fpr32h(ctx, fp0, fs);
7c979afd
LA
10475 gen_load_fpr32(ctx, fp1, ft);
10476 gen_store_fpr32(ctx, fp1, fd);
7f6613ce 10477 gen_store_fpr32h(ctx, fp0, fd);
a7812ae4
PB
10478 tcg_temp_free_i32(fp0);
10479 tcg_temp_free_i32(fp1);
b6d96bed 10480 }
5a5012ec 10481 break;
bf4120ad 10482 case OPC_PUU_PS:
e29c9628 10483 check_ps(ctx);
b6d96bed 10484 {
a7812ae4
PB
10485 TCGv_i32 fp0 = tcg_temp_new_i32();
10486 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed 10487
7f6613ce
PJ
10488 gen_load_fpr32h(ctx, fp0, fs);
10489 gen_load_fpr32h(ctx, fp1, ft);
7c979afd 10490 gen_store_fpr32(ctx, fp1, fd);
7f6613ce 10491 gen_store_fpr32h(ctx, fp0, fd);
a7812ae4
PB
10492 tcg_temp_free_i32(fp0);
10493 tcg_temp_free_i32(fp1);
b6d96bed 10494 }
5a5012ec 10495 break;
bf4120ad
NF
10496 case OPC_CMP_F_PS:
10497 case OPC_CMP_UN_PS:
10498 case OPC_CMP_EQ_PS:
10499 case OPC_CMP_UEQ_PS:
10500 case OPC_CMP_OLT_PS:
10501 case OPC_CMP_ULT_PS:
10502 case OPC_CMP_OLE_PS:
10503 case OPC_CMP_ULE_PS:
10504 case OPC_CMP_SF_PS:
10505 case OPC_CMP_NGLE_PS:
10506 case OPC_CMP_SEQ_PS:
10507 case OPC_CMP_NGL_PS:
10508 case OPC_CMP_LT_PS:
10509 case OPC_CMP_NGE_PS:
10510 case OPC_CMP_LE_PS:
10511 case OPC_CMP_NGT_PS:
8153667c
NF
10512 if (ctx->opcode & (1 << 6)) {
10513 gen_cmpabs_ps(ctx, func-48, ft, fs, cc);
8153667c
NF
10514 } else {
10515 gen_cmp_ps(ctx, func-48, ft, fs, cc);
5a1e8ffb 10516 }
6ea83fed 10517 break;
5a5012ec 10518 default:
9d68ac14 10519 MIPS_INVAL("farith");
9c708c7f 10520 generate_exception_end(ctx, EXCP_RI);
6ea83fed
FB
10521 return;
10522 }
6ea83fed 10523}
6af0bf9c 10524
5a5012ec 10525/* Coprocessor 3 (FPU) */
5e755519
TS
10526static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
10527 int fd, int fs, int base, int index)
7a387fff 10528{
4e2474d6 10529 TCGv t0 = tcg_temp_new();
7a387fff 10530
93b12ccc 10531 if (base == 0) {
6c5c1e20 10532 gen_load_gpr(t0, index);
93b12ccc 10533 } else if (index == 0) {
6c5c1e20 10534 gen_load_gpr(t0, base);
93b12ccc 10535 } else {
05168674 10536 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]);
93b12ccc 10537 }
5a5012ec 10538 /* Don't do NOP if destination is zero: we must perform the actual
ead9360e 10539 memory access. */
5a5012ec
TS
10540 switch (opc) {
10541 case OPC_LWXC1:
8c0ab41f 10542 check_cop1x(ctx);
b6d96bed 10543 {
a7812ae4 10544 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 10545
5f68f5ae 10546 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
585c88d5 10547 tcg_gen_trunc_tl_i32(fp0, t0);
7c979afd 10548 gen_store_fpr32(ctx, fp0, fd);
a7812ae4 10549 tcg_temp_free_i32(fp0);
b6d96bed 10550 }
5a5012ec
TS
10551 break;
10552 case OPC_LDXC1:
8c0ab41f
AJ
10553 check_cop1x(ctx);
10554 check_cp1_registers(ctx, fd);
b6d96bed 10555 {
a7812ae4 10556 TCGv_i64 fp0 = tcg_temp_new_i64();
5f68f5ae 10557 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
b6d96bed 10558 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10559 tcg_temp_free_i64(fp0);
b6d96bed 10560 }
5a5012ec
TS
10561 break;
10562 case OPC_LUXC1:
8c0ab41f 10563 check_cp1_64bitmode(ctx);
6c5c1e20 10564 tcg_gen_andi_tl(t0, t0, ~0x7);
b6d96bed 10565 {
a7812ae4 10566 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 10567
5f68f5ae 10568 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
b6d96bed 10569 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 10570 tcg_temp_free_i64(fp0);
b6d96bed 10571 }
5a5012ec
TS
10572 break;
10573 case OPC_SWXC1:
8c0ab41f 10574 check_cop1x(ctx);
b6d96bed 10575 {
a7812ae4 10576 TCGv_i32 fp0 = tcg_temp_new_i32();
7c979afd 10577 gen_load_fpr32(ctx, fp0, fs);
5f68f5ae 10578 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL);
a7812ae4 10579 tcg_temp_free_i32(fp0);
b6d96bed 10580 }
5a5012ec
TS
10581 break;
10582 case OPC_SDXC1:
8c0ab41f
AJ
10583 check_cop1x(ctx);
10584 check_cp1_registers(ctx, fs);
b6d96bed 10585 {
a7812ae4 10586 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 10587 gen_load_fpr64(ctx, fp0, fs);
5f68f5ae 10588 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
a7812ae4 10589 tcg_temp_free_i64(fp0);
b6d96bed 10590 }
5a5012ec
TS
10591 break;
10592 case OPC_SUXC1:
8c0ab41f 10593 check_cp1_64bitmode(ctx);
6c5c1e20 10594 tcg_gen_andi_tl(t0, t0, ~0x7);
b6d96bed 10595 {
a7812ae4 10596 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed 10597 gen_load_fpr64(ctx, fp0, fs);
5f68f5ae 10598 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
a7812ae4 10599 tcg_temp_free_i64(fp0);
b6d96bed 10600 }
5a5012ec 10601 break;
5a5012ec 10602 }
6c5c1e20 10603 tcg_temp_free(t0);
5a5012ec
TS
10604}
10605
5e755519
TS
10606static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
10607 int fd, int fr, int fs, int ft)
5a5012ec 10608{
5a5012ec
TS
10609 switch (opc) {
10610 case OPC_ALNV_PS:
e29c9628 10611 check_ps(ctx);
a16336e4 10612 {
a7812ae4 10613 TCGv t0 = tcg_temp_local_new();
c905fdac
AJ
10614 TCGv_i32 fp = tcg_temp_new_i32();
10615 TCGv_i32 fph = tcg_temp_new_i32();
42a268c2
RH
10616 TCGLabel *l1 = gen_new_label();
10617 TCGLabel *l2 = gen_new_label();
a16336e4 10618
6c5c1e20
TS
10619 gen_load_gpr(t0, fr);
10620 tcg_gen_andi_tl(t0, t0, 0x7);
6c5c1e20
TS
10621
10622 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
7c979afd 10623 gen_load_fpr32(ctx, fp, fs);
7f6613ce 10624 gen_load_fpr32h(ctx, fph, fs);
7c979afd 10625 gen_store_fpr32(ctx, fp, fd);
7f6613ce 10626 gen_store_fpr32h(ctx, fph, fd);
a16336e4
TS
10627 tcg_gen_br(l2);
10628 gen_set_label(l1);
6c5c1e20
TS
10629 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
10630 tcg_temp_free(t0);
a16336e4 10631#ifdef TARGET_WORDS_BIGENDIAN
7c979afd 10632 gen_load_fpr32(ctx, fp, fs);
7f6613ce
PJ
10633 gen_load_fpr32h(ctx, fph, ft);
10634 gen_store_fpr32h(ctx, fp, fd);
7c979afd 10635 gen_store_fpr32(ctx, fph, fd);
a16336e4 10636#else
7f6613ce 10637 gen_load_fpr32h(ctx, fph, fs);
7c979afd
LA
10638 gen_load_fpr32(ctx, fp, ft);
10639 gen_store_fpr32(ctx, fph, fd);
7f6613ce 10640 gen_store_fpr32h(ctx, fp, fd);
a16336e4
TS
10641#endif
10642 gen_set_label(l2);
c905fdac
AJ
10643 tcg_temp_free_i32(fp);
10644 tcg_temp_free_i32(fph);
a16336e4 10645 }
5a5012ec
TS
10646 break;
10647 case OPC_MADD_S:
b8aa4598 10648 check_cop1x(ctx);
b6d96bed 10649 {
a7812ae4
PB
10650 TCGv_i32 fp0 = tcg_temp_new_i32();
10651 TCGv_i32 fp1 = tcg_temp_new_i32();
10652 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed 10653
7c979afd
LA
10654 gen_load_fpr32(ctx, fp0, fs);
10655 gen_load_fpr32(ctx, fp1, ft);
10656 gen_load_fpr32(ctx, fp2, fr);
b3d6cd44 10657 gen_helper_float_madd_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10658 tcg_temp_free_i32(fp0);
10659 tcg_temp_free_i32(fp1);
7c979afd 10660 gen_store_fpr32(ctx, fp2, fd);
a7812ae4 10661 tcg_temp_free_i32(fp2);
b6d96bed 10662 }
5a5012ec
TS
10663 break;
10664 case OPC_MADD_D:
b8aa4598
TS
10665 check_cop1x(ctx);
10666 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 10667 {
a7812ae4
PB
10668 TCGv_i64 fp0 = tcg_temp_new_i64();
10669 TCGv_i64 fp1 = tcg_temp_new_i64();
10670 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10671
10672 gen_load_fpr64(ctx, fp0, fs);
10673 gen_load_fpr64(ctx, fp1, ft);
10674 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10675 gen_helper_float_madd_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10676 tcg_temp_free_i64(fp0);
10677 tcg_temp_free_i64(fp1);
b6d96bed 10678 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10679 tcg_temp_free_i64(fp2);
b6d96bed 10680 }
5a5012ec
TS
10681 break;
10682 case OPC_MADD_PS:
e29c9628 10683 check_ps(ctx);
b6d96bed 10684 {
a7812ae4
PB
10685 TCGv_i64 fp0 = tcg_temp_new_i64();
10686 TCGv_i64 fp1 = tcg_temp_new_i64();
10687 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10688
10689 gen_load_fpr64(ctx, fp0, fs);
10690 gen_load_fpr64(ctx, fp1, ft);
10691 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10692 gen_helper_float_madd_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10693 tcg_temp_free_i64(fp0);
10694 tcg_temp_free_i64(fp1);
b6d96bed 10695 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10696 tcg_temp_free_i64(fp2);
b6d96bed 10697 }
5a5012ec
TS
10698 break;
10699 case OPC_MSUB_S:
b8aa4598 10700 check_cop1x(ctx);
b6d96bed 10701 {
a7812ae4
PB
10702 TCGv_i32 fp0 = tcg_temp_new_i32();
10703 TCGv_i32 fp1 = tcg_temp_new_i32();
10704 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed 10705
7c979afd
LA
10706 gen_load_fpr32(ctx, fp0, fs);
10707 gen_load_fpr32(ctx, fp1, ft);
10708 gen_load_fpr32(ctx, fp2, fr);
b3d6cd44 10709 gen_helper_float_msub_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10710 tcg_temp_free_i32(fp0);
10711 tcg_temp_free_i32(fp1);
7c979afd 10712 gen_store_fpr32(ctx, fp2, fd);
a7812ae4 10713 tcg_temp_free_i32(fp2);
b6d96bed 10714 }
5a5012ec
TS
10715 break;
10716 case OPC_MSUB_D:
b8aa4598
TS
10717 check_cop1x(ctx);
10718 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 10719 {
a7812ae4
PB
10720 TCGv_i64 fp0 = tcg_temp_new_i64();
10721 TCGv_i64 fp1 = tcg_temp_new_i64();
10722 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10723
10724 gen_load_fpr64(ctx, fp0, fs);
10725 gen_load_fpr64(ctx, fp1, ft);
10726 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10727 gen_helper_float_msub_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10728 tcg_temp_free_i64(fp0);
10729 tcg_temp_free_i64(fp1);
b6d96bed 10730 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10731 tcg_temp_free_i64(fp2);
b6d96bed 10732 }
5a5012ec
TS
10733 break;
10734 case OPC_MSUB_PS:
e29c9628 10735 check_ps(ctx);
b6d96bed 10736 {
a7812ae4
PB
10737 TCGv_i64 fp0 = tcg_temp_new_i64();
10738 TCGv_i64 fp1 = tcg_temp_new_i64();
10739 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10740
10741 gen_load_fpr64(ctx, fp0, fs);
10742 gen_load_fpr64(ctx, fp1, ft);
10743 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10744 gen_helper_float_msub_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10745 tcg_temp_free_i64(fp0);
10746 tcg_temp_free_i64(fp1);
b6d96bed 10747 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10748 tcg_temp_free_i64(fp2);
b6d96bed 10749 }
5a5012ec
TS
10750 break;
10751 case OPC_NMADD_S:
b8aa4598 10752 check_cop1x(ctx);
b6d96bed 10753 {
a7812ae4
PB
10754 TCGv_i32 fp0 = tcg_temp_new_i32();
10755 TCGv_i32 fp1 = tcg_temp_new_i32();
10756 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed 10757
7c979afd
LA
10758 gen_load_fpr32(ctx, fp0, fs);
10759 gen_load_fpr32(ctx, fp1, ft);
10760 gen_load_fpr32(ctx, fp2, fr);
b3d6cd44 10761 gen_helper_float_nmadd_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10762 tcg_temp_free_i32(fp0);
10763 tcg_temp_free_i32(fp1);
7c979afd 10764 gen_store_fpr32(ctx, fp2, fd);
a7812ae4 10765 tcg_temp_free_i32(fp2);
b6d96bed 10766 }
5a5012ec
TS
10767 break;
10768 case OPC_NMADD_D:
b8aa4598
TS
10769 check_cop1x(ctx);
10770 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 10771 {
a7812ae4
PB
10772 TCGv_i64 fp0 = tcg_temp_new_i64();
10773 TCGv_i64 fp1 = tcg_temp_new_i64();
10774 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10775
10776 gen_load_fpr64(ctx, fp0, fs);
10777 gen_load_fpr64(ctx, fp1, ft);
10778 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10779 gen_helper_float_nmadd_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10780 tcg_temp_free_i64(fp0);
10781 tcg_temp_free_i64(fp1);
b6d96bed 10782 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10783 tcg_temp_free_i64(fp2);
b6d96bed 10784 }
5a5012ec
TS
10785 break;
10786 case OPC_NMADD_PS:
e29c9628 10787 check_ps(ctx);
b6d96bed 10788 {
a7812ae4
PB
10789 TCGv_i64 fp0 = tcg_temp_new_i64();
10790 TCGv_i64 fp1 = tcg_temp_new_i64();
10791 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10792
10793 gen_load_fpr64(ctx, fp0, fs);
10794 gen_load_fpr64(ctx, fp1, ft);
10795 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10796 gen_helper_float_nmadd_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10797 tcg_temp_free_i64(fp0);
10798 tcg_temp_free_i64(fp1);
b6d96bed 10799 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10800 tcg_temp_free_i64(fp2);
b6d96bed 10801 }
5a5012ec
TS
10802 break;
10803 case OPC_NMSUB_S:
b8aa4598 10804 check_cop1x(ctx);
b6d96bed 10805 {
a7812ae4
PB
10806 TCGv_i32 fp0 = tcg_temp_new_i32();
10807 TCGv_i32 fp1 = tcg_temp_new_i32();
10808 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed 10809
7c979afd
LA
10810 gen_load_fpr32(ctx, fp0, fs);
10811 gen_load_fpr32(ctx, fp1, ft);
10812 gen_load_fpr32(ctx, fp2, fr);
b3d6cd44 10813 gen_helper_float_nmsub_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10814 tcg_temp_free_i32(fp0);
10815 tcg_temp_free_i32(fp1);
7c979afd 10816 gen_store_fpr32(ctx, fp2, fd);
a7812ae4 10817 tcg_temp_free_i32(fp2);
b6d96bed 10818 }
5a5012ec
TS
10819 break;
10820 case OPC_NMSUB_D:
b8aa4598
TS
10821 check_cop1x(ctx);
10822 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 10823 {
a7812ae4
PB
10824 TCGv_i64 fp0 = tcg_temp_new_i64();
10825 TCGv_i64 fp1 = tcg_temp_new_i64();
10826 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10827
10828 gen_load_fpr64(ctx, fp0, fs);
10829 gen_load_fpr64(ctx, fp1, ft);
10830 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10831 gen_helper_float_nmsub_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10832 tcg_temp_free_i64(fp0);
10833 tcg_temp_free_i64(fp1);
b6d96bed 10834 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10835 tcg_temp_free_i64(fp2);
b6d96bed 10836 }
5a5012ec
TS
10837 break;
10838 case OPC_NMSUB_PS:
e29c9628 10839 check_ps(ctx);
b6d96bed 10840 {
a7812ae4
PB
10841 TCGv_i64 fp0 = tcg_temp_new_i64();
10842 TCGv_i64 fp1 = tcg_temp_new_i64();
10843 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
10844
10845 gen_load_fpr64(ctx, fp0, fs);
10846 gen_load_fpr64(ctx, fp1, ft);
10847 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 10848 gen_helper_float_nmsub_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
10849 tcg_temp_free_i64(fp0);
10850 tcg_temp_free_i64(fp1);
b6d96bed 10851 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 10852 tcg_temp_free_i64(fp2);
b6d96bed 10853 }
5a5012ec 10854 break;
923617a3 10855 default:
9d68ac14 10856 MIPS_INVAL("flt3_arith");
9c708c7f 10857 generate_exception_end(ctx, EXCP_RI);
5a5012ec
TS
10858 return;
10859 }
7a387fff
TS
10860}
10861
b00c7218 10862static void gen_rdhwr(DisasContext *ctx, int rt, int rd, int sel)
26ebe468
NF
10863{
10864 TCGv t0;
10865
b3167288
RH
10866#if !defined(CONFIG_USER_ONLY)
10867 /* The Linux kernel will emulate rdhwr if it's not supported natively.
10868 Therefore only check the ISA in system mode. */
d75c135e 10869 check_insn(ctx, ISA_MIPS32R2);
b3167288 10870#endif
26ebe468
NF
10871 t0 = tcg_temp_new();
10872
10873 switch (rd) {
10874 case 0:
895c2d04 10875 gen_helper_rdhwr_cpunum(t0, cpu_env);
26ebe468
NF
10876 gen_store_gpr(t0, rt);
10877 break;
10878 case 1:
895c2d04 10879 gen_helper_rdhwr_synci_step(t0, cpu_env);
26ebe468
NF
10880 gen_store_gpr(t0, rt);
10881 break;
10882 case 2:
eeb3bba8 10883 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
d673a68d
JH
10884 gen_io_start();
10885 }
895c2d04 10886 gen_helper_rdhwr_cc(t0, cpu_env);
eeb3bba8 10887 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
d673a68d
JH
10888 gen_io_end();
10889 }
26ebe468 10890 gen_store_gpr(t0, rt);
d673a68d 10891 /* Break the TB to be able to take timer interrupts immediately
b28425ba 10892 after reading count. DISAS_STOP isn't sufficient, we need to ensure
d673a68d 10893 we break completely out of translated code. */
eeb3bba8
EC
10894 gen_save_pc(ctx->base.pc_next + 4);
10895 ctx->base.is_jmp = DISAS_EXIT;
26ebe468
NF
10896 break;
10897 case 3:
895c2d04 10898 gen_helper_rdhwr_ccres(t0, cpu_env);
26ebe468
NF
10899 gen_store_gpr(t0, rt);
10900 break;
b00c7218
YK
10901 case 4:
10902 check_insn(ctx, ISA_MIPS32R6);
10903 if (sel != 0) {
10904 /* Performance counter registers are not implemented other than
10905 * control register 0.
10906 */
10907 generate_exception(ctx, EXCP_RI);
10908 }
10909 gen_helper_rdhwr_performance(t0, cpu_env);
10910 gen_store_gpr(t0, rt);
10911 break;
10912 case 5:
10913 check_insn(ctx, ISA_MIPS32R6);
10914 gen_helper_rdhwr_xnp(t0, cpu_env);
10915 gen_store_gpr(t0, rt);
10916 break;
26ebe468
NF
10917 case 29:
10918#if defined(CONFIG_USER_ONLY)
d279279e
PJ
10919 tcg_gen_ld_tl(t0, cpu_env,
10920 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
26ebe468
NF
10921 gen_store_gpr(t0, rt);
10922 break;
10923#else
d279279e
PJ
10924 if ((ctx->hflags & MIPS_HFLAG_CP0) ||
10925 (ctx->hflags & MIPS_HFLAG_HWRENA_ULR)) {
10926 tcg_gen_ld_tl(t0, cpu_env,
10927 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
10928 gen_store_gpr(t0, rt);
10929 } else {
9c708c7f 10930 generate_exception_end(ctx, EXCP_RI);
d279279e
PJ
10931 }
10932 break;
26ebe468
NF
10933#endif
10934 default: /* Invalid */
10935 MIPS_INVAL("rdhwr");
9c708c7f 10936 generate_exception_end(ctx, EXCP_RI);
26ebe468
NF
10937 break;
10938 }
10939 tcg_temp_free(t0);
10940}
10941
a5f53390
LA
10942static inline void clear_branch_hflags(DisasContext *ctx)
10943{
10944 ctx->hflags &= ~MIPS_HFLAG_BMASK;
eeb3bba8 10945 if (ctx->base.is_jmp == DISAS_NEXT) {
a5f53390
LA
10946 save_cpu_state(ctx, 0);
10947 } else {
10948 /* it is not safe to save ctx->hflags as hflags may be changed
10949 in execution time by the instruction in delay / forbidden slot. */
10950 tcg_gen_andi_i32(hflags, hflags, ~MIPS_HFLAG_BMASK);
10951 }
10952}
10953
31837be3 10954static void gen_branch(DisasContext *ctx, int insn_bytes)
c9602061
NF
10955{
10956 if (ctx->hflags & MIPS_HFLAG_BMASK) {
364d4831 10957 int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
c9602061 10958 /* Branches completion */
a5f53390 10959 clear_branch_hflags(ctx);
eeb3bba8 10960 ctx->base.is_jmp = DISAS_NORETURN;
c9602061 10961 /* FIXME: Need to clear can_do_io. */
364d4831 10962 switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
339cd2a8 10963 case MIPS_HFLAG_FBNSLOT:
eeb3bba8 10964 gen_goto_tb(ctx, 0, ctx->base.pc_next + insn_bytes);
339cd2a8 10965 break;
c9602061
NF
10966 case MIPS_HFLAG_B:
10967 /* unconditional branch */
364d4831
NF
10968 if (proc_hflags & MIPS_HFLAG_BX) {
10969 tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
10970 }
c9602061
NF
10971 gen_goto_tb(ctx, 0, ctx->btarget);
10972 break;
10973 case MIPS_HFLAG_BL:
10974 /* blikely taken case */
c9602061
NF
10975 gen_goto_tb(ctx, 0, ctx->btarget);
10976 break;
10977 case MIPS_HFLAG_BC:
10978 /* Conditional branch */
c9602061 10979 {
42a268c2 10980 TCGLabel *l1 = gen_new_label();
c9602061
NF
10981
10982 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
eeb3bba8 10983 gen_goto_tb(ctx, 1, ctx->base.pc_next + insn_bytes);
c9602061
NF
10984 gen_set_label(l1);
10985 gen_goto_tb(ctx, 0, ctx->btarget);
10986 }
10987 break;
10988 case MIPS_HFLAG_BR:
10989 /* unconditional branch to register */
d75c135e 10990 if (ctx->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
364d4831
NF
10991 TCGv t0 = tcg_temp_new();
10992 TCGv_i32 t1 = tcg_temp_new_i32();
10993
10994 tcg_gen_andi_tl(t0, btarget, 0x1);
10995 tcg_gen_trunc_tl_i32(t1, t0);
10996 tcg_temp_free(t0);
10997 tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
10998 tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
10999 tcg_gen_or_i32(hflags, hflags, t1);
11000 tcg_temp_free_i32(t1);
11001
11002 tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
11003 } else {
11004 tcg_gen_mov_tl(cpu_PC, btarget);
11005 }
eeb3bba8 11006 if (ctx->base.singlestep_enabled) {
c9602061 11007 save_cpu_state(ctx, 0);
9c708c7f 11008 gen_helper_raise_exception_debug(cpu_env);
c9602061 11009 }
7f11636d 11010 tcg_gen_lookup_and_goto_ptr();
c9602061
NF
11011 break;
11012 default:
a5f53390
LA
11013 fprintf(stderr, "unknown branch 0x%x\n", proc_hflags);
11014 abort();
c9602061
NF
11015 }
11016 }
11017}
11018
6893f074
YK
11019/* Compact Branches */
11020static void gen_compute_compact_branch(DisasContext *ctx, uint32_t opc,
11021 int rs, int rt, int32_t offset)
11022{
11023 int bcond_compute = 0;
11024 TCGv t0 = tcg_temp_new();
11025 TCGv t1 = tcg_temp_new();
65935f07 11026 int m16_lowbit = (ctx->hflags & MIPS_HFLAG_M16) != 0;
6893f074
YK
11027
11028 if (ctx->hflags & MIPS_HFLAG_BMASK) {
11029#ifdef MIPS_DEBUG_DISAS
11030 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
eeb3bba8 11031 "\n", ctx->base.pc_next);
6893f074 11032#endif
9c708c7f 11033 generate_exception_end(ctx, EXCP_RI);
6893f074
YK
11034 goto out;
11035 }
11036
11037 /* Load needed operands and calculate btarget */
11038 switch (opc) {
11039 /* compact branch */
11040 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
11041 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
11042 gen_load_gpr(t0, rs);
11043 gen_load_gpr(t1, rt);
11044 bcond_compute = 1;
eeb3bba8 11045 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
6893f074
YK
11046 if (rs <= rt && rs == 0) {
11047 /* OPC_BEQZALC, OPC_BNEZALC */
eeb3bba8 11048 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
6893f074
YK
11049 }
11050 break;
11051 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
11052 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
11053 gen_load_gpr(t0, rs);
11054 gen_load_gpr(t1, rt);
11055 bcond_compute = 1;
eeb3bba8 11056 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
6893f074
YK
11057 break;
11058 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
11059 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
11060 if (rs == 0 || rs == rt) {
11061 /* OPC_BLEZALC, OPC_BGEZALC */
11062 /* OPC_BGTZALC, OPC_BLTZALC */
eeb3bba8 11063 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
6893f074
YK
11064 }
11065 gen_load_gpr(t0, rs);
11066 gen_load_gpr(t1, rt);
11067 bcond_compute = 1;
eeb3bba8 11068 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
6893f074
YK
11069 break;
11070 case OPC_BC:
11071 case OPC_BALC:
eeb3bba8 11072 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
6893f074
YK
11073 break;
11074 case OPC_BEQZC:
11075 case OPC_BNEZC:
11076 if (rs != 0) {
11077 /* OPC_BEQZC, OPC_BNEZC */
11078 gen_load_gpr(t0, rs);
11079 bcond_compute = 1;
eeb3bba8 11080 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
6893f074
YK
11081 } else {
11082 /* OPC_JIC, OPC_JIALC */
11083 TCGv tbase = tcg_temp_new();
11084 TCGv toffset = tcg_temp_new();
11085
11086 gen_load_gpr(tbase, rt);
11087 tcg_gen_movi_tl(toffset, offset);
11088 gen_op_addr_add(ctx, btarget, tbase, toffset);
11089 tcg_temp_free(tbase);
11090 tcg_temp_free(toffset);
11091 }
11092 break;
11093 default:
11094 MIPS_INVAL("Compact branch/jump");
9c708c7f 11095 generate_exception_end(ctx, EXCP_RI);
6893f074
YK
11096 goto out;
11097 }
11098
11099 if (bcond_compute == 0) {
11100 /* Uncoditional compact branch */
11101 switch (opc) {
11102 case OPC_JIALC:
eeb3bba8 11103 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
6893f074
YK
11104 /* Fallthrough */
11105 case OPC_JIC:
11106 ctx->hflags |= MIPS_HFLAG_BR;
11107 break;
11108 case OPC_BALC:
eeb3bba8 11109 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
6893f074
YK
11110 /* Fallthrough */
11111 case OPC_BC:
11112 ctx->hflags |= MIPS_HFLAG_B;
11113 break;
11114 default:
11115 MIPS_INVAL("Compact branch/jump");
9c708c7f 11116 generate_exception_end(ctx, EXCP_RI);
6893f074
YK
11117 goto out;
11118 }
11119
11120 /* Generating branch here as compact branches don't have delay slot */
11121 gen_branch(ctx, 4);
11122 } else {
11123 /* Conditional compact branch */
11124 TCGLabel *fs = gen_new_label();
11125 save_cpu_state(ctx, 0);
11126
11127 switch (opc) {
11128 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
11129 if (rs == 0 && rt != 0) {
11130 /* OPC_BLEZALC */
11131 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
11132 } else if (rs != 0 && rt != 0 && rs == rt) {
11133 /* OPC_BGEZALC */
11134 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
11135 } else {
11136 /* OPC_BGEUC */
11137 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU), t0, t1, fs);
11138 }
11139 break;
11140 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
11141 if (rs == 0 && rt != 0) {
11142 /* OPC_BGTZALC */
11143 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
11144 } else if (rs != 0 && rt != 0 && rs == rt) {
11145 /* OPC_BLTZALC */
11146 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
11147 } else {
11148 /* OPC_BLTUC */
11149 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU), t0, t1, fs);
11150 }
11151 break;
11152 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
11153 if (rs == 0 && rt != 0) {
11154 /* OPC_BLEZC */
11155 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
11156 } else if (rs != 0 && rt != 0 && rs == rt) {
11157 /* OPC_BGEZC */
11158 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
11159 } else {
11160 /* OPC_BGEC */
11161 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE), t0, t1, fs);
11162 }
11163 break;
11164 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
11165 if (rs == 0 && rt != 0) {
11166 /* OPC_BGTZC */
11167 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
11168 } else if (rs != 0 && rt != 0 && rs == rt) {
11169 /* OPC_BLTZC */
11170 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
11171 } else {
11172 /* OPC_BLTC */
11173 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT), t0, t1, fs);
11174 }
11175 break;
11176 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
11177 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
11178 if (rs >= rt) {
11179 /* OPC_BOVC, OPC_BNVC */
11180 TCGv t2 = tcg_temp_new();
11181 TCGv t3 = tcg_temp_new();
11182 TCGv t4 = tcg_temp_new();
11183 TCGv input_overflow = tcg_temp_new();
11184
11185 gen_load_gpr(t0, rs);
11186 gen_load_gpr(t1, rt);
11187 tcg_gen_ext32s_tl(t2, t0);
11188 tcg_gen_setcond_tl(TCG_COND_NE, input_overflow, t2, t0);
11189 tcg_gen_ext32s_tl(t3, t1);
11190 tcg_gen_setcond_tl(TCG_COND_NE, t4, t3, t1);
11191 tcg_gen_or_tl(input_overflow, input_overflow, t4);
11192
11193 tcg_gen_add_tl(t4, t2, t3);
11194 tcg_gen_ext32s_tl(t4, t4);
11195 tcg_gen_xor_tl(t2, t2, t3);
11196 tcg_gen_xor_tl(t3, t4, t3);
11197 tcg_gen_andc_tl(t2, t3, t2);
11198 tcg_gen_setcondi_tl(TCG_COND_LT, t4, t2, 0);
11199 tcg_gen_or_tl(t4, t4, input_overflow);
11200 if (opc == OPC_BOVC) {
11201 /* OPC_BOVC */
11202 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t4, 0, fs);
11203 } else {
11204 /* OPC_BNVC */
11205 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t4, 0, fs);
11206 }
11207 tcg_temp_free(input_overflow);
11208 tcg_temp_free(t4);
11209 tcg_temp_free(t3);
11210 tcg_temp_free(t2);
11211 } else if (rs < rt && rs == 0) {
11212 /* OPC_BEQZALC, OPC_BNEZALC */
11213 if (opc == OPC_BEQZALC) {
11214 /* OPC_BEQZALC */
11215 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t1, 0, fs);
11216 } else {
11217 /* OPC_BNEZALC */
11218 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t1, 0, fs);
11219 }
11220 } else {
11221 /* OPC_BEQC, OPC_BNEC */
11222 if (opc == OPC_BEQC) {
11223 /* OPC_BEQC */
11224 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_EQ), t0, t1, fs);
11225 } else {
11226 /* OPC_BNEC */
11227 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_NE), t0, t1, fs);
11228 }
11229 }
11230 break;
11231 case OPC_BEQZC:
11232 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t0, 0, fs);
11233 break;
11234 case OPC_BNEZC:
11235 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t0, 0, fs);
11236 break;
11237 default:
11238 MIPS_INVAL("Compact conditional branch/jump");
9c708c7f 11239 generate_exception_end(ctx, EXCP_RI);
6893f074
YK
11240 goto out;
11241 }
11242
11243 /* Generating branch here as compact branches don't have delay slot */
11244 gen_goto_tb(ctx, 1, ctx->btarget);
11245 gen_set_label(fs);
11246
11247 ctx->hflags |= MIPS_HFLAG_FBNSLOT;
6893f074
YK
11248 }
11249
11250out:
11251 tcg_temp_free(t0);
11252 tcg_temp_free(t1);
11253}
11254
7a387fff 11255/* ISA extensions (ASEs) */
6af0bf9c 11256/* MIPS16 extension to MIPS32 */
6ea219d0
NF
11257
11258/* MIPS16 major opcodes */
11259enum {
11260 M16_OPC_ADDIUSP = 0x00,
11261 M16_OPC_ADDIUPC = 0x01,
11262 M16_OPC_B = 0x02,
11263 M16_OPC_JAL = 0x03,
11264 M16_OPC_BEQZ = 0x04,
11265 M16_OPC_BNEQZ = 0x05,
11266 M16_OPC_SHIFT = 0x06,
11267 M16_OPC_LD = 0x07,
11268 M16_OPC_RRIA = 0x08,
11269 M16_OPC_ADDIU8 = 0x09,
11270 M16_OPC_SLTI = 0x0a,
11271 M16_OPC_SLTIU = 0x0b,
11272 M16_OPC_I8 = 0x0c,
11273 M16_OPC_LI = 0x0d,
11274 M16_OPC_CMPI = 0x0e,
11275 M16_OPC_SD = 0x0f,
11276 M16_OPC_LB = 0x10,
11277 M16_OPC_LH = 0x11,
11278 M16_OPC_LWSP = 0x12,
11279 M16_OPC_LW = 0x13,
11280 M16_OPC_LBU = 0x14,
11281 M16_OPC_LHU = 0x15,
11282 M16_OPC_LWPC = 0x16,
11283 M16_OPC_LWU = 0x17,
11284 M16_OPC_SB = 0x18,
11285 M16_OPC_SH = 0x19,
11286 M16_OPC_SWSP = 0x1a,
11287 M16_OPC_SW = 0x1b,
11288 M16_OPC_RRR = 0x1c,
11289 M16_OPC_RR = 0x1d,
11290 M16_OPC_EXTEND = 0x1e,
11291 M16_OPC_I64 = 0x1f
11292};
11293
11294/* I8 funct field */
11295enum {
11296 I8_BTEQZ = 0x0,
11297 I8_BTNEZ = 0x1,
11298 I8_SWRASP = 0x2,
11299 I8_ADJSP = 0x3,
11300 I8_SVRS = 0x4,
11301 I8_MOV32R = 0x5,
11302 I8_MOVR32 = 0x7
11303};
11304
11305/* RRR f field */
11306enum {
11307 RRR_DADDU = 0x0,
11308 RRR_ADDU = 0x1,
11309 RRR_DSUBU = 0x2,
11310 RRR_SUBU = 0x3
11311};
11312
11313/* RR funct field */
11314enum {
11315 RR_JR = 0x00,
11316 RR_SDBBP = 0x01,
11317 RR_SLT = 0x02,
11318 RR_SLTU = 0x03,
11319 RR_SLLV = 0x04,
11320 RR_BREAK = 0x05,
11321 RR_SRLV = 0x06,
11322 RR_SRAV = 0x07,
11323 RR_DSRL = 0x08,
11324 RR_CMP = 0x0a,
11325 RR_NEG = 0x0b,
11326 RR_AND = 0x0c,
11327 RR_OR = 0x0d,
11328 RR_XOR = 0x0e,
11329 RR_NOT = 0x0f,
11330 RR_MFHI = 0x10,
11331 RR_CNVT = 0x11,
11332 RR_MFLO = 0x12,
11333 RR_DSRA = 0x13,
11334 RR_DSLLV = 0x14,
11335 RR_DSRLV = 0x16,
11336 RR_DSRAV = 0x17,
11337 RR_MULT = 0x18,
11338 RR_MULTU = 0x19,
11339 RR_DIV = 0x1a,
11340 RR_DIVU = 0x1b,
11341 RR_DMULT = 0x1c,
11342 RR_DMULTU = 0x1d,
11343 RR_DDIV = 0x1e,
11344 RR_DDIVU = 0x1f
11345};
11346
11347/* I64 funct field */
11348enum {
11349 I64_LDSP = 0x0,
11350 I64_SDSP = 0x1,
11351 I64_SDRASP = 0x2,
11352 I64_DADJSP = 0x3,
11353 I64_LDPC = 0x4,
364d4831 11354 I64_DADDIU5 = 0x5,
6ea219d0
NF
11355 I64_DADDIUPC = 0x6,
11356 I64_DADDIUSP = 0x7
11357};
11358
11359/* RR ry field for CNVT */
11360enum {
11361 RR_RY_CNVT_ZEB = 0x0,
11362 RR_RY_CNVT_ZEH = 0x1,
11363 RR_RY_CNVT_ZEW = 0x2,
11364 RR_RY_CNVT_SEB = 0x4,
11365 RR_RY_CNVT_SEH = 0x5,
11366 RR_RY_CNVT_SEW = 0x6,
11367};
11368
364d4831
NF
11369static int xlat (int r)
11370{
11371 static int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
11372
11373 return map[r];
11374}
11375
11376static void gen_mips16_save (DisasContext *ctx,
11377 int xsregs, int aregs,
11378 int do_ra, int do_s0, int do_s1,
11379 int framesize)
11380{
11381 TCGv t0 = tcg_temp_new();
11382 TCGv t1 = tcg_temp_new();
c48245f0 11383 TCGv t2 = tcg_temp_new();
364d4831
NF
11384 int args, astatic;
11385
11386 switch (aregs) {
11387 case 0:
11388 case 1:
11389 case 2:
11390 case 3:
11391 case 11:
11392 args = 0;
11393 break;
11394 case 4:
11395 case 5:
11396 case 6:
11397 case 7:
11398 args = 1;
11399 break;
11400 case 8:
11401 case 9:
11402 case 10:
11403 args = 2;
11404 break;
11405 case 12:
11406 case 13:
11407 args = 3;
11408 break;
11409 case 14:
11410 args = 4;
11411 break;
11412 default:
9c708c7f 11413 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
11414 return;
11415 }
11416
11417 switch (args) {
11418 case 4:
11419 gen_base_offset_addr(ctx, t0, 29, 12);
11420 gen_load_gpr(t1, 7);
5f68f5ae 11421 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
364d4831
NF
11422 /* Fall through */
11423 case 3:
11424 gen_base_offset_addr(ctx, t0, 29, 8);
11425 gen_load_gpr(t1, 6);
5f68f5ae 11426 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
364d4831
NF
11427 /* Fall through */
11428 case 2:
11429 gen_base_offset_addr(ctx, t0, 29, 4);
11430 gen_load_gpr(t1, 5);
5f68f5ae 11431 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
364d4831
NF
11432 /* Fall through */
11433 case 1:
11434 gen_base_offset_addr(ctx, t0, 29, 0);
11435 gen_load_gpr(t1, 4);
5f68f5ae 11436 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
364d4831
NF
11437 }
11438
11439 gen_load_gpr(t0, 29);
11440
5f68f5ae 11441#define DECR_AND_STORE(reg) do { \
c48245f0
MR
11442 tcg_gen_movi_tl(t2, -4); \
11443 gen_op_addr_add(ctx, t0, t0, t2); \
5f68f5ae
AJ
11444 gen_load_gpr(t1, reg); \
11445 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); \
364d4831
NF
11446 } while (0)
11447
11448 if (do_ra) {
11449 DECR_AND_STORE(31);
11450 }
11451
11452 switch (xsregs) {
11453 case 7:
11454 DECR_AND_STORE(30);
11455 /* Fall through */
11456 case 6:
11457 DECR_AND_STORE(23);
11458 /* Fall through */
11459 case 5:
11460 DECR_AND_STORE(22);
11461 /* Fall through */
11462 case 4:
11463 DECR_AND_STORE(21);
11464 /* Fall through */
11465 case 3:
11466 DECR_AND_STORE(20);
11467 /* Fall through */
11468 case 2:
11469 DECR_AND_STORE(19);
11470 /* Fall through */
11471 case 1:
11472 DECR_AND_STORE(18);
11473 }
11474
11475 if (do_s1) {
11476 DECR_AND_STORE(17);
11477 }
11478 if (do_s0) {
11479 DECR_AND_STORE(16);
11480 }
11481
11482 switch (aregs) {
11483 case 0:
11484 case 4:
11485 case 8:
11486 case 12:
11487 case 14:
11488 astatic = 0;
11489 break;
11490 case 1:
11491 case 5:
11492 case 9:
11493 case 13:
11494 astatic = 1;
11495 break;
11496 case 2:
11497 case 6:
11498 case 10:
11499 astatic = 2;
11500 break;
11501 case 3:
11502 case 7:
11503 astatic = 3;
11504 break;
11505 case 11:
11506 astatic = 4;
11507 break;
11508 default:
9c708c7f 11509 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
11510 return;
11511 }
11512
11513 if (astatic > 0) {
11514 DECR_AND_STORE(7);
11515 if (astatic > 1) {
11516 DECR_AND_STORE(6);
11517 if (astatic > 2) {
11518 DECR_AND_STORE(5);
11519 if (astatic > 3) {
11520 DECR_AND_STORE(4);
11521 }
11522 }
11523 }
11524 }
11525#undef DECR_AND_STORE
11526
c48245f0
MR
11527 tcg_gen_movi_tl(t2, -framesize);
11528 gen_op_addr_add(ctx, cpu_gpr[29], cpu_gpr[29], t2);
364d4831
NF
11529 tcg_temp_free(t0);
11530 tcg_temp_free(t1);
c48245f0 11531 tcg_temp_free(t2);
364d4831
NF
11532}
11533
11534static void gen_mips16_restore (DisasContext *ctx,
11535 int xsregs, int aregs,
11536 int do_ra, int do_s0, int do_s1,
11537 int framesize)
11538{
11539 int astatic;
11540 TCGv t0 = tcg_temp_new();
11541 TCGv t1 = tcg_temp_new();
c48245f0 11542 TCGv t2 = tcg_temp_new();
364d4831 11543
c48245f0
MR
11544 tcg_gen_movi_tl(t2, framesize);
11545 gen_op_addr_add(ctx, t0, cpu_gpr[29], t2);
364d4831 11546
5f68f5ae 11547#define DECR_AND_LOAD(reg) do { \
c48245f0
MR
11548 tcg_gen_movi_tl(t2, -4); \
11549 gen_op_addr_add(ctx, t0, t0, t2); \
5f68f5ae
AJ
11550 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL); \
11551 gen_store_gpr(t1, reg); \
364d4831
NF
11552 } while (0)
11553
11554 if (do_ra) {
11555 DECR_AND_LOAD(31);
11556 }
11557
11558 switch (xsregs) {
11559 case 7:
11560 DECR_AND_LOAD(30);
11561 /* Fall through */
11562 case 6:
11563 DECR_AND_LOAD(23);
11564 /* Fall through */
11565 case 5:
11566 DECR_AND_LOAD(22);
11567 /* Fall through */
11568 case 4:
11569 DECR_AND_LOAD(21);
11570 /* Fall through */
11571 case 3:
11572 DECR_AND_LOAD(20);
11573 /* Fall through */
11574 case 2:
11575 DECR_AND_LOAD(19);
11576 /* Fall through */
11577 case 1:
11578 DECR_AND_LOAD(18);
11579 }
11580
11581 if (do_s1) {
11582 DECR_AND_LOAD(17);
11583 }
11584 if (do_s0) {
11585 DECR_AND_LOAD(16);
11586 }
11587
11588 switch (aregs) {
11589 case 0:
11590 case 4:
11591 case 8:
11592 case 12:
11593 case 14:
11594 astatic = 0;
11595 break;
11596 case 1:
11597 case 5:
11598 case 9:
11599 case 13:
11600 astatic = 1;
11601 break;
11602 case 2:
11603 case 6:
11604 case 10:
11605 astatic = 2;
11606 break;
11607 case 3:
11608 case 7:
11609 astatic = 3;
11610 break;
11611 case 11:
11612 astatic = 4;
11613 break;
11614 default:
9c708c7f 11615 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
11616 return;
11617 }
11618
11619 if (astatic > 0) {
11620 DECR_AND_LOAD(7);
11621 if (astatic > 1) {
11622 DECR_AND_LOAD(6);
11623 if (astatic > 2) {
11624 DECR_AND_LOAD(5);
11625 if (astatic > 3) {
11626 DECR_AND_LOAD(4);
11627 }
11628 }
11629 }
11630 }
11631#undef DECR_AND_LOAD
11632
c48245f0
MR
11633 tcg_gen_movi_tl(t2, framesize);
11634 gen_op_addr_add(ctx, cpu_gpr[29], cpu_gpr[29], t2);
364d4831
NF
11635 tcg_temp_free(t0);
11636 tcg_temp_free(t1);
c48245f0 11637 tcg_temp_free(t2);
364d4831
NF
11638}
11639
11640static void gen_addiupc (DisasContext *ctx, int rx, int imm,
11641 int is_64_bit, int extended)
11642{
11643 TCGv t0;
11644
11645 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9c708c7f 11646 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
11647 return;
11648 }
11649
11650 t0 = tcg_temp_new();
11651
11652 tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
11653 tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
11654 if (!is_64_bit) {
11655 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
11656 }
11657
11658 tcg_temp_free(t0);
11659}
11660
0d74a222
LA
11661static void gen_cache_operation(DisasContext *ctx, uint32_t op, int base,
11662 int16_t offset)
11663{
11664 TCGv_i32 t0 = tcg_const_i32(op);
11665 TCGv t1 = tcg_temp_new();
11666 gen_base_offset_addr(ctx, t1, base, offset);
11667 gen_helper_cache(cpu_env, t1, t0);
11668}
11669
364d4831 11670#if defined(TARGET_MIPS64)
d75c135e 11671static void decode_i64_mips16 (DisasContext *ctx,
364d4831
NF
11672 int ry, int funct, int16_t offset,
11673 int extended)
11674{
11675 switch (funct) {
11676 case I64_LDSP:
d9224450 11677 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11678 check_mips_64(ctx);
11679 offset = extended ? offset : offset << 3;
d75c135e 11680 gen_ld(ctx, OPC_LD, ry, 29, offset);
364d4831
NF
11681 break;
11682 case I64_SDSP:
d9224450 11683 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11684 check_mips_64(ctx);
11685 offset = extended ? offset : offset << 3;
5c13fdfd 11686 gen_st(ctx, OPC_SD, ry, 29, offset);
364d4831
NF
11687 break;
11688 case I64_SDRASP:
d9224450 11689 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11690 check_mips_64(ctx);
11691 offset = extended ? offset : (ctx->opcode & 0xff) << 3;
5c13fdfd 11692 gen_st(ctx, OPC_SD, 31, 29, offset);
364d4831
NF
11693 break;
11694 case I64_DADJSP:
d9224450 11695 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11696 check_mips_64(ctx);
11697 offset = extended ? offset : ((int8_t)ctx->opcode) << 3;
d75c135e 11698 gen_arith_imm(ctx, OPC_DADDIU, 29, 29, offset);
364d4831
NF
11699 break;
11700 case I64_LDPC:
d9224450
MR
11701 check_insn(ctx, ISA_MIPS3);
11702 check_mips_64(ctx);
364d4831 11703 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9c708c7f 11704 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
11705 } else {
11706 offset = extended ? offset : offset << 3;
d75c135e 11707 gen_ld(ctx, OPC_LDPC, ry, 0, offset);
364d4831
NF
11708 }
11709 break;
11710 case I64_DADDIU5:
d9224450 11711 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11712 check_mips_64(ctx);
11713 offset = extended ? offset : ((int8_t)(offset << 3)) >> 3;
d75c135e 11714 gen_arith_imm(ctx, OPC_DADDIU, ry, ry, offset);
364d4831
NF
11715 break;
11716 case I64_DADDIUPC:
d9224450 11717 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11718 check_mips_64(ctx);
11719 offset = extended ? offset : offset << 2;
11720 gen_addiupc(ctx, ry, offset, 1, extended);
11721 break;
11722 case I64_DADDIUSP:
d9224450 11723 check_insn(ctx, ISA_MIPS3);
364d4831
NF
11724 check_mips_64(ctx);
11725 offset = extended ? offset : offset << 2;
d75c135e 11726 gen_arith_imm(ctx, OPC_DADDIU, ry, 29, offset);
364d4831
NF
11727 break;
11728 }
11729}
11730#endif
11731
240ce26a 11732static int decode_extended_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
364d4831 11733{
eeb3bba8 11734 int extend = cpu_lduw_code(env, ctx->base.pc_next + 2);
364d4831
NF
11735 int op, rx, ry, funct, sa;
11736 int16_t imm, offset;
11737
11738 ctx->opcode = (ctx->opcode << 16) | extend;
11739 op = (ctx->opcode >> 11) & 0x1f;
11740 sa = (ctx->opcode >> 22) & 0x1f;
11741 funct = (ctx->opcode >> 8) & 0x7;
11742 rx = xlat((ctx->opcode >> 8) & 0x7);
11743 ry = xlat((ctx->opcode >> 5) & 0x7);
11744 offset = imm = (int16_t) (((ctx->opcode >> 16) & 0x1f) << 11
11745 | ((ctx->opcode >> 21) & 0x3f) << 5
11746 | (ctx->opcode & 0x1f));
11747
11748 /* The extended opcodes cleverly reuse the opcodes from their 16-bit
11749 counterparts. */
11750 switch (op) {
11751 case M16_OPC_ADDIUSP:
d75c135e 11752 gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
364d4831
NF
11753 break;
11754 case M16_OPC_ADDIUPC:
11755 gen_addiupc(ctx, rx, imm, 0, 1);
11756 break;
11757 case M16_OPC_B:
b231c103 11758 gen_compute_branch(ctx, OPC_BEQ, 4, 0, 0, offset << 1, 0);
364d4831
NF
11759 /* No delay slot, so just process as a normal instruction */
11760 break;
11761 case M16_OPC_BEQZ:
b231c103 11762 gen_compute_branch(ctx, OPC_BEQ, 4, rx, 0, offset << 1, 0);
364d4831
NF
11763 /* No delay slot, so just process as a normal instruction */
11764 break;
11765 case M16_OPC_BNEQZ:
b231c103 11766 gen_compute_branch(ctx, OPC_BNE, 4, rx, 0, offset << 1, 0);
364d4831
NF
11767 /* No delay slot, so just process as a normal instruction */
11768 break;
11769 case M16_OPC_SHIFT:
11770 switch (ctx->opcode & 0x3) {
11771 case 0x0:
d75c135e 11772 gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
364d4831
NF
11773 break;
11774 case 0x1:
11775#if defined(TARGET_MIPS64)
11776 check_mips_64(ctx);
d75c135e 11777 gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
364d4831 11778#else
9c708c7f 11779 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
11780#endif
11781 break;
11782 case 0x2:
d75c135e 11783 gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
364d4831
NF
11784 break;
11785 case 0x3:
d75c135e 11786 gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
364d4831
NF
11787 break;
11788 }
11789 break;
11790#if defined(TARGET_MIPS64)
11791 case M16_OPC_LD:
d9224450 11792 check_insn(ctx, ISA_MIPS3);
d75de749 11793 check_mips_64(ctx);
d75c135e 11794 gen_ld(ctx, OPC_LD, ry, rx, offset);
364d4831
NF
11795 break;
11796#endif
11797 case M16_OPC_RRIA:
11798 imm = ctx->opcode & 0xf;
11799 imm = imm | ((ctx->opcode >> 20) & 0x7f) << 4;
11800 imm = imm | ((ctx->opcode >> 16) & 0xf) << 11;
11801 imm = (int16_t) (imm << 1) >> 1;
11802 if ((ctx->opcode >> 4) & 0x1) {
11803#if defined(TARGET_MIPS64)
11804 check_mips_64(ctx);
d75c135e 11805 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
364d4831 11806#else
9c708c7f 11807 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
11808#endif
11809 } else {
d75c135e 11810 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
364d4831
NF
11811 }
11812 break;
11813 case M16_OPC_ADDIU8:
d75c135e 11814 gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
364d4831
NF
11815 break;
11816 case M16_OPC_SLTI:
d75c135e 11817 gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
364d4831
NF
11818 break;
11819 case M16_OPC_SLTIU:
d75c135e 11820 gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
364d4831
NF
11821 break;
11822 case M16_OPC_I8:
11823 switch (funct) {
11824 case I8_BTEQZ:
b231c103 11825 gen_compute_branch(ctx, OPC_BEQ, 4, 24, 0, offset << 1, 0);
364d4831
NF
11826 break;
11827 case I8_BTNEZ:
b231c103 11828 gen_compute_branch(ctx, OPC_BNE, 4, 24, 0, offset << 1, 0);
364d4831
NF
11829 break;
11830 case I8_SWRASP:
5c13fdfd 11831 gen_st(ctx, OPC_SW, 31, 29, imm);
364d4831
NF
11832 break;
11833 case I8_ADJSP:
d75c135e 11834 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm);
364d4831
NF
11835 break;
11836 case I8_SVRS:
d9224450 11837 check_insn(ctx, ISA_MIPS32);
364d4831
NF
11838 {
11839 int xsregs = (ctx->opcode >> 24) & 0x7;
11840 int aregs = (ctx->opcode >> 16) & 0xf;
11841 int do_ra = (ctx->opcode >> 6) & 0x1;
11842 int do_s0 = (ctx->opcode >> 5) & 0x1;
11843 int do_s1 = (ctx->opcode >> 4) & 0x1;
11844 int framesize = (((ctx->opcode >> 20) & 0xf) << 4
11845 | (ctx->opcode & 0xf)) << 3;
11846
11847 if (ctx->opcode & (1 << 7)) {
11848 gen_mips16_save(ctx, xsregs, aregs,
11849 do_ra, do_s0, do_s1,
11850 framesize);
11851 } else {
11852 gen_mips16_restore(ctx, xsregs, aregs,
11853 do_ra, do_s0, do_s1,
11854 framesize);
11855 }
11856 }
11857 break;
11858 default:
9c708c7f 11859 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
11860 break;
11861 }
11862 break;
11863 case M16_OPC_LI:
11864 tcg_gen_movi_tl(cpu_gpr[rx], (uint16_t) imm);
11865 break;
11866 case M16_OPC_CMPI:
11867 tcg_gen_xori_tl(cpu_gpr[24], cpu_gpr[rx], (uint16_t) imm);
11868 break;
11869#if defined(TARGET_MIPS64)
11870 case M16_OPC_SD:
d9224450
MR
11871 check_insn(ctx, ISA_MIPS3);
11872 check_mips_64(ctx);
5c13fdfd 11873 gen_st(ctx, OPC_SD, ry, rx, offset);
364d4831
NF
11874 break;
11875#endif
11876 case M16_OPC_LB:
d75c135e 11877 gen_ld(ctx, OPC_LB, ry, rx, offset);
364d4831
NF
11878 break;
11879 case M16_OPC_LH:
d75c135e 11880 gen_ld(ctx, OPC_LH, ry, rx, offset);
364d4831
NF
11881 break;
11882 case M16_OPC_LWSP:
d75c135e 11883 gen_ld(ctx, OPC_LW, rx, 29, offset);
364d4831
NF
11884 break;
11885 case M16_OPC_LW:
d75c135e 11886 gen_ld(ctx, OPC_LW, ry, rx, offset);
364d4831
NF
11887 break;
11888 case M16_OPC_LBU:
d75c135e 11889 gen_ld(ctx, OPC_LBU, ry, rx, offset);
364d4831
NF
11890 break;
11891 case M16_OPC_LHU:
d75c135e 11892 gen_ld(ctx, OPC_LHU, ry, rx, offset);
364d4831
NF
11893 break;
11894 case M16_OPC_LWPC:
d75c135e 11895 gen_ld(ctx, OPC_LWPC, rx, 0, offset);
364d4831
NF
11896 break;
11897#if defined(TARGET_MIPS64)
11898 case M16_OPC_LWU:
d9224450
MR
11899 check_insn(ctx, ISA_MIPS3);
11900 check_mips_64(ctx);
d75c135e 11901 gen_ld(ctx, OPC_LWU, ry, rx, offset);
364d4831
NF
11902 break;
11903#endif
11904 case M16_OPC_SB:
5c13fdfd 11905 gen_st(ctx, OPC_SB, ry, rx, offset);
364d4831
NF
11906 break;
11907 case M16_OPC_SH:
5c13fdfd 11908 gen_st(ctx, OPC_SH, ry, rx, offset);
364d4831
NF
11909 break;
11910 case M16_OPC_SWSP:
5c13fdfd 11911 gen_st(ctx, OPC_SW, rx, 29, offset);
364d4831
NF
11912 break;
11913 case M16_OPC_SW:
5c13fdfd 11914 gen_st(ctx, OPC_SW, ry, rx, offset);
364d4831
NF
11915 break;
11916#if defined(TARGET_MIPS64)
11917 case M16_OPC_I64:
d75c135e 11918 decode_i64_mips16(ctx, ry, funct, offset, 1);
364d4831
NF
11919 break;
11920#endif
11921 default:
9c708c7f 11922 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
11923 break;
11924 }
11925
11926 return 4;
11927}
11928
3b3c1694
LA
11929static inline bool is_uhi(int sdbbp_code)
11930{
11931#ifdef CONFIG_USER_ONLY
11932 return false;
11933#else
11934 return semihosting_enabled() && sdbbp_code == 1;
11935#endif
11936}
11937
240ce26a 11938static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
364d4831
NF
11939{
11940 int rx, ry;
11941 int sa;
11942 int op, cnvt_op, op1, offset;
11943 int funct;
11944 int n_bytes;
11945
11946 op = (ctx->opcode >> 11) & 0x1f;
11947 sa = (ctx->opcode >> 2) & 0x7;
11948 sa = sa == 0 ? 8 : sa;
11949 rx = xlat((ctx->opcode >> 8) & 0x7);
11950 cnvt_op = (ctx->opcode >> 5) & 0x7;
11951 ry = xlat((ctx->opcode >> 5) & 0x7);
11952 op1 = offset = ctx->opcode & 0x1f;
11953
11954 n_bytes = 2;
11955
11956 switch (op) {
11957 case M16_OPC_ADDIUSP:
11958 {
11959 int16_t imm = ((uint8_t) ctx->opcode) << 2;
11960
d75c135e 11961 gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
364d4831
NF
11962 }
11963 break;
11964 case M16_OPC_ADDIUPC:
11965 gen_addiupc(ctx, rx, ((uint8_t) ctx->opcode) << 2, 0, 0);
11966 break;
11967 case M16_OPC_B:
11968 offset = (ctx->opcode & 0x7ff) << 1;
11969 offset = (int16_t)(offset << 4) >> 4;
b231c103 11970 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, offset, 0);
364d4831
NF
11971 /* No delay slot, so just process as a normal instruction */
11972 break;
11973 case M16_OPC_JAL:
eeb3bba8 11974 offset = cpu_lduw_code(env, ctx->base.pc_next + 2);
364d4831
NF
11975 offset = (((ctx->opcode & 0x1f) << 21)
11976 | ((ctx->opcode >> 5) & 0x1f) << 16
11977 | offset) << 2;
b231c103
YK
11978 op = ((ctx->opcode >> 10) & 0x1) ? OPC_JALX : OPC_JAL;
11979 gen_compute_branch(ctx, op, 4, rx, ry, offset, 2);
364d4831 11980 n_bytes = 4;
364d4831
NF
11981 break;
11982 case M16_OPC_BEQZ:
b231c103
YK
11983 gen_compute_branch(ctx, OPC_BEQ, 2, rx, 0,
11984 ((int8_t)ctx->opcode) << 1, 0);
364d4831
NF
11985 /* No delay slot, so just process as a normal instruction */
11986 break;
11987 case M16_OPC_BNEQZ:
b231c103
YK
11988 gen_compute_branch(ctx, OPC_BNE, 2, rx, 0,
11989 ((int8_t)ctx->opcode) << 1, 0);
364d4831
NF
11990 /* No delay slot, so just process as a normal instruction */
11991 break;
11992 case M16_OPC_SHIFT:
11993 switch (ctx->opcode & 0x3) {
11994 case 0x0:
d75c135e 11995 gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
364d4831
NF
11996 break;
11997 case 0x1:
11998#if defined(TARGET_MIPS64)
d9224450 11999 check_insn(ctx, ISA_MIPS3);
364d4831 12000 check_mips_64(ctx);
d75c135e 12001 gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
364d4831 12002#else
9c708c7f 12003 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
12004#endif
12005 break;
12006 case 0x2:
d75c135e 12007 gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
364d4831
NF
12008 break;
12009 case 0x3:
d75c135e 12010 gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
364d4831
NF
12011 break;
12012 }
12013 break;
12014#if defined(TARGET_MIPS64)
12015 case M16_OPC_LD:
d9224450 12016 check_insn(ctx, ISA_MIPS3);
364d4831 12017 check_mips_64(ctx);
d75c135e 12018 gen_ld(ctx, OPC_LD, ry, rx, offset << 3);
364d4831
NF
12019 break;
12020#endif
12021 case M16_OPC_RRIA:
12022 {
12023 int16_t imm = (int8_t)((ctx->opcode & 0xf) << 4) >> 4;
12024
12025 if ((ctx->opcode >> 4) & 1) {
12026#if defined(TARGET_MIPS64)
d9224450 12027 check_insn(ctx, ISA_MIPS3);
364d4831 12028 check_mips_64(ctx);
d75c135e 12029 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
364d4831 12030#else
9c708c7f 12031 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
12032#endif
12033 } else {
d75c135e 12034 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
364d4831
NF
12035 }
12036 }
12037 break;
12038 case M16_OPC_ADDIU8:
12039 {
12040 int16_t imm = (int8_t) ctx->opcode;
12041
d75c135e 12042 gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
364d4831
NF
12043 }
12044 break;
12045 case M16_OPC_SLTI:
12046 {
12047 int16_t imm = (uint8_t) ctx->opcode;
d75c135e 12048 gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
364d4831
NF
12049 }
12050 break;
12051 case M16_OPC_SLTIU:
12052 {
12053 int16_t imm = (uint8_t) ctx->opcode;
d75c135e 12054 gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
364d4831
NF
12055 }
12056 break;
12057 case M16_OPC_I8:
12058 {
12059 int reg32;
12060
12061 funct = (ctx->opcode >> 8) & 0x7;
12062 switch (funct) {
12063 case I8_BTEQZ:
12064 gen_compute_branch(ctx, OPC_BEQ, 2, 24, 0,
b231c103 12065 ((int8_t)ctx->opcode) << 1, 0);
364d4831
NF
12066 break;
12067 case I8_BTNEZ:
12068 gen_compute_branch(ctx, OPC_BNE, 2, 24, 0,
b231c103 12069 ((int8_t)ctx->opcode) << 1, 0);
364d4831
NF
12070 break;
12071 case I8_SWRASP:
5c13fdfd 12072 gen_st(ctx, OPC_SW, 31, 29, (ctx->opcode & 0xff) << 2);
364d4831
NF
12073 break;
12074 case I8_ADJSP:
d75c135e 12075 gen_arith_imm(ctx, OPC_ADDIU, 29, 29,
364d4831
NF
12076 ((int8_t)ctx->opcode) << 3);
12077 break;
12078 case I8_SVRS:
d9224450 12079 check_insn(ctx, ISA_MIPS32);
364d4831
NF
12080 {
12081 int do_ra = ctx->opcode & (1 << 6);
12082 int do_s0 = ctx->opcode & (1 << 5);
12083 int do_s1 = ctx->opcode & (1 << 4);
12084 int framesize = ctx->opcode & 0xf;
12085
12086 if (framesize == 0) {
12087 framesize = 128;
12088 } else {
12089 framesize = framesize << 3;
12090 }
12091
12092 if (ctx->opcode & (1 << 7)) {
12093 gen_mips16_save(ctx, 0, 0,
12094 do_ra, do_s0, do_s1, framesize);
12095 } else {
12096 gen_mips16_restore(ctx, 0, 0,
12097 do_ra, do_s0, do_s1, framesize);
12098 }
12099 }
12100 break;
12101 case I8_MOV32R:
12102 {
12103 int rz = xlat(ctx->opcode & 0x7);
12104
12105 reg32 = (((ctx->opcode >> 3) & 0x3) << 3) |
12106 ((ctx->opcode >> 5) & 0x7);
d75c135e 12107 gen_arith(ctx, OPC_ADDU, reg32, rz, 0);
364d4831
NF
12108 }
12109 break;
12110 case I8_MOVR32:
12111 reg32 = ctx->opcode & 0x1f;
d75c135e 12112 gen_arith(ctx, OPC_ADDU, ry, reg32, 0);
364d4831
NF
12113 break;
12114 default:
9c708c7f 12115 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
12116 break;
12117 }
12118 }
12119 break;
12120 case M16_OPC_LI:
12121 {
12122 int16_t imm = (uint8_t) ctx->opcode;
12123
d75c135e 12124 gen_arith_imm(ctx, OPC_ADDIU, rx, 0, imm);
364d4831
NF
12125 }
12126 break;
12127 case M16_OPC_CMPI:
12128 {
12129 int16_t imm = (uint8_t) ctx->opcode;
d75c135e 12130 gen_logic_imm(ctx, OPC_XORI, 24, rx, imm);
364d4831
NF
12131 }
12132 break;
12133#if defined(TARGET_MIPS64)
12134 case M16_OPC_SD:
d9224450 12135 check_insn(ctx, ISA_MIPS3);
364d4831 12136 check_mips_64(ctx);
5c13fdfd 12137 gen_st(ctx, OPC_SD, ry, rx, offset << 3);
364d4831
NF
12138 break;
12139#endif
12140 case M16_OPC_LB:
d75c135e 12141 gen_ld(ctx, OPC_LB, ry, rx, offset);
364d4831
NF
12142 break;
12143 case M16_OPC_LH:
d75c135e 12144 gen_ld(ctx, OPC_LH, ry, rx, offset << 1);
364d4831
NF
12145 break;
12146 case M16_OPC_LWSP:
d75c135e 12147 gen_ld(ctx, OPC_LW, rx, 29, ((uint8_t)ctx->opcode) << 2);
364d4831
NF
12148 break;
12149 case M16_OPC_LW:
d75c135e 12150 gen_ld(ctx, OPC_LW, ry, rx, offset << 2);
364d4831
NF
12151 break;
12152 case M16_OPC_LBU:
d75c135e 12153 gen_ld(ctx, OPC_LBU, ry, rx, offset);
364d4831
NF
12154 break;
12155 case M16_OPC_LHU:
d75c135e 12156 gen_ld(ctx, OPC_LHU, ry, rx, offset << 1);
364d4831
NF
12157 break;
12158 case M16_OPC_LWPC:
d75c135e 12159 gen_ld(ctx, OPC_LWPC, rx, 0, ((uint8_t)ctx->opcode) << 2);
364d4831
NF
12160 break;
12161#if defined (TARGET_MIPS64)
12162 case M16_OPC_LWU:
d9224450 12163 check_insn(ctx, ISA_MIPS3);
364d4831 12164 check_mips_64(ctx);
d75c135e 12165 gen_ld(ctx, OPC_LWU, ry, rx, offset << 2);
364d4831
NF
12166 break;
12167#endif
12168 case M16_OPC_SB:
5c13fdfd 12169 gen_st(ctx, OPC_SB, ry, rx, offset);
364d4831
NF
12170 break;
12171 case M16_OPC_SH:
5c13fdfd 12172 gen_st(ctx, OPC_SH, ry, rx, offset << 1);
364d4831
NF
12173 break;
12174 case M16_OPC_SWSP:
5c13fdfd 12175 gen_st(ctx, OPC_SW, rx, 29, ((uint8_t)ctx->opcode) << 2);
364d4831
NF
12176 break;
12177 case M16_OPC_SW:
5c13fdfd 12178 gen_st(ctx, OPC_SW, ry, rx, offset << 2);
364d4831
NF
12179 break;
12180 case M16_OPC_RRR:
12181 {
12182 int rz = xlat((ctx->opcode >> 2) & 0x7);
12183 int mips32_op;
12184
12185 switch (ctx->opcode & 0x3) {
12186 case RRR_ADDU:
12187 mips32_op = OPC_ADDU;
12188 break;
12189 case RRR_SUBU:
12190 mips32_op = OPC_SUBU;
12191 break;
12192#if defined(TARGET_MIPS64)
12193 case RRR_DADDU:
12194 mips32_op = OPC_DADDU;
d9224450 12195 check_insn(ctx, ISA_MIPS3);
364d4831
NF
12196 check_mips_64(ctx);
12197 break;
12198 case RRR_DSUBU:
12199 mips32_op = OPC_DSUBU;
d9224450 12200 check_insn(ctx, ISA_MIPS3);
364d4831
NF
12201 check_mips_64(ctx);
12202 break;
12203#endif
12204 default:
9c708c7f 12205 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
12206 goto done;
12207 }
12208
d75c135e 12209 gen_arith(ctx, mips32_op, rz, rx, ry);
364d4831
NF
12210 done:
12211 ;
12212 }
12213 break;
12214 case M16_OPC_RR:
12215 switch (op1) {
12216 case RR_JR:
12217 {
12218 int nd = (ctx->opcode >> 7) & 0x1;
12219 int link = (ctx->opcode >> 6) & 0x1;
12220 int ra = (ctx->opcode >> 5) & 0x1;
12221
d9224450
MR
12222 if (nd) {
12223 check_insn(ctx, ISA_MIPS32);
12224 }
12225
364d4831 12226 if (link) {
b231c103 12227 op = OPC_JALR;
364d4831
NF
12228 } else {
12229 op = OPC_JR;
12230 }
12231
b231c103
YK
12232 gen_compute_branch(ctx, op, 2, ra ? 31 : rx, 31, 0,
12233 (nd ? 0 : 2));
364d4831
NF
12234 }
12235 break;
12236 case RR_SDBBP:
3b3c1694
LA
12237 if (is_uhi(extract32(ctx->opcode, 5, 6))) {
12238 gen_helper_do_semihosting(cpu_env);
12239 } else {
12240 /* XXX: not clear which exception should be raised
12241 * when in debug mode...
12242 */
12243 check_insn(ctx, ISA_MIPS32);
9c708c7f 12244 generate_exception_end(ctx, EXCP_DBp);
3b3c1694 12245 }
364d4831
NF
12246 break;
12247 case RR_SLT:
d75c135e 12248 gen_slt(ctx, OPC_SLT, 24, rx, ry);
364d4831
NF
12249 break;
12250 case RR_SLTU:
d75c135e 12251 gen_slt(ctx, OPC_SLTU, 24, rx, ry);
364d4831
NF
12252 break;
12253 case RR_BREAK:
9c708c7f 12254 generate_exception_end(ctx, EXCP_BREAK);
364d4831
NF
12255 break;
12256 case RR_SLLV:
d75c135e 12257 gen_shift(ctx, OPC_SLLV, ry, rx, ry);
364d4831
NF
12258 break;
12259 case RR_SRLV:
d75c135e 12260 gen_shift(ctx, OPC_SRLV, ry, rx, ry);
364d4831
NF
12261 break;
12262 case RR_SRAV:
d75c135e 12263 gen_shift(ctx, OPC_SRAV, ry, rx, ry);
364d4831
NF
12264 break;
12265#if defined (TARGET_MIPS64)
12266 case RR_DSRL:
d9224450 12267 check_insn(ctx, ISA_MIPS3);
364d4831 12268 check_mips_64(ctx);
d75c135e 12269 gen_shift_imm(ctx, OPC_DSRL, ry, ry, sa);
364d4831
NF
12270 break;
12271#endif
12272 case RR_CMP:
d75c135e 12273 gen_logic(ctx, OPC_XOR, 24, rx, ry);
364d4831
NF
12274 break;
12275 case RR_NEG:
d75c135e 12276 gen_arith(ctx, OPC_SUBU, rx, 0, ry);
364d4831
NF
12277 break;
12278 case RR_AND:
d75c135e 12279 gen_logic(ctx, OPC_AND, rx, rx, ry);
364d4831
NF
12280 break;
12281 case RR_OR:
d75c135e 12282 gen_logic(ctx, OPC_OR, rx, rx, ry);
364d4831
NF
12283 break;
12284 case RR_XOR:
d75c135e 12285 gen_logic(ctx, OPC_XOR, rx, rx, ry);
364d4831
NF
12286 break;
12287 case RR_NOT:
d75c135e 12288 gen_logic(ctx, OPC_NOR, rx, ry, 0);
364d4831
NF
12289 break;
12290 case RR_MFHI:
26135ead 12291 gen_HILO(ctx, OPC_MFHI, 0, rx);
364d4831
NF
12292 break;
12293 case RR_CNVT:
d9224450 12294 check_insn(ctx, ISA_MIPS32);
364d4831
NF
12295 switch (cnvt_op) {
12296 case RR_RY_CNVT_ZEB:
12297 tcg_gen_ext8u_tl(cpu_gpr[rx], cpu_gpr[rx]);
12298 break;
12299 case RR_RY_CNVT_ZEH:
12300 tcg_gen_ext16u_tl(cpu_gpr[rx], cpu_gpr[rx]);
12301 break;
12302 case RR_RY_CNVT_SEB:
12303 tcg_gen_ext8s_tl(cpu_gpr[rx], cpu_gpr[rx]);
12304 break;
12305 case RR_RY_CNVT_SEH:
12306 tcg_gen_ext16s_tl(cpu_gpr[rx], cpu_gpr[rx]);
12307 break;
12308#if defined (TARGET_MIPS64)
12309 case RR_RY_CNVT_ZEW:
d9224450 12310 check_insn(ctx, ISA_MIPS64);
364d4831
NF
12311 check_mips_64(ctx);
12312 tcg_gen_ext32u_tl(cpu_gpr[rx], cpu_gpr[rx]);
12313 break;
12314 case RR_RY_CNVT_SEW:
d9224450 12315 check_insn(ctx, ISA_MIPS64);
364d4831
NF
12316 check_mips_64(ctx);
12317 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
12318 break;
12319#endif
12320 default:
9c708c7f 12321 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
12322 break;
12323 }
12324 break;
12325 case RR_MFLO:
26135ead 12326 gen_HILO(ctx, OPC_MFLO, 0, rx);
364d4831
NF
12327 break;
12328#if defined (TARGET_MIPS64)
12329 case RR_DSRA:
d9224450 12330 check_insn(ctx, ISA_MIPS3);
364d4831 12331 check_mips_64(ctx);
d75c135e 12332 gen_shift_imm(ctx, OPC_DSRA, ry, ry, sa);
364d4831
NF
12333 break;
12334 case RR_DSLLV:
d9224450 12335 check_insn(ctx, ISA_MIPS3);
364d4831 12336 check_mips_64(ctx);
d75c135e 12337 gen_shift(ctx, OPC_DSLLV, ry, rx, ry);
364d4831
NF
12338 break;
12339 case RR_DSRLV:
d9224450 12340 check_insn(ctx, ISA_MIPS3);
364d4831 12341 check_mips_64(ctx);
d75c135e 12342 gen_shift(ctx, OPC_DSRLV, ry, rx, ry);
364d4831
NF
12343 break;
12344 case RR_DSRAV:
d9224450 12345 check_insn(ctx, ISA_MIPS3);
364d4831 12346 check_mips_64(ctx);
d75c135e 12347 gen_shift(ctx, OPC_DSRAV, ry, rx, ry);
364d4831
NF
12348 break;
12349#endif
12350 case RR_MULT:
26135ead 12351 gen_muldiv(ctx, OPC_MULT, 0, rx, ry);
364d4831
NF
12352 break;
12353 case RR_MULTU:
26135ead 12354 gen_muldiv(ctx, OPC_MULTU, 0, rx, ry);
364d4831
NF
12355 break;
12356 case RR_DIV:
26135ead 12357 gen_muldiv(ctx, OPC_DIV, 0, rx, ry);
364d4831
NF
12358 break;
12359 case RR_DIVU:
26135ead 12360 gen_muldiv(ctx, OPC_DIVU, 0, rx, ry);
364d4831
NF
12361 break;
12362#if defined (TARGET_MIPS64)
12363 case RR_DMULT:
d9224450 12364 check_insn(ctx, ISA_MIPS3);
364d4831 12365 check_mips_64(ctx);
26135ead 12366 gen_muldiv(ctx, OPC_DMULT, 0, rx, ry);
364d4831
NF
12367 break;
12368 case RR_DMULTU:
d9224450 12369 check_insn(ctx, ISA_MIPS3);
364d4831 12370 check_mips_64(ctx);
26135ead 12371 gen_muldiv(ctx, OPC_DMULTU, 0, rx, ry);
364d4831
NF
12372 break;
12373 case RR_DDIV:
d9224450 12374 check_insn(ctx, ISA_MIPS3);
364d4831 12375 check_mips_64(ctx);
26135ead 12376 gen_muldiv(ctx, OPC_DDIV, 0, rx, ry);
364d4831
NF
12377 break;
12378 case RR_DDIVU:
d9224450 12379 check_insn(ctx, ISA_MIPS3);
364d4831 12380 check_mips_64(ctx);
26135ead 12381 gen_muldiv(ctx, OPC_DDIVU, 0, rx, ry);
364d4831
NF
12382 break;
12383#endif
12384 default:
9c708c7f 12385 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
12386 break;
12387 }
12388 break;
12389 case M16_OPC_EXTEND:
240ce26a 12390 decode_extended_mips16_opc(env, ctx);
364d4831
NF
12391 n_bytes = 4;
12392 break;
12393#if defined(TARGET_MIPS64)
12394 case M16_OPC_I64:
12395 funct = (ctx->opcode >> 8) & 0x7;
d75c135e 12396 decode_i64_mips16(ctx, ry, funct, offset, 0);
364d4831
NF
12397 break;
12398#endif
12399 default:
9c708c7f 12400 generate_exception_end(ctx, EXCP_RI);
364d4831
NF
12401 break;
12402 }
12403
12404 return n_bytes;
12405}
12406
211da992 12407/* microMIPS extension to MIPS32/MIPS64 */
6af0bf9c 12408
211da992
CWR
12409/*
12410 * microMIPS32/microMIPS64 major opcodes
12411 *
12412 * 1. MIPS Architecture for Programmers Volume II-B:
12413 * The microMIPS32 Instruction Set (Revision 3.05)
12414 *
12415 * Table 6.2 microMIPS32 Encoding of Major Opcode Field
12416 *
12417 * 2. MIPS Architecture For Programmers Volume II-A:
12418 * The MIPS64 Instruction Set (Revision 3.51)
12419 */
6af0bf9c 12420
3c824109
NF
12421enum {
12422 POOL32A = 0x00,
12423 POOL16A = 0x01,
12424 LBU16 = 0x02,
12425 MOVE16 = 0x03,
12426 ADDI32 = 0x04,
3a1f4268
YK
12427 R6_LUI = 0x04,
12428 AUI = 0x04,
3c824109
NF
12429 LBU32 = 0x05,
12430 SB32 = 0x06,
12431 LB32 = 0x07,
12432
12433 POOL32B = 0x08,
12434 POOL16B = 0x09,
12435 LHU16 = 0x0a,
12436 ANDI16 = 0x0b,
12437 ADDIU32 = 0x0c,
12438 LHU32 = 0x0d,
12439 SH32 = 0x0e,
12440 LH32 = 0x0f,
12441
12442 POOL32I = 0x10,
12443 POOL16C = 0x11,
12444 LWSP16 = 0x12,
12445 POOL16D = 0x13,
12446 ORI32 = 0x14,
12447 POOL32F = 0x15,
211da992
CWR
12448 POOL32S = 0x16, /* MIPS64 */
12449 DADDIU32 = 0x17, /* MIPS64 */
3c824109
NF
12450
12451 POOL32C = 0x18,
12452 LWGP16 = 0x19,
12453 LW16 = 0x1a,
12454 POOL16E = 0x1b,
12455 XORI32 = 0x1c,
12456 JALS32 = 0x1d,
3a1f4268
YK
12457 BOVC = 0x1d,
12458 BEQC = 0x1d,
12459 BEQZALC = 0x1d,
3c824109 12460 ADDIUPC = 0x1e,
3a1f4268
YK
12461 PCREL = 0x1e,
12462 BNVC = 0x1f,
12463 BNEC = 0x1f,
12464 BNEZALC = 0x1f,
3c824109 12465
3a1f4268
YK
12466 R6_BEQZC = 0x20,
12467 JIC = 0x20,
3c824109
NF
12468 POOL16F = 0x21,
12469 SB16 = 0x22,
12470 BEQZ16 = 0x23,
3a1f4268 12471 BEQZC16 = 0x23,
3c824109
NF
12472 SLTI32 = 0x24,
12473 BEQ32 = 0x25,
3a1f4268 12474 BC = 0x25,
3c824109
NF
12475 SWC132 = 0x26,
12476 LWC132 = 0x27,
12477
3a1f4268 12478 /* 0x29 is reserved */
3c824109 12479 RES_29 = 0x29,
3a1f4268
YK
12480 R6_BNEZC = 0x28,
12481 JIALC = 0x28,
3c824109
NF
12482 SH16 = 0x2a,
12483 BNEZ16 = 0x2b,
3a1f4268 12484 BNEZC16 = 0x2b,
3c824109
NF
12485 SLTIU32 = 0x2c,
12486 BNE32 = 0x2d,
3a1f4268 12487 BALC = 0x2d,
3c824109
NF
12488 SDC132 = 0x2e,
12489 LDC132 = 0x2f,
12490
3a1f4268 12491 /* 0x31 is reserved */
3c824109 12492 RES_31 = 0x31,
3a1f4268
YK
12493 BLEZALC = 0x30,
12494 BGEZALC = 0x30,
12495 BGEUC = 0x30,
3c824109
NF
12496 SWSP16 = 0x32,
12497 B16 = 0x33,
3a1f4268 12498 BC16 = 0x33,
3c824109
NF
12499 ANDI32 = 0x34,
12500 J32 = 0x35,
3a1f4268
YK
12501 BGTZC = 0x35,
12502 BLTZC = 0x35,
12503 BLTC = 0x35,
211da992
CWR
12504 SD32 = 0x36, /* MIPS64 */
12505 LD32 = 0x37, /* MIPS64 */
3c824109 12506
3a1f4268 12507 /* 0x39 is reserved */
3c824109 12508 RES_39 = 0x39,
3a1f4268
YK
12509 BGTZALC = 0x38,
12510 BLTZALC = 0x38,
12511 BLTUC = 0x38,
3c824109
NF
12512 SW16 = 0x3a,
12513 LI16 = 0x3b,
12514 JALX32 = 0x3c,
12515 JAL32 = 0x3d,
3a1f4268
YK
12516 BLEZC = 0x3d,
12517 BGEZC = 0x3d,
12518 BGEC = 0x3d,
3c824109
NF
12519 SW32 = 0x3e,
12520 LW32 = 0x3f
12521};
12522
3a1f4268
YK
12523/* PCREL Instructions perform PC-Relative address calculation. bits 20..16 */
12524enum {
12525 ADDIUPC_00 = 0x00,
c38a1d52
AR
12526 ADDIUPC_01 = 0x01,
12527 ADDIUPC_02 = 0x02,
12528 ADDIUPC_03 = 0x03,
12529 ADDIUPC_04 = 0x04,
12530 ADDIUPC_05 = 0x05,
12531 ADDIUPC_06 = 0x06,
3a1f4268
YK
12532 ADDIUPC_07 = 0x07,
12533 AUIPC = 0x1e,
12534 ALUIPC = 0x1f,
12535 LWPC_08 = 0x08,
c38a1d52
AR
12536 LWPC_09 = 0x09,
12537 LWPC_0A = 0x0A,
12538 LWPC_0B = 0x0B,
12539 LWPC_0C = 0x0C,
12540 LWPC_0D = 0x0D,
12541 LWPC_0E = 0x0E,
3a1f4268
YK
12542 LWPC_0F = 0x0F,
12543};
12544
3c824109
NF
12545/* POOL32A encoding of minor opcode field */
12546
12547enum {
12548 /* These opcodes are distinguished only by bits 9..6; those bits are
12549 * what are recorded below. */
12550 SLL32 = 0x0,
12551 SRL32 = 0x1,
12552 SRA = 0x2,
12553 ROTR = 0x3,
3a1f4268
YK
12554 SELEQZ = 0x5,
12555 SELNEZ = 0x6,
b00c7218 12556 R6_RDHWR = 0x7,
3c824109
NF
12557
12558 SLLV = 0x0,
12559 SRLV = 0x1,
12560 SRAV = 0x2,
12561 ROTRV = 0x3,
12562 ADD = 0x4,
12563 ADDU32 = 0x5,
12564 SUB = 0x6,
12565 SUBU32 = 0x7,
12566 MUL = 0x8,
12567 AND = 0x9,
12568 OR32 = 0xa,
12569 NOR = 0xb,
12570 XOR32 = 0xc,
12571 SLT = 0xd,
12572 SLTU = 0xe,
12573
12574 MOVN = 0x0,
3a1f4268 12575 R6_MUL = 0x0,
3c824109 12576 MOVZ = 0x1,
3a1f4268
YK
12577 MUH = 0x1,
12578 MULU = 0x2,
12579 MUHU = 0x3,
3c824109 12580 LWXS = 0x4,
3a1f4268
YK
12581 R6_DIV = 0x4,
12582 MOD = 0x5,
12583 R6_DIVU = 0x6,
12584 MODU = 0x7,
3c824109
NF
12585
12586 /* The following can be distinguished by their lower 6 bits. */
dbd8af98 12587 BREAK32 = 0x07,
3c824109 12588 INS = 0x0c,
3a1f4268
YK
12589 LSA = 0x0f,
12590 ALIGN = 0x1f,
3c824109 12591 EXT = 0x2c,
bb238210
YK
12592 POOL32AXF = 0x3c,
12593 SIGRIE = 0x3f
3c824109
NF
12594};
12595
12596/* POOL32AXF encoding of minor opcode field extension */
12597
d132c79f
CWR
12598/*
12599 * 1. MIPS Architecture for Programmers Volume II-B:
12600 * The microMIPS32 Instruction Set (Revision 3.05)
12601 *
12602 * Table 6.5 POOL32Axf Encoding of Minor Opcode Extension Field
12603 *
12604 * 2. MIPS Architecture for Programmers VolumeIV-e:
12605 * The MIPS DSP Application-Specific Extension
12606 * to the microMIPS32 Architecture (Revision 2.34)
12607 *
12608 * Table 5.5 POOL32Axf Encoding of Minor Opcode Extension Field
12609 */
12610
3c824109
NF
12611enum {
12612 /* bits 11..6 */
12613 TEQ = 0x00,
12614 TGE = 0x08,
12615 TGEU = 0x10,
12616 TLT = 0x20,
12617 TLTU = 0x28,
12618 TNE = 0x30,
12619
12620 MFC0 = 0x03,
12621 MTC0 = 0x0b,
12622
d132c79f
CWR
12623 /* begin of microMIPS32 DSP */
12624
3c824109
NF
12625 /* bits 13..12 for 0x01 */
12626 MFHI_ACC = 0x0,
12627 MFLO_ACC = 0x1,
12628 MTHI_ACC = 0x2,
12629 MTLO_ACC = 0x3,
12630
12631 /* bits 13..12 for 0x2a */
12632 MADD_ACC = 0x0,
12633 MADDU_ACC = 0x1,
12634 MSUB_ACC = 0x2,
12635 MSUBU_ACC = 0x3,
12636
12637 /* bits 13..12 for 0x32 */
12638 MULT_ACC = 0x0,
6801038b 12639 MULTU_ACC = 0x1,
3c824109 12640
d132c79f
CWR
12641 /* end of microMIPS32 DSP */
12642
3c824109 12643 /* bits 15..12 for 0x2c */
3a1f4268 12644 BITSWAP = 0x0,
3c824109
NF
12645 SEB = 0x2,
12646 SEH = 0x3,
12647 CLO = 0x4,
12648 CLZ = 0x5,
12649 RDHWR = 0x6,
12650 WSBH = 0x7,
12651 MULT = 0x8,
12652 MULTU = 0x9,
12653 DIV = 0xa,
12654 DIVU = 0xb,
12655 MADD = 0xc,
12656 MADDU = 0xd,
12657 MSUB = 0xe,
12658 MSUBU = 0xf,
12659
12660 /* bits 15..12 for 0x34 */
12661 MFC2 = 0x4,
12662 MTC2 = 0x5,
12663 MFHC2 = 0x8,
12664 MTHC2 = 0x9,
12665 CFC2 = 0xc,
12666 CTC2 = 0xd,
12667
12668 /* bits 15..12 for 0x3c */
12669 JALR = 0x0,
12670 JR = 0x0, /* alias */
3a1f4268
YK
12671 JALRC = 0x0,
12672 JRC = 0x0,
3c824109 12673 JALR_HB = 0x1,
3a1f4268 12674 JALRC_HB = 0x1,
3c824109
NF
12675 JALRS = 0x4,
12676 JALRS_HB = 0x5,
12677
12678 /* bits 15..12 for 0x05 */
12679 RDPGPR = 0xe,
12680 WRPGPR = 0xf,
12681
12682 /* bits 15..12 for 0x0d */
12683 TLBP = 0x0,
12684 TLBR = 0x1,
12685 TLBWI = 0x2,
12686 TLBWR = 0x3,
e60ec063
YK
12687 TLBINV = 0x4,
12688 TLBINVF = 0x5,
3c824109
NF
12689 WAIT = 0x9,
12690 IRET = 0xd,
12691 DERET = 0xe,
12692 ERET = 0xf,
12693
12694 /* bits 15..12 for 0x15 */
12695 DMT = 0x0,
12696 DVPE = 0x1,
12697 EMT = 0x2,
12698 EVPE = 0x3,
12699
12700 /* bits 15..12 for 0x1d */
12701 DI = 0x4,
12702 EI = 0x5,
12703
12704 /* bits 15..12 for 0x2d */
12705 SYNC = 0x6,
12706 SYSCALL = 0x8,
12707 SDBBP = 0xd,
12708
12709 /* bits 15..12 for 0x35 */
12710 MFHI32 = 0x0,
12711 MFLO32 = 0x1,
12712 MTHI32 = 0x2,
12713 MTLO32 = 0x3,
12714};
12715
12716/* POOL32B encoding of minor opcode field (bits 15..12) */
12717
12718enum {
12719 LWC2 = 0x0,
12720 LWP = 0x1,
12721 LDP = 0x4,
12722 LWM32 = 0x5,
12723 CACHE = 0x6,
12724 LDM = 0x7,
12725 SWC2 = 0x8,
12726 SWP = 0x9,
12727 SDP = 0xc,
12728 SWM32 = 0xd,
12729 SDM = 0xf
12730};
12731
12732/* POOL32C encoding of minor opcode field (bits 15..12) */
12733
12734enum {
12735 LWL = 0x0,
12736 SWL = 0x8,
12737 LWR = 0x1,
12738 SWR = 0x9,
12739 PREF = 0x2,
8fffc646 12740 ST_EVA = 0xa,
3c824109
NF
12741 LL = 0x3,
12742 SC = 0xb,
12743 LDL = 0x4,
12744 SDL = 0xc,
12745 LDR = 0x5,
12746 SDR = 0xd,
8fffc646 12747 LD_EVA = 0x6,
3c824109
NF
12748 LWU = 0xe,
12749 LLD = 0x7,
12750 SCD = 0xf
12751};
12752
8fffc646
JH
12753/* POOL32C LD-EVA encoding of minor opcode field (bits 11..9) */
12754
12755enum {
12756 LBUE = 0x0,
12757 LHUE = 0x1,
12758 LWLE = 0x2,
12759 LWRE = 0x3,
12760 LBE = 0x4,
12761 LHE = 0x5,
12762 LLE = 0x6,
12763 LWE = 0x7,
12764};
12765
12766/* POOL32C ST-EVA encoding of minor opcode field (bits 11..9) */
12767
12768enum {
12769 SWLE = 0x0,
12770 SWRE = 0x1,
12771 PREFE = 0x2,
12772 CACHEE = 0x3,
12773 SBE = 0x4,
12774 SHE = 0x5,
12775 SCE = 0x6,
12776 SWE = 0x7,
12777};
12778
3c824109
NF
12779/* POOL32F encoding of minor opcode field (bits 5..0) */
12780
12781enum {
12782 /* These are the bit 7..6 values */
12783 ADD_FMT = 0x0,
3c824109
NF
12784
12785 SUB_FMT = 0x1,
3c824109
NF
12786
12787 MUL_FMT = 0x2,
12788
12789 DIV_FMT = 0x3,
12790
12791 /* These are the bit 8..6 values */
3a1f4268 12792 MOVN_FMT = 0x0,
3c824109
NF
12793 RSQRT2_FMT = 0x0,
12794 MOVF_FMT = 0x0,
3a1f4268
YK
12795 RINT_FMT = 0x0,
12796 SELNEZ_FMT = 0x0,
3c824109 12797
3a1f4268 12798 MOVZ_FMT = 0x1,
3c824109
NF
12799 LWXC1 = 0x1,
12800 MOVT_FMT = 0x1,
3a1f4268
YK
12801 CLASS_FMT = 0x1,
12802 SELEQZ_FMT = 0x1,
3c824109
NF
12803
12804 PLL_PS = 0x2,
12805 SWXC1 = 0x2,
3a1f4268 12806 SEL_FMT = 0x2,
3c824109
NF
12807
12808 PLU_PS = 0x3,
12809 LDXC1 = 0x3,
12810
3a1f4268 12811 MOVN_FMT_04 = 0x4,
3c824109
NF
12812 PUL_PS = 0x4,
12813 SDXC1 = 0x4,
12814 RECIP2_FMT = 0x4,
12815
3a1f4268 12816 MOVZ_FMT_05 = 0x05,
3c824109
NF
12817 PUU_PS = 0x5,
12818 LUXC1 = 0x5,
12819
12820 CVT_PS_S = 0x6,
12821 SUXC1 = 0x6,
12822 ADDR_PS = 0x6,
12823 PREFX = 0x6,
3a1f4268 12824 MADDF_FMT = 0x6,
3c824109
NF
12825
12826 MULR_PS = 0x7,
3a1f4268 12827 MSUBF_FMT = 0x7,
3c824109
NF
12828
12829 MADD_S = 0x01,
12830 MADD_D = 0x09,
12831 MADD_PS = 0x11,
12832 ALNV_PS = 0x19,
12833 MSUB_S = 0x21,
12834 MSUB_D = 0x29,
12835 MSUB_PS = 0x31,
12836
12837 NMADD_S = 0x02,
12838 NMADD_D = 0x0a,
12839 NMADD_PS = 0x12,
12840 NMSUB_S = 0x22,
12841 NMSUB_D = 0x2a,
12842 NMSUB_PS = 0x32,
12843
3a1f4268
YK
12844 MIN_FMT = 0x3,
12845 MAX_FMT = 0xb,
12846 MINA_FMT = 0x23,
12847 MAXA_FMT = 0x2b,
3c824109
NF
12848 POOL32FXF = 0x3b,
12849
12850 CABS_COND_FMT = 0x1c, /* MIPS3D */
3a1f4268
YK
12851 C_COND_FMT = 0x3c,
12852
12853 CMP_CONDN_S = 0x5,
12854 CMP_CONDN_D = 0x15
3c824109
NF
12855};
12856
12857/* POOL32Fxf encoding of minor opcode extension field */
12858
12859enum {
12860 CVT_L = 0x04,
12861 RSQRT_FMT = 0x08,
12862 FLOOR_L = 0x0c,
12863 CVT_PW_PS = 0x1c,
12864 CVT_W = 0x24,
12865 SQRT_FMT = 0x28,
12866 FLOOR_W = 0x2c,
12867 CVT_PS_PW = 0x3c,
12868 CFC1 = 0x40,
12869 RECIP_FMT = 0x48,
12870 CEIL_L = 0x4c,
12871 CTC1 = 0x60,
12872 CEIL_W = 0x6c,
12873 MFC1 = 0x80,
12874 CVT_S_PL = 0x84,
12875 TRUNC_L = 0x8c,
12876 MTC1 = 0xa0,
12877 CVT_S_PU = 0xa4,
12878 TRUNC_W = 0xac,
12879 MFHC1 = 0xc0,
12880 ROUND_L = 0xcc,
12881 MTHC1 = 0xe0,
12882 ROUND_W = 0xec,
12883
12884 MOV_FMT = 0x01,
12885 MOVF = 0x05,
12886 ABS_FMT = 0x0d,
12887 RSQRT1_FMT = 0x1d,
12888 MOVT = 0x25,
12889 NEG_FMT = 0x2d,
12890 CVT_D = 0x4d,
12891 RECIP1_FMT = 0x5d,
12892 CVT_S = 0x6d
12893};
12894
12895/* POOL32I encoding of minor opcode field (bits 25..21) */
12896
12897enum {
12898 BLTZ = 0x00,
12899 BLTZAL = 0x01,
12900 BGEZ = 0x02,
12901 BGEZAL = 0x03,
12902 BLEZ = 0x04,
12903 BNEZC = 0x05,
12904 BGTZ = 0x06,
12905 BEQZC = 0x07,
12906 TLTI = 0x08,
3a1f4268 12907 BC1EQZC = 0x08,
3c824109 12908 TGEI = 0x09,
3a1f4268 12909 BC1NEZC = 0x09,
3c824109 12910 TLTIU = 0x0a,
3a1f4268 12911 BC2EQZC = 0x0a,
3c824109 12912 TGEIU = 0x0b,
3a1f4268 12913 BC2NEZC = 0x0a,
3c824109 12914 TNEI = 0x0c,
3a1f4268 12915 R6_SYNCI = 0x0c,
3c824109
NF
12916 LUI = 0x0d,
12917 TEQI = 0x0e,
12918 SYNCI = 0x10,
12919 BLTZALS = 0x11,
12920 BGEZALS = 0x13,
12921 BC2F = 0x14,
12922 BC2T = 0x15,
12923 BPOSGE64 = 0x1a,
12924 BPOSGE32 = 0x1b,
12925 /* These overlap and are distinguished by bit16 of the instruction */
12926 BC1F = 0x1c,
12927 BC1T = 0x1d,
12928 BC1ANY2F = 0x1c,
12929 BC1ANY2T = 0x1d,
12930 BC1ANY4F = 0x1e,
12931 BC1ANY4T = 0x1f
12932};
12933
12934/* POOL16A encoding of minor opcode field */
12935
12936enum {
12937 ADDU16 = 0x0,
12938 SUBU16 = 0x1
12939};
12940
12941/* POOL16B encoding of minor opcode field */
12942
12943enum {
12944 SLL16 = 0x0,
12945 SRL16 = 0x1
12946};
12947
12948/* POOL16C encoding of minor opcode field */
12949
12950enum {
12951 NOT16 = 0x00,
12952 XOR16 = 0x04,
12953 AND16 = 0x08,
12954 OR16 = 0x0c,
12955 LWM16 = 0x10,
12956 SWM16 = 0x14,
12957 JR16 = 0x18,
12958 JRC16 = 0x1a,
12959 JALR16 = 0x1c,
12960 JALR16S = 0x1e,
12961 MFHI16 = 0x20,
12962 MFLO16 = 0x24,
12963 BREAK16 = 0x28,
12964 SDBBP16 = 0x2c,
12965 JRADDIUSP = 0x30
12966};
12967
3a1f4268
YK
12968/* R6 POOL16C encoding of minor opcode field (bits 0..5) */
12969
12970enum {
12971 R6_NOT16 = 0x00,
12972 R6_AND16 = 0x01,
12973 R6_LWM16 = 0x02,
12974 R6_JRC16 = 0x03,
12975 MOVEP = 0x04,
c38a1d52
AR
12976 MOVEP_05 = 0x05,
12977 MOVEP_06 = 0x06,
3a1f4268
YK
12978 MOVEP_07 = 0x07,
12979 R6_XOR16 = 0x08,
12980 R6_OR16 = 0x09,
12981 R6_SWM16 = 0x0a,
12982 JALRC16 = 0x0b,
12983 MOVEP_0C = 0x0c,
c38a1d52
AR
12984 MOVEP_0D = 0x0d,
12985 MOVEP_0E = 0x0e,
3a1f4268
YK
12986 MOVEP_0F = 0x0f,
12987 JRCADDIUSP = 0x13,
12988 R6_BREAK16 = 0x1b,
12989 R6_SDBBP16 = 0x3b
12990};
12991
3c824109
NF
12992/* POOL16D encoding of minor opcode field */
12993
12994enum {
12995 ADDIUS5 = 0x0,
12996 ADDIUSP = 0x1
12997};
12998
12999/* POOL16E encoding of minor opcode field */
13000
13001enum {
13002 ADDIUR2 = 0x0,
13003 ADDIUR1SP = 0x1
13004};
13005
13006static int mmreg (int r)
13007{
13008 static const int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
13009
13010 return map[r];
13011}
13012
13013/* Used for 16-bit store instructions. */
13014static int mmreg2 (int r)
13015{
13016 static const int map[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
13017
13018 return map[r];
13019}
13020
13021#define uMIPS_RD(op) ((op >> 7) & 0x7)
13022#define uMIPS_RS(op) ((op >> 4) & 0x7)
13023#define uMIPS_RS2(op) uMIPS_RS(op)
13024#define uMIPS_RS1(op) ((op >> 1) & 0x7)
13025#define uMIPS_RD5(op) ((op >> 5) & 0x1f)
13026#define uMIPS_RS5(op) (op & 0x1f)
13027
13028/* Signed immediate */
13029#define SIMM(op, start, width) \
13030 ((int32_t)(((op >> start) & ((~0U) >> (32-width))) \
13031 << (32-width)) \
13032 >> (32-width))
13033/* Zero-extended immediate */
13034#define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
13035
d75c135e 13036static void gen_addiur1sp(DisasContext *ctx)
3c824109
NF
13037{
13038 int rd = mmreg(uMIPS_RD(ctx->opcode));
13039
d75c135e 13040 gen_arith_imm(ctx, OPC_ADDIU, rd, 29, ((ctx->opcode >> 1) & 0x3f) << 2);
3c824109
NF
13041}
13042
d75c135e 13043static void gen_addiur2(DisasContext *ctx)
3c824109
NF
13044{
13045 static const int decoded_imm[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
13046 int rd = mmreg(uMIPS_RD(ctx->opcode));
13047 int rs = mmreg(uMIPS_RS(ctx->opcode));
13048
d75c135e 13049 gen_arith_imm(ctx, OPC_ADDIU, rd, rs, decoded_imm[ZIMM(ctx->opcode, 1, 3)]);
3c824109
NF
13050}
13051
d75c135e 13052static void gen_addiusp(DisasContext *ctx)
3c824109
NF
13053{
13054 int encoded = ZIMM(ctx->opcode, 1, 9);
13055 int decoded;
13056
13057 if (encoded <= 1) {
13058 decoded = 256 + encoded;
13059 } else if (encoded <= 255) {
13060 decoded = encoded;
13061 } else if (encoded <= 509) {
13062 decoded = encoded - 512;
13063 } else {
13064 decoded = encoded - 768;
13065 }
13066
d75c135e 13067 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, decoded << 2);
3c824109
NF
13068}
13069
d75c135e 13070static void gen_addius5(DisasContext *ctx)
3c824109
NF
13071{
13072 int imm = SIMM(ctx->opcode, 1, 4);
13073 int rd = (ctx->opcode >> 5) & 0x1f;
13074
d75c135e 13075 gen_arith_imm(ctx, OPC_ADDIU, rd, rd, imm);
3c824109
NF
13076}
13077
d75c135e 13078static void gen_andi16(DisasContext *ctx)
3c824109
NF
13079{
13080 static const int decoded_imm[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
13081 31, 32, 63, 64, 255, 32768, 65535 };
13082 int rd = mmreg(uMIPS_RD(ctx->opcode));
13083 int rs = mmreg(uMIPS_RS(ctx->opcode));
13084 int encoded = ZIMM(ctx->opcode, 0, 4);
13085
d75c135e 13086 gen_logic_imm(ctx, OPC_ANDI, rd, rs, decoded_imm[encoded]);
3c824109
NF
13087}
13088
13089static void gen_ldst_multiple (DisasContext *ctx, uint32_t opc, int reglist,
13090 int base, int16_t offset)
13091{
13092 TCGv t0, t1;
13093 TCGv_i32 t2;
13094
13095 if (ctx->hflags & MIPS_HFLAG_BMASK) {
9c708c7f 13096 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
13097 return;
13098 }
13099
13100 t0 = tcg_temp_new();
13101
13102 gen_base_offset_addr(ctx, t0, base, offset);
13103
13104 t1 = tcg_const_tl(reglist);
13105 t2 = tcg_const_i32(ctx->mem_idx);
6af0bf9c 13106
3c824109
NF
13107 save_cpu_state(ctx, 1);
13108 switch (opc) {
13109 case LWM32:
895c2d04 13110 gen_helper_lwm(cpu_env, t0, t1, t2);
3c824109
NF
13111 break;
13112 case SWM32:
895c2d04 13113 gen_helper_swm(cpu_env, t0, t1, t2);
3c824109
NF
13114 break;
13115#ifdef TARGET_MIPS64
13116 case LDM:
895c2d04 13117 gen_helper_ldm(cpu_env, t0, t1, t2);
3c824109
NF
13118 break;
13119 case SDM:
895c2d04 13120 gen_helper_sdm(cpu_env, t0, t1, t2);
3c824109 13121 break;
6af0bf9c 13122#endif
3c824109 13123 }
3c824109 13124 tcg_temp_free(t0);
33087598 13125 tcg_temp_free(t1);
3c824109
NF
13126 tcg_temp_free_i32(t2);
13127}
6af0bf9c 13128
3c824109 13129
240ce26a 13130static void gen_pool16c_insn(DisasContext *ctx)
6af0bf9c 13131{
3c824109
NF
13132 int rd = mmreg((ctx->opcode >> 3) & 0x7);
13133 int rs = mmreg(ctx->opcode & 0x7);
6af0bf9c 13134
3c824109
NF
13135 switch (((ctx->opcode) >> 4) & 0x3f) {
13136 case NOT16 + 0:
13137 case NOT16 + 1:
13138 case NOT16 + 2:
13139 case NOT16 + 3:
d75c135e 13140 gen_logic(ctx, OPC_NOR, rd, rs, 0);
3c824109
NF
13141 break;
13142 case XOR16 + 0:
13143 case XOR16 + 1:
13144 case XOR16 + 2:
13145 case XOR16 + 3:
d75c135e 13146 gen_logic(ctx, OPC_XOR, rd, rd, rs);
3c824109
NF
13147 break;
13148 case AND16 + 0:
13149 case AND16 + 1:
13150 case AND16 + 2:
13151 case AND16 + 3:
d75c135e 13152 gen_logic(ctx, OPC_AND, rd, rd, rs);
3c824109
NF
13153 break;
13154 case OR16 + 0:
13155 case OR16 + 1:
13156 case OR16 + 2:
13157 case OR16 + 3:
d75c135e 13158 gen_logic(ctx, OPC_OR, rd, rd, rs);
3c824109
NF
13159 break;
13160 case LWM16 + 0:
13161 case LWM16 + 1:
13162 case LWM16 + 2:
13163 case LWM16 + 3:
13164 {
13165 static const int lwm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
13166 int offset = ZIMM(ctx->opcode, 0, 4);
13167
13168 gen_ldst_multiple(ctx, LWM32, lwm_convert[(ctx->opcode >> 4) & 0x3],
13169 29, offset << 2);
13170 }
13171 break;
13172 case SWM16 + 0:
13173 case SWM16 + 1:
13174 case SWM16 + 2:
13175 case SWM16 + 3:
13176 {
13177 static const int swm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
13178 int offset = ZIMM(ctx->opcode, 0, 4);
13179
13180 gen_ldst_multiple(ctx, SWM32, swm_convert[(ctx->opcode >> 4) & 0x3],
13181 29, offset << 2);
13182 }
13183 break;
13184 case JR16 + 0:
13185 case JR16 + 1:
13186 {
13187 int reg = ctx->opcode & 0x1f;
13188
b231c103 13189 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 4);
3c824109 13190 }
3c824109
NF
13191 break;
13192 case JRC16 + 0:
13193 case JRC16 + 1:
13194 {
13195 int reg = ctx->opcode & 0x1f;
b231c103 13196 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 0);
3c824109
NF
13197 /* Let normal delay slot handling in our caller take us
13198 to the branch target. */
13199 }
13200 break;
13201 case JALR16 + 0:
13202 case JALR16 + 1:
b231c103
YK
13203 gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 4);
13204 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
13205 break;
3c824109
NF
13206 case JALR16S + 0:
13207 case JALR16S + 1:
b231c103
YK
13208 gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 2);
13209 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
3c824109
NF
13210 break;
13211 case MFHI16 + 0:
13212 case MFHI16 + 1:
26135ead 13213 gen_HILO(ctx, OPC_MFHI, 0, uMIPS_RS5(ctx->opcode));
3c824109
NF
13214 break;
13215 case MFLO16 + 0:
13216 case MFLO16 + 1:
26135ead 13217 gen_HILO(ctx, OPC_MFLO, 0, uMIPS_RS5(ctx->opcode));
3c824109
NF
13218 break;
13219 case BREAK16:
9c708c7f 13220 generate_exception_end(ctx, EXCP_BREAK);
3c824109
NF
13221 break;
13222 case SDBBP16:
3b3c1694
LA
13223 if (is_uhi(extract32(ctx->opcode, 0, 4))) {
13224 gen_helper_do_semihosting(cpu_env);
13225 } else {
13226 /* XXX: not clear which exception should be raised
13227 * when in debug mode...
13228 */
13229 check_insn(ctx, ISA_MIPS32);
9c708c7f 13230 generate_exception_end(ctx, EXCP_DBp);
3b3c1694 13231 }
3c824109
NF
13232 break;
13233 case JRADDIUSP + 0:
13234 case JRADDIUSP + 1:
13235 {
13236 int imm = ZIMM(ctx->opcode, 0, 5);
b231c103 13237 gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0, 0);
d75c135e 13238 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
3c824109
NF
13239 /* Let normal delay slot handling in our caller take us
13240 to the branch target. */
13241 }
13242 break;
13243 default:
9c708c7f 13244 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
13245 break;
13246 }
13247}
13248
ed7ce6c0
YK
13249static inline void gen_movep(DisasContext *ctx, int enc_dest, int enc_rt,
13250 int enc_rs)
13251{
13252 int rd, rs, re, rt;
13253 static const int rd_enc[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
13254 static const int re_enc[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
13255 static const int rs_rt_enc[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
13256 rd = rd_enc[enc_dest];
13257 re = re_enc[enc_dest];
13258 rs = rs_rt_enc[enc_rs];
13259 rt = rs_rt_enc[enc_rt];
13260 if (rs) {
13261 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
13262 } else {
13263 tcg_gen_movi_tl(cpu_gpr[rd], 0);
13264 }
13265 if (rt) {
13266 tcg_gen_mov_tl(cpu_gpr[re], cpu_gpr[rt]);
13267 } else {
13268 tcg_gen_movi_tl(cpu_gpr[re], 0);
13269 }
13270}
13271
13272static void gen_pool16c_r6_insn(DisasContext *ctx)
13273{
13274 int rt = mmreg((ctx->opcode >> 7) & 0x7);
13275 int rs = mmreg((ctx->opcode >> 4) & 0x7);
13276
13277 switch (ctx->opcode & 0xf) {
13278 case R6_NOT16:
13279 gen_logic(ctx, OPC_NOR, rt, rs, 0);
13280 break;
13281 case R6_AND16:
13282 gen_logic(ctx, OPC_AND, rt, rt, rs);
13283 break;
13284 case R6_LWM16:
13285 {
13286 int lwm_converted = 0x11 + extract32(ctx->opcode, 8, 2);
13287 int offset = extract32(ctx->opcode, 4, 4);
13288 gen_ldst_multiple(ctx, LWM32, lwm_converted, 29, offset << 2);
13289 }
13290 break;
13291 case R6_JRC16: /* JRCADDIUSP */
13292 if ((ctx->opcode >> 4) & 1) {
13293 /* JRCADDIUSP */
13294 int imm = extract32(ctx->opcode, 5, 5);
13295 gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0, 0);
13296 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
13297 } else {
13298 /* JRC16 */
e1555d7d 13299 rs = extract32(ctx->opcode, 5, 5);
ed7ce6c0
YK
13300 gen_compute_branch(ctx, OPC_JR, 2, rs, 0, 0, 0);
13301 }
13302 break;
c38a1d52
AR
13303 case MOVEP:
13304 case MOVEP_05:
13305 case MOVEP_06:
13306 case MOVEP_07:
13307 case MOVEP_0C:
13308 case MOVEP_0D:
13309 case MOVEP_0E:
13310 case MOVEP_0F:
ed7ce6c0
YK
13311 {
13312 int enc_dest = uMIPS_RD(ctx->opcode);
13313 int enc_rt = uMIPS_RS2(ctx->opcode);
13314 int enc_rs = (ctx->opcode & 3) | ((ctx->opcode >> 1) & 4);
13315 gen_movep(ctx, enc_dest, enc_rt, enc_rs);
13316 }
13317 break;
13318 case R6_XOR16:
13319 gen_logic(ctx, OPC_XOR, rt, rt, rs);
13320 break;
13321 case R6_OR16:
13322 gen_logic(ctx, OPC_OR, rt, rt, rs);
13323 break;
13324 case R6_SWM16:
13325 {
13326 int swm_converted = 0x11 + extract32(ctx->opcode, 8, 2);
13327 int offset = extract32(ctx->opcode, 4, 4);
13328 gen_ldst_multiple(ctx, SWM32, swm_converted, 29, offset << 2);
13329 }
13330 break;
13331 case JALRC16: /* BREAK16, SDBBP16 */
13332 switch (ctx->opcode & 0x3f) {
13333 case JALRC16:
13334 case JALRC16 + 0x20:
13335 /* JALRC16 */
13336 gen_compute_branch(ctx, OPC_JALR, 2, (ctx->opcode >> 5) & 0x1f,
13337 31, 0, 0);
13338 break;
13339 case R6_BREAK16:
13340 /* BREAK16 */
13341 generate_exception(ctx, EXCP_BREAK);
13342 break;
13343 case R6_SDBBP16:
13344 /* SDBBP16 */
060ebfef
LA
13345 if (is_uhi(extract32(ctx->opcode, 6, 4))) {
13346 gen_helper_do_semihosting(cpu_env);
ed7ce6c0 13347 } else {
060ebfef
LA
13348 if (ctx->hflags & MIPS_HFLAG_SBRI) {
13349 generate_exception(ctx, EXCP_RI);
13350 } else {
13351 generate_exception(ctx, EXCP_DBp);
13352 }
ed7ce6c0
YK
13353 }
13354 break;
13355 }
13356 break;
13357 default:
13358 generate_exception(ctx, EXCP_RI);
13359 break;
13360 }
13361}
13362
3c824109
NF
13363static void gen_ldxs (DisasContext *ctx, int base, int index, int rd)
13364{
13365 TCGv t0 = tcg_temp_new();
13366 TCGv t1 = tcg_temp_new();
13367
13368 gen_load_gpr(t0, base);
13369
13370 if (index != 0) {
13371 gen_load_gpr(t1, index);
13372 tcg_gen_shli_tl(t1, t1, 2);
13373 gen_op_addr_add(ctx, t0, t1, t0);
13374 }
13375
5f68f5ae 13376 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
3c824109
NF
13377 gen_store_gpr(t1, rd);
13378
13379 tcg_temp_free(t0);
13380 tcg_temp_free(t1);
13381}
13382
13383static void gen_ldst_pair (DisasContext *ctx, uint32_t opc, int rd,
13384 int base, int16_t offset)
13385{
3c824109
NF
13386 TCGv t0, t1;
13387
36c6711b 13388 if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31) {
9c708c7f 13389 generate_exception_end(ctx, EXCP_RI);
d796321b
FB
13390 return;
13391 }
13392
3c824109
NF
13393 t0 = tcg_temp_new();
13394 t1 = tcg_temp_new();
8e9ade68 13395
3c824109
NF
13396 gen_base_offset_addr(ctx, t0, base, offset);
13397
13398 switch (opc) {
13399 case LWP:
36c6711b 13400 if (rd == base) {
9c708c7f 13401 generate_exception_end(ctx, EXCP_RI);
36c6711b
EJ
13402 return;
13403 }
5f68f5ae 13404 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
3c824109
NF
13405 gen_store_gpr(t1, rd);
13406 tcg_gen_movi_tl(t1, 4);
13407 gen_op_addr_add(ctx, t0, t0, t1);
5f68f5ae 13408 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
3c824109 13409 gen_store_gpr(t1, rd+1);
3c824109
NF
13410 break;
13411 case SWP:
3c824109 13412 gen_load_gpr(t1, rd);
5f68f5ae 13413 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
3c824109
NF
13414 tcg_gen_movi_tl(t1, 4);
13415 gen_op_addr_add(ctx, t0, t0, t1);
13416 gen_load_gpr(t1, rd+1);
5f68f5ae 13417 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
3c824109
NF
13418 break;
13419#ifdef TARGET_MIPS64
13420 case LDP:
36c6711b 13421 if (rd == base) {
9c708c7f 13422 generate_exception_end(ctx, EXCP_RI);
36c6711b
EJ
13423 return;
13424 }
5f68f5ae 13425 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
3c824109
NF
13426 gen_store_gpr(t1, rd);
13427 tcg_gen_movi_tl(t1, 8);
13428 gen_op_addr_add(ctx, t0, t0, t1);
5f68f5ae 13429 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
3c824109 13430 gen_store_gpr(t1, rd+1);
3c824109
NF
13431 break;
13432 case SDP:
3c824109 13433 gen_load_gpr(t1, rd);
5f68f5ae 13434 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
3c824109
NF
13435 tcg_gen_movi_tl(t1, 8);
13436 gen_op_addr_add(ctx, t0, t0, t1);
13437 gen_load_gpr(t1, rd+1);
5f68f5ae 13438 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
3c824109
NF
13439 break;
13440#endif
6af0bf9c 13441 }
3c824109
NF
13442 tcg_temp_free(t0);
13443 tcg_temp_free(t1);
13444}
618b0fe9 13445
d208ac0c
LA
13446static void gen_sync(int stype)
13447{
13448 TCGBar tcg_mo = TCG_BAR_SC;
13449
13450 switch (stype) {
13451 case 0x4: /* SYNC_WMB */
13452 tcg_mo |= TCG_MO_ST_ST;
13453 break;
13454 case 0x10: /* SYNC_MB */
13455 tcg_mo |= TCG_MO_ALL;
13456 break;
13457 case 0x11: /* SYNC_ACQUIRE */
13458 tcg_mo |= TCG_MO_LD_LD | TCG_MO_LD_ST;
13459 break;
13460 case 0x12: /* SYNC_RELEASE */
13461 tcg_mo |= TCG_MO_ST_ST | TCG_MO_LD_ST;
13462 break;
13463 case 0x13: /* SYNC_RMB */
13464 tcg_mo |= TCG_MO_LD_LD;
13465 break;
13466 default:
13467 tcg_mo |= TCG_MO_ALL;
13468 break;
13469 }
13470
13471 tcg_gen_mb(tcg_mo);
13472}
13473
240ce26a 13474static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
3c824109
NF
13475{
13476 int extension = (ctx->opcode >> 6) & 0x3f;
13477 int minor = (ctx->opcode >> 12) & 0xf;
13478 uint32_t mips32_op;
13479
13480 switch (extension) {
13481 case TEQ:
13482 mips32_op = OPC_TEQ;
13483 goto do_trap;
13484 case TGE:
13485 mips32_op = OPC_TGE;
13486 goto do_trap;
13487 case TGEU:
13488 mips32_op = OPC_TGEU;
13489 goto do_trap;
13490 case TLT:
13491 mips32_op = OPC_TLT;
13492 goto do_trap;
13493 case TLTU:
13494 mips32_op = OPC_TLTU;
13495 goto do_trap;
13496 case TNE:
13497 mips32_op = OPC_TNE;
13498 do_trap:
13499 gen_trap(ctx, mips32_op, rs, rt, -1);
13500 break;
13501#ifndef CONFIG_USER_ONLY
13502 case MFC0:
13503 case MFC0 + 32:
2e15497c 13504 check_cp0_enabled(ctx);
3c824109
NF
13505 if (rt == 0) {
13506 /* Treat as NOP. */
13507 break;
13508 }
d75c135e 13509 gen_mfc0(ctx, cpu_gpr[rt], rs, (ctx->opcode >> 11) & 0x7);
3c824109
NF
13510 break;
13511 case MTC0:
13512 case MTC0 + 32:
2e15497c 13513 check_cp0_enabled(ctx);
3c824109
NF
13514 {
13515 TCGv t0 = tcg_temp_new();
618b0fe9 13516
3c824109 13517 gen_load_gpr(t0, rt);
d75c135e 13518 gen_mtc0(ctx, t0, rs, (ctx->opcode >> 11) & 0x7);
3c824109
NF
13519 tcg_temp_free(t0);
13520 }
13521 break;
13522#endif
a1fc6246
LA
13523 case 0x2a:
13524 switch (minor & 3) {
13525 case MADD_ACC:
13526 gen_muldiv(ctx, OPC_MADD, (ctx->opcode >> 14) & 3, rs, rt);
13527 break;
13528 case MADDU_ACC:
13529 gen_muldiv(ctx, OPC_MADDU, (ctx->opcode >> 14) & 3, rs, rt);
13530 break;
13531 case MSUB_ACC:
13532 gen_muldiv(ctx, OPC_MSUB, (ctx->opcode >> 14) & 3, rs, rt);
13533 break;
13534 case MSUBU_ACC:
13535 gen_muldiv(ctx, OPC_MSUBU, (ctx->opcode >> 14) & 3, rs, rt);
13536 break;
13537 default:
13538 goto pool32axf_invalid;
13539 }
13540 break;
13541 case 0x32:
13542 switch (minor & 3) {
13543 case MULT_ACC:
13544 gen_muldiv(ctx, OPC_MULT, (ctx->opcode >> 14) & 3, rs, rt);
13545 break;
13546 case MULTU_ACC:
13547 gen_muldiv(ctx, OPC_MULTU, (ctx->opcode >> 14) & 3, rs, rt);
13548 break;
13549 default:
13550 goto pool32axf_invalid;
13551 }
13552 break;
3c824109
NF
13553 case 0x2c:
13554 switch (minor) {
e0332095
YK
13555 case BITSWAP:
13556 check_insn(ctx, ISA_MIPS32R6);
13557 gen_bitswap(ctx, OPC_BITSWAP, rs, rt);
13558 break;
3c824109
NF
13559 case SEB:
13560 gen_bshfl(ctx, OPC_SEB, rs, rt);
13561 break;
13562 case SEH:
13563 gen_bshfl(ctx, OPC_SEH, rs, rt);
13564 break;
13565 case CLO:
13566 mips32_op = OPC_CLO;
13567 goto do_cl;
13568 case CLZ:
13569 mips32_op = OPC_CLZ;
13570 do_cl:
d75c135e 13571 check_insn(ctx, ISA_MIPS32);
3c824109
NF
13572 gen_cl(ctx, mips32_op, rt, rs);
13573 break;
13574 case RDHWR:
b00c7218
YK
13575 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13576 gen_rdhwr(ctx, rt, rs, 0);
3c824109
NF
13577 break;
13578 case WSBH:
13579 gen_bshfl(ctx, OPC_WSBH, rs, rt);
13580 break;
13581 case MULT:
9e8f441a 13582 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 13583 mips32_op = OPC_MULT;
26135ead 13584 goto do_mul;
3c824109 13585 case MULTU:
9e8f441a 13586 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 13587 mips32_op = OPC_MULTU;
26135ead 13588 goto do_mul;
3c824109 13589 case DIV:
9e8f441a 13590 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 13591 mips32_op = OPC_DIV;
26135ead 13592 goto do_div;
3c824109 13593 case DIVU:
9e8f441a 13594 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 13595 mips32_op = OPC_DIVU;
26135ead
RS
13596 goto do_div;
13597 do_div:
13598 check_insn(ctx, ISA_MIPS32);
13599 gen_muldiv(ctx, mips32_op, 0, rs, rt);
13600 break;
3c824109 13601 case MADD:
9e8f441a 13602 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 13603 mips32_op = OPC_MADD;
26135ead 13604 goto do_mul;
3c824109 13605 case MADDU:
9e8f441a 13606 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 13607 mips32_op = OPC_MADDU;
26135ead 13608 goto do_mul;
3c824109 13609 case MSUB:
9e8f441a 13610 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 13611 mips32_op = OPC_MSUB;
26135ead 13612 goto do_mul;
3c824109 13613 case MSUBU:
9e8f441a 13614 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 13615 mips32_op = OPC_MSUBU;
26135ead 13616 do_mul:
d75c135e 13617 check_insn(ctx, ISA_MIPS32);
a1fc6246 13618 gen_muldiv(ctx, mips32_op, 0, rs, rt);
3c824109
NF
13619 break;
13620 default:
13621 goto pool32axf_invalid;
13622 }
13623 break;
13624 case 0x34:
13625 switch (minor) {
13626 case MFC2:
13627 case MTC2:
13628 case MFHC2:
13629 case MTHC2:
13630 case CFC2:
13631 case CTC2:
13632 generate_exception_err(ctx, EXCP_CpU, 2);
13633 break;
13634 default:
13635 goto pool32axf_invalid;
13636 }
13637 break;
13638 case 0x3c:
13639 switch (minor) {
65935f07
YK
13640 case JALR: /* JALRC */
13641 case JALR_HB: /* JALRC_HB */
13642 if (ctx->insn_flags & ISA_MIPS32R6) {
13643 /* JALRC, JALRC_HB */
13644 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 0);
13645 } else {
13646 /* JALR, JALR_HB */
13647 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 4);
13648 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
13649 }
3c824109
NF
13650 break;
13651 case JALRS:
13652 case JALRS_HB:
9e8f441a 13653 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
13654 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 2);
13655 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
3c824109
NF
13656 break;
13657 default:
13658 goto pool32axf_invalid;
13659 }
13660 break;
13661 case 0x05:
13662 switch (minor) {
13663 case RDPGPR:
2e15497c 13664 check_cp0_enabled(ctx);
d75c135e 13665 check_insn(ctx, ISA_MIPS32R2);
1bf5902d 13666 gen_load_srsgpr(rs, rt);
3c824109
NF
13667 break;
13668 case WRPGPR:
2e15497c 13669 check_cp0_enabled(ctx);
d75c135e 13670 check_insn(ctx, ISA_MIPS32R2);
1bf5902d 13671 gen_store_srsgpr(rs, rt);
3c824109
NF
13672 break;
13673 default:
13674 goto pool32axf_invalid;
13675 }
13676 break;
13677#ifndef CONFIG_USER_ONLY
13678 case 0x0d:
13679 switch (minor) {
13680 case TLBP:
13681 mips32_op = OPC_TLBP;
13682 goto do_cp0;
13683 case TLBR:
13684 mips32_op = OPC_TLBR;
13685 goto do_cp0;
13686 case TLBWI:
13687 mips32_op = OPC_TLBWI;
13688 goto do_cp0;
13689 case TLBWR:
13690 mips32_op = OPC_TLBWR;
13691 goto do_cp0;
e60ec063
YK
13692 case TLBINV:
13693 mips32_op = OPC_TLBINV;
13694 goto do_cp0;
13695 case TLBINVF:
13696 mips32_op = OPC_TLBINVF;
13697 goto do_cp0;
3c824109
NF
13698 case WAIT:
13699 mips32_op = OPC_WAIT;
13700 goto do_cp0;
13701 case DERET:
13702 mips32_op = OPC_DERET;
13703 goto do_cp0;
13704 case ERET:
13705 mips32_op = OPC_ERET;
13706 do_cp0:
13707 gen_cp0(env, ctx, mips32_op, rt, rs);
13708 break;
13709 default:
13710 goto pool32axf_invalid;
13711 }
13712 break;
13713 case 0x1d:
13714 switch (minor) {
13715 case DI:
2e15497c 13716 check_cp0_enabled(ctx);
3c824109
NF
13717 {
13718 TCGv t0 = tcg_temp_new();
13719
13720 save_cpu_state(ctx, 1);
895c2d04 13721 gen_helper_di(t0, cpu_env);
3c824109
NF
13722 gen_store_gpr(t0, rs);
13723 /* Stop translation as we may have switched the execution mode */
eeb3bba8 13724 ctx->base.is_jmp = DISAS_STOP;
3c824109
NF
13725 tcg_temp_free(t0);
13726 }
13727 break;
13728 case EI:
2e15497c 13729 check_cp0_enabled(ctx);
3c824109
NF
13730 {
13731 TCGv t0 = tcg_temp_new();
13732
13733 save_cpu_state(ctx, 1);
895c2d04 13734 gen_helper_ei(t0, cpu_env);
3c824109 13735 gen_store_gpr(t0, rs);
b28425ba 13736 /* DISAS_STOP isn't sufficient, we need to ensure we break out
b74cddcb 13737 of translated code to check for pending interrupts. */
eeb3bba8
EC
13738 gen_save_pc(ctx->base.pc_next + 4);
13739 ctx->base.is_jmp = DISAS_EXIT;
3c824109
NF
13740 tcg_temp_free(t0);
13741 }
13742 break;
13743 default:
13744 goto pool32axf_invalid;
13745 }
13746 break;
13747#endif
13748 case 0x2d:
13749 switch (minor) {
13750 case SYNC:
d208ac0c 13751 gen_sync(extract32(ctx->opcode, 16, 5));
3c824109
NF
13752 break;
13753 case SYSCALL:
9c708c7f 13754 generate_exception_end(ctx, EXCP_SYSCALL);
3c824109
NF
13755 break;
13756 case SDBBP:
3b3c1694
LA
13757 if (is_uhi(extract32(ctx->opcode, 16, 10))) {
13758 gen_helper_do_semihosting(cpu_env);
13759 } else {
13760 check_insn(ctx, ISA_MIPS32);
e0332095 13761 if (ctx->hflags & MIPS_HFLAG_SBRI) {
9c708c7f 13762 generate_exception_end(ctx, EXCP_RI);
e0332095 13763 } else {
9c708c7f 13764 generate_exception_end(ctx, EXCP_DBp);
e0332095 13765 }
3b3c1694 13766 }
3c824109
NF
13767 break;
13768 default:
13769 goto pool32axf_invalid;
13770 }
13771 break;
a1fc6246 13772 case 0x01:
26135ead 13773 switch (minor & 3) {
a1fc6246 13774 case MFHI_ACC:
26135ead 13775 gen_HILO(ctx, OPC_MFHI, minor >> 2, rs);
3c824109 13776 break;
a1fc6246 13777 case MFLO_ACC:
26135ead 13778 gen_HILO(ctx, OPC_MFLO, minor >> 2, rs);
3c824109 13779 break;
a1fc6246 13780 case MTHI_ACC:
26135ead 13781 gen_HILO(ctx, OPC_MTHI, minor >> 2, rs);
3c824109 13782 break;
a1fc6246 13783 case MTLO_ACC:
26135ead 13784 gen_HILO(ctx, OPC_MTLO, minor >> 2, rs);
3c824109
NF
13785 break;
13786 default:
13787 goto pool32axf_invalid;
13788 }
13789 break;
a1fc6246 13790 case 0x35:
9e8f441a 13791 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a1fc6246
LA
13792 switch (minor) {
13793 case MFHI32:
13794 gen_HILO(ctx, OPC_MFHI, 0, rs);
13795 break;
13796 case MFLO32:
13797 gen_HILO(ctx, OPC_MFLO, 0, rs);
13798 break;
13799 case MTHI32:
13800 gen_HILO(ctx, OPC_MTHI, 0, rs);
13801 break;
13802 case MTLO32:
13803 gen_HILO(ctx, OPC_MTLO, 0, rs);
13804 break;
13805 default:
13806 goto pool32axf_invalid;
13807 }
13808 break;
3c824109
NF
13809 default:
13810 pool32axf_invalid:
13811 MIPS_INVAL("pool32axf");
9c708c7f 13812 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
13813 break;
13814 }
13815}
13816
13817/* Values for microMIPS fmt field. Variable-width, depending on which
13818 formats the instruction supports. */
13819
13820enum {
13821 FMT_SD_S = 0,
13822 FMT_SD_D = 1,
13823
13824 FMT_SDPS_S = 0,
13825 FMT_SDPS_D = 1,
13826 FMT_SDPS_PS = 2,
13827
13828 FMT_SWL_S = 0,
13829 FMT_SWL_W = 1,
13830 FMT_SWL_L = 2,
13831
13832 FMT_DWL_D = 0,
13833 FMT_DWL_W = 1,
13834 FMT_DWL_L = 2
13835};
13836
d75c135e 13837static void gen_pool32fxf(DisasContext *ctx, int rt, int rs)
3c824109
NF
13838{
13839 int extension = (ctx->opcode >> 6) & 0x3ff;
13840 uint32_t mips32_op;
13841
13842#define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
13843#define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
13844#define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
13845
13846 switch (extension) {
13847 case FLOAT_1BIT_FMT(CFC1, 0):
13848 mips32_op = OPC_CFC1;
13849 goto do_cp1;
13850 case FLOAT_1BIT_FMT(CTC1, 0):
13851 mips32_op = OPC_CTC1;
13852 goto do_cp1;
13853 case FLOAT_1BIT_FMT(MFC1, 0):
13854 mips32_op = OPC_MFC1;
13855 goto do_cp1;
13856 case FLOAT_1BIT_FMT(MTC1, 0):
13857 mips32_op = OPC_MTC1;
13858 goto do_cp1;
13859 case FLOAT_1BIT_FMT(MFHC1, 0):
13860 mips32_op = OPC_MFHC1;
13861 goto do_cp1;
13862 case FLOAT_1BIT_FMT(MTHC1, 0):
13863 mips32_op = OPC_MTHC1;
13864 do_cp1:
13865 gen_cp1(ctx, mips32_op, rt, rs);
13866 break;
13867
13868 /* Reciprocal square root */
13869 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_S):
13870 mips32_op = OPC_RSQRT_S;
13871 goto do_unaryfp;
13872 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_D):
13873 mips32_op = OPC_RSQRT_D;
13874 goto do_unaryfp;
13875
13876 /* Square root */
13877 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_S):
13878 mips32_op = OPC_SQRT_S;
13879 goto do_unaryfp;
13880 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_D):
13881 mips32_op = OPC_SQRT_D;
13882 goto do_unaryfp;
13883
13884 /* Reciprocal */
13885 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_S):
13886 mips32_op = OPC_RECIP_S;
13887 goto do_unaryfp;
13888 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_D):
13889 mips32_op = OPC_RECIP_D;
13890 goto do_unaryfp;
13891
13892 /* Floor */
13893 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_S):
13894 mips32_op = OPC_FLOOR_L_S;
13895 goto do_unaryfp;
13896 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_D):
13897 mips32_op = OPC_FLOOR_L_D;
13898 goto do_unaryfp;
13899 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_S):
13900 mips32_op = OPC_FLOOR_W_S;
13901 goto do_unaryfp;
13902 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_D):
13903 mips32_op = OPC_FLOOR_W_D;
13904 goto do_unaryfp;
13905
13906 /* Ceiling */
13907 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_S):
13908 mips32_op = OPC_CEIL_L_S;
13909 goto do_unaryfp;
13910 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_D):
13911 mips32_op = OPC_CEIL_L_D;
13912 goto do_unaryfp;
13913 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_S):
13914 mips32_op = OPC_CEIL_W_S;
13915 goto do_unaryfp;
13916 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_D):
13917 mips32_op = OPC_CEIL_W_D;
13918 goto do_unaryfp;
13919
13920 /* Truncation */
13921 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_S):
13922 mips32_op = OPC_TRUNC_L_S;
13923 goto do_unaryfp;
13924 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_D):
13925 mips32_op = OPC_TRUNC_L_D;
13926 goto do_unaryfp;
13927 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_S):
13928 mips32_op = OPC_TRUNC_W_S;
13929 goto do_unaryfp;
13930 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_D):
13931 mips32_op = OPC_TRUNC_W_D;
13932 goto do_unaryfp;
13933
13934 /* Round */
13935 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_S):
13936 mips32_op = OPC_ROUND_L_S;
13937 goto do_unaryfp;
13938 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_D):
13939 mips32_op = OPC_ROUND_L_D;
13940 goto do_unaryfp;
13941 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_S):
13942 mips32_op = OPC_ROUND_W_S;
13943 goto do_unaryfp;
13944 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_D):
13945 mips32_op = OPC_ROUND_W_D;
13946 goto do_unaryfp;
13947
13948 /* Integer to floating-point conversion */
13949 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_S):
13950 mips32_op = OPC_CVT_L_S;
13951 goto do_unaryfp;
13952 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_D):
13953 mips32_op = OPC_CVT_L_D;
13954 goto do_unaryfp;
13955 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_S):
13956 mips32_op = OPC_CVT_W_S;
13957 goto do_unaryfp;
13958 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_D):
13959 mips32_op = OPC_CVT_W_D;
13960 goto do_unaryfp;
13961
13962 /* Paired-foo conversions */
13963 case FLOAT_1BIT_FMT(CVT_S_PL, 0):
13964 mips32_op = OPC_CVT_S_PL;
13965 goto do_unaryfp;
13966 case FLOAT_1BIT_FMT(CVT_S_PU, 0):
13967 mips32_op = OPC_CVT_S_PU;
13968 goto do_unaryfp;
13969 case FLOAT_1BIT_FMT(CVT_PW_PS, 0):
13970 mips32_op = OPC_CVT_PW_PS;
13971 goto do_unaryfp;
13972 case FLOAT_1BIT_FMT(CVT_PS_PW, 0):
13973 mips32_op = OPC_CVT_PS_PW;
13974 goto do_unaryfp;
13975
13976 /* Floating-point moves */
13977 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_S):
13978 mips32_op = OPC_MOV_S;
13979 goto do_unaryfp;
13980 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_D):
13981 mips32_op = OPC_MOV_D;
13982 goto do_unaryfp;
13983 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_PS):
13984 mips32_op = OPC_MOV_PS;
13985 goto do_unaryfp;
13986
13987 /* Absolute value */
13988 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_S):
13989 mips32_op = OPC_ABS_S;
13990 goto do_unaryfp;
13991 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_D):
13992 mips32_op = OPC_ABS_D;
13993 goto do_unaryfp;
13994 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_PS):
13995 mips32_op = OPC_ABS_PS;
13996 goto do_unaryfp;
13997
13998 /* Negation */
13999 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_S):
14000 mips32_op = OPC_NEG_S;
14001 goto do_unaryfp;
14002 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_D):
14003 mips32_op = OPC_NEG_D;
14004 goto do_unaryfp;
14005 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_PS):
14006 mips32_op = OPC_NEG_PS;
14007 goto do_unaryfp;
14008
14009 /* Reciprocal square root step */
14010 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_S):
14011 mips32_op = OPC_RSQRT1_S;
14012 goto do_unaryfp;
14013 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_D):
14014 mips32_op = OPC_RSQRT1_D;
14015 goto do_unaryfp;
14016 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_PS):
14017 mips32_op = OPC_RSQRT1_PS;
14018 goto do_unaryfp;
14019
14020 /* Reciprocal step */
14021 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_S):
14022 mips32_op = OPC_RECIP1_S;
14023 goto do_unaryfp;
14024 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_D):
14025 mips32_op = OPC_RECIP1_S;
14026 goto do_unaryfp;
14027 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_PS):
14028 mips32_op = OPC_RECIP1_PS;
14029 goto do_unaryfp;
14030
14031 /* Conversions from double */
14032 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_S):
14033 mips32_op = OPC_CVT_D_S;
14034 goto do_unaryfp;
14035 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_W):
14036 mips32_op = OPC_CVT_D_W;
14037 goto do_unaryfp;
14038 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_L):
14039 mips32_op = OPC_CVT_D_L;
14040 goto do_unaryfp;
14041
14042 /* Conversions from single */
14043 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_D):
14044 mips32_op = OPC_CVT_S_D;
14045 goto do_unaryfp;
14046 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_W):
14047 mips32_op = OPC_CVT_S_W;
14048 goto do_unaryfp;
14049 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_L):
14050 mips32_op = OPC_CVT_S_L;
14051 do_unaryfp:
14052 gen_farith(ctx, mips32_op, -1, rs, rt, 0);
14053 break;
14054
14055 /* Conditional moves on floating-point codes */
14056 case COND_FLOAT_MOV(MOVT, 0):
14057 case COND_FLOAT_MOV(MOVT, 1):
14058 case COND_FLOAT_MOV(MOVT, 2):
14059 case COND_FLOAT_MOV(MOVT, 3):
14060 case COND_FLOAT_MOV(MOVT, 4):
14061 case COND_FLOAT_MOV(MOVT, 5):
14062 case COND_FLOAT_MOV(MOVT, 6):
14063 case COND_FLOAT_MOV(MOVT, 7):
9e8f441a 14064 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14065 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 1);
14066 break;
14067 case COND_FLOAT_MOV(MOVF, 0):
14068 case COND_FLOAT_MOV(MOVF, 1):
14069 case COND_FLOAT_MOV(MOVF, 2):
14070 case COND_FLOAT_MOV(MOVF, 3):
14071 case COND_FLOAT_MOV(MOVF, 4):
14072 case COND_FLOAT_MOV(MOVF, 5):
14073 case COND_FLOAT_MOV(MOVF, 6):
14074 case COND_FLOAT_MOV(MOVF, 7):
9e8f441a 14075 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14076 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 0);
14077 break;
14078 default:
14079 MIPS_INVAL("pool32fxf");
9c708c7f 14080 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
14081 break;
14082 }
14083}
14084
f60eeb0c 14085static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx)
3c824109
NF
14086{
14087 int32_t offset;
14088 uint16_t insn;
14089 int rt, rs, rd, rr;
14090 int16_t imm;
8fffc646 14091 uint32_t op, minor, minor2, mips32_op;
3c824109
NF
14092 uint32_t cond, fmt, cc;
14093
eeb3bba8 14094 insn = cpu_lduw_code(env, ctx->base.pc_next + 2);
3c824109
NF
14095 ctx->opcode = (ctx->opcode << 16) | insn;
14096
14097 rt = (ctx->opcode >> 21) & 0x1f;
14098 rs = (ctx->opcode >> 16) & 0x1f;
14099 rd = (ctx->opcode >> 11) & 0x1f;
14100 rr = (ctx->opcode >> 6) & 0x1f;
14101 imm = (int16_t) ctx->opcode;
14102
14103 op = (ctx->opcode >> 26) & 0x3f;
14104 switch (op) {
14105 case POOL32A:
14106 minor = ctx->opcode & 0x3f;
14107 switch (minor) {
14108 case 0x00:
14109 minor = (ctx->opcode >> 6) & 0xf;
14110 switch (minor) {
14111 case SLL32:
14112 mips32_op = OPC_SLL;
14113 goto do_shifti;
14114 case SRA:
14115 mips32_op = OPC_SRA;
14116 goto do_shifti;
14117 case SRL32:
14118 mips32_op = OPC_SRL;
14119 goto do_shifti;
14120 case ROTR:
14121 mips32_op = OPC_ROTR;
14122 do_shifti:
d75c135e 14123 gen_shift_imm(ctx, mips32_op, rt, rs, rd);
3c824109 14124 break;
e0332095
YK
14125 case SELEQZ:
14126 check_insn(ctx, ISA_MIPS32R6);
14127 gen_cond_move(ctx, OPC_SELEQZ, rd, rs, rt);
14128 break;
14129 case SELNEZ:
14130 check_insn(ctx, ISA_MIPS32R6);
14131 gen_cond_move(ctx, OPC_SELNEZ, rd, rs, rt);
14132 break;
b00c7218
YK
14133 case R6_RDHWR:
14134 check_insn(ctx, ISA_MIPS32R6);
14135 gen_rdhwr(ctx, rt, rs, extract32(ctx->opcode, 11, 3));
14136 break;
3c824109
NF
14137 default:
14138 goto pool32a_invalid;
14139 }
14140 break;
14141 case 0x10:
14142 minor = (ctx->opcode >> 6) & 0xf;
14143 switch (minor) {
14144 /* Arithmetic */
14145 case ADD:
14146 mips32_op = OPC_ADD;
14147 goto do_arith;
14148 case ADDU32:
14149 mips32_op = OPC_ADDU;
14150 goto do_arith;
14151 case SUB:
14152 mips32_op = OPC_SUB;
14153 goto do_arith;
14154 case SUBU32:
14155 mips32_op = OPC_SUBU;
14156 goto do_arith;
14157 case MUL:
9e8f441a 14158 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14159 mips32_op = OPC_MUL;
14160 do_arith:
d75c135e 14161 gen_arith(ctx, mips32_op, rd, rs, rt);
3c824109
NF
14162 break;
14163 /* Shifts */
14164 case SLLV:
14165 mips32_op = OPC_SLLV;
14166 goto do_shift;
14167 case SRLV:
14168 mips32_op = OPC_SRLV;
14169 goto do_shift;
14170 case SRAV:
14171 mips32_op = OPC_SRAV;
14172 goto do_shift;
14173 case ROTRV:
14174 mips32_op = OPC_ROTRV;
14175 do_shift:
d75c135e 14176 gen_shift(ctx, mips32_op, rd, rs, rt);
3c824109
NF
14177 break;
14178 /* Logical operations */
14179 case AND:
14180 mips32_op = OPC_AND;
14181 goto do_logic;
14182 case OR32:
14183 mips32_op = OPC_OR;
14184 goto do_logic;
14185 case NOR:
14186 mips32_op = OPC_NOR;
14187 goto do_logic;
14188 case XOR32:
14189 mips32_op = OPC_XOR;
14190 do_logic:
d75c135e 14191 gen_logic(ctx, mips32_op, rd, rs, rt);
3c824109
NF
14192 break;
14193 /* Set less than */
14194 case SLT:
14195 mips32_op = OPC_SLT;
14196 goto do_slt;
14197 case SLTU:
14198 mips32_op = OPC_SLTU;
14199 do_slt:
d75c135e 14200 gen_slt(ctx, mips32_op, rd, rs, rt);
3c824109
NF
14201 break;
14202 default:
14203 goto pool32a_invalid;
14204 }
14205 break;
14206 case 0x18:
14207 minor = (ctx->opcode >> 6) & 0xf;
14208 switch (minor) {
14209 /* Conditional moves */
e0332095
YK
14210 case MOVN: /* MUL */
14211 if (ctx->insn_flags & ISA_MIPS32R6) {
14212 /* MUL */
14213 gen_r6_muldiv(ctx, R6_OPC_MUL, rd, rs, rt);
14214 } else {
14215 /* MOVN */
14216 gen_cond_move(ctx, OPC_MOVN, rd, rs, rt);
14217 }
14218 break;
14219 case MOVZ: /* MUH */
14220 if (ctx->insn_flags & ISA_MIPS32R6) {
14221 /* MUH */
14222 gen_r6_muldiv(ctx, R6_OPC_MUH, rd, rs, rt);
14223 } else {
14224 /* MOVZ */
14225 gen_cond_move(ctx, OPC_MOVZ, rd, rs, rt);
14226 }
14227 break;
14228 case MULU:
14229 check_insn(ctx, ISA_MIPS32R6);
14230 gen_r6_muldiv(ctx, R6_OPC_MULU, rd, rs, rt);
14231 break;
14232 case MUHU:
14233 check_insn(ctx, ISA_MIPS32R6);
14234 gen_r6_muldiv(ctx, R6_OPC_MUHU, rd, rs, rt);
14235 break;
14236 case LWXS: /* DIV */
14237 if (ctx->insn_flags & ISA_MIPS32R6) {
14238 /* DIV */
14239 gen_r6_muldiv(ctx, R6_OPC_DIV, rd, rs, rt);
14240 } else {
14241 /* LWXS */
14242 gen_ldxs(ctx, rs, rt, rd);
14243 }
14244 break;
14245 case MOD:
14246 check_insn(ctx, ISA_MIPS32R6);
14247 gen_r6_muldiv(ctx, R6_OPC_MOD, rd, rs, rt);
14248 break;
14249 case R6_DIVU:
14250 check_insn(ctx, ISA_MIPS32R6);
14251 gen_r6_muldiv(ctx, R6_OPC_DIVU, rd, rs, rt);
3c824109 14252 break;
e0332095
YK
14253 case MODU:
14254 check_insn(ctx, ISA_MIPS32R6);
14255 gen_r6_muldiv(ctx, R6_OPC_MODU, rd, rs, rt);
3c824109
NF
14256 break;
14257 default:
14258 goto pool32a_invalid;
14259 }
14260 break;
14261 case INS:
14262 gen_bitops(ctx, OPC_INS, rt, rs, rr, rd);
14263 return;
e0332095
YK
14264 case LSA:
14265 check_insn(ctx, ISA_MIPS32R6);
14266 gen_lsa(ctx, OPC_LSA, rd, rs, rt,
14267 extract32(ctx->opcode, 9, 2));
14268 break;
14269 case ALIGN:
14270 check_insn(ctx, ISA_MIPS32R6);
14271 gen_align(ctx, OPC_ALIGN, rd, rs, rt,
14272 extract32(ctx->opcode, 9, 2));
14273 break;
3c824109
NF
14274 case EXT:
14275 gen_bitops(ctx, OPC_EXT, rt, rs, rr, rd);
14276 return;
14277 case POOL32AXF:
240ce26a 14278 gen_pool32axf(env, ctx, rt, rs);
3c824109 14279 break;
dbd8af98 14280 case BREAK32:
9c708c7f 14281 generate_exception_end(ctx, EXCP_BREAK);
3c824109 14282 break;
bb238210
YK
14283 case SIGRIE:
14284 check_insn(ctx, ISA_MIPS32R6);
14285 generate_exception_end(ctx, EXCP_RI);
14286 break;
3c824109
NF
14287 default:
14288 pool32a_invalid:
14289 MIPS_INVAL("pool32a");
9c708c7f 14290 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
14291 break;
14292 }
14293 break;
14294 case POOL32B:
14295 minor = (ctx->opcode >> 12) & 0xf;
14296 switch (minor) {
14297 case CACHE:
2e15497c 14298 check_cp0_enabled(ctx);
0d74a222
LA
14299 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
14300 gen_cache_operation(ctx, rt, rs, imm);
14301 }
3c824109
NF
14302 break;
14303 case LWC2:
14304 case SWC2:
14305 /* COP2: Not implemented. */
14306 generate_exception_err(ctx, EXCP_CpU, 2);
14307 break;
3c824109
NF
14308#ifdef TARGET_MIPS64
14309 case LDP:
14310 case SDP:
d9224450
MR
14311 check_insn(ctx, ISA_MIPS3);
14312 check_mips_64(ctx);
3c824109 14313#endif
146dd620 14314 /* fall through */
d9224450
MR
14315 case LWP:
14316 case SWP:
3c824109
NF
14317 gen_ldst_pair(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
14318 break;
3c824109
NF
14319#ifdef TARGET_MIPS64
14320 case LDM:
14321 case SDM:
d9224450
MR
14322 check_insn(ctx, ISA_MIPS3);
14323 check_mips_64(ctx);
3c824109 14324#endif
146dd620 14325 /* fall through */
d9224450
MR
14326 case LWM32:
14327 case SWM32:
3c824109
NF
14328 gen_ldst_multiple(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
14329 break;
14330 default:
14331 MIPS_INVAL("pool32b");
9c708c7f 14332 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
14333 break;
14334 }
14335 break;
14336 case POOL32F:
5ab5c041 14337 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
3c824109
NF
14338 minor = ctx->opcode & 0x3f;
14339 check_cp1_enabled(ctx);
14340 switch (minor) {
14341 case ALNV_PS:
9e8f441a 14342 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14343 mips32_op = OPC_ALNV_PS;
14344 goto do_madd;
14345 case MADD_S:
9e8f441a 14346 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14347 mips32_op = OPC_MADD_S;
14348 goto do_madd;
14349 case MADD_D:
9e8f441a 14350 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14351 mips32_op = OPC_MADD_D;
14352 goto do_madd;
14353 case MADD_PS:
9e8f441a 14354 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14355 mips32_op = OPC_MADD_PS;
14356 goto do_madd;
14357 case MSUB_S:
9e8f441a 14358 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14359 mips32_op = OPC_MSUB_S;
14360 goto do_madd;
14361 case MSUB_D:
9e8f441a 14362 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14363 mips32_op = OPC_MSUB_D;
14364 goto do_madd;
14365 case MSUB_PS:
9e8f441a 14366 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14367 mips32_op = OPC_MSUB_PS;
14368 goto do_madd;
14369 case NMADD_S:
9e8f441a 14370 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14371 mips32_op = OPC_NMADD_S;
14372 goto do_madd;
14373 case NMADD_D:
9e8f441a 14374 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14375 mips32_op = OPC_NMADD_D;
14376 goto do_madd;
14377 case NMADD_PS:
9e8f441a 14378 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14379 mips32_op = OPC_NMADD_PS;
14380 goto do_madd;
14381 case NMSUB_S:
9e8f441a 14382 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14383 mips32_op = OPC_NMSUB_S;
14384 goto do_madd;
14385 case NMSUB_D:
9e8f441a 14386 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14387 mips32_op = OPC_NMSUB_D;
14388 goto do_madd;
14389 case NMSUB_PS:
9e8f441a 14390 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14391 mips32_op = OPC_NMSUB_PS;
14392 do_madd:
14393 gen_flt3_arith(ctx, mips32_op, rd, rr, rs, rt);
14394 break;
14395 case CABS_COND_FMT:
9e8f441a 14396 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14397 cond = (ctx->opcode >> 6) & 0xf;
14398 cc = (ctx->opcode >> 13) & 0x7;
14399 fmt = (ctx->opcode >> 10) & 0x3;
14400 switch (fmt) {
14401 case 0x0:
14402 gen_cmpabs_s(ctx, cond, rt, rs, cc);
14403 break;
14404 case 0x1:
14405 gen_cmpabs_d(ctx, cond, rt, rs, cc);
14406 break;
14407 case 0x2:
14408 gen_cmpabs_ps(ctx, cond, rt, rs, cc);
14409 break;
14410 default:
14411 goto pool32f_invalid;
14412 }
14413 break;
14414 case C_COND_FMT:
9e8f441a 14415 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14416 cond = (ctx->opcode >> 6) & 0xf;
14417 cc = (ctx->opcode >> 13) & 0x7;
14418 fmt = (ctx->opcode >> 10) & 0x3;
14419 switch (fmt) {
14420 case 0x0:
14421 gen_cmp_s(ctx, cond, rt, rs, cc);
14422 break;
14423 case 0x1:
14424 gen_cmp_d(ctx, cond, rt, rs, cc);
14425 break;
14426 case 0x2:
14427 gen_cmp_ps(ctx, cond, rt, rs, cc);
14428 break;
14429 default:
14430 goto pool32f_invalid;
14431 }
14432 break;
2a24a7ba
YK
14433 case CMP_CONDN_S:
14434 check_insn(ctx, ISA_MIPS32R6);
14435 gen_r6_cmp_s(ctx, (ctx->opcode >> 6) & 0x1f, rt, rs, rd);
14436 break;
14437 case CMP_CONDN_D:
14438 check_insn(ctx, ISA_MIPS32R6);
14439 gen_r6_cmp_d(ctx, (ctx->opcode >> 6) & 0x1f, rt, rs, rd);
14440 break;
3c824109 14441 case POOL32FXF:
d75c135e 14442 gen_pool32fxf(ctx, rt, rs);
3c824109
NF
14443 break;
14444 case 0x00:
14445 /* PLL foo */
14446 switch ((ctx->opcode >> 6) & 0x7) {
14447 case PLL_PS:
14448 mips32_op = OPC_PLL_PS;
14449 goto do_ps;
14450 case PLU_PS:
14451 mips32_op = OPC_PLU_PS;
14452 goto do_ps;
14453 case PUL_PS:
14454 mips32_op = OPC_PUL_PS;
14455 goto do_ps;
14456 case PUU_PS:
14457 mips32_op = OPC_PUU_PS;
14458 goto do_ps;
14459 case CVT_PS_S:
9e8f441a 14460 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14461 mips32_op = OPC_CVT_PS_S;
14462 do_ps:
14463 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
14464 break;
14465 default:
14466 goto pool32f_invalid;
14467 }
14468 break;
2a24a7ba
YK
14469 case MIN_FMT:
14470 check_insn(ctx, ISA_MIPS32R6);
14471 switch ((ctx->opcode >> 9) & 0x3) {
14472 case FMT_SDPS_S:
14473 gen_farith(ctx, OPC_MIN_S, rt, rs, rd, 0);
14474 break;
14475 case FMT_SDPS_D:
14476 gen_farith(ctx, OPC_MIN_D, rt, rs, rd, 0);
14477 break;
14478 default:
14479 goto pool32f_invalid;
14480 }
14481 break;
3c824109
NF
14482 case 0x08:
14483 /* [LS][WDU]XC1 */
14484 switch ((ctx->opcode >> 6) & 0x7) {
14485 case LWXC1:
9e8f441a 14486 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14487 mips32_op = OPC_LWXC1;
14488 goto do_ldst_cp1;
14489 case SWXC1:
9e8f441a 14490 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14491 mips32_op = OPC_SWXC1;
14492 goto do_ldst_cp1;
14493 case LDXC1:
9e8f441a 14494 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14495 mips32_op = OPC_LDXC1;
14496 goto do_ldst_cp1;
14497 case SDXC1:
9e8f441a 14498 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14499 mips32_op = OPC_SDXC1;
14500 goto do_ldst_cp1;
14501 case LUXC1:
9e8f441a 14502 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14503 mips32_op = OPC_LUXC1;
14504 goto do_ldst_cp1;
14505 case SUXC1:
9e8f441a 14506 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14507 mips32_op = OPC_SUXC1;
14508 do_ldst_cp1:
14509 gen_flt3_ldst(ctx, mips32_op, rd, rd, rt, rs);
14510 break;
14511 default:
14512 goto pool32f_invalid;
14513 }
14514 break;
2a24a7ba
YK
14515 case MAX_FMT:
14516 check_insn(ctx, ISA_MIPS32R6);
14517 switch ((ctx->opcode >> 9) & 0x3) {
14518 case FMT_SDPS_S:
14519 gen_farith(ctx, OPC_MAX_S, rt, rs, rd, 0);
14520 break;
14521 case FMT_SDPS_D:
14522 gen_farith(ctx, OPC_MAX_D, rt, rs, rd, 0);
14523 break;
14524 default:
14525 goto pool32f_invalid;
14526 }
14527 break;
3c824109
NF
14528 case 0x18:
14529 /* 3D insns */
9e8f441a 14530 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14531 fmt = (ctx->opcode >> 9) & 0x3;
14532 switch ((ctx->opcode >> 6) & 0x7) {
14533 case RSQRT2_FMT:
14534 switch (fmt) {
14535 case FMT_SDPS_S:
14536 mips32_op = OPC_RSQRT2_S;
14537 goto do_3d;
14538 case FMT_SDPS_D:
14539 mips32_op = OPC_RSQRT2_D;
14540 goto do_3d;
14541 case FMT_SDPS_PS:
14542 mips32_op = OPC_RSQRT2_PS;
14543 goto do_3d;
14544 default:
14545 goto pool32f_invalid;
14546 }
14547 break;
14548 case RECIP2_FMT:
14549 switch (fmt) {
14550 case FMT_SDPS_S:
14551 mips32_op = OPC_RECIP2_S;
14552 goto do_3d;
14553 case FMT_SDPS_D:
14554 mips32_op = OPC_RECIP2_D;
14555 goto do_3d;
14556 case FMT_SDPS_PS:
14557 mips32_op = OPC_RECIP2_PS;
14558 goto do_3d;
14559 default:
14560 goto pool32f_invalid;
14561 }
14562 break;
14563 case ADDR_PS:
14564 mips32_op = OPC_ADDR_PS;
14565 goto do_3d;
14566 case MULR_PS:
14567 mips32_op = OPC_MULR_PS;
14568 do_3d:
14569 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
14570 break;
14571 default:
14572 goto pool32f_invalid;
14573 }
14574 break;
14575 case 0x20:
2a24a7ba 14576 /* MOV[FT].fmt, PREFX, RINT.fmt, CLASS.fmt*/
3c824109
NF
14577 cc = (ctx->opcode >> 13) & 0x7;
14578 fmt = (ctx->opcode >> 9) & 0x3;
14579 switch ((ctx->opcode >> 6) & 0x7) {
2a24a7ba
YK
14580 case MOVF_FMT: /* RINT_FMT */
14581 if (ctx->insn_flags & ISA_MIPS32R6) {
14582 /* RINT_FMT */
14583 switch (fmt) {
14584 case FMT_SDPS_S:
14585 gen_farith(ctx, OPC_RINT_S, 0, rt, rs, 0);
14586 break;
14587 case FMT_SDPS_D:
14588 gen_farith(ctx, OPC_RINT_D, 0, rt, rs, 0);
14589 break;
14590 default:
14591 goto pool32f_invalid;
14592 }
14593 } else {
14594 /* MOVF_FMT */
14595 switch (fmt) {
14596 case FMT_SDPS_S:
14597 gen_movcf_s(ctx, rs, rt, cc, 0);
14598 break;
14599 case FMT_SDPS_D:
14600 gen_movcf_d(ctx, rs, rt, cc, 0);
14601 break;
14602 case FMT_SDPS_PS:
14603 check_ps(ctx);
14604 gen_movcf_ps(ctx, rs, rt, cc, 0);
14605 break;
14606 default:
14607 goto pool32f_invalid;
14608 }
3c824109
NF
14609 }
14610 break;
2a24a7ba
YK
14611 case MOVT_FMT: /* CLASS_FMT */
14612 if (ctx->insn_flags & ISA_MIPS32R6) {
14613 /* CLASS_FMT */
14614 switch (fmt) {
14615 case FMT_SDPS_S:
14616 gen_farith(ctx, OPC_CLASS_S, 0, rt, rs, 0);
14617 break;
14618 case FMT_SDPS_D:
14619 gen_farith(ctx, OPC_CLASS_D, 0, rt, rs, 0);
14620 break;
14621 default:
14622 goto pool32f_invalid;
14623 }
14624 } else {
14625 /* MOVT_FMT */
14626 switch (fmt) {
14627 case FMT_SDPS_S:
14628 gen_movcf_s(ctx, rs, rt, cc, 1);
14629 break;
14630 case FMT_SDPS_D:
14631 gen_movcf_d(ctx, rs, rt, cc, 1);
14632 break;
14633 case FMT_SDPS_PS:
14634 check_ps(ctx);
14635 gen_movcf_ps(ctx, rs, rt, cc, 1);
14636 break;
14637 default:
14638 goto pool32f_invalid;
14639 }
3c824109
NF
14640 }
14641 break;
14642 case PREFX:
9e8f441a 14643 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14644 break;
14645 default:
14646 goto pool32f_invalid;
14647 }
14648 break;
14649#define FINSN_3ARG_SDPS(prfx) \
14650 switch ((ctx->opcode >> 8) & 0x3) { \
14651 case FMT_SDPS_S: \
14652 mips32_op = OPC_##prfx##_S; \
14653 goto do_fpop; \
14654 case FMT_SDPS_D: \
14655 mips32_op = OPC_##prfx##_D; \
14656 goto do_fpop; \
14657 case FMT_SDPS_PS: \
e29c9628 14658 check_ps(ctx); \
3c824109
NF
14659 mips32_op = OPC_##prfx##_PS; \
14660 goto do_fpop; \
14661 default: \
14662 goto pool32f_invalid; \
14663 }
2a24a7ba
YK
14664 case MINA_FMT:
14665 check_insn(ctx, ISA_MIPS32R6);
14666 switch ((ctx->opcode >> 9) & 0x3) {
14667 case FMT_SDPS_S:
14668 gen_farith(ctx, OPC_MINA_S, rt, rs, rd, 0);
14669 break;
14670 case FMT_SDPS_D:
14671 gen_farith(ctx, OPC_MINA_D, rt, rs, rd, 0);
14672 break;
14673 default:
14674 goto pool32f_invalid;
14675 }
14676 break;
14677 case MAXA_FMT:
14678 check_insn(ctx, ISA_MIPS32R6);
14679 switch ((ctx->opcode >> 9) & 0x3) {
14680 case FMT_SDPS_S:
14681 gen_farith(ctx, OPC_MAXA_S, rt, rs, rd, 0);
14682 break;
14683 case FMT_SDPS_D:
14684 gen_farith(ctx, OPC_MAXA_D, rt, rs, rd, 0);
14685 break;
14686 default:
14687 goto pool32f_invalid;
14688 }
14689 break;
3c824109
NF
14690 case 0x30:
14691 /* regular FP ops */
14692 switch ((ctx->opcode >> 6) & 0x3) {
14693 case ADD_FMT:
14694 FINSN_3ARG_SDPS(ADD);
14695 break;
14696 case SUB_FMT:
14697 FINSN_3ARG_SDPS(SUB);
14698 break;
14699 case MUL_FMT:
14700 FINSN_3ARG_SDPS(MUL);
14701 break;
14702 case DIV_FMT:
14703 fmt = (ctx->opcode >> 8) & 0x3;
14704 if (fmt == 1) {
14705 mips32_op = OPC_DIV_D;
14706 } else if (fmt == 0) {
14707 mips32_op = OPC_DIV_S;
14708 } else {
14709 goto pool32f_invalid;
14710 }
14711 goto do_fpop;
14712 default:
14713 goto pool32f_invalid;
14714 }
14715 break;
14716 case 0x38:
14717 /* cmovs */
2a24a7ba
YK
14718 switch ((ctx->opcode >> 6) & 0x7) {
14719 case MOVN_FMT: /* SELNEZ_FMT */
14720 if (ctx->insn_flags & ISA_MIPS32R6) {
14721 /* SELNEZ_FMT */
14722 switch ((ctx->opcode >> 9) & 0x3) {
14723 case FMT_SDPS_S:
14724 gen_sel_s(ctx, OPC_SELNEZ_S, rd, rt, rs);
14725 break;
14726 case FMT_SDPS_D:
14727 gen_sel_d(ctx, OPC_SELNEZ_D, rd, rt, rs);
14728 break;
14729 default:
14730 goto pool32f_invalid;
14731 }
14732 } else {
14733 /* MOVN_FMT */
14734 FINSN_3ARG_SDPS(MOVN);
14735 }
14736 break;
14737 case MOVN_FMT_04:
14738 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14739 FINSN_3ARG_SDPS(MOVN);
14740 break;
2a24a7ba
YK
14741 case MOVZ_FMT: /* SELEQZ_FMT */
14742 if (ctx->insn_flags & ISA_MIPS32R6) {
14743 /* SELEQZ_FMT */
14744 switch ((ctx->opcode >> 9) & 0x3) {
14745 case FMT_SDPS_S:
14746 gen_sel_s(ctx, OPC_SELEQZ_S, rd, rt, rs);
14747 break;
14748 case FMT_SDPS_D:
14749 gen_sel_d(ctx, OPC_SELEQZ_D, rd, rt, rs);
14750 break;
14751 default:
14752 goto pool32f_invalid;
14753 }
14754 } else {
14755 /* MOVZ_FMT */
14756 FINSN_3ARG_SDPS(MOVZ);
14757 }
14758 break;
14759 case MOVZ_FMT_05:
14760 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14761 FINSN_3ARG_SDPS(MOVZ);
14762 break;
2a24a7ba
YK
14763 case SEL_FMT:
14764 check_insn(ctx, ISA_MIPS32R6);
14765 switch ((ctx->opcode >> 9) & 0x3) {
14766 case FMT_SDPS_S:
14767 gen_sel_s(ctx, OPC_SEL_S, rd, rt, rs);
14768 break;
14769 case FMT_SDPS_D:
14770 gen_sel_d(ctx, OPC_SEL_D, rd, rt, rs);
14771 break;
14772 default:
14773 goto pool32f_invalid;
14774 }
14775 break;
14776 case MADDF_FMT:
14777 check_insn(ctx, ISA_MIPS32R6);
14778 switch ((ctx->opcode >> 9) & 0x3) {
14779 case FMT_SDPS_S:
14780 mips32_op = OPC_MADDF_S;
14781 goto do_fpop;
14782 case FMT_SDPS_D:
14783 mips32_op = OPC_MADDF_D;
14784 goto do_fpop;
14785 default:
14786 goto pool32f_invalid;
14787 }
14788 break;
14789 case MSUBF_FMT:
14790 check_insn(ctx, ISA_MIPS32R6);
14791 switch ((ctx->opcode >> 9) & 0x3) {
14792 case FMT_SDPS_S:
14793 mips32_op = OPC_MSUBF_S;
14794 goto do_fpop;
14795 case FMT_SDPS_D:
14796 mips32_op = OPC_MSUBF_D;
14797 goto do_fpop;
14798 default:
14799 goto pool32f_invalid;
14800 }
14801 break;
3c824109
NF
14802 default:
14803 goto pool32f_invalid;
14804 }
14805 break;
14806 do_fpop:
14807 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
14808 break;
14809 default:
14810 pool32f_invalid:
14811 MIPS_INVAL("pool32f");
9c708c7f 14812 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
14813 break;
14814 }
14815 } else {
14816 generate_exception_err(ctx, EXCP_CpU, 1);
14817 }
14818 break;
14819 case POOL32I:
14820 minor = (ctx->opcode >> 21) & 0x1f;
14821 switch (minor) {
14822 case BLTZ:
9e8f441a 14823 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
14824 gen_compute_branch(ctx, OPC_BLTZ, 4, rs, -1, imm << 1, 4);
14825 break;
3c824109 14826 case BLTZAL:
9e8f441a 14827 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
14828 gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 4);
14829 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14830 break;
3c824109 14831 case BLTZALS:
9e8f441a 14832 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
14833 gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 2);
14834 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14835 break;
3c824109 14836 case BGEZ:
9e8f441a 14837 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
14838 gen_compute_branch(ctx, OPC_BGEZ, 4, rs, -1, imm << 1, 4);
14839 break;
3c824109 14840 case BGEZAL:
9e8f441a 14841 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
14842 gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 4);
14843 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14844 break;
3c824109 14845 case BGEZALS:
9e8f441a 14846 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
14847 gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 2);
14848 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14849 break;
3c824109 14850 case BLEZ:
9e8f441a 14851 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103
YK
14852 gen_compute_branch(ctx, OPC_BLEZ, 4, rs, -1, imm << 1, 4);
14853 break;
3c824109 14854 case BGTZ:
9e8f441a 14855 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b231c103 14856 gen_compute_branch(ctx, OPC_BGTZ, 4, rs, -1, imm << 1, 4);
3c824109
NF
14857 break;
14858
14859 /* Traps */
65935f07
YK
14860 case TLTI: /* BC1EQZC */
14861 if (ctx->insn_flags & ISA_MIPS32R6) {
14862 /* BC1EQZC */
14863 check_cp1_enabled(ctx);
14864 gen_compute_branch1_r6(ctx, OPC_BC1EQZ, rs, imm << 1, 0);
14865 } else {
14866 /* TLTI */
14867 mips32_op = OPC_TLTI;
14868 goto do_trapi;
14869 }
14870 break;
14871 case TGEI: /* BC1NEZC */
14872 if (ctx->insn_flags & ISA_MIPS32R6) {
14873 /* BC1NEZC */
14874 check_cp1_enabled(ctx);
14875 gen_compute_branch1_r6(ctx, OPC_BC1NEZ, rs, imm << 1, 0);
14876 } else {
14877 /* TGEI */
14878 mips32_op = OPC_TGEI;
14879 goto do_trapi;
14880 }
14881 break;
3c824109 14882 case TLTIU:
9e8f441a 14883 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14884 mips32_op = OPC_TLTIU;
14885 goto do_trapi;
14886 case TGEIU:
9e8f441a 14887 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14888 mips32_op = OPC_TGEIU;
14889 goto do_trapi;
3b4a5489
YK
14890 case TNEI: /* SYNCI */
14891 if (ctx->insn_flags & ISA_MIPS32R6) {
14892 /* SYNCI */
14893 /* Break the TB to be able to sync copied instructions
14894 immediately */
eeb3bba8 14895 ctx->base.is_jmp = DISAS_STOP;
3b4a5489
YK
14896 } else {
14897 /* TNEI */
14898 mips32_op = OPC_TNEI;
14899 goto do_trapi;
14900 }
14901 break;
3c824109 14902 case TEQI:
9e8f441a 14903 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14904 mips32_op = OPC_TEQI;
14905 do_trapi:
14906 gen_trap(ctx, mips32_op, rs, -1, imm);
14907 break;
14908
14909 case BNEZC:
14910 case BEQZC:
9e8f441a 14911 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 14912 gen_compute_branch(ctx, minor == BNEZC ? OPC_BNE : OPC_BEQ,
b231c103 14913 4, rs, 0, imm << 1, 0);
3c824109
NF
14914 /* Compact branches don't have a delay slot, so just let
14915 the normal delay slot handling take us to the branch
14916 target. */
14917 break;
14918 case LUI:
9e8f441a 14919 check_insn_opc_removed(ctx, ISA_MIPS32R6);
5e88759a 14920 gen_logic_imm(ctx, OPC_LUI, rs, 0, imm);
3c824109
NF
14921 break;
14922 case SYNCI:
9e8f441a 14923 check_insn_opc_removed(ctx, ISA_MIPS32R6);
a83bddd6
DZ
14924 /* Break the TB to be able to sync copied instructions
14925 immediately */
eeb3bba8 14926 ctx->base.is_jmp = DISAS_STOP;
3c824109
NF
14927 break;
14928 case BC2F:
14929 case BC2T:
9e8f441a 14930 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14931 /* COP2: Not implemented. */
14932 generate_exception_err(ctx, EXCP_CpU, 2);
14933 break;
14934 case BC1F:
9e8f441a 14935 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14936 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1FANY2 : OPC_BC1F;
14937 goto do_cp1branch;
14938 case BC1T:
9e8f441a 14939 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14940 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1TANY2 : OPC_BC1T;
14941 goto do_cp1branch;
14942 case BC1ANY4F:
9e8f441a 14943 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14944 mips32_op = OPC_BC1FANY4;
14945 goto do_cp1mips3d;
14946 case BC1ANY4T:
9e8f441a 14947 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109
NF
14948 mips32_op = OPC_BC1TANY4;
14949 do_cp1mips3d:
14950 check_cop1x(ctx);
d75c135e 14951 check_insn(ctx, ASE_MIPS3D);
3c824109
NF
14952 /* Fall through */
14953 do_cp1branch:
272f458d
MR
14954 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
14955 check_cp1_enabled(ctx);
14956 gen_compute_branch1(ctx, mips32_op,
14957 (ctx->opcode >> 18) & 0x7, imm << 1);
14958 } else {
14959 generate_exception_err(ctx, EXCP_CpU, 1);
14960 }
3c824109
NF
14961 break;
14962 case BPOSGE64:
14963 case BPOSGE32:
14964 /* MIPS DSP: not implemented */
14965 /* Fall through */
14966 default:
14967 MIPS_INVAL("pool32i");
9c708c7f 14968 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
14969 break;
14970 }
14971 break;
14972 case POOL32C:
14973 minor = (ctx->opcode >> 12) & 0xf;
3b4a5489
YK
14974 offset = sextract32(ctx->opcode, 0,
14975 (ctx->insn_flags & ISA_MIPS32R6) ? 9 : 12);
3c824109
NF
14976 switch (minor) {
14977 case LWL:
9e8f441a 14978 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 14979 mips32_op = OPC_LWL;
5c13fdfd 14980 goto do_ld_lr;
3c824109 14981 case SWL:
9e8f441a 14982 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 14983 mips32_op = OPC_SWL;
5c13fdfd 14984 goto do_st_lr;
3c824109 14985 case LWR:
9e8f441a 14986 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 14987 mips32_op = OPC_LWR;
5c13fdfd 14988 goto do_ld_lr;
3c824109 14989 case SWR:
9e8f441a 14990 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 14991 mips32_op = OPC_SWR;
5c13fdfd 14992 goto do_st_lr;
3c824109
NF
14993#if defined(TARGET_MIPS64)
14994 case LDL:
d9224450
MR
14995 check_insn(ctx, ISA_MIPS3);
14996 check_mips_64(ctx);
9e8f441a 14997 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 14998 mips32_op = OPC_LDL;
5c13fdfd 14999 goto do_ld_lr;
3c824109 15000 case SDL:
d9224450
MR
15001 check_insn(ctx, ISA_MIPS3);
15002 check_mips_64(ctx);
9e8f441a 15003 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 15004 mips32_op = OPC_SDL;
5c13fdfd 15005 goto do_st_lr;
3c824109 15006 case LDR:
d9224450
MR
15007 check_insn(ctx, ISA_MIPS3);
15008 check_mips_64(ctx);
9e8f441a 15009 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 15010 mips32_op = OPC_LDR;
5c13fdfd 15011 goto do_ld_lr;
3c824109 15012 case SDR:
d9224450
MR
15013 check_insn(ctx, ISA_MIPS3);
15014 check_mips_64(ctx);
9e8f441a 15015 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 15016 mips32_op = OPC_SDR;
5c13fdfd 15017 goto do_st_lr;
3c824109 15018 case LWU:
d9224450
MR
15019 check_insn(ctx, ISA_MIPS3);
15020 check_mips_64(ctx);
3c824109 15021 mips32_op = OPC_LWU;
5c13fdfd 15022 goto do_ld_lr;
3c824109 15023 case LLD:
d9224450
MR
15024 check_insn(ctx, ISA_MIPS3);
15025 check_mips_64(ctx);
3c824109 15026 mips32_op = OPC_LLD;
5c13fdfd 15027 goto do_ld_lr;
3c824109
NF
15028#endif
15029 case LL:
15030 mips32_op = OPC_LL;
5c13fdfd
AJ
15031 goto do_ld_lr;
15032 do_ld_lr:
3b4a5489 15033 gen_ld(ctx, mips32_op, rt, rs, offset);
5c13fdfd
AJ
15034 break;
15035 do_st_lr:
8fffc646 15036 gen_st(ctx, mips32_op, rt, rs, offset);
3c824109
NF
15037 break;
15038 case SC:
3b4a5489 15039 gen_st_cond(ctx, OPC_SC, rt, rs, offset);
3c824109
NF
15040 break;
15041#if defined(TARGET_MIPS64)
15042 case SCD:
d9224450
MR
15043 check_insn(ctx, ISA_MIPS3);
15044 check_mips_64(ctx);
3b4a5489 15045 gen_st_cond(ctx, OPC_SCD, rt, rs, offset);
3c824109
NF
15046 break;
15047#endif
8fffc646
JH
15048 case LD_EVA:
15049 if (!ctx->eva) {
15050 MIPS_INVAL("pool32c ld-eva");
15051 generate_exception_end(ctx, EXCP_RI);
15052 break;
15053 }
15054 check_cp0_enabled(ctx);
15055
15056 minor2 = (ctx->opcode >> 9) & 0x7;
15057 offset = sextract32(ctx->opcode, 0, 9);
15058 switch (minor2) {
15059 case LBUE:
15060 mips32_op = OPC_LBUE;
15061 goto do_ld_lr;
15062 case LHUE:
15063 mips32_op = OPC_LHUE;
15064 goto do_ld_lr;
15065 case LWLE:
15066 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15067 mips32_op = OPC_LWLE;
15068 goto do_ld_lr;
15069 case LWRE:
15070 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15071 mips32_op = OPC_LWRE;
15072 goto do_ld_lr;
15073 case LBE:
15074 mips32_op = OPC_LBE;
15075 goto do_ld_lr;
15076 case LHE:
15077 mips32_op = OPC_LHE;
15078 goto do_ld_lr;
15079 case LLE:
15080 mips32_op = OPC_LLE;
15081 goto do_ld_lr;
15082 case LWE:
15083 mips32_op = OPC_LWE;
15084 goto do_ld_lr;
15085 };
15086 break;
15087 case ST_EVA:
15088 if (!ctx->eva) {
15089 MIPS_INVAL("pool32c st-eva");
15090 generate_exception_end(ctx, EXCP_RI);
15091 break;
15092 }
15093 check_cp0_enabled(ctx);
15094
15095 minor2 = (ctx->opcode >> 9) & 0x7;
15096 offset = sextract32(ctx->opcode, 0, 9);
15097 switch (minor2) {
15098 case SWLE:
15099 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15100 mips32_op = OPC_SWLE;
15101 goto do_st_lr;
15102 case SWRE:
15103 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15104 mips32_op = OPC_SWRE;
15105 goto do_st_lr;
15106 case PREFE:
15107 /* Treat as no-op */
15108 if ((ctx->insn_flags & ISA_MIPS32R6) && (rt >= 24)) {
15109 /* hint codes 24-31 are reserved and signal RI */
15110 generate_exception(ctx, EXCP_RI);
15111 }
15112 break;
15113 case CACHEE:
15114 /* Treat as no-op */
15115 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
15116 gen_cache_operation(ctx, rt, rs, offset);
15117 }
15118 break;
15119 case SBE:
15120 mips32_op = OPC_SBE;
15121 goto do_st_lr;
15122 case SHE:
15123 mips32_op = OPC_SHE;
15124 goto do_st_lr;
15125 case SCE:
15126 gen_st_cond(ctx, OPC_SCE, rt, rs, offset);
15127 break;
15128 case SWE:
15129 mips32_op = OPC_SWE;
15130 goto do_st_lr;
15131 };
15132 break;
3c824109
NF
15133 case PREF:
15134 /* Treat as no-op */
3b4a5489
YK
15135 if ((ctx->insn_flags & ISA_MIPS32R6) && (rt >= 24)) {
15136 /* hint codes 24-31 are reserved and signal RI */
15137 generate_exception(ctx, EXCP_RI);
15138 }
3c824109
NF
15139 break;
15140 default:
15141 MIPS_INVAL("pool32c");
9c708c7f 15142 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
15143 break;
15144 }
15145 break;
ab39ee45
YK
15146 case ADDI32: /* AUI, LUI */
15147 if (ctx->insn_flags & ISA_MIPS32R6) {
15148 /* AUI, LUI */
15149 gen_logic_imm(ctx, OPC_LUI, rt, rs, imm);
15150 } else {
15151 /* ADDI32 */
15152 mips32_op = OPC_ADDI;
15153 goto do_addi;
15154 }
15155 break;
3c824109
NF
15156 case ADDIU32:
15157 mips32_op = OPC_ADDIU;
15158 do_addi:
d75c135e 15159 gen_arith_imm(ctx, mips32_op, rt, rs, imm);
3c824109
NF
15160 break;
15161
15162 /* Logical operations */
15163 case ORI32:
15164 mips32_op = OPC_ORI;
15165 goto do_logici;
15166 case XORI32:
15167 mips32_op = OPC_XORI;
15168 goto do_logici;
15169 case ANDI32:
15170 mips32_op = OPC_ANDI;
15171 do_logici:
d75c135e 15172 gen_logic_imm(ctx, mips32_op, rt, rs, imm);
3c824109
NF
15173 break;
15174
15175 /* Set less than immediate */
15176 case SLTI32:
15177 mips32_op = OPC_SLTI;
15178 goto do_slti;
15179 case SLTIU32:
15180 mips32_op = OPC_SLTIU;
15181 do_slti:
d75c135e 15182 gen_slt_imm(ctx, mips32_op, rt, rs, imm);
3c824109
NF
15183 break;
15184 case JALX32:
9e8f441a 15185 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 15186 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
b231c103
YK
15187 gen_compute_branch(ctx, OPC_JALX, 4, rt, rs, offset, 4);
15188 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
3c824109 15189 break;
65935f07
YK
15190 case JALS32: /* BOVC, BEQC, BEQZALC */
15191 if (ctx->insn_flags & ISA_MIPS32R6) {
15192 if (rs >= rt) {
15193 /* BOVC */
15194 mips32_op = OPC_BOVC;
15195 } else if (rs < rt && rs == 0) {
15196 /* BEQZALC */
15197 mips32_op = OPC_BEQZALC;
15198 } else {
15199 /* BEQC */
15200 mips32_op = OPC_BEQC;
15201 }
15202 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
15203 } else {
15204 /* JALS32 */
15205 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 1;
15206 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs, offset, 2);
15207 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
15208 }
3c824109 15209 break;
65935f07
YK
15210 case BEQ32: /* BC */
15211 if (ctx->insn_flags & ISA_MIPS32R6) {
15212 /* BC */
15213 gen_compute_compact_branch(ctx, OPC_BC, 0, 0,
15214 sextract32(ctx->opcode << 1, 0, 27));
15215 } else {
15216 /* BEQ32 */
15217 gen_compute_branch(ctx, OPC_BEQ, 4, rt, rs, imm << 1, 4);
15218 }
3c824109 15219 break;
65935f07
YK
15220 case BNE32: /* BALC */
15221 if (ctx->insn_flags & ISA_MIPS32R6) {
15222 /* BALC */
15223 gen_compute_compact_branch(ctx, OPC_BALC, 0, 0,
15224 sextract32(ctx->opcode << 1, 0, 27));
15225 } else {
15226 /* BNE32 */
15227 gen_compute_branch(ctx, OPC_BNE, 4, rt, rs, imm << 1, 4);
15228 }
3c824109 15229 break;
65935f07
YK
15230 case J32: /* BGTZC, BLTZC, BLTC */
15231 if (ctx->insn_flags & ISA_MIPS32R6) {
15232 if (rs == 0 && rt != 0) {
15233 /* BGTZC */
15234 mips32_op = OPC_BGTZC;
15235 } else if (rs != 0 && rt != 0 && rs == rt) {
15236 /* BLTZC */
15237 mips32_op = OPC_BLTZC;
15238 } else {
15239 /* BLTC */
15240 mips32_op = OPC_BLTC;
15241 }
15242 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
15243 } else {
15244 /* J32 */
15245 gen_compute_branch(ctx, OPC_J, 4, rt, rs,
15246 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
15247 }
3c824109 15248 break;
65935f07
YK
15249 case JAL32: /* BLEZC, BGEZC, BGEC */
15250 if (ctx->insn_flags & ISA_MIPS32R6) {
15251 if (rs == 0 && rt != 0) {
15252 /* BLEZC */
15253 mips32_op = OPC_BLEZC;
15254 } else if (rs != 0 && rt != 0 && rs == rt) {
15255 /* BGEZC */
15256 mips32_op = OPC_BGEZC;
15257 } else {
15258 /* BGEC */
15259 mips32_op = OPC_BGEC;
15260 }
15261 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
15262 } else {
15263 /* JAL32 */
15264 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs,
15265 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
15266 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
15267 }
3c824109
NF
15268 break;
15269 /* Floating point (COP1) */
15270 case LWC132:
15271 mips32_op = OPC_LWC1;
15272 goto do_cop1;
15273 case LDC132:
15274 mips32_op = OPC_LDC1;
15275 goto do_cop1;
15276 case SWC132:
15277 mips32_op = OPC_SWC1;
15278 goto do_cop1;
15279 case SDC132:
15280 mips32_op = OPC_SDC1;
15281 do_cop1:
5ab5c041 15282 gen_cop1_ldst(ctx, mips32_op, rt, rs, imm);
3c824109 15283 break;
ab39ee45
YK
15284 case ADDIUPC: /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
15285 if (ctx->insn_flags & ISA_MIPS32R6) {
15286 /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
15287 switch ((ctx->opcode >> 16) & 0x1f) {
c38a1d52
AR
15288 case ADDIUPC_00:
15289 case ADDIUPC_01:
15290 case ADDIUPC_02:
15291 case ADDIUPC_03:
15292 case ADDIUPC_04:
15293 case ADDIUPC_05:
15294 case ADDIUPC_06:
15295 case ADDIUPC_07:
eeb3bba8 15296 gen_pcrel(ctx, OPC_ADDIUPC, ctx->base.pc_next & ~0x3, rt);
ab39ee45
YK
15297 break;
15298 case AUIPC:
eeb3bba8 15299 gen_pcrel(ctx, OPC_AUIPC, ctx->base.pc_next, rt);
ab39ee45
YK
15300 break;
15301 case ALUIPC:
eeb3bba8 15302 gen_pcrel(ctx, OPC_ALUIPC, ctx->base.pc_next, rt);
ab39ee45 15303 break;
c38a1d52
AR
15304 case LWPC_08:
15305 case LWPC_09:
15306 case LWPC_0A:
15307 case LWPC_0B:
15308 case LWPC_0C:
15309 case LWPC_0D:
15310 case LWPC_0E:
15311 case LWPC_0F:
eeb3bba8 15312 gen_pcrel(ctx, R6_OPC_LWPC, ctx->base.pc_next & ~0x3, rt);
ab39ee45
YK
15313 break;
15314 default:
15315 generate_exception(ctx, EXCP_RI);
15316 break;
15317 }
15318 } else {
15319 /* ADDIUPC */
3c824109 15320 int reg = mmreg(ZIMM(ctx->opcode, 23, 3));
e1555d7d 15321 offset = SIMM(ctx->opcode, 0, 23) << 2;
3c824109
NF
15322
15323 gen_addiupc(ctx, reg, offset, 0, 0);
15324 }
15325 break;
65935f07
YK
15326 case BNVC: /* BNEC, BNEZALC */
15327 check_insn(ctx, ISA_MIPS32R6);
15328 if (rs >= rt) {
15329 /* BNVC */
15330 mips32_op = OPC_BNVC;
15331 } else if (rs < rt && rs == 0) {
15332 /* BNEZALC */
15333 mips32_op = OPC_BNEZALC;
15334 } else {
15335 /* BNEC */
15336 mips32_op = OPC_BNEC;
15337 }
15338 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
15339 break;
15340 case R6_BNEZC: /* JIALC */
15341 check_insn(ctx, ISA_MIPS32R6);
15342 if (rt != 0) {
15343 /* BNEZC */
15344 gen_compute_compact_branch(ctx, OPC_BNEZC, rt, 0,
15345 sextract32(ctx->opcode << 1, 0, 22));
15346 } else {
15347 /* JIALC */
15348 gen_compute_compact_branch(ctx, OPC_JIALC, 0, rs, imm);
15349 }
15350 break;
15351 case R6_BEQZC: /* JIC */
15352 check_insn(ctx, ISA_MIPS32R6);
15353 if (rt != 0) {
15354 /* BEQZC */
15355 gen_compute_compact_branch(ctx, OPC_BEQZC, rt, 0,
15356 sextract32(ctx->opcode << 1, 0, 22));
15357 } else {
15358 /* JIC */
15359 gen_compute_compact_branch(ctx, OPC_JIC, 0, rs, imm);
15360 }
15361 break;
15362 case BLEZALC: /* BGEZALC, BGEUC */
15363 check_insn(ctx, ISA_MIPS32R6);
15364 if (rs == 0 && rt != 0) {
15365 /* BLEZALC */
15366 mips32_op = OPC_BLEZALC;
15367 } else if (rs != 0 && rt != 0 && rs == rt) {
15368 /* BGEZALC */
15369 mips32_op = OPC_BGEZALC;
15370 } else {
15371 /* BGEUC */
15372 mips32_op = OPC_BGEUC;
15373 }
15374 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
15375 break;
15376 case BGTZALC: /* BLTZALC, BLTUC */
15377 check_insn(ctx, ISA_MIPS32R6);
15378 if (rs == 0 && rt != 0) {
15379 /* BGTZALC */
15380 mips32_op = OPC_BGTZALC;
15381 } else if (rs != 0 && rt != 0 && rs == rt) {
15382 /* BLTZALC */
15383 mips32_op = OPC_BLTZALC;
15384 } else {
15385 /* BLTUC */
15386 mips32_op = OPC_BLTUC;
15387 }
15388 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
15389 break;
3c824109
NF
15390 /* Loads and stores */
15391 case LB32:
15392 mips32_op = OPC_LB;
5c13fdfd 15393 goto do_ld;
3c824109
NF
15394 case LBU32:
15395 mips32_op = OPC_LBU;
5c13fdfd 15396 goto do_ld;
3c824109
NF
15397 case LH32:
15398 mips32_op = OPC_LH;
5c13fdfd 15399 goto do_ld;
3c824109
NF
15400 case LHU32:
15401 mips32_op = OPC_LHU;
5c13fdfd 15402 goto do_ld;
3c824109
NF
15403 case LW32:
15404 mips32_op = OPC_LW;
5c13fdfd 15405 goto do_ld;
3c824109
NF
15406#ifdef TARGET_MIPS64
15407 case LD32:
d9224450
MR
15408 check_insn(ctx, ISA_MIPS3);
15409 check_mips_64(ctx);
3c824109 15410 mips32_op = OPC_LD;
5c13fdfd 15411 goto do_ld;
3c824109 15412 case SD32:
d9224450
MR
15413 check_insn(ctx, ISA_MIPS3);
15414 check_mips_64(ctx);
3c824109 15415 mips32_op = OPC_SD;
5c13fdfd 15416 goto do_st;
3c824109
NF
15417#endif
15418 case SB32:
15419 mips32_op = OPC_SB;
5c13fdfd 15420 goto do_st;
3c824109
NF
15421 case SH32:
15422 mips32_op = OPC_SH;
5c13fdfd 15423 goto do_st;
3c824109
NF
15424 case SW32:
15425 mips32_op = OPC_SW;
5c13fdfd
AJ
15426 goto do_st;
15427 do_ld:
d75c135e 15428 gen_ld(ctx, mips32_op, rt, rs, imm);
5c13fdfd
AJ
15429 break;
15430 do_st:
15431 gen_st(ctx, mips32_op, rt, rs, imm);
3c824109
NF
15432 break;
15433 default:
9c708c7f 15434 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
15435 break;
15436 }
15437}
15438
240ce26a 15439static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx)
3c824109
NF
15440{
15441 uint32_t op;
15442
15443 /* make sure instructions are on a halfword boundary */
eeb3bba8
EC
15444 if (ctx->base.pc_next & 0x1) {
15445 env->CP0_BadVAddr = ctx->base.pc_next;
9c708c7f 15446 generate_exception_end(ctx, EXCP_AdEL);
3c824109
NF
15447 return 2;
15448 }
15449
15450 op = (ctx->opcode >> 10) & 0x3f;
15451 /* Enforce properly-sized instructions in a delay slot */
b231c103
YK
15452 if (ctx->hflags & MIPS_HFLAG_BDS_STRICT) {
15453 switch (op & 0x7) { /* MSB-3..MSB-5 */
15454 case 0:
15455 /* POOL32A, POOL32B, POOL32I, POOL32C */
15456 case 4:
15457 /* ADDI32, ADDIU32, ORI32, XORI32, SLTI32, SLTIU32, ANDI32, JALX32 */
15458 case 5:
15459 /* LBU32, LHU32, POOL32F, JALS32, BEQ32, BNE32, J32, JAL32 */
15460 case 6:
15461 /* SB32, SH32, ADDIUPC, SWC132, SDC132, SW32 */
15462 case 7:
15463 /* LB32, LH32, LWC132, LDC132, LW32 */
15464 if (ctx->hflags & MIPS_HFLAG_BDS16) {
9c708c7f 15465 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
15466 return 2;
15467 }
15468 break;
b231c103
YK
15469 case 1:
15470 /* POOL16A, POOL16B, POOL16C, LWGP16, POOL16F */
15471 case 2:
15472 /* LBU16, LHU16, LWSP16, LW16, SB16, SH16, SWSP16, SW16 */
15473 case 3:
15474 /* MOVE16, ANDI16, POOL16D, POOL16E, BEQZ16, BNEZ16, B16, LI16 */
15475 if (ctx->hflags & MIPS_HFLAG_BDS32) {
9c708c7f 15476 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
15477 return 2;
15478 }
15479 break;
3c824109
NF
15480 }
15481 }
b231c103 15482
3c824109
NF
15483 switch (op) {
15484 case POOL16A:
15485 {
15486 int rd = mmreg(uMIPS_RD(ctx->opcode));
15487 int rs1 = mmreg(uMIPS_RS1(ctx->opcode));
15488 int rs2 = mmreg(uMIPS_RS2(ctx->opcode));
15489 uint32_t opc = 0;
15490
15491 switch (ctx->opcode & 0x1) {
15492 case ADDU16:
15493 opc = OPC_ADDU;
15494 break;
15495 case SUBU16:
15496 opc = OPC_SUBU;
15497 break;
15498 }
ed7ce6c0
YK
15499 if (ctx->insn_flags & ISA_MIPS32R6) {
15500 /* In the Release 6 the register number location in
15501 * the instruction encoding has changed.
15502 */
15503 gen_arith(ctx, opc, rs1, rd, rs2);
15504 } else {
15505 gen_arith(ctx, opc, rd, rs1, rs2);
15506 }
3c824109
NF
15507 }
15508 break;
15509 case POOL16B:
15510 {
15511 int rd = mmreg(uMIPS_RD(ctx->opcode));
15512 int rs = mmreg(uMIPS_RS(ctx->opcode));
15513 int amount = (ctx->opcode >> 1) & 0x7;
15514 uint32_t opc = 0;
15515 amount = amount == 0 ? 8 : amount;
15516
15517 switch (ctx->opcode & 0x1) {
15518 case SLL16:
15519 opc = OPC_SLL;
15520 break;
15521 case SRL16:
15522 opc = OPC_SRL;
15523 break;
15524 }
15525
d75c135e 15526 gen_shift_imm(ctx, opc, rd, rs, amount);
3c824109
NF
15527 }
15528 break;
15529 case POOL16C:
ed7ce6c0
YK
15530 if (ctx->insn_flags & ISA_MIPS32R6) {
15531 gen_pool16c_r6_insn(ctx);
15532 } else {
15533 gen_pool16c_insn(ctx);
15534 }
3c824109
NF
15535 break;
15536 case LWGP16:
15537 {
15538 int rd = mmreg(uMIPS_RD(ctx->opcode));
15539 int rb = 28; /* GP */
15540 int16_t offset = SIMM(ctx->opcode, 0, 7) << 2;
15541
d75c135e 15542 gen_ld(ctx, OPC_LW, rd, rb, offset);
3c824109
NF
15543 }
15544 break;
15545 case POOL16F:
9e8f441a 15546 check_insn_opc_removed(ctx, ISA_MIPS32R6);
3c824109 15547 if (ctx->opcode & 1) {
9c708c7f 15548 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
15549 } else {
15550 /* MOVEP */
15551 int enc_dest = uMIPS_RD(ctx->opcode);
15552 int enc_rt = uMIPS_RS2(ctx->opcode);
15553 int enc_rs = uMIPS_RS1(ctx->opcode);
ed7ce6c0 15554 gen_movep(ctx, enc_dest, enc_rt, enc_rs);
3c824109
NF
15555 }
15556 break;
15557 case LBU16:
15558 {
15559 int rd = mmreg(uMIPS_RD(ctx->opcode));
15560 int rb = mmreg(uMIPS_RS(ctx->opcode));
15561 int16_t offset = ZIMM(ctx->opcode, 0, 4);
15562 offset = (offset == 0xf ? -1 : offset);
15563
d75c135e 15564 gen_ld(ctx, OPC_LBU, rd, rb, offset);
3c824109
NF
15565 }
15566 break;
15567 case LHU16:
15568 {
15569 int rd = mmreg(uMIPS_RD(ctx->opcode));
15570 int rb = mmreg(uMIPS_RS(ctx->opcode));
15571 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
15572
d75c135e 15573 gen_ld(ctx, OPC_LHU, rd, rb, offset);
3c824109
NF
15574 }
15575 break;
15576 case LWSP16:
15577 {
15578 int rd = (ctx->opcode >> 5) & 0x1f;
15579 int rb = 29; /* SP */
15580 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
15581
d75c135e 15582 gen_ld(ctx, OPC_LW, rd, rb, offset);
3c824109
NF
15583 }
15584 break;
15585 case LW16:
15586 {
15587 int rd = mmreg(uMIPS_RD(ctx->opcode));
15588 int rb = mmreg(uMIPS_RS(ctx->opcode));
15589 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
15590
d75c135e 15591 gen_ld(ctx, OPC_LW, rd, rb, offset);
3c824109
NF
15592 }
15593 break;
15594 case SB16:
15595 {
15596 int rd = mmreg2(uMIPS_RD(ctx->opcode));
15597 int rb = mmreg(uMIPS_RS(ctx->opcode));
15598 int16_t offset = ZIMM(ctx->opcode, 0, 4);
15599
5c13fdfd 15600 gen_st(ctx, OPC_SB, rd, rb, offset);
3c824109
NF
15601 }
15602 break;
15603 case SH16:
15604 {
15605 int rd = mmreg2(uMIPS_RD(ctx->opcode));
15606 int rb = mmreg(uMIPS_RS(ctx->opcode));
15607 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
15608
5c13fdfd 15609 gen_st(ctx, OPC_SH, rd, rb, offset);
3c824109
NF
15610 }
15611 break;
15612 case SWSP16:
15613 {
15614 int rd = (ctx->opcode >> 5) & 0x1f;
15615 int rb = 29; /* SP */
15616 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
15617
5c13fdfd 15618 gen_st(ctx, OPC_SW, rd, rb, offset);
3c824109
NF
15619 }
15620 break;
15621 case SW16:
15622 {
15623 int rd = mmreg2(uMIPS_RD(ctx->opcode));
15624 int rb = mmreg(uMIPS_RS(ctx->opcode));
15625 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
15626
5c13fdfd 15627 gen_st(ctx, OPC_SW, rd, rb, offset);
3c824109
NF
15628 }
15629 break;
15630 case MOVE16:
15631 {
15632 int rd = uMIPS_RD5(ctx->opcode);
15633 int rs = uMIPS_RS5(ctx->opcode);
15634
7215d7e7 15635 gen_arith(ctx, OPC_ADDU, rd, rs, 0);
3c824109
NF
15636 }
15637 break;
15638 case ANDI16:
d75c135e 15639 gen_andi16(ctx);
3c824109
NF
15640 break;
15641 case POOL16D:
15642 switch (ctx->opcode & 0x1) {
15643 case ADDIUS5:
d75c135e 15644 gen_addius5(ctx);
3c824109
NF
15645 break;
15646 case ADDIUSP:
d75c135e 15647 gen_addiusp(ctx);
3c824109
NF
15648 break;
15649 }
15650 break;
15651 case POOL16E:
15652 switch (ctx->opcode & 0x1) {
15653 case ADDIUR2:
d75c135e 15654 gen_addiur2(ctx);
3c824109
NF
15655 break;
15656 case ADDIUR1SP:
d75c135e 15657 gen_addiur1sp(ctx);
3c824109
NF
15658 break;
15659 }
15660 break;
65935f07 15661 case B16: /* BC16 */
3c824109 15662 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0,
65935f07
YK
15663 sextract32(ctx->opcode, 0, 10) << 1,
15664 (ctx->insn_flags & ISA_MIPS32R6) ? 0 : 4);
3c824109 15665 break;
65935f07
YK
15666 case BNEZ16: /* BNEZC16 */
15667 case BEQZ16: /* BEQZC16 */
3c824109
NF
15668 gen_compute_branch(ctx, op == BNEZ16 ? OPC_BNE : OPC_BEQ, 2,
15669 mmreg(uMIPS_RD(ctx->opcode)),
65935f07
YK
15670 0, sextract32(ctx->opcode, 0, 7) << 1,
15671 (ctx->insn_flags & ISA_MIPS32R6) ? 0 : 4);
15672
3c824109
NF
15673 break;
15674 case LI16:
15675 {
15676 int reg = mmreg(uMIPS_RD(ctx->opcode));
15677 int imm = ZIMM(ctx->opcode, 0, 7);
15678
15679 imm = (imm == 0x7f ? -1 : imm);
15680 tcg_gen_movi_tl(cpu_gpr[reg], imm);
15681 }
15682 break;
3c824109 15683 case RES_29:
3c824109 15684 case RES_31:
3c824109 15685 case RES_39:
9c708c7f 15686 generate_exception_end(ctx, EXCP_RI);
3c824109
NF
15687 break;
15688 default:
f60eeb0c 15689 decode_micromips32_opc(env, ctx);
3c824109
NF
15690 return 4;
15691 }
15692
15693 return 2;
15694}
15695
15696/* SmartMIPS extension to MIPS32 */
15697
15698#if defined(TARGET_MIPS64)
15699
15700/* MDMX extension to MIPS64 */
15701
15702#endif
15703
9b1a1d68 15704/* MIPSDSP functions. */
d75c135e 15705static void gen_mipsdsp_ld(DisasContext *ctx, uint32_t opc,
9b1a1d68
JL
15706 int rd, int base, int offset)
15707{
9b1a1d68
JL
15708 TCGv t0;
15709
9b1a1d68
JL
15710 check_dsp(ctx);
15711 t0 = tcg_temp_new();
15712
15713 if (base == 0) {
15714 gen_load_gpr(t0, offset);
15715 } else if (offset == 0) {
15716 gen_load_gpr(t0, base);
15717 } else {
15718 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[offset]);
15719 }
15720
9b1a1d68
JL
15721 switch (opc) {
15722 case OPC_LBUX:
5f68f5ae 15723 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB);
9b1a1d68 15724 gen_store_gpr(t0, rd);
9b1a1d68
JL
15725 break;
15726 case OPC_LHX:
5f68f5ae 15727 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW);
9b1a1d68 15728 gen_store_gpr(t0, rd);
9b1a1d68
JL
15729 break;
15730 case OPC_LWX:
5f68f5ae 15731 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
9b1a1d68 15732 gen_store_gpr(t0, rd);
9b1a1d68
JL
15733 break;
15734#if defined(TARGET_MIPS64)
15735 case OPC_LDX:
5f68f5ae 15736 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
9b1a1d68 15737 gen_store_gpr(t0, rd);
9b1a1d68
JL
15738 break;
15739#endif
15740 }
9b1a1d68
JL
15741 tcg_temp_free(t0);
15742}
15743
461c08df
JL
15744static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
15745 int ret, int v1, int v2)
15746{
461c08df
JL
15747 TCGv v1_t;
15748 TCGv v2_t;
15749
15750 if (ret == 0) {
15751 /* Treat as NOP. */
461c08df
JL
15752 return;
15753 }
15754
15755 v1_t = tcg_temp_new();
15756 v2_t = tcg_temp_new();
15757
15758 gen_load_gpr(v1_t, v1);
15759 gen_load_gpr(v2_t, v2);
15760
15761 switch (op1) {
15762 /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
15763 case OPC_MULT_G_2E:
15764 check_dspr2(ctx);
15765 switch (op2) {
15766 case OPC_ADDUH_QB:
15767 gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t);
15768 break;
15769 case OPC_ADDUH_R_QB:
15770 gen_helper_adduh_r_qb(cpu_gpr[ret], v1_t, v2_t);
15771 break;
15772 case OPC_ADDQH_PH:
15773 gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t);
15774 break;
15775 case OPC_ADDQH_R_PH:
15776 gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
15777 break;
15778 case OPC_ADDQH_W:
15779 gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t);
15780 break;
15781 case OPC_ADDQH_R_W:
15782 gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t);
15783 break;
15784 case OPC_SUBUH_QB:
15785 gen_helper_subuh_qb(cpu_gpr[ret], v1_t, v2_t);
15786 break;
15787 case OPC_SUBUH_R_QB:
15788 gen_helper_subuh_r_qb(cpu_gpr[ret], v1_t, v2_t);
15789 break;
15790 case OPC_SUBQH_PH:
15791 gen_helper_subqh_ph(cpu_gpr[ret], v1_t, v2_t);
15792 break;
15793 case OPC_SUBQH_R_PH:
15794 gen_helper_subqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
15795 break;
15796 case OPC_SUBQH_W:
15797 gen_helper_subqh_w(cpu_gpr[ret], v1_t, v2_t);
15798 break;
15799 case OPC_SUBQH_R_W:
15800 gen_helper_subqh_r_w(cpu_gpr[ret], v1_t, v2_t);
15801 break;
15802 }
15803 break;
15804 case OPC_ABSQ_S_PH_DSP:
15805 switch (op2) {
15806 case OPC_ABSQ_S_QB:
15807 check_dspr2(ctx);
15808 gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, cpu_env);
15809 break;
15810 case OPC_ABSQ_S_PH:
15811 check_dsp(ctx);
15812 gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, cpu_env);
15813 break;
15814 case OPC_ABSQ_S_W:
15815 check_dsp(ctx);
15816 gen_helper_absq_s_w(cpu_gpr[ret], v2_t, cpu_env);
15817 break;
15818 case OPC_PRECEQ_W_PHL:
15819 check_dsp(ctx);
15820 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000);
15821 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
15822 break;
15823 case OPC_PRECEQ_W_PHR:
15824 check_dsp(ctx);
15825 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF);
15826 tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16);
15827 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
15828 break;
15829 case OPC_PRECEQU_PH_QBL:
15830 check_dsp(ctx);
15831 gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t);
15832 break;
15833 case OPC_PRECEQU_PH_QBR:
15834 check_dsp(ctx);
15835 gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t);
15836 break;
15837 case OPC_PRECEQU_PH_QBLA:
15838 check_dsp(ctx);
15839 gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t);
15840 break;
15841 case OPC_PRECEQU_PH_QBRA:
15842 check_dsp(ctx);
15843 gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t);
15844 break;
15845 case OPC_PRECEU_PH_QBL:
15846 check_dsp(ctx);
15847 gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t);
15848 break;
15849 case OPC_PRECEU_PH_QBR:
15850 check_dsp(ctx);
15851 gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t);
15852 break;
15853 case OPC_PRECEU_PH_QBLA:
15854 check_dsp(ctx);
15855 gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t);
15856 break;
15857 case OPC_PRECEU_PH_QBRA:
15858 check_dsp(ctx);
15859 gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t);
15860 break;
15861 }
15862 break;
15863 case OPC_ADDU_QB_DSP:
15864 switch (op2) {
15865 case OPC_ADDQ_PH:
15866 check_dsp(ctx);
15867 gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15868 break;
15869 case OPC_ADDQ_S_PH:
15870 check_dsp(ctx);
15871 gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15872 break;
15873 case OPC_ADDQ_S_W:
15874 check_dsp(ctx);
15875 gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15876 break;
15877 case OPC_ADDU_QB:
15878 check_dsp(ctx);
15879 gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15880 break;
15881 case OPC_ADDU_S_QB:
15882 check_dsp(ctx);
15883 gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15884 break;
15885 case OPC_ADDU_PH:
15886 check_dspr2(ctx);
15887 gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15888 break;
15889 case OPC_ADDU_S_PH:
15890 check_dspr2(ctx);
15891 gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15892 break;
15893 case OPC_SUBQ_PH:
15894 check_dsp(ctx);
15895 gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15896 break;
15897 case OPC_SUBQ_S_PH:
15898 check_dsp(ctx);
15899 gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15900 break;
15901 case OPC_SUBQ_S_W:
15902 check_dsp(ctx);
15903 gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15904 break;
15905 case OPC_SUBU_QB:
15906 check_dsp(ctx);
15907 gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15908 break;
15909 case OPC_SUBU_S_QB:
15910 check_dsp(ctx);
15911 gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15912 break;
15913 case OPC_SUBU_PH:
15914 check_dspr2(ctx);
15915 gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15916 break;
15917 case OPC_SUBU_S_PH:
15918 check_dspr2(ctx);
15919 gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15920 break;
15921 case OPC_ADDSC:
15922 check_dsp(ctx);
15923 gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15924 break;
15925 case OPC_ADDWC:
15926 check_dsp(ctx);
15927 gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15928 break;
15929 case OPC_MODSUB:
15930 check_dsp(ctx);
15931 gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t);
15932 break;
15933 case OPC_RADDU_W_QB:
15934 check_dsp(ctx);
15935 gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t);
15936 break;
15937 }
15938 break;
15939 case OPC_CMPU_EQ_QB_DSP:
15940 switch (op2) {
15941 case OPC_PRECR_QB_PH:
15942 check_dspr2(ctx);
15943 gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t);
15944 break;
15945 case OPC_PRECRQ_QB_PH:
15946 check_dsp(ctx);
15947 gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t);
15948 break;
15949 case OPC_PRECR_SRA_PH_W:
15950 check_dspr2(ctx);
15951 {
15952 TCGv_i32 sa_t = tcg_const_i32(v2);
15953 gen_helper_precr_sra_ph_w(cpu_gpr[ret], sa_t, v1_t,
15954 cpu_gpr[ret]);
15955 tcg_temp_free_i32(sa_t);
15956 break;
15957 }
15958 case OPC_PRECR_SRA_R_PH_W:
15959 check_dspr2(ctx);
15960 {
15961 TCGv_i32 sa_t = tcg_const_i32(v2);
15962 gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t,
15963 cpu_gpr[ret]);
15964 tcg_temp_free_i32(sa_t);
15965 break;
15966 }
15967 case OPC_PRECRQ_PH_W:
15968 check_dsp(ctx);
15969 gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t);
15970 break;
15971 case OPC_PRECRQ_RS_PH_W:
15972 check_dsp(ctx);
15973 gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15974 break;
15975 case OPC_PRECRQU_S_QB_PH:
15976 check_dsp(ctx);
15977 gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15978 break;
15979 }
15980 break;
15981#ifdef TARGET_MIPS64
15982 case OPC_ABSQ_S_QH_DSP:
15983 switch (op2) {
15984 case OPC_PRECEQ_L_PWL:
15985 check_dsp(ctx);
15986 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull);
15987 break;
15988 case OPC_PRECEQ_L_PWR:
15989 check_dsp(ctx);
15990 tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32);
15991 break;
15992 case OPC_PRECEQ_PW_QHL:
15993 check_dsp(ctx);
15994 gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t);
15995 break;
15996 case OPC_PRECEQ_PW_QHR:
15997 check_dsp(ctx);
15998 gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t);
15999 break;
16000 case OPC_PRECEQ_PW_QHLA:
16001 check_dsp(ctx);
16002 gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t);
16003 break;
16004 case OPC_PRECEQ_PW_QHRA:
16005 check_dsp(ctx);
16006 gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t);
16007 break;
16008 case OPC_PRECEQU_QH_OBL:
16009 check_dsp(ctx);
16010 gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t);
16011 break;
16012 case OPC_PRECEQU_QH_OBR:
16013 check_dsp(ctx);
16014 gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t);
16015 break;
16016 case OPC_PRECEQU_QH_OBLA:
16017 check_dsp(ctx);
16018 gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t);
16019 break;
16020 case OPC_PRECEQU_QH_OBRA:
16021 check_dsp(ctx);
16022 gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t);
16023 break;
16024 case OPC_PRECEU_QH_OBL:
16025 check_dsp(ctx);
16026 gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t);
16027 break;
16028 case OPC_PRECEU_QH_OBR:
16029 check_dsp(ctx);
16030 gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t);
16031 break;
16032 case OPC_PRECEU_QH_OBLA:
16033 check_dsp(ctx);
16034 gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t);
16035 break;
16036 case OPC_PRECEU_QH_OBRA:
16037 check_dsp(ctx);
16038 gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t);
16039 break;
16040 case OPC_ABSQ_S_OB:
16041 check_dspr2(ctx);
16042 gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, cpu_env);
16043 break;
16044 case OPC_ABSQ_S_PW:
16045 check_dsp(ctx);
16046 gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, cpu_env);
16047 break;
16048 case OPC_ABSQ_S_QH:
16049 check_dsp(ctx);
16050 gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, cpu_env);
16051 break;
16052 }
16053 break;
16054 case OPC_ADDU_OB_DSP:
16055 switch (op2) {
16056 case OPC_RADDU_L_OB:
16057 check_dsp(ctx);
16058 gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t);
16059 break;
16060 case OPC_SUBQ_PW:
16061 check_dsp(ctx);
16062 gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16063 break;
16064 case OPC_SUBQ_S_PW:
16065 check_dsp(ctx);
16066 gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16067 break;
16068 case OPC_SUBQ_QH:
16069 check_dsp(ctx);
16070 gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16071 break;
16072 case OPC_SUBQ_S_QH:
16073 check_dsp(ctx);
16074 gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16075 break;
16076 case OPC_SUBU_OB:
16077 check_dsp(ctx);
16078 gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16079 break;
16080 case OPC_SUBU_S_OB:
16081 check_dsp(ctx);
16082 gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16083 break;
16084 case OPC_SUBU_QH:
16085 check_dspr2(ctx);
16086 gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16087 break;
16088 case OPC_SUBU_S_QH:
16089 check_dspr2(ctx);
16090 gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16091 break;
16092 case OPC_SUBUH_OB:
16093 check_dspr2(ctx);
16094 gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t);
16095 break;
16096 case OPC_SUBUH_R_OB:
16097 check_dspr2(ctx);
16098 gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t);
16099 break;
16100 case OPC_ADDQ_PW:
16101 check_dsp(ctx);
16102 gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16103 break;
16104 case OPC_ADDQ_S_PW:
16105 check_dsp(ctx);
16106 gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16107 break;
16108 case OPC_ADDQ_QH:
16109 check_dsp(ctx);
16110 gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16111 break;
16112 case OPC_ADDQ_S_QH:
16113 check_dsp(ctx);
16114 gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16115 break;
16116 case OPC_ADDU_OB:
16117 check_dsp(ctx);
16118 gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16119 break;
16120 case OPC_ADDU_S_OB:
16121 check_dsp(ctx);
16122 gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16123 break;
16124 case OPC_ADDU_QH:
16125 check_dspr2(ctx);
16126 gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16127 break;
16128 case OPC_ADDU_S_QH:
16129 check_dspr2(ctx);
16130 gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16131 break;
16132 case OPC_ADDUH_OB:
16133 check_dspr2(ctx);
16134 gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t);
16135 break;
16136 case OPC_ADDUH_R_OB:
16137 check_dspr2(ctx);
16138 gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t);
16139 break;
16140 }
16141 break;
16142 case OPC_CMPU_EQ_OB_DSP:
16143 switch (op2) {
16144 case OPC_PRECR_OB_QH:
16145 check_dspr2(ctx);
16146 gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t);
16147 break;
16148 case OPC_PRECR_SRA_QH_PW:
16149 check_dspr2(ctx);
16150 {
16151 TCGv_i32 ret_t = tcg_const_i32(ret);
16152 gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t);
16153 tcg_temp_free_i32(ret_t);
16154 break;
16155 }
16156 case OPC_PRECR_SRA_R_QH_PW:
16157 check_dspr2(ctx);
16158 {
16159 TCGv_i32 sa_v = tcg_const_i32(ret);
16160 gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v);
16161 tcg_temp_free_i32(sa_v);
16162 break;
16163 }
16164 case OPC_PRECRQ_OB_QH:
16165 check_dsp(ctx);
16166 gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t);
16167 break;
16168 case OPC_PRECRQ_PW_L:
16169 check_dsp(ctx);
16170 gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t);
16171 break;
16172 case OPC_PRECRQ_QH_PW:
16173 check_dsp(ctx);
16174 gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t);
16175 break;
16176 case OPC_PRECRQ_RS_QH_PW:
16177 check_dsp(ctx);
16178 gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16179 break;
16180 case OPC_PRECRQU_S_OB_QH:
16181 check_dsp(ctx);
16182 gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16183 break;
16184 }
16185 break;
16186#endif
16187 }
16188
16189 tcg_temp_free(v1_t);
16190 tcg_temp_free(v2_t);
461c08df 16191}
9b1a1d68 16192
77c5fa8b
JL
16193static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc,
16194 int ret, int v1, int v2)
16195{
16196 uint32_t op2;
77c5fa8b
JL
16197 TCGv t0;
16198 TCGv v1_t;
16199 TCGv v2_t;
16200
16201 if (ret == 0) {
16202 /* Treat as NOP. */
77c5fa8b
JL
16203 return;
16204 }
16205
16206 t0 = tcg_temp_new();
16207 v1_t = tcg_temp_new();
16208 v2_t = tcg_temp_new();
16209
16210 tcg_gen_movi_tl(t0, v1);
16211 gen_load_gpr(v1_t, v1);
16212 gen_load_gpr(v2_t, v2);
16213
16214 switch (opc) {
16215 case OPC_SHLL_QB_DSP:
16216 {
16217 op2 = MASK_SHLL_QB(ctx->opcode);
16218 switch (op2) {
16219 case OPC_SHLL_QB:
16220 check_dsp(ctx);
16221 gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, cpu_env);
16222 break;
16223 case OPC_SHLLV_QB:
16224 check_dsp(ctx);
16225 gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16226 break;
16227 case OPC_SHLL_PH:
16228 check_dsp(ctx);
16229 gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
16230 break;
16231 case OPC_SHLLV_PH:
16232 check_dsp(ctx);
16233 gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16234 break;
16235 case OPC_SHLL_S_PH:
16236 check_dsp(ctx);
16237 gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
16238 break;
16239 case OPC_SHLLV_S_PH:
16240 check_dsp(ctx);
16241 gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16242 break;
16243 case OPC_SHLL_S_W:
16244 check_dsp(ctx);
16245 gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, cpu_env);
16246 break;
16247 case OPC_SHLLV_S_W:
16248 check_dsp(ctx);
16249 gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16250 break;
16251 case OPC_SHRL_QB:
16252 check_dsp(ctx);
16253 gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t);
16254 break;
16255 case OPC_SHRLV_QB:
16256 check_dsp(ctx);
16257 gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t);
16258 break;
16259 case OPC_SHRL_PH:
16260 check_dspr2(ctx);
16261 gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t);
16262 break;
16263 case OPC_SHRLV_PH:
16264 check_dspr2(ctx);
16265 gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t);
16266 break;
16267 case OPC_SHRA_QB:
16268 check_dspr2(ctx);
16269 gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t);
16270 break;
16271 case OPC_SHRA_R_QB:
16272 check_dspr2(ctx);
16273 gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t);
16274 break;
16275 case OPC_SHRAV_QB:
16276 check_dspr2(ctx);
16277 gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t);
16278 break;
16279 case OPC_SHRAV_R_QB:
16280 check_dspr2(ctx);
16281 gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t);
16282 break;
16283 case OPC_SHRA_PH:
16284 check_dsp(ctx);
16285 gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t);
16286 break;
16287 case OPC_SHRA_R_PH:
16288 check_dsp(ctx);
16289 gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t);
16290 break;
16291 case OPC_SHRAV_PH:
16292 check_dsp(ctx);
16293 gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t);
16294 break;
16295 case OPC_SHRAV_R_PH:
16296 check_dsp(ctx);
16297 gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t);
16298 break;
16299 case OPC_SHRA_R_W:
16300 check_dsp(ctx);
16301 gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t);
16302 break;
16303 case OPC_SHRAV_R_W:
16304 check_dsp(ctx);
16305 gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t);
16306 break;
16307 default: /* Invalid */
16308 MIPS_INVAL("MASK SHLL.QB");
9c708c7f 16309 generate_exception_end(ctx, EXCP_RI);
77c5fa8b
JL
16310 break;
16311 }
16312 break;
16313 }
16314#ifdef TARGET_MIPS64
16315 case OPC_SHLL_OB_DSP:
16316 op2 = MASK_SHLL_OB(ctx->opcode);
16317 switch (op2) {
16318 case OPC_SHLL_PW:
16319 check_dsp(ctx);
16320 gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
16321 break;
16322 case OPC_SHLLV_PW:
16323 check_dsp(ctx);
16324 gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
16325 break;
16326 case OPC_SHLL_S_PW:
16327 check_dsp(ctx);
16328 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
16329 break;
16330 case OPC_SHLLV_S_PW:
16331 check_dsp(ctx);
16332 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
16333 break;
16334 case OPC_SHLL_OB:
16335 check_dsp(ctx);
16336 gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, cpu_env);
16337 break;
16338 case OPC_SHLLV_OB:
16339 check_dsp(ctx);
16340 gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, cpu_env);
16341 break;
16342 case OPC_SHLL_QH:
16343 check_dsp(ctx);
16344 gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
16345 break;
16346 case OPC_SHLLV_QH:
16347 check_dsp(ctx);
16348 gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
16349 break;
16350 case OPC_SHLL_S_QH:
16351 check_dsp(ctx);
16352 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
16353 break;
16354 case OPC_SHLLV_S_QH:
16355 check_dsp(ctx);
16356 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
16357 break;
16358 case OPC_SHRA_OB:
16359 check_dspr2(ctx);
16360 gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0);
16361 break;
16362 case OPC_SHRAV_OB:
16363 check_dspr2(ctx);
16364 gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t);
16365 break;
16366 case OPC_SHRA_R_OB:
16367 check_dspr2(ctx);
16368 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0);
16369 break;
16370 case OPC_SHRAV_R_OB:
16371 check_dspr2(ctx);
16372 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t);
16373 break;
16374 case OPC_SHRA_PW:
16375 check_dsp(ctx);
16376 gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0);
16377 break;
16378 case OPC_SHRAV_PW:
16379 check_dsp(ctx);
16380 gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t);
16381 break;
16382 case OPC_SHRA_R_PW:
16383 check_dsp(ctx);
16384 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0);
16385 break;
16386 case OPC_SHRAV_R_PW:
16387 check_dsp(ctx);
16388 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t);
16389 break;
16390 case OPC_SHRA_QH:
16391 check_dsp(ctx);
16392 gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0);
16393 break;
16394 case OPC_SHRAV_QH:
16395 check_dsp(ctx);
16396 gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t);
16397 break;
16398 case OPC_SHRA_R_QH:
16399 check_dsp(ctx);
16400 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0);
16401 break;
16402 case OPC_SHRAV_R_QH:
16403 check_dsp(ctx);
16404 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t);
16405 break;
16406 case OPC_SHRL_OB:
16407 check_dsp(ctx);
16408 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0);
16409 break;
16410 case OPC_SHRLV_OB:
16411 check_dsp(ctx);
16412 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t);
16413 break;
16414 case OPC_SHRL_QH:
16415 check_dspr2(ctx);
16416 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0);
16417 break;
16418 case OPC_SHRLV_QH:
16419 check_dspr2(ctx);
16420 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t);
16421 break;
16422 default: /* Invalid */
16423 MIPS_INVAL("MASK SHLL.OB");
9c708c7f 16424 generate_exception_end(ctx, EXCP_RI);
77c5fa8b
JL
16425 break;
16426 }
16427 break;
16428#endif
16429 }
16430
16431 tcg_temp_free(t0);
16432 tcg_temp_free(v1_t);
16433 tcg_temp_free(v2_t);
77c5fa8b
JL
16434}
16435
a22260ae
JL
16436static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2,
16437 int ret, int v1, int v2, int check_ret)
16438{
a22260ae
JL
16439 TCGv_i32 t0;
16440 TCGv v1_t;
16441 TCGv v2_t;
16442
16443 if ((ret == 0) && (check_ret == 1)) {
16444 /* Treat as NOP. */
a22260ae
JL
16445 return;
16446 }
16447
16448 t0 = tcg_temp_new_i32();
16449 v1_t = tcg_temp_new();
16450 v2_t = tcg_temp_new();
16451
16452 tcg_gen_movi_i32(t0, ret);
16453 gen_load_gpr(v1_t, v1);
16454 gen_load_gpr(v2_t, v2);
16455
16456 switch (op1) {
16457 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
16458 * the same mask and op1. */
16459 case OPC_MULT_G_2E:
639eadb9 16460 check_dspr2(ctx);
a22260ae
JL
16461 switch (op2) {
16462 case OPC_MUL_PH:
16463 gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16464 break;
16465 case OPC_MUL_S_PH:
16466 gen_helper_mul_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16467 break;
16468 case OPC_MULQ_S_W:
16469 gen_helper_mulq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16470 break;
16471 case OPC_MULQ_RS_W:
16472 gen_helper_mulq_rs_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16473 break;
16474 }
16475 break;
16476 case OPC_DPA_W_PH_DSP:
16477 switch (op2) {
16478 case OPC_DPAU_H_QBL:
16479 check_dsp(ctx);
16480 gen_helper_dpau_h_qbl(t0, v1_t, v2_t, cpu_env);
16481 break;
16482 case OPC_DPAU_H_QBR:
16483 check_dsp(ctx);
16484 gen_helper_dpau_h_qbr(t0, v1_t, v2_t, cpu_env);
16485 break;
16486 case OPC_DPSU_H_QBL:
16487 check_dsp(ctx);
16488 gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, cpu_env);
16489 break;
16490 case OPC_DPSU_H_QBR:
16491 check_dsp(ctx);
16492 gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, cpu_env);
16493 break;
16494 case OPC_DPA_W_PH:
16495 check_dspr2(ctx);
16496 gen_helper_dpa_w_ph(t0, v1_t, v2_t, cpu_env);
16497 break;
16498 case OPC_DPAX_W_PH:
16499 check_dspr2(ctx);
16500 gen_helper_dpax_w_ph(t0, v1_t, v2_t, cpu_env);
16501 break;
16502 case OPC_DPAQ_S_W_PH:
16503 check_dsp(ctx);
16504 gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
16505 break;
16506 case OPC_DPAQX_S_W_PH:
16507 check_dspr2(ctx);
16508 gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
16509 break;
16510 case OPC_DPAQX_SA_W_PH:
16511 check_dspr2(ctx);
16512 gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
16513 break;
16514 case OPC_DPS_W_PH:
16515 check_dspr2(ctx);
16516 gen_helper_dps_w_ph(t0, v1_t, v2_t, cpu_env);
16517 break;
16518 case OPC_DPSX_W_PH:
16519 check_dspr2(ctx);
16520 gen_helper_dpsx_w_ph(t0, v1_t, v2_t, cpu_env);
16521 break;
16522 case OPC_DPSQ_S_W_PH:
16523 check_dsp(ctx);
16524 gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, cpu_env);
16525 break;
16526 case OPC_DPSQX_S_W_PH:
16527 check_dspr2(ctx);
16528 gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
16529 break;
16530 case OPC_DPSQX_SA_W_PH:
16531 check_dspr2(ctx);
16532 gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
16533 break;
16534 case OPC_MULSAQ_S_W_PH:
16535 check_dsp(ctx);
16536 gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
16537 break;
16538 case OPC_DPAQ_SA_L_W:
16539 check_dsp(ctx);
16540 gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, cpu_env);
16541 break;
16542 case OPC_DPSQ_SA_L_W:
16543 check_dsp(ctx);
16544 gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, cpu_env);
16545 break;
16546 case OPC_MAQ_S_W_PHL:
16547 check_dsp(ctx);
16548 gen_helper_maq_s_w_phl(t0, v1_t, v2_t, cpu_env);
16549 break;
16550 case OPC_MAQ_S_W_PHR:
16551 check_dsp(ctx);
16552 gen_helper_maq_s_w_phr(t0, v1_t, v2_t, cpu_env);
16553 break;
16554 case OPC_MAQ_SA_W_PHL:
16555 check_dsp(ctx);
16556 gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, cpu_env);
16557 break;
16558 case OPC_MAQ_SA_W_PHR:
16559 check_dsp(ctx);
16560 gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, cpu_env);
16561 break;
16562 case OPC_MULSA_W_PH:
16563 check_dspr2(ctx);
16564 gen_helper_mulsa_w_ph(t0, v1_t, v2_t, cpu_env);
16565 break;
16566 }
16567 break;
16568#ifdef TARGET_MIPS64
16569 case OPC_DPAQ_W_QH_DSP:
16570 {
16571 int ac = ret & 0x03;
16572 tcg_gen_movi_i32(t0, ac);
16573
16574 switch (op2) {
16575 case OPC_DMADD:
16576 check_dsp(ctx);
16577 gen_helper_dmadd(v1_t, v2_t, t0, cpu_env);
16578 break;
16579 case OPC_DMADDU:
16580 check_dsp(ctx);
16581 gen_helper_dmaddu(v1_t, v2_t, t0, cpu_env);
16582 break;
16583 case OPC_DMSUB:
16584 check_dsp(ctx);
16585 gen_helper_dmsub(v1_t, v2_t, t0, cpu_env);
16586 break;
16587 case OPC_DMSUBU:
16588 check_dsp(ctx);
16589 gen_helper_dmsubu(v1_t, v2_t, t0, cpu_env);
16590 break;
16591 case OPC_DPA_W_QH:
16592 check_dspr2(ctx);
16593 gen_helper_dpa_w_qh(v1_t, v2_t, t0, cpu_env);
16594 break;
16595 case OPC_DPAQ_S_W_QH:
16596 check_dsp(ctx);
16597 gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
16598 break;
16599 case OPC_DPAQ_SA_L_PW:
16600 check_dsp(ctx);
16601 gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
16602 break;
16603 case OPC_DPAU_H_OBL:
16604 check_dsp(ctx);
16605 gen_helper_dpau_h_obl(v1_t, v2_t, t0, cpu_env);
16606 break;
16607 case OPC_DPAU_H_OBR:
16608 check_dsp(ctx);
16609 gen_helper_dpau_h_obr(v1_t, v2_t, t0, cpu_env);
16610 break;
16611 case OPC_DPS_W_QH:
16612 check_dspr2(ctx);
16613 gen_helper_dps_w_qh(v1_t, v2_t, t0, cpu_env);
16614 break;
16615 case OPC_DPSQ_S_W_QH:
16616 check_dsp(ctx);
16617 gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, cpu_env);
16618 break;
16619 case OPC_DPSQ_SA_L_PW:
16620 check_dsp(ctx);
16621 gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
16622 break;
16623 case OPC_DPSU_H_OBL:
16624 check_dsp(ctx);
16625 gen_helper_dpsu_h_obl(v1_t, v2_t, t0, cpu_env);
16626 break;
16627 case OPC_DPSU_H_OBR:
16628 check_dsp(ctx);
16629 gen_helper_dpsu_h_obr(v1_t, v2_t, t0, cpu_env);
16630 break;
16631 case OPC_MAQ_S_L_PWL:
16632 check_dsp(ctx);
16633 gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, cpu_env);
16634 break;
16635 case OPC_MAQ_S_L_PWR:
16636 check_dsp(ctx);
16637 gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, cpu_env);
16638 break;
16639 case OPC_MAQ_S_W_QHLL:
16640 check_dsp(ctx);
16641 gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, cpu_env);
16642 break;
16643 case OPC_MAQ_SA_W_QHLL:
16644 check_dsp(ctx);
16645 gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, cpu_env);
16646 break;
16647 case OPC_MAQ_S_W_QHLR:
16648 check_dsp(ctx);
16649 gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, cpu_env);
16650 break;
16651 case OPC_MAQ_SA_W_QHLR:
16652 check_dsp(ctx);
16653 gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, cpu_env);
16654 break;
16655 case OPC_MAQ_S_W_QHRL:
16656 check_dsp(ctx);
16657 gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, cpu_env);
16658 break;
16659 case OPC_MAQ_SA_W_QHRL:
16660 check_dsp(ctx);
16661 gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, cpu_env);
16662 break;
16663 case OPC_MAQ_S_W_QHRR:
16664 check_dsp(ctx);
16665 gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, cpu_env);
16666 break;
16667 case OPC_MAQ_SA_W_QHRR:
16668 check_dsp(ctx);
16669 gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, cpu_env);
16670 break;
16671 case OPC_MULSAQ_S_L_PW:
16672 check_dsp(ctx);
16673 gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, cpu_env);
16674 break;
16675 case OPC_MULSAQ_S_W_QH:
16676 check_dsp(ctx);
16677 gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
16678 break;
16679 }
16680 }
16681 break;
16682#endif
16683 case OPC_ADDU_QB_DSP:
16684 switch (op2) {
16685 case OPC_MULEU_S_PH_QBL:
16686 check_dsp(ctx);
16687 gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16688 break;
16689 case OPC_MULEU_S_PH_QBR:
16690 check_dsp(ctx);
16691 gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16692 break;
16693 case OPC_MULQ_RS_PH:
16694 check_dsp(ctx);
16695 gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16696 break;
16697 case OPC_MULEQ_S_W_PHL:
16698 check_dsp(ctx);
16699 gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16700 break;
16701 case OPC_MULEQ_S_W_PHR:
16702 check_dsp(ctx);
16703 gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16704 break;
16705 case OPC_MULQ_S_PH:
16706 check_dspr2(ctx);
16707 gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16708 break;
16709 }
16710 break;
16711#ifdef TARGET_MIPS64
16712 case OPC_ADDU_OB_DSP:
16713 switch (op2) {
16714 case OPC_MULEQ_S_PW_QHL:
16715 check_dsp(ctx);
16716 gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16717 break;
16718 case OPC_MULEQ_S_PW_QHR:
16719 check_dsp(ctx);
16720 gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16721 break;
16722 case OPC_MULEU_S_QH_OBL:
16723 check_dsp(ctx);
16724 gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16725 break;
16726 case OPC_MULEU_S_QH_OBR:
16727 check_dsp(ctx);
16728 gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16729 break;
16730 case OPC_MULQ_RS_QH:
16731 check_dsp(ctx);
16732 gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16733 break;
16734 }
16735 break;
16736#endif
16737 }
16738
16739 tcg_temp_free_i32(t0);
16740 tcg_temp_free(v1_t);
16741 tcg_temp_free(v2_t);
a22260ae
JL
16742}
16743
d75c135e 16744static void gen_mipsdsp_bitinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
1cb6686c
JL
16745 int ret, int val)
16746{
1cb6686c
JL
16747 int16_t imm;
16748 TCGv t0;
16749 TCGv val_t;
16750
16751 if (ret == 0) {
16752 /* Treat as NOP. */
1cb6686c
JL
16753 return;
16754 }
16755
16756 t0 = tcg_temp_new();
16757 val_t = tcg_temp_new();
16758 gen_load_gpr(val_t, val);
16759
16760 switch (op1) {
16761 case OPC_ABSQ_S_PH_DSP:
16762 switch (op2) {
16763 case OPC_BITREV:
16764 check_dsp(ctx);
16765 gen_helper_bitrev(cpu_gpr[ret], val_t);
16766 break;
16767 case OPC_REPL_QB:
16768 check_dsp(ctx);
16769 {
16770 target_long result;
16771 imm = (ctx->opcode >> 16) & 0xFF;
16772 result = (uint32_t)imm << 24 |
16773 (uint32_t)imm << 16 |
16774 (uint32_t)imm << 8 |
16775 (uint32_t)imm;
16776 result = (int32_t)result;
16777 tcg_gen_movi_tl(cpu_gpr[ret], result);
16778 }
16779 break;
16780 case OPC_REPLV_QB:
16781 check_dsp(ctx);
16782 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
16783 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
16784 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16785 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
16786 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16787 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
16788 break;
16789 case OPC_REPL_PH:
16790 check_dsp(ctx);
16791 {
16792 imm = (ctx->opcode >> 16) & 0x03FF;
c4aaba92 16793 imm = (int16_t)(imm << 6) >> 6;
1cb6686c
JL
16794 tcg_gen_movi_tl(cpu_gpr[ret], \
16795 (target_long)((int32_t)imm << 16 | \
c4aaba92 16796 (uint16_t)imm));
1cb6686c
JL
16797 }
16798 break;
16799 case OPC_REPLV_PH:
16800 check_dsp(ctx);
16801 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
16802 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
16803 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16804 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
16805 break;
16806 }
16807 break;
16808#ifdef TARGET_MIPS64
16809 case OPC_ABSQ_S_QH_DSP:
16810 switch (op2) {
16811 case OPC_REPL_OB:
16812 check_dsp(ctx);
16813 {
16814 target_long temp;
16815
16816 imm = (ctx->opcode >> 16) & 0xFF;
16817 temp = ((uint64_t)imm << 8) | (uint64_t)imm;
16818 temp = (temp << 16) | temp;
16819 temp = (temp << 32) | temp;
16820 tcg_gen_movi_tl(cpu_gpr[ret], temp);
16821 break;
16822 }
16823 case OPC_REPL_PW:
16824 check_dsp(ctx);
16825 {
16826 target_long temp;
16827
16828 imm = (ctx->opcode >> 16) & 0x03FF;
16829 imm = (int16_t)(imm << 6) >> 6;
16830 temp = ((target_long)imm << 32) \
16831 | ((target_long)imm & 0xFFFFFFFF);
16832 tcg_gen_movi_tl(cpu_gpr[ret], temp);
16833 break;
16834 }
16835 case OPC_REPL_QH:
16836 check_dsp(ctx);
16837 {
16838 target_long temp;
16839
16840 imm = (ctx->opcode >> 16) & 0x03FF;
16841 imm = (int16_t)(imm << 6) >> 6;
16842
16843 temp = ((uint64_t)(uint16_t)imm << 48) |
16844 ((uint64_t)(uint16_t)imm << 32) |
16845 ((uint64_t)(uint16_t)imm << 16) |
16846 (uint64_t)(uint16_t)imm;
16847 tcg_gen_movi_tl(cpu_gpr[ret], temp);
16848 break;
16849 }
16850 case OPC_REPLV_OB:
16851 check_dsp(ctx);
16852 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
16853 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
16854 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16855 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
16856 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16857 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
16858 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16859 break;
16860 case OPC_REPLV_PW:
16861 check_dsp(ctx);
16862 tcg_gen_ext32u_i64(cpu_gpr[ret], val_t);
16863 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
16864 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16865 break;
16866 case OPC_REPLV_QH:
16867 check_dsp(ctx);
16868 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
16869 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
16870 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16871 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
16872 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16873 break;
16874 }
16875 break;
16876#endif
16877 }
16878 tcg_temp_free(t0);
16879 tcg_temp_free(val_t);
1cb6686c
JL
16880}
16881
26690560
JL
16882static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx,
16883 uint32_t op1, uint32_t op2,
16884 int ret, int v1, int v2, int check_ret)
16885{
26690560
JL
16886 TCGv t1;
16887 TCGv v1_t;
16888 TCGv v2_t;
16889
16890 if ((ret == 0) && (check_ret == 1)) {
16891 /* Treat as NOP. */
26690560
JL
16892 return;
16893 }
16894
26690560
JL
16895 t1 = tcg_temp_new();
16896 v1_t = tcg_temp_new();
16897 v2_t = tcg_temp_new();
16898
16899 gen_load_gpr(v1_t, v1);
16900 gen_load_gpr(v2_t, v2);
16901
16902 switch (op1) {
26690560
JL
16903 case OPC_CMPU_EQ_QB_DSP:
16904 switch (op2) {
16905 case OPC_CMPU_EQ_QB:
16906 check_dsp(ctx);
16907 gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
16908 break;
16909 case OPC_CMPU_LT_QB:
16910 check_dsp(ctx);
16911 gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
16912 break;
16913 case OPC_CMPU_LE_QB:
16914 check_dsp(ctx);
16915 gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
16916 break;
16917 case OPC_CMPGU_EQ_QB:
16918 check_dsp(ctx);
16919 gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t);
16920 break;
16921 case OPC_CMPGU_LT_QB:
16922 check_dsp(ctx);
16923 gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t);
16924 break;
16925 case OPC_CMPGU_LE_QB:
16926 check_dsp(ctx);
16927 gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t);
16928 break;
16929 case OPC_CMPGDU_EQ_QB:
16930 check_dspr2(ctx);
16931 gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t);
16932 tcg_gen_mov_tl(cpu_gpr[ret], t1);
16933 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
16934 tcg_gen_shli_tl(t1, t1, 24);
16935 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
16936 break;
16937 case OPC_CMPGDU_LT_QB:
16938 check_dspr2(ctx);
16939 gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t);
16940 tcg_gen_mov_tl(cpu_gpr[ret], t1);
16941 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
16942 tcg_gen_shli_tl(t1, t1, 24);
16943 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
16944 break;
16945 case OPC_CMPGDU_LE_QB:
16946 check_dspr2(ctx);
16947 gen_helper_cmpgu_le_qb(t1, v1_t, v2_t);
16948 tcg_gen_mov_tl(cpu_gpr[ret], t1);
16949 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
16950 tcg_gen_shli_tl(t1, t1, 24);
16951 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
16952 break;
16953 case OPC_CMP_EQ_PH:
16954 check_dsp(ctx);
16955 gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
16956 break;
16957 case OPC_CMP_LT_PH:
16958 check_dsp(ctx);
16959 gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
16960 break;
16961 case OPC_CMP_LE_PH:
16962 check_dsp(ctx);
16963 gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
16964 break;
16965 case OPC_PICK_QB:
16966 check_dsp(ctx);
16967 gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16968 break;
16969 case OPC_PICK_PH:
16970 check_dsp(ctx);
16971 gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16972 break;
16973 case OPC_PACKRL_PH:
16974 check_dsp(ctx);
16975 gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t);
16976 break;
16977 }
16978 break;
16979#ifdef TARGET_MIPS64
16980 case OPC_CMPU_EQ_OB_DSP:
16981 switch (op2) {
16982 case OPC_CMP_EQ_PW:
16983 check_dsp(ctx);
16984 gen_helper_cmp_eq_pw(v1_t, v2_t, cpu_env);
16985 break;
16986 case OPC_CMP_LT_PW:
16987 check_dsp(ctx);
16988 gen_helper_cmp_lt_pw(v1_t, v2_t, cpu_env);
16989 break;
16990 case OPC_CMP_LE_PW:
16991 check_dsp(ctx);
16992 gen_helper_cmp_le_pw(v1_t, v2_t, cpu_env);
16993 break;
16994 case OPC_CMP_EQ_QH:
16995 check_dsp(ctx);
16996 gen_helper_cmp_eq_qh(v1_t, v2_t, cpu_env);
16997 break;
16998 case OPC_CMP_LT_QH:
16999 check_dsp(ctx);
17000 gen_helper_cmp_lt_qh(v1_t, v2_t, cpu_env);
17001 break;
17002 case OPC_CMP_LE_QH:
17003 check_dsp(ctx);
17004 gen_helper_cmp_le_qh(v1_t, v2_t, cpu_env);
17005 break;
17006 case OPC_CMPGDU_EQ_OB:
17007 check_dspr2(ctx);
17008 gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
17009 break;
17010 case OPC_CMPGDU_LT_OB:
17011 check_dspr2(ctx);
17012 gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
17013 break;
17014 case OPC_CMPGDU_LE_OB:
17015 check_dspr2(ctx);
17016 gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
17017 break;
17018 case OPC_CMPGU_EQ_OB:
17019 check_dsp(ctx);
17020 gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t);
17021 break;
17022 case OPC_CMPGU_LT_OB:
17023 check_dsp(ctx);
17024 gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t);
17025 break;
17026 case OPC_CMPGU_LE_OB:
17027 check_dsp(ctx);
17028 gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t);
17029 break;
17030 case OPC_CMPU_EQ_OB:
17031 check_dsp(ctx);
17032 gen_helper_cmpu_eq_ob(v1_t, v2_t, cpu_env);
17033 break;
17034 case OPC_CMPU_LT_OB:
17035 check_dsp(ctx);
17036 gen_helper_cmpu_lt_ob(v1_t, v2_t, cpu_env);
17037 break;
17038 case OPC_CMPU_LE_OB:
17039 check_dsp(ctx);
17040 gen_helper_cmpu_le_ob(v1_t, v2_t, cpu_env);
17041 break;
17042 case OPC_PACKRL_PW:
17043 check_dsp(ctx);
17044 gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t);
17045 break;
17046 case OPC_PICK_OB:
17047 check_dsp(ctx);
17048 gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
17049 break;
17050 case OPC_PICK_PW:
17051 check_dsp(ctx);
17052 gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
17053 break;
17054 case OPC_PICK_QH:
17055 check_dsp(ctx);
17056 gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
17057 break;
17058 }
17059 break;
df6126a7
AJ
17060#endif
17061 }
17062
17063 tcg_temp_free(t1);
17064 tcg_temp_free(v1_t);
17065 tcg_temp_free(v2_t);
df6126a7
AJ
17066}
17067
17068static void gen_mipsdsp_append(CPUMIPSState *env, DisasContext *ctx,
17069 uint32_t op1, int rt, int rs, int sa)
17070{
df6126a7
AJ
17071 TCGv t0;
17072
17073 check_dspr2(ctx);
17074
17075 if (rt == 0) {
17076 /* Treat as NOP. */
df6126a7
AJ
17077 return;
17078 }
17079
17080 t0 = tcg_temp_new();
17081 gen_load_gpr(t0, rs);
17082
17083 switch (op1) {
17084 case OPC_APPEND_DSP:
17085 switch (MASK_APPEND(ctx->opcode)) {
17086 case OPC_APPEND:
17087 if (sa != 0) {
17088 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 32 - sa);
17089 }
17090 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
17091 break;
17092 case OPC_PREPEND:
17093 if (sa != 0) {
17094 tcg_gen_ext32u_tl(cpu_gpr[rt], cpu_gpr[rt]);
17095 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
17096 tcg_gen_shli_tl(t0, t0, 32 - sa);
17097 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
17098 }
17099 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
17100 break;
17101 case OPC_BALIGN:
17102 sa &= 3;
17103 if (sa != 0 && sa != 2) {
17104 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
17105 tcg_gen_ext32u_tl(t0, t0);
17106 tcg_gen_shri_tl(t0, t0, 8 * (4 - sa));
17107 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
17108 }
17109 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
17110 break;
17111 default: /* Invalid */
17112 MIPS_INVAL("MASK APPEND");
9c708c7f 17113 generate_exception_end(ctx, EXCP_RI);
df6126a7
AJ
17114 break;
17115 }
17116 break;
17117#ifdef TARGET_MIPS64
26690560 17118 case OPC_DAPPEND_DSP:
df6126a7 17119 switch (MASK_DAPPEND(ctx->opcode)) {
26690560 17120 case OPC_DAPPEND:
df6126a7
AJ
17121 if (sa != 0) {
17122 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 64 - sa);
17123 }
26690560
JL
17124 break;
17125 case OPC_PREPENDD:
df6126a7
AJ
17126 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], 0x20 | sa);
17127 tcg_gen_shli_tl(t0, t0, 64 - (0x20 | sa));
17128 tcg_gen_or_tl(cpu_gpr[rt], t0, t0);
26690560
JL
17129 break;
17130 case OPC_PREPENDW:
df6126a7
AJ
17131 if (sa != 0) {
17132 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
17133 tcg_gen_shli_tl(t0, t0, 64 - sa);
17134 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
17135 }
26690560
JL
17136 break;
17137 case OPC_DBALIGN:
df6126a7
AJ
17138 sa &= 7;
17139 if (sa != 0 && sa != 2 && sa != 4) {
17140 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
17141 tcg_gen_shri_tl(t0, t0, 8 * (8 - sa));
17142 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
17143 }
26690560
JL
17144 break;
17145 default: /* Invalid */
17146 MIPS_INVAL("MASK DAPPEND");
9c708c7f 17147 generate_exception_end(ctx, EXCP_RI);
26690560
JL
17148 break;
17149 }
17150 break;
17151#endif
17152 }
df6126a7 17153 tcg_temp_free(t0);
26690560
JL
17154}
17155
b53371ed
JL
17156static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
17157 int ret, int v1, int v2, int check_ret)
17158
17159{
b53371ed
JL
17160 TCGv t0;
17161 TCGv t1;
17162 TCGv v1_t;
17163 TCGv v2_t;
17164 int16_t imm;
17165
17166 if ((ret == 0) && (check_ret == 1)) {
17167 /* Treat as NOP. */
b53371ed
JL
17168 return;
17169 }
17170
17171 t0 = tcg_temp_new();
17172 t1 = tcg_temp_new();
17173 v1_t = tcg_temp_new();
17174 v2_t = tcg_temp_new();
17175
17176 gen_load_gpr(v1_t, v1);
17177 gen_load_gpr(v2_t, v2);
17178
17179 switch (op1) {
17180 case OPC_EXTR_W_DSP:
17181 check_dsp(ctx);
17182 switch (op2) {
17183 case OPC_EXTR_W:
17184 tcg_gen_movi_tl(t0, v2);
17185 tcg_gen_movi_tl(t1, v1);
17186 gen_helper_extr_w(cpu_gpr[ret], t0, t1, cpu_env);
17187 break;
17188 case OPC_EXTR_R_W:
17189 tcg_gen_movi_tl(t0, v2);
17190 tcg_gen_movi_tl(t1, v1);
17191 gen_helper_extr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
17192 break;
17193 case OPC_EXTR_RS_W:
17194 tcg_gen_movi_tl(t0, v2);
17195 tcg_gen_movi_tl(t1, v1);
17196 gen_helper_extr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
17197 break;
17198 case OPC_EXTR_S_H:
17199 tcg_gen_movi_tl(t0, v2);
17200 tcg_gen_movi_tl(t1, v1);
17201 gen_helper_extr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
17202 break;
17203 case OPC_EXTRV_S_H:
17204 tcg_gen_movi_tl(t0, v2);
17205 gen_helper_extr_s_h(cpu_gpr[ret], t0, v1_t, cpu_env);
17206 break;
17207 case OPC_EXTRV_W:
17208 tcg_gen_movi_tl(t0, v2);
17209 gen_helper_extr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
17210 break;
17211 case OPC_EXTRV_R_W:
17212 tcg_gen_movi_tl(t0, v2);
17213 gen_helper_extr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
17214 break;
17215 case OPC_EXTRV_RS_W:
17216 tcg_gen_movi_tl(t0, v2);
17217 gen_helper_extr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
17218 break;
17219 case OPC_EXTP:
17220 tcg_gen_movi_tl(t0, v2);
17221 tcg_gen_movi_tl(t1, v1);
17222 gen_helper_extp(cpu_gpr[ret], t0, t1, cpu_env);
17223 break;
17224 case OPC_EXTPV:
17225 tcg_gen_movi_tl(t0, v2);
17226 gen_helper_extp(cpu_gpr[ret], t0, v1_t, cpu_env);
17227 break;
17228 case OPC_EXTPDP:
17229 tcg_gen_movi_tl(t0, v2);
17230 tcg_gen_movi_tl(t1, v1);
17231 gen_helper_extpdp(cpu_gpr[ret], t0, t1, cpu_env);
17232 break;
17233 case OPC_EXTPDPV:
17234 tcg_gen_movi_tl(t0, v2);
17235 gen_helper_extpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
17236 break;
17237 case OPC_SHILO:
17238 imm = (ctx->opcode >> 20) & 0x3F;
17239 tcg_gen_movi_tl(t0, ret);
17240 tcg_gen_movi_tl(t1, imm);
17241 gen_helper_shilo(t0, t1, cpu_env);
17242 break;
17243 case OPC_SHILOV:
17244 tcg_gen_movi_tl(t0, ret);
17245 gen_helper_shilo(t0, v1_t, cpu_env);
17246 break;
17247 case OPC_MTHLIP:
17248 tcg_gen_movi_tl(t0, ret);
17249 gen_helper_mthlip(t0, v1_t, cpu_env);
17250 break;
17251 case OPC_WRDSP:
17252 imm = (ctx->opcode >> 11) & 0x3FF;
17253 tcg_gen_movi_tl(t0, imm);
17254 gen_helper_wrdsp(v1_t, t0, cpu_env);
17255 break;
17256 case OPC_RDDSP:
17257 imm = (ctx->opcode >> 16) & 0x03FF;
17258 tcg_gen_movi_tl(t0, imm);
17259 gen_helper_rddsp(cpu_gpr[ret], t0, cpu_env);
17260 break;
17261 }
17262 break;
17263#ifdef TARGET_MIPS64
17264 case OPC_DEXTR_W_DSP:
17265 check_dsp(ctx);
17266 switch (op2) {
17267 case OPC_DMTHLIP:
17268 tcg_gen_movi_tl(t0, ret);
17269 gen_helper_dmthlip(v1_t, t0, cpu_env);
17270 break;
17271 case OPC_DSHILO:
17272 {
17273 int shift = (ctx->opcode >> 19) & 0x7F;
17274 int ac = (ctx->opcode >> 11) & 0x03;
17275 tcg_gen_movi_tl(t0, shift);
17276 tcg_gen_movi_tl(t1, ac);
17277 gen_helper_dshilo(t0, t1, cpu_env);
17278 break;
17279 }
17280 case OPC_DSHILOV:
17281 {
17282 int ac = (ctx->opcode >> 11) & 0x03;
17283 tcg_gen_movi_tl(t0, ac);
17284 gen_helper_dshilo(v1_t, t0, cpu_env);
17285 break;
17286 }
17287 case OPC_DEXTP:
17288 tcg_gen_movi_tl(t0, v2);
17289 tcg_gen_movi_tl(t1, v1);
17290
17291 gen_helper_dextp(cpu_gpr[ret], t0, t1, cpu_env);
17292 break;
17293 case OPC_DEXTPV:
17294 tcg_gen_movi_tl(t0, v2);
17295 gen_helper_dextp(cpu_gpr[ret], t0, v1_t, cpu_env);
17296 break;
17297 case OPC_DEXTPDP:
17298 tcg_gen_movi_tl(t0, v2);
17299 tcg_gen_movi_tl(t1, v1);
17300 gen_helper_dextpdp(cpu_gpr[ret], t0, t1, cpu_env);
17301 break;
17302 case OPC_DEXTPDPV:
17303 tcg_gen_movi_tl(t0, v2);
17304 gen_helper_dextpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
17305 break;
17306 case OPC_DEXTR_L:
17307 tcg_gen_movi_tl(t0, v2);
17308 tcg_gen_movi_tl(t1, v1);
17309 gen_helper_dextr_l(cpu_gpr[ret], t0, t1, cpu_env);
17310 break;
17311 case OPC_DEXTR_R_L:
17312 tcg_gen_movi_tl(t0, v2);
17313 tcg_gen_movi_tl(t1, v1);
17314 gen_helper_dextr_r_l(cpu_gpr[ret], t0, t1, cpu_env);
17315 break;
17316 case OPC_DEXTR_RS_L:
17317 tcg_gen_movi_tl(t0, v2);
17318 tcg_gen_movi_tl(t1, v1);
17319 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, t1, cpu_env);
17320 break;
17321 case OPC_DEXTR_W:
17322 tcg_gen_movi_tl(t0, v2);
17323 tcg_gen_movi_tl(t1, v1);
17324 gen_helper_dextr_w(cpu_gpr[ret], t0, t1, cpu_env);
17325 break;
17326 case OPC_DEXTR_R_W:
17327 tcg_gen_movi_tl(t0, v2);
17328 tcg_gen_movi_tl(t1, v1);
17329 gen_helper_dextr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
17330 break;
17331 case OPC_DEXTR_RS_W:
17332 tcg_gen_movi_tl(t0, v2);
17333 tcg_gen_movi_tl(t1, v1);
17334 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
17335 break;
17336 case OPC_DEXTR_S_H:
17337 tcg_gen_movi_tl(t0, v2);
17338 tcg_gen_movi_tl(t1, v1);
17339 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
17340 break;
17341 case OPC_DEXTRV_S_H:
17342 tcg_gen_movi_tl(t0, v2);
17343 tcg_gen_movi_tl(t1, v1);
17344 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
17345 break;
17346 case OPC_DEXTRV_L:
17347 tcg_gen_movi_tl(t0, v2);
17348 gen_helper_dextr_l(cpu_gpr[ret], t0, v1_t, cpu_env);
17349 break;
17350 case OPC_DEXTRV_R_L:
17351 tcg_gen_movi_tl(t0, v2);
17352 gen_helper_dextr_r_l(cpu_gpr[ret], t0, v1_t, cpu_env);
17353 break;
17354 case OPC_DEXTRV_RS_L:
17355 tcg_gen_movi_tl(t0, v2);
17356 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, v1_t, cpu_env);
17357 break;
17358 case OPC_DEXTRV_W:
17359 tcg_gen_movi_tl(t0, v2);
17360 gen_helper_dextr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
17361 break;
17362 case OPC_DEXTRV_R_W:
17363 tcg_gen_movi_tl(t0, v2);
17364 gen_helper_dextr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
17365 break;
17366 case OPC_DEXTRV_RS_W:
17367 tcg_gen_movi_tl(t0, v2);
17368 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
17369 break;
17370 }
17371 break;
17372#endif
17373 }
17374
17375 tcg_temp_free(t0);
17376 tcg_temp_free(t1);
17377 tcg_temp_free(v1_t);
17378 tcg_temp_free(v2_t);
b53371ed
JL
17379}
17380
9b1a1d68
JL
17381/* End MIPSDSP functions. */
17382
10dc65db
LA
17383static void decode_opc_special_r6(CPUMIPSState *env, DisasContext *ctx)
17384{
4267d3e6 17385 int rs, rt, rd, sa;
b42ee5e1 17386 uint32_t op1, op2;
10dc65db
LA
17387
17388 rs = (ctx->opcode >> 21) & 0x1f;
17389 rt = (ctx->opcode >> 16) & 0x1f;
17390 rd = (ctx->opcode >> 11) & 0x1f;
4267d3e6 17391 sa = (ctx->opcode >> 6) & 0x1f;
10dc65db
LA
17392
17393 op1 = MASK_SPECIAL(ctx->opcode);
17394 switch (op1) {
d4ea6acd 17395 case OPC_LSA:
1f1b4c00 17396 gen_lsa(ctx, op1, rd, rs, rt, extract32(ctx->opcode, 6, 2));
d4ea6acd 17397 break;
c2e19f3c
AM
17398 case OPC_MULT:
17399 case OPC_MULTU:
17400 case OPC_DIV:
17401 case OPC_DIVU:
b42ee5e1
LA
17402 op2 = MASK_R6_MULDIV(ctx->opcode);
17403 switch (op2) {
17404 case R6_OPC_MUL:
17405 case R6_OPC_MUH:
17406 case R6_OPC_MULU:
17407 case R6_OPC_MUHU:
17408 case R6_OPC_DIV:
17409 case R6_OPC_MOD:
17410 case R6_OPC_DIVU:
17411 case R6_OPC_MODU:
17412 gen_r6_muldiv(ctx, op2, rd, rs, rt);
17413 break;
17414 default:
17415 MIPS_INVAL("special_r6 muldiv");
9c708c7f 17416 generate_exception_end(ctx, EXCP_RI);
b42ee5e1
LA
17417 break;
17418 }
17419 break;
10dc65db
LA
17420 case OPC_SELEQZ:
17421 case OPC_SELNEZ:
17422 gen_cond_move(ctx, op1, rd, rs, rt);
17423 break;
4267d3e6
LA
17424 case R6_OPC_CLO:
17425 case R6_OPC_CLZ:
17426 if (rt == 0 && sa == 1) {
17427 /* Major opcode and function field is shared with preR6 MFHI/MTHI.
17428 We need additionally to check other fields */
17429 gen_cl(ctx, op1, rd, rs);
17430 } else {
9c708c7f 17431 generate_exception_end(ctx, EXCP_RI);
4267d3e6
LA
17432 }
17433 break;
17434 case R6_OPC_SDBBP:
3b3c1694
LA
17435 if (is_uhi(extract32(ctx->opcode, 6, 20))) {
17436 gen_helper_do_semihosting(cpu_env);
faf1f68b 17437 } else {
3b3c1694 17438 if (ctx->hflags & MIPS_HFLAG_SBRI) {
9c708c7f 17439 generate_exception_end(ctx, EXCP_RI);
3b3c1694 17440 } else {
9c708c7f 17441 generate_exception_end(ctx, EXCP_DBp);
3b3c1694 17442 }
faf1f68b 17443 }
4267d3e6 17444 break;
b42ee5e1 17445#if defined(TARGET_MIPS64)
d4ea6acd
LA
17446 case OPC_DLSA:
17447 check_mips_64(ctx);
1f1b4c00 17448 gen_lsa(ctx, op1, rd, rs, rt, extract32(ctx->opcode, 6, 2));
d4ea6acd 17449 break;
4267d3e6
LA
17450 case R6_OPC_DCLO:
17451 case R6_OPC_DCLZ:
17452 if (rt == 0 && sa == 1) {
17453 /* Major opcode and function field is shared with preR6 MFHI/MTHI.
17454 We need additionally to check other fields */
17455 check_mips_64(ctx);
17456 gen_cl(ctx, op1, rd, rs);
17457 } else {
9c708c7f 17458 generate_exception_end(ctx, EXCP_RI);
4267d3e6
LA
17459 }
17460 break;
c2e19f3c
AM
17461 case OPC_DMULT:
17462 case OPC_DMULTU:
17463 case OPC_DDIV:
17464 case OPC_DDIVU:
17465
b42ee5e1
LA
17466 op2 = MASK_R6_MULDIV(ctx->opcode);
17467 switch (op2) {
17468 case R6_OPC_DMUL:
17469 case R6_OPC_DMUH:
17470 case R6_OPC_DMULU:
17471 case R6_OPC_DMUHU:
17472 case R6_OPC_DDIV:
17473 case R6_OPC_DMOD:
17474 case R6_OPC_DDIVU:
17475 case R6_OPC_DMODU:
17476 check_mips_64(ctx);
17477 gen_r6_muldiv(ctx, op2, rd, rs, rt);
17478 break;
17479 default:
17480 MIPS_INVAL("special_r6 muldiv");
9c708c7f 17481 generate_exception_end(ctx, EXCP_RI);
b42ee5e1
LA
17482 break;
17483 }
17484 break;
17485#endif
10dc65db
LA
17486 default: /* Invalid */
17487 MIPS_INVAL("special_r6");
9c708c7f 17488 generate_exception_end(ctx, EXCP_RI);
10dc65db
LA
17489 break;
17490 }
17491}
17492
17493static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx)
17494{
b42ee5e1 17495 int rs, rt, rd, sa;
10dc65db
LA
17496 uint32_t op1;
17497
17498 rs = (ctx->opcode >> 21) & 0x1f;
17499 rt = (ctx->opcode >> 16) & 0x1f;
17500 rd = (ctx->opcode >> 11) & 0x1f;
b42ee5e1 17501 sa = (ctx->opcode >> 6) & 0x1f;
10dc65db
LA
17502
17503 op1 = MASK_SPECIAL(ctx->opcode);
17504 switch (op1) {
17505 case OPC_MOVN: /* Conditional move */
17506 case OPC_MOVZ:
17507 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32 |
17508 INSN_LOONGSON2E | INSN_LOONGSON2F);
17509 gen_cond_move(ctx, op1, rd, rs, rt);
17510 break;
17511 case OPC_MFHI: /* Move from HI/LO */
17512 case OPC_MFLO:
17513 gen_HILO(ctx, op1, rs & 3, rd);
17514 break;
17515 case OPC_MTHI:
17516 case OPC_MTLO: /* Move to HI/LO */
17517 gen_HILO(ctx, op1, rd & 3, rs);
17518 break;
17519 case OPC_MOVCI:
17520 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
17521 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
17522 check_cp1_enabled(ctx);
17523 gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
17524 (ctx->opcode >> 16) & 1);
17525 } else {
17526 generate_exception_err(ctx, EXCP_CpU, 1);
17527 }
17528 break;
b42ee5e1
LA
17529 case OPC_MULT:
17530 case OPC_MULTU:
17531 if (sa) {
17532 check_insn(ctx, INSN_VR54XX);
17533 op1 = MASK_MUL_VR54XX(ctx->opcode);
17534 gen_mul_vr54xx(ctx, op1, rd, rs, rt);
17535 } else {
17536 gen_muldiv(ctx, op1, rd & 3, rs, rt);
17537 }
17538 break;
17539 case OPC_DIV:
17540 case OPC_DIVU:
17541 gen_muldiv(ctx, op1, 0, rs, rt);
17542 break;
17543#if defined(TARGET_MIPS64)
c2e19f3c
AM
17544 case OPC_DMULT:
17545 case OPC_DMULTU:
17546 case OPC_DDIV:
17547 case OPC_DDIVU:
b42ee5e1
LA
17548 check_insn(ctx, ISA_MIPS3);
17549 check_mips_64(ctx);
17550 gen_muldiv(ctx, op1, 0, rs, rt);
17551 break;
17552#endif
0aefa333 17553 case OPC_JR:
b231c103 17554 gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
0aefa333 17555 break;
4267d3e6
LA
17556 case OPC_SPIM:
17557#ifdef MIPS_STRICT_STANDARD
17558 MIPS_INVAL("SPIM");
9c708c7f 17559 generate_exception_end(ctx, EXCP_RI);
4267d3e6
LA
17560#else
17561 /* Implemented as RI exception for now. */
17562 MIPS_INVAL("spim (unofficial)");
9c708c7f 17563 generate_exception_end(ctx, EXCP_RI);
4267d3e6
LA
17564#endif
17565 break;
10dc65db
LA
17566 default: /* Invalid */
17567 MIPS_INVAL("special_legacy");
9c708c7f 17568 generate_exception_end(ctx, EXCP_RI);
10dc65db
LA
17569 break;
17570 }
17571}
17572
099e5b4d 17573static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx)
3c824109 17574{
3c824109 17575 int rs, rt, rd, sa;
099e5b4d 17576 uint32_t op1;
3c824109 17577
3c824109
NF
17578 rs = (ctx->opcode >> 21) & 0x1f;
17579 rt = (ctx->opcode >> 16) & 0x1f;
17580 rd = (ctx->opcode >> 11) & 0x1f;
17581 sa = (ctx->opcode >> 6) & 0x1f;
099e5b4d
LA
17582
17583 op1 = MASK_SPECIAL(ctx->opcode);
17584 switch (op1) {
17585 case OPC_SLL: /* Shift with immediate */
339cd2a8
LA
17586 if (sa == 5 && rd == 0 &&
17587 rs == 0 && rt == 0) { /* PAUSE */
17588 if ((ctx->insn_flags & ISA_MIPS32R6) &&
17589 (ctx->hflags & MIPS_HFLAG_BMASK)) {
9c708c7f 17590 generate_exception_end(ctx, EXCP_RI);
339cd2a8
LA
17591 break;
17592 }
17593 }
17594 /* Fallthrough */
099e5b4d
LA
17595 case OPC_SRA:
17596 gen_shift_imm(ctx, op1, rd, rt, sa);
17597 break;
17598 case OPC_SRL:
17599 switch ((ctx->opcode >> 21) & 0x1f) {
17600 case 1:
17601 /* rotr is decoded as srl on non-R2 CPUs */
17602 if (ctx->insn_flags & ISA_MIPS32R2) {
17603 op1 = OPC_ROTR;
ea63e2c3 17604 }
099e5b4d
LA
17605 /* Fallthrough */
17606 case 0:
17607 gen_shift_imm(ctx, op1, rd, rt, sa);
ea63e2c3 17608 break;
099e5b4d 17609 default:
9c708c7f 17610 generate_exception_end(ctx, EXCP_RI);
ea63e2c3 17611 break;
099e5b4d
LA
17612 }
17613 break;
c2e19f3c
AM
17614 case OPC_ADD:
17615 case OPC_ADDU:
17616 case OPC_SUB:
17617 case OPC_SUBU:
099e5b4d
LA
17618 gen_arith(ctx, op1, rd, rs, rt);
17619 break;
17620 case OPC_SLLV: /* Shifts */
17621 case OPC_SRAV:
17622 gen_shift(ctx, op1, rd, rs, rt);
17623 break;
17624 case OPC_SRLV:
17625 switch ((ctx->opcode >> 6) & 0x1f) {
17626 case 1:
17627 /* rotrv is decoded as srlv on non-R2 CPUs */
17628 if (ctx->insn_flags & ISA_MIPS32R2) {
17629 op1 = OPC_ROTRV;
26135ead 17630 }
099e5b4d
LA
17631 /* Fallthrough */
17632 case 0:
17633 gen_shift(ctx, op1, rd, rs, rt);
26135ead 17634 break;
099e5b4d 17635 default:
9c708c7f 17636 generate_exception_end(ctx, EXCP_RI);
6af0bf9c 17637 break;
099e5b4d
LA
17638 }
17639 break;
17640 case OPC_SLT: /* Set on less than */
17641 case OPC_SLTU:
17642 gen_slt(ctx, op1, rd, rs, rt);
17643 break;
17644 case OPC_AND: /* Logic*/
17645 case OPC_OR:
17646 case OPC_NOR:
17647 case OPC_XOR:
17648 gen_logic(ctx, op1, rd, rs, rt);
17649 break;
0aefa333 17650 case OPC_JALR:
b231c103 17651 gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
099e5b4d 17652 break;
c2e19f3c
AM
17653 case OPC_TGE: /* Traps */
17654 case OPC_TGEU:
17655 case OPC_TLT:
17656 case OPC_TLTU:
17657 case OPC_TEQ:
099e5b4d 17658 case OPC_TNE:
d9224450 17659 check_insn(ctx, ISA_MIPS2);
099e5b4d
LA
17660 gen_trap(ctx, op1, rs, rt, -1);
17661 break;
d4ea6acd 17662 case OPC_LSA: /* OPC_PMON */
f7685877
YK
17663 if ((ctx->insn_flags & ISA_MIPS32R6) ||
17664 (env->CP0_Config3 & (1 << CP0C3_MSAP))) {
d4ea6acd
LA
17665 decode_opc_special_r6(env, ctx);
17666 } else {
17667 /* Pmon entry point, also R4010 selsl */
b48cfdff 17668#ifdef MIPS_STRICT_STANDARD
d4ea6acd 17669 MIPS_INVAL("PMON / selsl");
9c708c7f 17670 generate_exception_end(ctx, EXCP_RI);
b48cfdff 17671#else
d4ea6acd 17672 gen_helper_0e0i(pmon, sa);
b48cfdff 17673#endif
d4ea6acd 17674 }
099e5b4d
LA
17675 break;
17676 case OPC_SYSCALL:
9c708c7f 17677 generate_exception_end(ctx, EXCP_SYSCALL);
099e5b4d
LA
17678 break;
17679 case OPC_BREAK:
9c708c7f 17680 generate_exception_end(ctx, EXCP_BREAK);
099e5b4d 17681 break;
099e5b4d 17682 case OPC_SYNC:
d9224450 17683 check_insn(ctx, ISA_MIPS2);
d208ac0c 17684 gen_sync(extract32(ctx->opcode, 6, 5));
099e5b4d 17685 break;
4ad40f36 17686
d26bc211 17687#if defined(TARGET_MIPS64)
099e5b4d
LA
17688 /* MIPS64 specific opcodes */
17689 case OPC_DSLL:
17690 case OPC_DSRA:
17691 case OPC_DSLL32:
17692 case OPC_DSRA32:
17693 check_insn(ctx, ISA_MIPS3);
17694 check_mips_64(ctx);
17695 gen_shift_imm(ctx, op1, rd, rt, sa);
17696 break;
17697 case OPC_DSRL:
17698 switch ((ctx->opcode >> 21) & 0x1f) {
17699 case 1:
17700 /* drotr is decoded as dsrl on non-R2 CPUs */
17701 if (ctx->insn_flags & ISA_MIPS32R2) {
17702 op1 = OPC_DROTR;
ea63e2c3 17703 }
099e5b4d
LA
17704 /* Fallthrough */
17705 case 0:
d75c135e 17706 check_insn(ctx, ISA_MIPS3);
e189e748 17707 check_mips_64(ctx);
099e5b4d 17708 gen_shift_imm(ctx, op1, rd, rt, sa);
7a387fff 17709 break;
099e5b4d 17710 default:
9c708c7f 17711 generate_exception_end(ctx, EXCP_RI);
460f00c4 17712 break;
099e5b4d
LA
17713 }
17714 break;
17715 case OPC_DSRL32:
17716 switch ((ctx->opcode >> 21) & 0x1f) {
17717 case 1:
17718 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
17719 if (ctx->insn_flags & ISA_MIPS32R2) {
17720 op1 = OPC_DROTR32;
ea63e2c3 17721 }
099e5b4d
LA
17722 /* Fallthrough */
17723 case 0:
d75c135e 17724 check_insn(ctx, ISA_MIPS3);
e189e748 17725 check_mips_64(ctx);
099e5b4d 17726 gen_shift_imm(ctx, op1, rd, rt, sa);
7a387fff 17727 break;
099e5b4d 17728 default:
9c708c7f 17729 generate_exception_end(ctx, EXCP_RI);
6af0bf9c
FB
17730 break;
17731 }
17732 break;
c2e19f3c
AM
17733 case OPC_DADD:
17734 case OPC_DADDU:
17735 case OPC_DSUB:
17736 case OPC_DSUBU:
099e5b4d
LA
17737 check_insn(ctx, ISA_MIPS3);
17738 check_mips_64(ctx);
17739 gen_arith(ctx, op1, rd, rs, rt);
17740 break;
17741 case OPC_DSLLV:
17742 case OPC_DSRAV:
17743 check_insn(ctx, ISA_MIPS3);
17744 check_mips_64(ctx);
17745 gen_shift(ctx, op1, rd, rs, rt);
17746 break;
17747 case OPC_DSRLV:
17748 switch ((ctx->opcode >> 6) & 0x1f) {
17749 case 1:
17750 /* drotrv is decoded as dsrlv on non-R2 CPUs */
17751 if (ctx->insn_flags & ISA_MIPS32R2) {
17752 op1 = OPC_DROTRV;
6af0bf9c 17753 }
099e5b4d
LA
17754 /* Fallthrough */
17755 case 0:
17756 check_insn(ctx, ISA_MIPS3);
e189e748 17757 check_mips_64(ctx);
099e5b4d 17758 gen_shift(ctx, op1, rd, rs, rt);
161f85e6 17759 break;
099e5b4d 17760 default:
9c708c7f 17761 generate_exception_end(ctx, EXCP_RI);
6af0bf9c
FB
17762 break;
17763 }
17764 break;
f7685877
YK
17765 case OPC_DLSA:
17766 if ((ctx->insn_flags & ISA_MIPS32R6) ||
17767 (env->CP0_Config3 & (1 << CP0C3_MSAP))) {
17768 decode_opc_special_r6(env, ctx);
17769 }
17770 break;
099e5b4d 17771#endif
10dc65db
LA
17772 default:
17773 if (ctx->insn_flags & ISA_MIPS32R6) {
17774 decode_opc_special_r6(env, ctx);
17775 } else {
17776 decode_opc_special_legacy(env, ctx);
17777 }
17778 }
17779}
17780
10dc65db 17781static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx)
099e5b4d
LA
17782{
17783 int rs, rt, rd;
17784 uint32_t op1;
6c5c1e20 17785
4267d3e6
LA
17786 check_insn_opc_removed(ctx, ISA_MIPS32R6);
17787
099e5b4d
LA
17788 rs = (ctx->opcode >> 21) & 0x1f;
17789 rt = (ctx->opcode >> 16) & 0x1f;
17790 rd = (ctx->opcode >> 11) & 0x1f;
17791
17792 op1 = MASK_SPECIAL2(ctx->opcode);
17793 switch (op1) {
c2e19f3c
AM
17794 case OPC_MADD: /* Multiply and add/sub */
17795 case OPC_MADDU:
17796 case OPC_MSUB:
17797 case OPC_MSUBU:
099e5b4d
LA
17798 check_insn(ctx, ISA_MIPS32);
17799 gen_muldiv(ctx, op1, rd & 3, rs, rt);
17800 break;
17801 case OPC_MUL:
099e5b4d
LA
17802 gen_arith(ctx, op1, rd, rs, rt);
17803 break;
fac5a073
LA
17804 case OPC_DIV_G_2F:
17805 case OPC_DIVU_G_2F:
17806 case OPC_MULT_G_2F:
17807 case OPC_MULTU_G_2F:
17808 case OPC_MOD_G_2F:
17809 case OPC_MODU_G_2F:
17810 check_insn(ctx, INSN_LOONGSON2F);
17811 gen_loongson_integer(ctx, op1, rd, rs, rt);
17812 break;
099e5b4d
LA
17813 case OPC_CLO:
17814 case OPC_CLZ:
17815 check_insn(ctx, ISA_MIPS32);
17816 gen_cl(ctx, op1, rd, rs);
17817 break;
17818 case OPC_SDBBP:
3b3c1694
LA
17819 if (is_uhi(extract32(ctx->opcode, 6, 20))) {
17820 gen_helper_do_semihosting(cpu_env);
17821 } else {
17822 /* XXX: not clear which exception should be raised
17823 * when in debug mode...
17824 */
17825 check_insn(ctx, ISA_MIPS32);
9c708c7f 17826 generate_exception_end(ctx, EXCP_DBp);
3b3c1694 17827 }
099e5b4d 17828 break;
9b1a1d68 17829#if defined(TARGET_MIPS64)
099e5b4d
LA
17830 case OPC_DCLO:
17831 case OPC_DCLZ:
17832 check_insn(ctx, ISA_MIPS64);
17833 check_mips_64(ctx);
17834 gen_cl(ctx, op1, rd, rs);
17835 break;
4267d3e6
LA
17836 case OPC_DMULT_G_2F:
17837 case OPC_DMULTU_G_2F:
17838 case OPC_DDIV_G_2F:
17839 case OPC_DDIVU_G_2F:
17840 case OPC_DMOD_G_2F:
17841 case OPC_DMODU_G_2F:
17842 check_insn(ctx, INSN_LOONGSON2F);
17843 gen_loongson_integer(ctx, op1, rd, rs, rt);
17844 break;
10dc65db 17845#endif
4267d3e6
LA
17846 default: /* Invalid */
17847 MIPS_INVAL("special2_legacy");
9c708c7f 17848 generate_exception_end(ctx, EXCP_RI);
4267d3e6 17849 break;
10dc65db
LA
17850 }
17851}
17852
17853static void decode_opc_special3_r6(CPUMIPSState *env, DisasContext *ctx)
17854{
15eacb9b
YK
17855 int rs, rt, rd, sa;
17856 uint32_t op1, op2;
10dc65db
LA
17857 int16_t imm;
17858
17859 rs = (ctx->opcode >> 21) & 0x1f;
17860 rt = (ctx->opcode >> 16) & 0x1f;
15eacb9b
YK
17861 rd = (ctx->opcode >> 11) & 0x1f;
17862 sa = (ctx->opcode >> 6) & 0x1f;
10dc65db
LA
17863 imm = (int16_t)ctx->opcode >> 7;
17864
17865 op1 = MASK_SPECIAL3(ctx->opcode);
17866 switch (op1) {
bf7910c6
LA
17867 case R6_OPC_PREF:
17868 if (rt >= 24) {
17869 /* hint codes 24-31 are reserved and signal RI */
9c708c7f 17870 generate_exception_end(ctx, EXCP_RI);
bf7910c6
LA
17871 }
17872 /* Treat as NOP. */
17873 break;
17874 case R6_OPC_CACHE:
40d48212 17875 check_cp0_enabled(ctx);
0d74a222
LA
17876 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
17877 gen_cache_operation(ctx, rt, rs, imm);
17878 }
bf7910c6 17879 break;
10dc65db
LA
17880 case R6_OPC_SC:
17881 gen_st_cond(ctx, op1, rt, rs, imm);
17882 break;
17883 case R6_OPC_LL:
17884 gen_ld(ctx, op1, rt, rs, imm);
17885 break;
15eacb9b
YK
17886 case OPC_BSHFL:
17887 {
17888 if (rd == 0) {
17889 /* Treat as NOP. */
17890 break;
17891 }
15eacb9b
YK
17892 op2 = MASK_BSHFL(ctx->opcode);
17893 switch (op2) {
c2e19f3c
AM
17894 case OPC_ALIGN:
17895 case OPC_ALIGN_END:
1f1b4c00 17896 gen_align(ctx, OPC_ALIGN, rd, rs, rt, sa & 3);
15eacb9b
YK
17897 break;
17898 case OPC_BITSWAP:
1f1b4c00 17899 gen_bitswap(ctx, op2, rd, rt);
15eacb9b
YK
17900 break;
17901 }
15eacb9b
YK
17902 }
17903 break;
bf7910c6
LA
17904#if defined(TARGET_MIPS64)
17905 case R6_OPC_SCD:
17906 gen_st_cond(ctx, op1, rt, rs, imm);
17907 break;
17908 case R6_OPC_LLD:
17909 gen_ld(ctx, op1, rt, rs, imm);
17910 break;
15eacb9b
YK
17911 case OPC_DBSHFL:
17912 check_mips_64(ctx);
17913 {
17914 if (rd == 0) {
17915 /* Treat as NOP. */
17916 break;
17917 }
15eacb9b
YK
17918 op2 = MASK_DBSHFL(ctx->opcode);
17919 switch (op2) {
c2e19f3c
AM
17920 case OPC_DALIGN:
17921 case OPC_DALIGN_END:
1f1b4c00 17922 gen_align(ctx, OPC_DALIGN, rd, rs, rt, sa & 7);
15eacb9b
YK
17923 break;
17924 case OPC_DBITSWAP:
1f1b4c00 17925 gen_bitswap(ctx, op2, rd, rt);
15eacb9b
YK
17926 break;
17927 }
1f1b4c00 17928
15eacb9b
YK
17929 }
17930 break;
bf7910c6 17931#endif
10dc65db
LA
17932 default: /* Invalid */
17933 MIPS_INVAL("special3_r6");
9c708c7f 17934 generate_exception_end(ctx, EXCP_RI);
10dc65db
LA
17935 break;
17936 }
17937}
17938
17939static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx)
17940{
fac5a073 17941 int rs, rt, rd;
099e5b4d 17942 uint32_t op1, op2;
099e5b4d
LA
17943
17944 rs = (ctx->opcode >> 21) & 0x1f;
17945 rt = (ctx->opcode >> 16) & 0x1f;
17946 rd = (ctx->opcode >> 11) & 0x1f;
099e5b4d
LA
17947
17948 op1 = MASK_SPECIAL3(ctx->opcode);
17949 switch (op1) {
c2e19f3c
AM
17950 case OPC_DIV_G_2E:
17951 case OPC_DIVU_G_2E:
17952 case OPC_MOD_G_2E:
17953 case OPC_MODU_G_2E:
17954 case OPC_MULT_G_2E:
17955 case OPC_MULTU_G_2E:
099e5b4d
LA
17956 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
17957 * the same mask and op1. */
17958 if ((ctx->insn_flags & ASE_DSPR2) && (op1 == OPC_MULT_G_2E)) {
17959 op2 = MASK_ADDUH_QB(ctx->opcode);
461c08df 17960 switch (op2) {
099e5b4d
LA
17961 case OPC_ADDUH_QB:
17962 case OPC_ADDUH_R_QB:
17963 case OPC_ADDQH_PH:
17964 case OPC_ADDQH_R_PH:
17965 case OPC_ADDQH_W:
17966 case OPC_ADDQH_R_W:
17967 case OPC_SUBUH_QB:
17968 case OPC_SUBUH_R_QB:
17969 case OPC_SUBQH_PH:
17970 case OPC_SUBQH_R_PH:
17971 case OPC_SUBQH_W:
17972 case OPC_SUBQH_R_W:
461c08df
JL
17973 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
17974 break;
099e5b4d
LA
17975 case OPC_MUL_PH:
17976 case OPC_MUL_S_PH:
17977 case OPC_MULQ_S_W:
17978 case OPC_MULQ_RS_W:
17979 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
1cb6686c 17980 break;
461c08df 17981 default:
099e5b4d 17982 MIPS_INVAL("MASK ADDUH.QB");
9c708c7f 17983 generate_exception_end(ctx, EXCP_RI);
461c08df
JL
17984 break;
17985 }
099e5b4d
LA
17986 } else if (ctx->insn_flags & INSN_LOONGSON2E) {
17987 gen_loongson_integer(ctx, op1, rd, rs, rt);
17988 } else {
9c708c7f 17989 generate_exception_end(ctx, EXCP_RI);
099e5b4d
LA
17990 }
17991 break;
17992 case OPC_LX_DSP:
17993 op2 = MASK_LX(ctx->opcode);
17994 switch (op2) {
17995#if defined(TARGET_MIPS64)
17996 case OPC_LDX:
17997#endif
17998 case OPC_LBUX:
17999 case OPC_LHX:
18000 case OPC_LWX:
18001 gen_mipsdsp_ld(ctx, op2, rd, rs, rt);
18002 break;
18003 default: /* Invalid */
18004 MIPS_INVAL("MASK LX");
9c708c7f 18005 generate_exception_end(ctx, EXCP_RI);
099e5b4d
LA
18006 break;
18007 }
18008 break;
18009 case OPC_ABSQ_S_PH_DSP:
18010 op2 = MASK_ABSQ_S_PH(ctx->opcode);
18011 switch (op2) {
18012 case OPC_ABSQ_S_QB:
18013 case OPC_ABSQ_S_PH:
18014 case OPC_ABSQ_S_W:
18015 case OPC_PRECEQ_W_PHL:
18016 case OPC_PRECEQ_W_PHR:
18017 case OPC_PRECEQU_PH_QBL:
18018 case OPC_PRECEQU_PH_QBR:
18019 case OPC_PRECEQU_PH_QBLA:
18020 case OPC_PRECEQU_PH_QBRA:
18021 case OPC_PRECEU_PH_QBL:
18022 case OPC_PRECEU_PH_QBR:
18023 case OPC_PRECEU_PH_QBLA:
18024 case OPC_PRECEU_PH_QBRA:
18025 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
18026 break;
18027 case OPC_BITREV:
18028 case OPC_REPL_QB:
18029 case OPC_REPLV_QB:
18030 case OPC_REPL_PH:
18031 case OPC_REPLV_PH:
18032 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
18033 break;
18034 default:
18035 MIPS_INVAL("MASK ABSQ_S.PH");
9c708c7f 18036 generate_exception_end(ctx, EXCP_RI);
099e5b4d
LA
18037 break;
18038 }
18039 break;
18040 case OPC_ADDU_QB_DSP:
18041 op2 = MASK_ADDU_QB(ctx->opcode);
18042 switch (op2) {
18043 case OPC_ADDQ_PH:
18044 case OPC_ADDQ_S_PH:
18045 case OPC_ADDQ_S_W:
18046 case OPC_ADDU_QB:
18047 case OPC_ADDU_S_QB:
18048 case OPC_ADDU_PH:
18049 case OPC_ADDU_S_PH:
18050 case OPC_SUBQ_PH:
18051 case OPC_SUBQ_S_PH:
18052 case OPC_SUBQ_S_W:
18053 case OPC_SUBU_QB:
18054 case OPC_SUBU_S_QB:
18055 case OPC_SUBU_PH:
18056 case OPC_SUBU_S_PH:
18057 case OPC_ADDSC:
18058 case OPC_ADDWC:
18059 case OPC_MODSUB:
18060 case OPC_RADDU_W_QB:
18061 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
18062 break;
18063 case OPC_MULEU_S_PH_QBL:
18064 case OPC_MULEU_S_PH_QBR:
18065 case OPC_MULQ_RS_PH:
18066 case OPC_MULEQ_S_W_PHL:
18067 case OPC_MULEQ_S_W_PHR:
18068 case OPC_MULQ_S_PH:
18069 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
18070 break;
18071 default: /* Invalid */
18072 MIPS_INVAL("MASK ADDU.QB");
9c708c7f 18073 generate_exception_end(ctx, EXCP_RI);
461c08df 18074 break;
461c08df 18075
099e5b4d
LA
18076 }
18077 break;
18078 case OPC_CMPU_EQ_QB_DSP:
18079 op2 = MASK_CMPU_EQ_QB(ctx->opcode);
18080 switch (op2) {
18081 case OPC_PRECR_SRA_PH_W:
18082 case OPC_PRECR_SRA_R_PH_W:
18083 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
461c08df 18084 break;
099e5b4d
LA
18085 case OPC_PRECR_QB_PH:
18086 case OPC_PRECRQ_QB_PH:
18087 case OPC_PRECRQ_PH_W:
18088 case OPC_PRECRQ_RS_PH_W:
18089 case OPC_PRECRQU_S_QB_PH:
18090 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
461c08df 18091 break;
099e5b4d
LA
18092 case OPC_CMPU_EQ_QB:
18093 case OPC_CMPU_LT_QB:
18094 case OPC_CMPU_LE_QB:
18095 case OPC_CMP_EQ_PH:
18096 case OPC_CMP_LT_PH:
18097 case OPC_CMP_LE_PH:
18098 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
77c5fa8b 18099 break;
099e5b4d
LA
18100 case OPC_CMPGU_EQ_QB:
18101 case OPC_CMPGU_LT_QB:
18102 case OPC_CMPGU_LE_QB:
18103 case OPC_CMPGDU_EQ_QB:
18104 case OPC_CMPGDU_LT_QB:
18105 case OPC_CMPGDU_LE_QB:
18106 case OPC_PICK_QB:
18107 case OPC_PICK_PH:
18108 case OPC_PACKRL_PH:
18109 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
18110 break;
18111 default: /* Invalid */
18112 MIPS_INVAL("MASK CMPU.EQ.QB");
9c708c7f 18113 generate_exception_end(ctx, EXCP_RI);
099e5b4d
LA
18114 break;
18115 }
18116 break;
18117 case OPC_SHLL_QB_DSP:
18118 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
18119 break;
18120 case OPC_DPA_W_PH_DSP:
18121 op2 = MASK_DPA_W_PH(ctx->opcode);
18122 switch (op2) {
18123 case OPC_DPAU_H_QBL:
18124 case OPC_DPAU_H_QBR:
18125 case OPC_DPSU_H_QBL:
18126 case OPC_DPSU_H_QBR:
18127 case OPC_DPA_W_PH:
18128 case OPC_DPAX_W_PH:
18129 case OPC_DPAQ_S_W_PH:
18130 case OPC_DPAQX_S_W_PH:
18131 case OPC_DPAQX_SA_W_PH:
18132 case OPC_DPS_W_PH:
18133 case OPC_DPSX_W_PH:
18134 case OPC_DPSQ_S_W_PH:
18135 case OPC_DPSQX_S_W_PH:
18136 case OPC_DPSQX_SA_W_PH:
18137 case OPC_MULSAQ_S_W_PH:
18138 case OPC_DPAQ_SA_L_W:
18139 case OPC_DPSQ_SA_L_W:
18140 case OPC_MAQ_S_W_PHL:
18141 case OPC_MAQ_S_W_PHR:
18142 case OPC_MAQ_SA_W_PHL:
18143 case OPC_MAQ_SA_W_PHR:
18144 case OPC_MULSA_W_PH:
18145 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
18146 break;
18147 default: /* Invalid */
18148 MIPS_INVAL("MASK DPAW.PH");
9c708c7f 18149 generate_exception_end(ctx, EXCP_RI);
099e5b4d
LA
18150 break;
18151 }
18152 break;
18153 case OPC_INSV_DSP:
18154 op2 = MASK_INSV(ctx->opcode);
18155 switch (op2) {
18156 case OPC_INSV:
18157 check_dsp(ctx);
18158 {
18159 TCGv t0, t1;
18160
18161 if (rt == 0) {
099e5b4d
LA
18162 break;
18163 }
18164
18165 t0 = tcg_temp_new();
18166 t1 = tcg_temp_new();
18167
18168 gen_load_gpr(t0, rt);
18169 gen_load_gpr(t1, rs);
18170
18171 gen_helper_insv(cpu_gpr[rt], cpu_env, t1, t0);
18172
18173 tcg_temp_free(t0);
18174 tcg_temp_free(t1);
a22260ae
JL
18175 break;
18176 }
099e5b4d
LA
18177 default: /* Invalid */
18178 MIPS_INVAL("MASK INSV");
9c708c7f 18179 generate_exception_end(ctx, EXCP_RI);
099e5b4d
LA
18180 break;
18181 }
18182 break;
18183 case OPC_APPEND_DSP:
18184 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
18185 break;
18186 case OPC_EXTR_W_DSP:
18187 op2 = MASK_EXTR_W(ctx->opcode);
18188 switch (op2) {
18189 case OPC_EXTR_W:
18190 case OPC_EXTR_R_W:
18191 case OPC_EXTR_RS_W:
18192 case OPC_EXTR_S_H:
18193 case OPC_EXTRV_S_H:
18194 case OPC_EXTRV_W:
18195 case OPC_EXTRV_R_W:
18196 case OPC_EXTRV_RS_W:
18197 case OPC_EXTP:
18198 case OPC_EXTPV:
18199 case OPC_EXTPDP:
18200 case OPC_EXTPDPV:
18201 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
18202 break;
18203 case OPC_RDDSP:
18204 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 1);
18205 break;
18206 case OPC_SHILO:
18207 case OPC_SHILOV:
18208 case OPC_MTHLIP:
18209 case OPC_WRDSP:
18210 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
18211 break;
18212 default: /* Invalid */
18213 MIPS_INVAL("MASK EXTR.W");
9c708c7f 18214 generate_exception_end(ctx, EXCP_RI);
099e5b4d
LA
18215 break;
18216 }
18217 break;
099e5b4d 18218#if defined(TARGET_MIPS64)
c2e19f3c
AM
18219 case OPC_DDIV_G_2E:
18220 case OPC_DDIVU_G_2E:
18221 case OPC_DMULT_G_2E:
18222 case OPC_DMULTU_G_2E:
18223 case OPC_DMOD_G_2E:
18224 case OPC_DMODU_G_2E:
fac5a073
LA
18225 check_insn(ctx, INSN_LOONGSON2E);
18226 gen_loongson_integer(ctx, op1, rd, rs, rt);
099e5b4d 18227 break;
099e5b4d
LA
18228 case OPC_ABSQ_S_QH_DSP:
18229 op2 = MASK_ABSQ_S_QH(ctx->opcode);
18230 switch (op2) {
18231 case OPC_PRECEQ_L_PWL:
18232 case OPC_PRECEQ_L_PWR:
18233 case OPC_PRECEQ_PW_QHL:
18234 case OPC_PRECEQ_PW_QHR:
18235 case OPC_PRECEQ_PW_QHLA:
18236 case OPC_PRECEQ_PW_QHRA:
18237 case OPC_PRECEQU_QH_OBL:
18238 case OPC_PRECEQU_QH_OBR:
18239 case OPC_PRECEQU_QH_OBLA:
18240 case OPC_PRECEQU_QH_OBRA:
18241 case OPC_PRECEU_QH_OBL:
18242 case OPC_PRECEU_QH_OBR:
18243 case OPC_PRECEU_QH_OBLA:
18244 case OPC_PRECEU_QH_OBRA:
18245 case OPC_ABSQ_S_OB:
18246 case OPC_ABSQ_S_PW:
18247 case OPC_ABSQ_S_QH:
18248 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
18249 break;
18250 case OPC_REPL_OB:
18251 case OPC_REPL_PW:
18252 case OPC_REPL_QH:
18253 case OPC_REPLV_OB:
18254 case OPC_REPLV_PW:
18255 case OPC_REPLV_QH:
18256 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
18257 break;
18258 default: /* Invalid */
18259 MIPS_INVAL("MASK ABSQ_S.QH");
9c708c7f 18260 generate_exception_end(ctx, EXCP_RI);
099e5b4d
LA
18261 break;
18262 }
18263 break;
18264 case OPC_ADDU_OB_DSP:
18265 op2 = MASK_ADDU_OB(ctx->opcode);
18266 switch (op2) {
18267 case OPC_RADDU_L_OB:
18268 case OPC_SUBQ_PW:
18269 case OPC_SUBQ_S_PW:
18270 case OPC_SUBQ_QH:
18271 case OPC_SUBQ_S_QH:
18272 case OPC_SUBU_OB:
18273 case OPC_SUBU_S_OB:
18274 case OPC_SUBU_QH:
18275 case OPC_SUBU_S_QH:
18276 case OPC_SUBUH_OB:
18277 case OPC_SUBUH_R_OB:
18278 case OPC_ADDQ_PW:
18279 case OPC_ADDQ_S_PW:
18280 case OPC_ADDQ_QH:
18281 case OPC_ADDQ_S_QH:
18282 case OPC_ADDU_OB:
18283 case OPC_ADDU_S_OB:
18284 case OPC_ADDU_QH:
18285 case OPC_ADDU_S_QH:
18286 case OPC_ADDUH_OB:
18287 case OPC_ADDUH_R_OB:
18288 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
a22260ae 18289 break;
099e5b4d
LA
18290 case OPC_MULEQ_S_PW_QHL:
18291 case OPC_MULEQ_S_PW_QHR:
18292 case OPC_MULEU_S_QH_OBL:
18293 case OPC_MULEU_S_QH_OBR:
18294 case OPC_MULQ_RS_QH:
18295 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
1cb6686c 18296 break;
099e5b4d
LA
18297 default: /* Invalid */
18298 MIPS_INVAL("MASK ADDU.OB");
9c708c7f 18299 generate_exception_end(ctx, EXCP_RI);
26690560 18300 break;
099e5b4d
LA
18301 }
18302 break;
18303 case OPC_CMPU_EQ_OB_DSP:
18304 op2 = MASK_CMPU_EQ_OB(ctx->opcode);
18305 switch (op2) {
18306 case OPC_PRECR_SRA_QH_PW:
18307 case OPC_PRECR_SRA_R_QH_PW:
18308 /* Return value is rt. */
18309 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
b53371ed 18310 break;
099e5b4d
LA
18311 case OPC_PRECR_OB_QH:
18312 case OPC_PRECRQ_OB_QH:
18313 case OPC_PRECRQ_PW_L:
18314 case OPC_PRECRQ_QH_PW:
18315 case OPC_PRECRQ_RS_QH_PW:
18316 case OPC_PRECRQU_S_OB_QH:
18317 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
4368b29a 18318 break;
099e5b4d
LA
18319 case OPC_CMPU_EQ_OB:
18320 case OPC_CMPU_LT_OB:
18321 case OPC_CMPU_LE_OB:
18322 case OPC_CMP_EQ_QH:
18323 case OPC_CMP_LT_QH:
18324 case OPC_CMP_LE_QH:
18325 case OPC_CMP_EQ_PW:
18326 case OPC_CMP_LT_PW:
18327 case OPC_CMP_LE_PW:
18328 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
7a387fff 18329 break;
099e5b4d
LA
18330 case OPC_CMPGDU_EQ_OB:
18331 case OPC_CMPGDU_LT_OB:
18332 case OPC_CMPGDU_LE_OB:
18333 case OPC_CMPGU_EQ_OB:
18334 case OPC_CMPGU_LT_OB:
18335 case OPC_CMPGU_LE_OB:
18336 case OPC_PACKRL_PW:
18337 case OPC_PICK_OB:
18338 case OPC_PICK_PW:
18339 case OPC_PICK_QH:
18340 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
c6d6dd7c 18341 break;
099e5b4d
LA
18342 default: /* Invalid */
18343 MIPS_INVAL("MASK CMPU_EQ.OB");
9c708c7f 18344 generate_exception_end(ctx, EXCP_RI);
161f85e6 18345 break;
099e5b4d
LA
18346 }
18347 break;
18348 case OPC_DAPPEND_DSP:
18349 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
18350 break;
18351 case OPC_DEXTR_W_DSP:
18352 op2 = MASK_DEXTR_W(ctx->opcode);
18353 switch (op2) {
18354 case OPC_DEXTP:
18355 case OPC_DEXTPDP:
18356 case OPC_DEXTPDPV:
18357 case OPC_DEXTPV:
18358 case OPC_DEXTR_L:
18359 case OPC_DEXTR_R_L:
18360 case OPC_DEXTR_RS_L:
18361 case OPC_DEXTR_W:
18362 case OPC_DEXTR_R_W:
18363 case OPC_DEXTR_RS_W:
18364 case OPC_DEXTR_S_H:
18365 case OPC_DEXTRV_L:
18366 case OPC_DEXTRV_R_L:
18367 case OPC_DEXTRV_RS_L:
18368 case OPC_DEXTRV_S_H:
18369 case OPC_DEXTRV_W:
18370 case OPC_DEXTRV_R_W:
18371 case OPC_DEXTRV_RS_W:
18372 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
461c08df 18373 break;
099e5b4d
LA
18374 case OPC_DMTHLIP:
18375 case OPC_DSHILO:
18376 case OPC_DSHILOV:
18377 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
461c08df 18378 break;
099e5b4d
LA
18379 default: /* Invalid */
18380 MIPS_INVAL("MASK EXTR.W");
9c708c7f 18381 generate_exception_end(ctx, EXCP_RI);
461c08df 18382 break;
099e5b4d
LA
18383 }
18384 break;
18385 case OPC_DPAQ_W_QH_DSP:
18386 op2 = MASK_DPAQ_W_QH(ctx->opcode);
18387 switch (op2) {
18388 case OPC_DPAU_H_OBL:
18389 case OPC_DPAU_H_OBR:
18390 case OPC_DPSU_H_OBL:
18391 case OPC_DPSU_H_OBR:
18392 case OPC_DPA_W_QH:
18393 case OPC_DPAQ_S_W_QH:
18394 case OPC_DPS_W_QH:
18395 case OPC_DPSQ_S_W_QH:
18396 case OPC_MULSAQ_S_W_QH:
18397 case OPC_DPAQ_SA_L_PW:
18398 case OPC_DPSQ_SA_L_PW:
18399 case OPC_MULSAQ_S_L_PW:
18400 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
18401 break;
18402 case OPC_MAQ_S_W_QHLL:
18403 case OPC_MAQ_S_W_QHLR:
18404 case OPC_MAQ_S_W_QHRL:
18405 case OPC_MAQ_S_W_QHRR:
18406 case OPC_MAQ_SA_W_QHLL:
18407 case OPC_MAQ_SA_W_QHLR:
18408 case OPC_MAQ_SA_W_QHRL:
18409 case OPC_MAQ_SA_W_QHRR:
18410 case OPC_MAQ_S_L_PWL:
18411 case OPC_MAQ_S_L_PWR:
18412 case OPC_DMADD:
18413 case OPC_DMADDU:
18414 case OPC_DMSUB:
18415 case OPC_DMSUBU:
18416 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
26690560 18417 break;
099e5b4d
LA
18418 default: /* Invalid */
18419 MIPS_INVAL("MASK DPAQ.W.QH");
9c708c7f 18420 generate_exception_end(ctx, EXCP_RI);
b53371ed 18421 break;
099e5b4d
LA
18422 }
18423 break;
18424 case OPC_DINSV_DSP:
18425 op2 = MASK_INSV(ctx->opcode);
18426 switch (op2) {
18427 case OPC_DINSV:
18428 {
18429 TCGv t0, t1;
18430
18431 if (rt == 0) {
a22260ae
JL
18432 break;
18433 }
099e5b4d 18434 check_dsp(ctx);
1cb6686c 18435
099e5b4d
LA
18436 t0 = tcg_temp_new();
18437 t1 = tcg_temp_new();
1cb6686c 18438
099e5b4d
LA
18439 gen_load_gpr(t0, rt);
18440 gen_load_gpr(t1, rs);
1cb6686c 18441
099e5b4d 18442 gen_helper_dinsv(cpu_gpr[rt], cpu_env, t1, t0);
62eb3b9a 18443
099e5b4d
LA
18444 tcg_temp_free(t0);
18445 tcg_temp_free(t1);
77c5fa8b 18446 break;
099e5b4d 18447 }
7a387fff 18448 default: /* Invalid */
099e5b4d 18449 MIPS_INVAL("MASK DINSV");
9c708c7f 18450 generate_exception_end(ctx, EXCP_RI);
7a387fff
TS
18451 break;
18452 }
18453 break;
099e5b4d
LA
18454 case OPC_SHLL_OB_DSP:
18455 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
18456 break;
18457#endif
fac5a073
LA
18458 default: /* Invalid */
18459 MIPS_INVAL("special3_legacy");
9c708c7f 18460 generate_exception_end(ctx, EXCP_RI);
fac5a073
LA
18461 break;
18462 }
18463}
18464
18465static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx)
18466{
18467 int rs, rt, rd, sa;
18468 uint32_t op1, op2;
76964147 18469 int16_t imm;
fac5a073
LA
18470
18471 rs = (ctx->opcode >> 21) & 0x1f;
18472 rt = (ctx->opcode >> 16) & 0x1f;
18473 rd = (ctx->opcode >> 11) & 0x1f;
18474 sa = (ctx->opcode >> 6) & 0x1f;
76964147 18475 imm = sextract32(ctx->opcode, 7, 9);
fac5a073
LA
18476
18477 op1 = MASK_SPECIAL3(ctx->opcode);
76964147
JH
18478
18479 /*
18480 * EVA loads and stores overlap Loongson 2E instructions decoded by
18481 * decode_opc_special3_legacy(), so be careful to allow their decoding when
18482 * EVA is absent.
18483 */
18484 if (ctx->eva) {
18485 switch (op1) {
c2e19f3c
AM
18486 case OPC_LWLE:
18487 case OPC_LWRE:
76964147
JH
18488 check_insn_opc_removed(ctx, ISA_MIPS32R6);
18489 /* fall through */
c2e19f3c
AM
18490 case OPC_LBUE:
18491 case OPC_LHUE:
18492 case OPC_LBE:
18493 case OPC_LHE:
18494 case OPC_LLE:
18495 case OPC_LWE:
76964147
JH
18496 check_cp0_enabled(ctx);
18497 gen_ld(ctx, op1, rt, rs, imm);
18498 return;
c2e19f3c
AM
18499 case OPC_SWLE:
18500 case OPC_SWRE:
76964147
JH
18501 check_insn_opc_removed(ctx, ISA_MIPS32R6);
18502 /* fall through */
c2e19f3c
AM
18503 case OPC_SBE:
18504 case OPC_SHE:
76964147
JH
18505 case OPC_SWE:
18506 check_cp0_enabled(ctx);
18507 gen_st(ctx, op1, rt, rs, imm);
18508 return;
18509 case OPC_SCE:
18510 check_cp0_enabled(ctx);
18511 gen_st_cond(ctx, op1, rt, rs, imm);
18512 return;
18513 case OPC_CACHEE:
18514 check_cp0_enabled(ctx);
18515 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
18516 gen_cache_operation(ctx, rt, rs, imm);
18517 }
18518 /* Treat as NOP. */
18519 return;
18520 case OPC_PREFE:
18521 check_cp0_enabled(ctx);
18522 /* Treat as NOP. */
18523 return;
18524 }
18525 }
18526
fac5a073
LA
18527 switch (op1) {
18528 case OPC_EXT:
18529 case OPC_INS:
18530 check_insn(ctx, ISA_MIPS32R2);
18531 gen_bitops(ctx, op1, rt, rs, sa, rd);
18532 break;
18533 case OPC_BSHFL:
fac5a073 18534 op2 = MASK_BSHFL(ctx->opcode);
15eacb9b 18535 switch (op2) {
c2e19f3c
AM
18536 case OPC_ALIGN:
18537 case OPC_ALIGN_END:
15eacb9b
YK
18538 case OPC_BITSWAP:
18539 check_insn(ctx, ISA_MIPS32R6);
18540 decode_opc_special3_r6(env, ctx);
18541 break;
18542 default:
18543 check_insn(ctx, ISA_MIPS32R2);
18544 gen_bshfl(ctx, op2, rt, rd);
18545 break;
18546 }
fac5a073
LA
18547 break;
18548#if defined(TARGET_MIPS64)
c2e19f3c
AM
18549 case OPC_DEXTM:
18550 case OPC_DEXTU:
18551 case OPC_DEXT:
18552 case OPC_DINSM:
18553 case OPC_DINSU:
18554 case OPC_DINS:
fac5a073
LA
18555 check_insn(ctx, ISA_MIPS64R2);
18556 check_mips_64(ctx);
18557 gen_bitops(ctx, op1, rt, rs, sa, rd);
18558 break;
18559 case OPC_DBSHFL:
fac5a073 18560 op2 = MASK_DBSHFL(ctx->opcode);
15eacb9b 18561 switch (op2) {
c2e19f3c
AM
18562 case OPC_DALIGN:
18563 case OPC_DALIGN_END:
15eacb9b
YK
18564 case OPC_DBITSWAP:
18565 check_insn(ctx, ISA_MIPS32R6);
18566 decode_opc_special3_r6(env, ctx);
18567 break;
18568 default:
18569 check_insn(ctx, ISA_MIPS64R2);
18570 check_mips_64(ctx);
18571 op2 = MASK_DBSHFL(ctx->opcode);
18572 gen_bshfl(ctx, op2, rt, rd);
18573 break;
18574 }
fac5a073
LA
18575 break;
18576#endif
18577 case OPC_RDHWR:
b00c7218 18578 gen_rdhwr(ctx, rt, rd, extract32(ctx->opcode, 6, 3));
fac5a073
LA
18579 break;
18580 case OPC_FORK:
18581 check_insn(ctx, ASE_MT);
18582 {
18583 TCGv t0 = tcg_temp_new();
18584 TCGv t1 = tcg_temp_new();
18585
18586 gen_load_gpr(t0, rt);
18587 gen_load_gpr(t1, rs);
18588 gen_helper_fork(t0, t1);
18589 tcg_temp_free(t0);
18590 tcg_temp_free(t1);
18591 }
18592 break;
18593 case OPC_YIELD:
18594 check_insn(ctx, ASE_MT);
18595 {
18596 TCGv t0 = tcg_temp_new();
18597
fac5a073
LA
18598 gen_load_gpr(t0, rs);
18599 gen_helper_yield(t0, cpu_env, t0);
18600 gen_store_gpr(t0, rd);
18601 tcg_temp_free(t0);
18602 }
18603 break;
10dc65db
LA
18604 default:
18605 if (ctx->insn_flags & ISA_MIPS32R6) {
18606 decode_opc_special3_r6(env, ctx);
18607 } else {
18608 decode_opc_special3_legacy(env, ctx);
18609 }
099e5b4d
LA
18610 }
18611}
18612
863f264d
YK
18613/* MIPS SIMD Architecture (MSA) */
18614static inline int check_msa_access(DisasContext *ctx)
18615{
18616 if (unlikely((ctx->hflags & MIPS_HFLAG_FPU) &&
18617 !(ctx->hflags & MIPS_HFLAG_F64))) {
9c708c7f 18618 generate_exception_end(ctx, EXCP_RI);
863f264d
YK
18619 return 0;
18620 }
18621
18622 if (unlikely(!(ctx->hflags & MIPS_HFLAG_MSA))) {
18623 if (ctx->insn_flags & ASE_MSA) {
9c708c7f 18624 generate_exception_end(ctx, EXCP_MSADIS);
863f264d
YK
18625 return 0;
18626 } else {
9c708c7f 18627 generate_exception_end(ctx, EXCP_RI);
863f264d
YK
18628 return 0;
18629 }
18630 }
18631 return 1;
18632}
18633
5692c6e1
YK
18634static void gen_check_zero_element(TCGv tresult, uint8_t df, uint8_t wt)
18635{
18636 /* generates tcg ops to check if any element is 0 */
18637 /* Note this function only works with MSA_WRLEN = 128 */
18638 uint64_t eval_zero_or_big = 0;
18639 uint64_t eval_big = 0;
18640 TCGv_i64 t0 = tcg_temp_new_i64();
18641 TCGv_i64 t1 = tcg_temp_new_i64();
18642 switch (df) {
18643 case DF_BYTE:
18644 eval_zero_or_big = 0x0101010101010101ULL;
18645 eval_big = 0x8080808080808080ULL;
18646 break;
18647 case DF_HALF:
18648 eval_zero_or_big = 0x0001000100010001ULL;
18649 eval_big = 0x8000800080008000ULL;
18650 break;
18651 case DF_WORD:
18652 eval_zero_or_big = 0x0000000100000001ULL;
18653 eval_big = 0x8000000080000000ULL;
18654 break;
18655 case DF_DOUBLE:
18656 eval_zero_or_big = 0x0000000000000001ULL;
18657 eval_big = 0x8000000000000000ULL;
18658 break;
18659 }
18660 tcg_gen_subi_i64(t0, msa_wr_d[wt<<1], eval_zero_or_big);
18661 tcg_gen_andc_i64(t0, t0, msa_wr_d[wt<<1]);
18662 tcg_gen_andi_i64(t0, t0, eval_big);
18663 tcg_gen_subi_i64(t1, msa_wr_d[(wt<<1)+1], eval_zero_or_big);
18664 tcg_gen_andc_i64(t1, t1, msa_wr_d[(wt<<1)+1]);
18665 tcg_gen_andi_i64(t1, t1, eval_big);
18666 tcg_gen_or_i64(t0, t0, t1);
18667 /* if all bits are zero then all elements are not zero */
18668 /* if some bit is non-zero then some element is zero */
18669 tcg_gen_setcondi_i64(TCG_COND_NE, t0, t0, 0);
18670 tcg_gen_trunc_i64_tl(tresult, t0);
18671 tcg_temp_free_i64(t0);
18672 tcg_temp_free_i64(t1);
18673}
18674
18675static void gen_msa_branch(CPUMIPSState *env, DisasContext *ctx, uint32_t op1)
18676{
18677 uint8_t df = (ctx->opcode >> 21) & 0x3;
18678 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
18679 int64_t s16 = (int16_t)ctx->opcode;
18680
18681 check_msa_access(ctx);
18682
075a1fe7 18683 if (ctx->hflags & MIPS_HFLAG_BMASK) {
9c708c7f 18684 generate_exception_end(ctx, EXCP_RI);
5692c6e1
YK
18685 return;
18686 }
18687 switch (op1) {
18688 case OPC_BZ_V:
18689 case OPC_BNZ_V:
18690 {
18691 TCGv_i64 t0 = tcg_temp_new_i64();
18692 tcg_gen_or_i64(t0, msa_wr_d[wt<<1], msa_wr_d[(wt<<1)+1]);
18693 tcg_gen_setcondi_i64((op1 == OPC_BZ_V) ?
18694 TCG_COND_EQ : TCG_COND_NE, t0, t0, 0);
18695 tcg_gen_trunc_i64_tl(bcond, t0);
18696 tcg_temp_free_i64(t0);
18697 }
18698 break;
18699 case OPC_BZ_B:
18700 case OPC_BZ_H:
18701 case OPC_BZ_W:
18702 case OPC_BZ_D:
18703 gen_check_zero_element(bcond, df, wt);
18704 break;
18705 case OPC_BNZ_B:
18706 case OPC_BNZ_H:
18707 case OPC_BNZ_W:
18708 case OPC_BNZ_D:
18709 gen_check_zero_element(bcond, df, wt);
18710 tcg_gen_setcondi_tl(TCG_COND_EQ, bcond, bcond, 0);
18711 break;
18712 }
18713
eeb3bba8 18714 ctx->btarget = ctx->base.pc_next + (s16 << 2) + 4;
5692c6e1
YK
18715
18716 ctx->hflags |= MIPS_HFLAG_BC;
18717 ctx->hflags |= MIPS_HFLAG_BDS32;
18718}
18719
4c789546
YK
18720static void gen_msa_i8(CPUMIPSState *env, DisasContext *ctx)
18721{
18722#define MASK_MSA_I8(op) (MASK_MSA_MINOR(op) | (op & (0x03 << 24)))
18723 uint8_t i8 = (ctx->opcode >> 16) & 0xff;
18724 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18725 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18726
18727 TCGv_i32 twd = tcg_const_i32(wd);
18728 TCGv_i32 tws = tcg_const_i32(ws);
18729 TCGv_i32 ti8 = tcg_const_i32(i8);
18730
18731 switch (MASK_MSA_I8(ctx->opcode)) {
18732 case OPC_ANDI_B:
18733 gen_helper_msa_andi_b(cpu_env, twd, tws, ti8);
18734 break;
18735 case OPC_ORI_B:
18736 gen_helper_msa_ori_b(cpu_env, twd, tws, ti8);
18737 break;
18738 case OPC_NORI_B:
18739 gen_helper_msa_nori_b(cpu_env, twd, tws, ti8);
18740 break;
18741 case OPC_XORI_B:
18742 gen_helper_msa_xori_b(cpu_env, twd, tws, ti8);
18743 break;
18744 case OPC_BMNZI_B:
18745 gen_helper_msa_bmnzi_b(cpu_env, twd, tws, ti8);
18746 break;
18747 case OPC_BMZI_B:
18748 gen_helper_msa_bmzi_b(cpu_env, twd, tws, ti8);
18749 break;
18750 case OPC_BSELI_B:
18751 gen_helper_msa_bseli_b(cpu_env, twd, tws, ti8);
18752 break;
18753 case OPC_SHF_B:
18754 case OPC_SHF_H:
18755 case OPC_SHF_W:
18756 {
18757 uint8_t df = (ctx->opcode >> 24) & 0x3;
18758 if (df == DF_DOUBLE) {
9c708c7f 18759 generate_exception_end(ctx, EXCP_RI);
4c789546
YK
18760 } else {
18761 TCGv_i32 tdf = tcg_const_i32(df);
18762 gen_helper_msa_shf_df(cpu_env, tdf, twd, tws, ti8);
18763 tcg_temp_free_i32(tdf);
18764 }
18765 }
18766 break;
18767 default:
18768 MIPS_INVAL("MSA instruction");
9c708c7f 18769 generate_exception_end(ctx, EXCP_RI);
4c789546
YK
18770 break;
18771 }
18772
18773 tcg_temp_free_i32(twd);
18774 tcg_temp_free_i32(tws);
18775 tcg_temp_free_i32(ti8);
18776}
18777
80e71591
YK
18778static void gen_msa_i5(CPUMIPSState *env, DisasContext *ctx)
18779{
18780#define MASK_MSA_I5(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
18781 uint8_t df = (ctx->opcode >> 21) & 0x3;
18782 int8_t s5 = (int8_t) sextract32(ctx->opcode, 16, 5);
18783 uint8_t u5 = (ctx->opcode >> 16) & 0x1f;
18784 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18785 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18786
18787 TCGv_i32 tdf = tcg_const_i32(df);
18788 TCGv_i32 twd = tcg_const_i32(wd);
18789 TCGv_i32 tws = tcg_const_i32(ws);
18790 TCGv_i32 timm = tcg_temp_new_i32();
18791 tcg_gen_movi_i32(timm, u5);
18792
18793 switch (MASK_MSA_I5(ctx->opcode)) {
18794 case OPC_ADDVI_df:
18795 gen_helper_msa_addvi_df(cpu_env, tdf, twd, tws, timm);
18796 break;
18797 case OPC_SUBVI_df:
18798 gen_helper_msa_subvi_df(cpu_env, tdf, twd, tws, timm);
18799 break;
18800 case OPC_MAXI_S_df:
18801 tcg_gen_movi_i32(timm, s5);
18802 gen_helper_msa_maxi_s_df(cpu_env, tdf, twd, tws, timm);
18803 break;
18804 case OPC_MAXI_U_df:
18805 gen_helper_msa_maxi_u_df(cpu_env, tdf, twd, tws, timm);
18806 break;
18807 case OPC_MINI_S_df:
18808 tcg_gen_movi_i32(timm, s5);
18809 gen_helper_msa_mini_s_df(cpu_env, tdf, twd, tws, timm);
18810 break;
18811 case OPC_MINI_U_df:
18812 gen_helper_msa_mini_u_df(cpu_env, tdf, twd, tws, timm);
18813 break;
18814 case OPC_CEQI_df:
18815 tcg_gen_movi_i32(timm, s5);
18816 gen_helper_msa_ceqi_df(cpu_env, tdf, twd, tws, timm);
18817 break;
18818 case OPC_CLTI_S_df:
18819 tcg_gen_movi_i32(timm, s5);
18820 gen_helper_msa_clti_s_df(cpu_env, tdf, twd, tws, timm);
18821 break;
18822 case OPC_CLTI_U_df:
18823 gen_helper_msa_clti_u_df(cpu_env, tdf, twd, tws, timm);
18824 break;
18825 case OPC_CLEI_S_df:
18826 tcg_gen_movi_i32(timm, s5);
18827 gen_helper_msa_clei_s_df(cpu_env, tdf, twd, tws, timm);
18828 break;
18829 case OPC_CLEI_U_df:
18830 gen_helper_msa_clei_u_df(cpu_env, tdf, twd, tws, timm);
18831 break;
18832 case OPC_LDI_df:
18833 {
18834 int32_t s10 = sextract32(ctx->opcode, 11, 10);
18835 tcg_gen_movi_i32(timm, s10);
18836 gen_helper_msa_ldi_df(cpu_env, tdf, twd, timm);
18837 }
18838 break;
18839 default:
18840 MIPS_INVAL("MSA instruction");
9c708c7f 18841 generate_exception_end(ctx, EXCP_RI);
80e71591
YK
18842 break;
18843 }
18844
18845 tcg_temp_free_i32(tdf);
18846 tcg_temp_free_i32(twd);
18847 tcg_temp_free_i32(tws);
18848 tcg_temp_free_i32(timm);
18849}
18850
d4cf28de
YK
18851static void gen_msa_bit(CPUMIPSState *env, DisasContext *ctx)
18852{
18853#define MASK_MSA_BIT(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
18854 uint8_t dfm = (ctx->opcode >> 16) & 0x7f;
18855 uint32_t df = 0, m = 0;
18856 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18857 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18858
18859 TCGv_i32 tdf;
18860 TCGv_i32 tm;
18861 TCGv_i32 twd;
18862 TCGv_i32 tws;
18863
18864 if ((dfm & 0x40) == 0x00) {
18865 m = dfm & 0x3f;
18866 df = DF_DOUBLE;
18867 } else if ((dfm & 0x60) == 0x40) {
18868 m = dfm & 0x1f;
18869 df = DF_WORD;
18870 } else if ((dfm & 0x70) == 0x60) {
18871 m = dfm & 0x0f;
18872 df = DF_HALF;
18873 } else if ((dfm & 0x78) == 0x70) {
18874 m = dfm & 0x7;
18875 df = DF_BYTE;
18876 } else {
9c708c7f 18877 generate_exception_end(ctx, EXCP_RI);
d4cf28de
YK
18878 return;
18879 }
18880
18881 tdf = tcg_const_i32(df);
18882 tm = tcg_const_i32(m);
18883 twd = tcg_const_i32(wd);
18884 tws = tcg_const_i32(ws);
18885
18886 switch (MASK_MSA_BIT(ctx->opcode)) {
18887 case OPC_SLLI_df:
18888 gen_helper_msa_slli_df(cpu_env, tdf, twd, tws, tm);
18889 break;
18890 case OPC_SRAI_df:
18891 gen_helper_msa_srai_df(cpu_env, tdf, twd, tws, tm);
18892 break;
18893 case OPC_SRLI_df:
18894 gen_helper_msa_srli_df(cpu_env, tdf, twd, tws, tm);
18895 break;
18896 case OPC_BCLRI_df:
18897 gen_helper_msa_bclri_df(cpu_env, tdf, twd, tws, tm);
18898 break;
18899 case OPC_BSETI_df:
18900 gen_helper_msa_bseti_df(cpu_env, tdf, twd, tws, tm);
18901 break;
18902 case OPC_BNEGI_df:
18903 gen_helper_msa_bnegi_df(cpu_env, tdf, twd, tws, tm);
18904 break;
18905 case OPC_BINSLI_df:
18906 gen_helper_msa_binsli_df(cpu_env, tdf, twd, tws, tm);
18907 break;
18908 case OPC_BINSRI_df:
18909 gen_helper_msa_binsri_df(cpu_env, tdf, twd, tws, tm);
18910 break;
18911 case OPC_SAT_S_df:
18912 gen_helper_msa_sat_s_df(cpu_env, tdf, twd, tws, tm);
18913 break;
18914 case OPC_SAT_U_df:
18915 gen_helper_msa_sat_u_df(cpu_env, tdf, twd, tws, tm);
18916 break;
18917 case OPC_SRARI_df:
18918 gen_helper_msa_srari_df(cpu_env, tdf, twd, tws, tm);
18919 break;
18920 case OPC_SRLRI_df:
18921 gen_helper_msa_srlri_df(cpu_env, tdf, twd, tws, tm);
18922 break;
18923 default:
18924 MIPS_INVAL("MSA instruction");
9c708c7f 18925 generate_exception_end(ctx, EXCP_RI);
d4cf28de
YK
18926 break;
18927 }
18928
18929 tcg_temp_free_i32(tdf);
18930 tcg_temp_free_i32(tm);
18931 tcg_temp_free_i32(twd);
18932 tcg_temp_free_i32(tws);
18933}
18934
28f99f08
YK
18935static void gen_msa_3r(CPUMIPSState *env, DisasContext *ctx)
18936{
18937#define MASK_MSA_3R(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
18938 uint8_t df = (ctx->opcode >> 21) & 0x3;
18939 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
18940 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18941 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18942
18943 TCGv_i32 tdf = tcg_const_i32(df);
18944 TCGv_i32 twd = tcg_const_i32(wd);
18945 TCGv_i32 tws = tcg_const_i32(ws);
18946 TCGv_i32 twt = tcg_const_i32(wt);
18947
18948 switch (MASK_MSA_3R(ctx->opcode)) {
18949 case OPC_SLL_df:
18950 gen_helper_msa_sll_df(cpu_env, tdf, twd, tws, twt);
18951 break;
18952 case OPC_ADDV_df:
18953 gen_helper_msa_addv_df(cpu_env, tdf, twd, tws, twt);
18954 break;
18955 case OPC_CEQ_df:
18956 gen_helper_msa_ceq_df(cpu_env, tdf, twd, tws, twt);
18957 break;
18958 case OPC_ADD_A_df:
18959 gen_helper_msa_add_a_df(cpu_env, tdf, twd, tws, twt);
18960 break;
18961 case OPC_SUBS_S_df:
18962 gen_helper_msa_subs_s_df(cpu_env, tdf, twd, tws, twt);
18963 break;
18964 case OPC_MULV_df:
18965 gen_helper_msa_mulv_df(cpu_env, tdf, twd, tws, twt);
18966 break;
18967 case OPC_SLD_df:
18968 gen_helper_msa_sld_df(cpu_env, tdf, twd, tws, twt);
18969 break;
18970 case OPC_VSHF_df:
18971 gen_helper_msa_vshf_df(cpu_env, tdf, twd, tws, twt);
18972 break;
18973 case OPC_SRA_df:
18974 gen_helper_msa_sra_df(cpu_env, tdf, twd, tws, twt);
18975 break;
18976 case OPC_SUBV_df:
18977 gen_helper_msa_subv_df(cpu_env, tdf, twd, tws, twt);
18978 break;
18979 case OPC_ADDS_A_df:
18980 gen_helper_msa_adds_a_df(cpu_env, tdf, twd, tws, twt);
18981 break;
18982 case OPC_SUBS_U_df:
18983 gen_helper_msa_subs_u_df(cpu_env, tdf, twd, tws, twt);
18984 break;
18985 case OPC_MADDV_df:
18986 gen_helper_msa_maddv_df(cpu_env, tdf, twd, tws, twt);
18987 break;
18988 case OPC_SPLAT_df:
18989 gen_helper_msa_splat_df(cpu_env, tdf, twd, tws, twt);
18990 break;
18991 case OPC_SRAR_df:
18992 gen_helper_msa_srar_df(cpu_env, tdf, twd, tws, twt);
18993 break;
18994 case OPC_SRL_df:
18995 gen_helper_msa_srl_df(cpu_env, tdf, twd, tws, twt);
18996 break;
18997 case OPC_MAX_S_df:
18998 gen_helper_msa_max_s_df(cpu_env, tdf, twd, tws, twt);
18999 break;
19000 case OPC_CLT_S_df:
19001 gen_helper_msa_clt_s_df(cpu_env, tdf, twd, tws, twt);
19002 break;
19003 case OPC_ADDS_S_df:
19004 gen_helper_msa_adds_s_df(cpu_env, tdf, twd, tws, twt);
19005 break;
19006 case OPC_SUBSUS_U_df:
19007 gen_helper_msa_subsus_u_df(cpu_env, tdf, twd, tws, twt);
19008 break;
19009 case OPC_MSUBV_df:
19010 gen_helper_msa_msubv_df(cpu_env, tdf, twd, tws, twt);
19011 break;
19012 case OPC_PCKEV_df:
19013 gen_helper_msa_pckev_df(cpu_env, tdf, twd, tws, twt);
19014 break;
19015 case OPC_SRLR_df:
19016 gen_helper_msa_srlr_df(cpu_env, tdf, twd, tws, twt);
19017 break;
19018 case OPC_BCLR_df:
19019 gen_helper_msa_bclr_df(cpu_env, tdf, twd, tws, twt);
19020 break;
19021 case OPC_MAX_U_df:
19022 gen_helper_msa_max_u_df(cpu_env, tdf, twd, tws, twt);
19023 break;
19024 case OPC_CLT_U_df:
19025 gen_helper_msa_clt_u_df(cpu_env, tdf, twd, tws, twt);
19026 break;
19027 case OPC_ADDS_U_df:
19028 gen_helper_msa_adds_u_df(cpu_env, tdf, twd, tws, twt);
19029 break;
19030 case OPC_SUBSUU_S_df:
19031 gen_helper_msa_subsuu_s_df(cpu_env, tdf, twd, tws, twt);
19032 break;
19033 case OPC_PCKOD_df:
19034 gen_helper_msa_pckod_df(cpu_env, tdf, twd, tws, twt);
19035 break;
19036 case OPC_BSET_df:
19037 gen_helper_msa_bset_df(cpu_env, tdf, twd, tws, twt);
19038 break;
19039 case OPC_MIN_S_df:
19040 gen_helper_msa_min_s_df(cpu_env, tdf, twd, tws, twt);
19041 break;
19042 case OPC_CLE_S_df:
19043 gen_helper_msa_cle_s_df(cpu_env, tdf, twd, tws, twt);
19044 break;
19045 case OPC_AVE_S_df:
19046 gen_helper_msa_ave_s_df(cpu_env, tdf, twd, tws, twt);
19047 break;
19048 case OPC_ASUB_S_df:
19049 gen_helper_msa_asub_s_df(cpu_env, tdf, twd, tws, twt);
19050 break;
19051 case OPC_DIV_S_df:
19052 gen_helper_msa_div_s_df(cpu_env, tdf, twd, tws, twt);
19053 break;
19054 case OPC_ILVL_df:
19055 gen_helper_msa_ilvl_df(cpu_env, tdf, twd, tws, twt);
19056 break;
19057 case OPC_BNEG_df:
19058 gen_helper_msa_bneg_df(cpu_env, tdf, twd, tws, twt);
19059 break;
19060 case OPC_MIN_U_df:
19061 gen_helper_msa_min_u_df(cpu_env, tdf, twd, tws, twt);
19062 break;
19063 case OPC_CLE_U_df:
19064 gen_helper_msa_cle_u_df(cpu_env, tdf, twd, tws, twt);
19065 break;
19066 case OPC_AVE_U_df:
19067 gen_helper_msa_ave_u_df(cpu_env, tdf, twd, tws, twt);
19068 break;
19069 case OPC_ASUB_U_df:
19070 gen_helper_msa_asub_u_df(cpu_env, tdf, twd, tws, twt);
19071 break;
19072 case OPC_DIV_U_df:
19073 gen_helper_msa_div_u_df(cpu_env, tdf, twd, tws, twt);
19074 break;
19075 case OPC_ILVR_df:
19076 gen_helper_msa_ilvr_df(cpu_env, tdf, twd, tws, twt);
19077 break;
19078 case OPC_BINSL_df:
19079 gen_helper_msa_binsl_df(cpu_env, tdf, twd, tws, twt);
19080 break;
19081 case OPC_MAX_A_df:
19082 gen_helper_msa_max_a_df(cpu_env, tdf, twd, tws, twt);
19083 break;
19084 case OPC_AVER_S_df:
19085 gen_helper_msa_aver_s_df(cpu_env, tdf, twd, tws, twt);
19086 break;
19087 case OPC_MOD_S_df:
19088 gen_helper_msa_mod_s_df(cpu_env, tdf, twd, tws, twt);
19089 break;
19090 case OPC_ILVEV_df:
19091 gen_helper_msa_ilvev_df(cpu_env, tdf, twd, tws, twt);
19092 break;
19093 case OPC_BINSR_df:
19094 gen_helper_msa_binsr_df(cpu_env, tdf, twd, tws, twt);
19095 break;
19096 case OPC_MIN_A_df:
19097 gen_helper_msa_min_a_df(cpu_env, tdf, twd, tws, twt);
19098 break;
19099 case OPC_AVER_U_df:
19100 gen_helper_msa_aver_u_df(cpu_env, tdf, twd, tws, twt);
19101 break;
19102 case OPC_MOD_U_df:
19103 gen_helper_msa_mod_u_df(cpu_env, tdf, twd, tws, twt);
19104 break;
19105 case OPC_ILVOD_df:
19106 gen_helper_msa_ilvod_df(cpu_env, tdf, twd, tws, twt);
19107 break;
19108
19109 case OPC_DOTP_S_df:
19110 case OPC_DOTP_U_df:
19111 case OPC_DPADD_S_df:
19112 case OPC_DPADD_U_df:
19113 case OPC_DPSUB_S_df:
19114 case OPC_HADD_S_df:
19115 case OPC_DPSUB_U_df:
19116 case OPC_HADD_U_df:
19117 case OPC_HSUB_S_df:
19118 case OPC_HSUB_U_df:
19119 if (df == DF_BYTE) {
9c708c7f
PD
19120 generate_exception_end(ctx, EXCP_RI);
19121 break;
28f99f08
YK
19122 }
19123 switch (MASK_MSA_3R(ctx->opcode)) {
19124 case OPC_DOTP_S_df:
19125 gen_helper_msa_dotp_s_df(cpu_env, tdf, twd, tws, twt);
19126 break;
19127 case OPC_DOTP_U_df:
19128 gen_helper_msa_dotp_u_df(cpu_env, tdf, twd, tws, twt);
19129 break;
19130 case OPC_DPADD_S_df:
19131 gen_helper_msa_dpadd_s_df(cpu_env, tdf, twd, tws, twt);
19132 break;
19133 case OPC_DPADD_U_df:
19134 gen_helper_msa_dpadd_u_df(cpu_env, tdf, twd, tws, twt);
19135 break;
19136 case OPC_DPSUB_S_df:
19137 gen_helper_msa_dpsub_s_df(cpu_env, tdf, twd, tws, twt);
19138 break;
19139 case OPC_HADD_S_df:
19140 gen_helper_msa_hadd_s_df(cpu_env, tdf, twd, tws, twt);
19141 break;
19142 case OPC_DPSUB_U_df:
19143 gen_helper_msa_dpsub_u_df(cpu_env, tdf, twd, tws, twt);
19144 break;
19145 case OPC_HADD_U_df:
19146 gen_helper_msa_hadd_u_df(cpu_env, tdf, twd, tws, twt);
19147 break;
19148 case OPC_HSUB_S_df:
19149 gen_helper_msa_hsub_s_df(cpu_env, tdf, twd, tws, twt);
19150 break;
19151 case OPC_HSUB_U_df:
19152 gen_helper_msa_hsub_u_df(cpu_env, tdf, twd, tws, twt);
19153 break;
19154 }
19155 break;
19156 default:
19157 MIPS_INVAL("MSA instruction");
9c708c7f 19158 generate_exception_end(ctx, EXCP_RI);
28f99f08
YK
19159 break;
19160 }
19161 tcg_temp_free_i32(twd);
19162 tcg_temp_free_i32(tws);
19163 tcg_temp_free_i32(twt);
19164 tcg_temp_free_i32(tdf);
19165}
19166
1e608ec1
YK
19167static void gen_msa_elm_3e(CPUMIPSState *env, DisasContext *ctx)
19168{
19169#define MASK_MSA_ELM_DF3E(op) (MASK_MSA_MINOR(op) | (op & (0x3FF << 16)))
19170 uint8_t source = (ctx->opcode >> 11) & 0x1f;
19171 uint8_t dest = (ctx->opcode >> 6) & 0x1f;
19172 TCGv telm = tcg_temp_new();
19173 TCGv_i32 tsr = tcg_const_i32(source);
19174 TCGv_i32 tdt = tcg_const_i32(dest);
19175
19176 switch (MASK_MSA_ELM_DF3E(ctx->opcode)) {
19177 case OPC_CTCMSA:
19178 gen_load_gpr(telm, source);
19179 gen_helper_msa_ctcmsa(cpu_env, telm, tdt);
19180 break;
19181 case OPC_CFCMSA:
19182 gen_helper_msa_cfcmsa(telm, cpu_env, tsr);
19183 gen_store_gpr(telm, dest);
19184 break;
19185 case OPC_MOVE_V:
19186 gen_helper_msa_move_v(cpu_env, tdt, tsr);
19187 break;
19188 default:
19189 MIPS_INVAL("MSA instruction");
9c708c7f 19190 generate_exception_end(ctx, EXCP_RI);
1e608ec1
YK
19191 break;
19192 }
19193
19194 tcg_temp_free(telm);
19195 tcg_temp_free_i32(tdt);
19196 tcg_temp_free_i32(tsr);
19197}
19198
19199static void gen_msa_elm_df(CPUMIPSState *env, DisasContext *ctx, uint32_t df,
19200 uint32_t n)
19201{
19202#define MASK_MSA_ELM(op) (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
19203 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
19204 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
19205
19206 TCGv_i32 tws = tcg_const_i32(ws);
19207 TCGv_i32 twd = tcg_const_i32(wd);
19208 TCGv_i32 tn = tcg_const_i32(n);
19209 TCGv_i32 tdf = tcg_const_i32(df);
19210
19211 switch (MASK_MSA_ELM(ctx->opcode)) {
19212 case OPC_SLDI_df:
19213 gen_helper_msa_sldi_df(cpu_env, tdf, twd, tws, tn);
19214 break;
19215 case OPC_SPLATI_df:
19216 gen_helper_msa_splati_df(cpu_env, tdf, twd, tws, tn);
19217 break;
19218 case OPC_INSVE_df:
19219 gen_helper_msa_insve_df(cpu_env, tdf, twd, tws, tn);
19220 break;
19221 case OPC_COPY_S_df:
19222 case OPC_COPY_U_df:
19223 case OPC_INSERT_df:
19224#if !defined(TARGET_MIPS64)
19225 /* Double format valid only for MIPS64 */
19226 if (df == DF_DOUBLE) {
9c708c7f 19227 generate_exception_end(ctx, EXCP_RI);
1e608ec1
YK
19228 break;
19229 }
19230#endif
19231 switch (MASK_MSA_ELM(ctx->opcode)) {
19232 case OPC_COPY_S_df:
cab48881
MD
19233 if (likely(wd != 0)) {
19234 gen_helper_msa_copy_s_df(cpu_env, tdf, twd, tws, tn);
19235 }
1e608ec1
YK
19236 break;
19237 case OPC_COPY_U_df:
cab48881
MD
19238 if (likely(wd != 0)) {
19239 gen_helper_msa_copy_u_df(cpu_env, tdf, twd, tws, tn);
19240 }
1e608ec1
YK
19241 break;
19242 case OPC_INSERT_df:
19243 gen_helper_msa_insert_df(cpu_env, tdf, twd, tws, tn);
19244 break;
19245 }
19246 break;
19247 default:
19248 MIPS_INVAL("MSA instruction");
9c708c7f 19249 generate_exception_end(ctx, EXCP_RI);
1e608ec1
YK
19250 }
19251 tcg_temp_free_i32(twd);
19252 tcg_temp_free_i32(tws);
19253 tcg_temp_free_i32(tn);
19254 tcg_temp_free_i32(tdf);
19255}
19256
19257static void gen_msa_elm(CPUMIPSState *env, DisasContext *ctx)
19258{
19259 uint8_t dfn = (ctx->opcode >> 16) & 0x3f;
19260 uint32_t df = 0, n = 0;
19261
19262 if ((dfn & 0x30) == 0x00) {
19263 n = dfn & 0x0f;
19264 df = DF_BYTE;
19265 } else if ((dfn & 0x38) == 0x20) {
19266 n = dfn & 0x07;
19267 df = DF_HALF;
19268 } else if ((dfn & 0x3c) == 0x30) {
19269 n = dfn & 0x03;
19270 df = DF_WORD;
19271 } else if ((dfn & 0x3e) == 0x38) {
19272 n = dfn & 0x01;
19273 df = DF_DOUBLE;
19274 } else if (dfn == 0x3E) {
19275 /* CTCMSA, CFCMSA, MOVE.V */
19276 gen_msa_elm_3e(env, ctx);
19277 return;
19278 } else {
9c708c7f 19279 generate_exception_end(ctx, EXCP_RI);
1e608ec1
YK
19280 return;
19281 }
19282
19283 gen_msa_elm_df(env, ctx, df, n);
19284}
19285
7d05b9c8
YK
19286static void gen_msa_3rf(CPUMIPSState *env, DisasContext *ctx)
19287{
19288#define MASK_MSA_3RF(op) (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
19289 uint8_t df = (ctx->opcode >> 21) & 0x1;
19290 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
19291 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
19292 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
19293
19294 TCGv_i32 twd = tcg_const_i32(wd);
19295 TCGv_i32 tws = tcg_const_i32(ws);
19296 TCGv_i32 twt = tcg_const_i32(wt);
19297 TCGv_i32 tdf = tcg_temp_new_i32();
19298
19299 /* adjust df value for floating-point instruction */
19300 tcg_gen_movi_i32(tdf, df + 2);
19301
19302 switch (MASK_MSA_3RF(ctx->opcode)) {
19303 case OPC_FCAF_df:
19304 gen_helper_msa_fcaf_df(cpu_env, tdf, twd, tws, twt);
19305 break;
19306 case OPC_FADD_df:
19307 gen_helper_msa_fadd_df(cpu_env, tdf, twd, tws, twt);
19308 break;
19309 case OPC_FCUN_df:
19310 gen_helper_msa_fcun_df(cpu_env, tdf, twd, tws, twt);
19311 break;
19312 case OPC_FSUB_df:
19313 gen_helper_msa_fsub_df(cpu_env, tdf, twd, tws, twt);
19314 break;
19315 case OPC_FCOR_df:
19316 gen_helper_msa_fcor_df(cpu_env, tdf, twd, tws, twt);
19317 break;
19318 case OPC_FCEQ_df:
19319 gen_helper_msa_fceq_df(cpu_env, tdf, twd, tws, twt);
19320 break;
19321 case OPC_FMUL_df:
19322 gen_helper_msa_fmul_df(cpu_env, tdf, twd, tws, twt);
19323 break;
19324 case OPC_FCUNE_df:
19325 gen_helper_msa_fcune_df(cpu_env, tdf, twd, tws, twt);
19326 break;
19327 case OPC_FCUEQ_df:
19328 gen_helper_msa_fcueq_df(cpu_env, tdf, twd, tws, twt);
19329 break;
19330 case OPC_FDIV_df:
19331 gen_helper_msa_fdiv_df(cpu_env, tdf, twd, tws, twt);
19332 break;
19333 case OPC_FCNE_df:
19334 gen_helper_msa_fcne_df(cpu_env, tdf, twd, tws, twt);
19335 break;
19336 case OPC_FCLT_df:
19337 gen_helper_msa_fclt_df(cpu_env, tdf, twd, tws, twt);
19338 break;
19339 case OPC_FMADD_df:
19340 gen_helper_msa_fmadd_df(cpu_env, tdf, twd, tws, twt);
19341 break;
19342 case OPC_MUL_Q_df:
19343 tcg_gen_movi_i32(tdf, df + 1);
19344 gen_helper_msa_mul_q_df(cpu_env, tdf, twd, tws, twt);
19345 break;
19346 case OPC_FCULT_df:
19347 gen_helper_msa_fcult_df(cpu_env, tdf, twd, tws, twt);
19348 break;
19349 case OPC_FMSUB_df:
19350 gen_helper_msa_fmsub_df(cpu_env, tdf, twd, tws, twt);
19351 break;
19352 case OPC_MADD_Q_df:
19353 tcg_gen_movi_i32(tdf, df + 1);
19354 gen_helper_msa_madd_q_df(cpu_env, tdf, twd, tws, twt);
19355 break;
19356 case OPC_FCLE_df:
19357 gen_helper_msa_fcle_df(cpu_env, tdf, twd, tws, twt);
19358 break;
19359 case OPC_MSUB_Q_df:
19360 tcg_gen_movi_i32(tdf, df + 1);
19361 gen_helper_msa_msub_q_df(cpu_env, tdf, twd, tws, twt);
19362 break;
19363 case OPC_FCULE_df:
19364 gen_helper_msa_fcule_df(cpu_env, tdf, twd, tws, twt);
19365 break;
19366 case OPC_FEXP2_df:
19367 gen_helper_msa_fexp2_df(cpu_env, tdf, twd, tws, twt);
19368 break;
19369 case OPC_FSAF_df:
19370 gen_helper_msa_fsaf_df(cpu_env, tdf, twd, tws, twt);
19371 break;
19372 case OPC_FEXDO_df:
19373 gen_helper_msa_fexdo_df(cpu_env, tdf, twd, tws, twt);
19374 break;
19375 case OPC_FSUN_df:
19376 gen_helper_msa_fsun_df(cpu_env, tdf, twd, tws, twt);
19377 break;
19378 case OPC_FSOR_df:
19379 gen_helper_msa_fsor_df(cpu_env, tdf, twd, tws, twt);
19380 break;
19381 case OPC_FSEQ_df:
19382 gen_helper_msa_fseq_df(cpu_env, tdf, twd, tws, twt);
19383 break;
19384 case OPC_FTQ_df:
19385 gen_helper_msa_ftq_df(cpu_env, tdf, twd, tws, twt);
19386 break;
19387 case OPC_FSUNE_df:
19388 gen_helper_msa_fsune_df(cpu_env, tdf, twd, tws, twt);
19389 break;
19390 case OPC_FSUEQ_df:
19391 gen_helper_msa_fsueq_df(cpu_env, tdf, twd, tws, twt);
19392 break;
19393 case OPC_FSNE_df:
19394 gen_helper_msa_fsne_df(cpu_env, tdf, twd, tws, twt);
19395 break;
19396 case OPC_FSLT_df:
19397 gen_helper_msa_fslt_df(cpu_env, tdf, twd, tws, twt);
19398 break;
19399 case OPC_FMIN_df:
19400 gen_helper_msa_fmin_df(cpu_env, tdf, twd, tws, twt);
19401 break;
19402 case OPC_MULR_Q_df:
19403 tcg_gen_movi_i32(tdf, df + 1);
19404 gen_helper_msa_mulr_q_df(cpu_env, tdf, twd, tws, twt);
19405 break;
19406 case OPC_FSULT_df:
19407 gen_helper_msa_fsult_df(cpu_env, tdf, twd, tws, twt);
19408 break;
19409 case OPC_FMIN_A_df:
19410 gen_helper_msa_fmin_a_df(cpu_env, tdf, twd, tws, twt);
19411 break;
19412 case OPC_MADDR_Q_df:
19413 tcg_gen_movi_i32(tdf, df + 1);
19414 gen_helper_msa_maddr_q_df(cpu_env, tdf, twd, tws, twt);
19415 break;
19416 case OPC_FSLE_df:
19417 gen_helper_msa_fsle_df(cpu_env, tdf, twd, tws, twt);
19418 break;
19419 case OPC_FMAX_df:
19420 gen_helper_msa_fmax_df(cpu_env, tdf, twd, tws, twt);
19421 break;
19422 case OPC_MSUBR_Q_df:
19423 tcg_gen_movi_i32(tdf, df + 1);
19424 gen_helper_msa_msubr_q_df(cpu_env, tdf, twd, tws, twt);
19425 break;
19426 case OPC_FSULE_df:
19427 gen_helper_msa_fsule_df(cpu_env, tdf, twd, tws, twt);
19428 break;
19429 case OPC_FMAX_A_df:
19430 gen_helper_msa_fmax_a_df(cpu_env, tdf, twd, tws, twt);
19431 break;
19432 default:
19433 MIPS_INVAL("MSA instruction");
9c708c7f 19434 generate_exception_end(ctx, EXCP_RI);
7d05b9c8
YK
19435 break;
19436 }
19437
19438 tcg_temp_free_i32(twd);
19439 tcg_temp_free_i32(tws);
19440 tcg_temp_free_i32(twt);
19441 tcg_temp_free_i32(tdf);
19442}
19443
cbe50b9a
YK
19444static void gen_msa_2r(CPUMIPSState *env, DisasContext *ctx)
19445{
19446#define MASK_MSA_2R(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
19447 (op & (0x7 << 18)))
19448 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
19449 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
19450 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
19451 uint8_t df = (ctx->opcode >> 16) & 0x3;
19452 TCGv_i32 twd = tcg_const_i32(wd);
19453 TCGv_i32 tws = tcg_const_i32(ws);
19454 TCGv_i32 twt = tcg_const_i32(wt);
19455 TCGv_i32 tdf = tcg_const_i32(df);
19456
19457 switch (MASK_MSA_2R(ctx->opcode)) {
19458 case OPC_FILL_df:
19459#if !defined(TARGET_MIPS64)
19460 /* Double format valid only for MIPS64 */
19461 if (df == DF_DOUBLE) {
9c708c7f 19462 generate_exception_end(ctx, EXCP_RI);
cbe50b9a
YK
19463 break;
19464 }
19465#endif
19466 gen_helper_msa_fill_df(cpu_env, tdf, twd, tws); /* trs */
19467 break;
19468 case OPC_PCNT_df:
19469 gen_helper_msa_pcnt_df(cpu_env, tdf, twd, tws);
19470 break;
19471 case OPC_NLOC_df:
19472 gen_helper_msa_nloc_df(cpu_env, tdf, twd, tws);
19473 break;
19474 case OPC_NLZC_df:
19475 gen_helper_msa_nlzc_df(cpu_env, tdf, twd, tws);
19476 break;
19477 default:
19478 MIPS_INVAL("MSA instruction");
9c708c7f 19479 generate_exception_end(ctx, EXCP_RI);
cbe50b9a
YK
19480 break;
19481 }
19482
19483 tcg_temp_free_i32(twd);
19484 tcg_temp_free_i32(tws);
19485 tcg_temp_free_i32(twt);
19486 tcg_temp_free_i32(tdf);
19487}
19488
3bdeb688
YK
19489static void gen_msa_2rf(CPUMIPSState *env, DisasContext *ctx)
19490{
19491#define MASK_MSA_2RF(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
19492 (op & (0xf << 17)))
19493 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
19494 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
19495 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
19496 uint8_t df = (ctx->opcode >> 16) & 0x1;
19497 TCGv_i32 twd = tcg_const_i32(wd);
19498 TCGv_i32 tws = tcg_const_i32(ws);
19499 TCGv_i32 twt = tcg_const_i32(wt);
19500 /* adjust df value for floating-point instruction */
19501 TCGv_i32 tdf = tcg_const_i32(df + 2);
19502
19503 switch (MASK_MSA_2RF(ctx->opcode)) {
19504 case OPC_FCLASS_df:
19505 gen_helper_msa_fclass_df(cpu_env, tdf, twd, tws);
19506 break;
19507 case OPC_FTRUNC_S_df:
19508 gen_helper_msa_ftrunc_s_df(cpu_env, tdf, twd, tws);
19509 break;
19510 case OPC_FTRUNC_U_df:
19511 gen_helper_msa_ftrunc_u_df(cpu_env, tdf, twd, tws);
19512 break;
19513 case OPC_FSQRT_df:
19514 gen_helper_msa_fsqrt_df(cpu_env, tdf, twd, tws);
19515 break;
19516 case OPC_FRSQRT_df:
19517 gen_helper_msa_frsqrt_df(cpu_env, tdf, twd, tws);
19518 break;
19519 case OPC_FRCP_df:
19520 gen_helper_msa_frcp_df(cpu_env, tdf, twd, tws);
19521 break;
19522 case OPC_FRINT_df:
19523 gen_helper_msa_frint_df(cpu_env, tdf, twd, tws);
19524 break;
19525 case OPC_FLOG2_df:
19526 gen_helper_msa_flog2_df(cpu_env, tdf, twd, tws);
19527 break;
19528 case OPC_FEXUPL_df:
19529 gen_helper_msa_fexupl_df(cpu_env, tdf, twd, tws);
19530 break;
19531 case OPC_FEXUPR_df:
19532 gen_helper_msa_fexupr_df(cpu_env, tdf, twd, tws);
19533 break;
19534 case OPC_FFQL_df:
19535 gen_helper_msa_ffql_df(cpu_env, tdf, twd, tws);
19536 break;
19537 case OPC_FFQR_df:
19538 gen_helper_msa_ffqr_df(cpu_env, tdf, twd, tws);
19539 break;
19540 case OPC_FTINT_S_df:
19541 gen_helper_msa_ftint_s_df(cpu_env, tdf, twd, tws);
19542 break;
19543 case OPC_FTINT_U_df:
19544 gen_helper_msa_ftint_u_df(cpu_env, tdf, twd, tws);
19545 break;
19546 case OPC_FFINT_S_df:
19547 gen_helper_msa_ffint_s_df(cpu_env, tdf, twd, tws);
19548 break;
19549 case OPC_FFINT_U_df:
19550 gen_helper_msa_ffint_u_df(cpu_env, tdf, twd, tws);
19551 break;
19552 }
19553
19554 tcg_temp_free_i32(twd);
19555 tcg_temp_free_i32(tws);
19556 tcg_temp_free_i32(twt);
19557 tcg_temp_free_i32(tdf);
19558}
19559
cbe50b9a
YK
19560static void gen_msa_vec_v(CPUMIPSState *env, DisasContext *ctx)
19561{
19562#define MASK_MSA_VEC(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)))
19563 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
19564 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
19565 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
19566 TCGv_i32 twd = tcg_const_i32(wd);
19567 TCGv_i32 tws = tcg_const_i32(ws);
19568 TCGv_i32 twt = tcg_const_i32(wt);
19569
19570 switch (MASK_MSA_VEC(ctx->opcode)) {
19571 case OPC_AND_V:
19572 gen_helper_msa_and_v(cpu_env, twd, tws, twt);
19573 break;
19574 case OPC_OR_V:
19575 gen_helper_msa_or_v(cpu_env, twd, tws, twt);
19576 break;
19577 case OPC_NOR_V:
19578 gen_helper_msa_nor_v(cpu_env, twd, tws, twt);
19579 break;
19580 case OPC_XOR_V:
19581 gen_helper_msa_xor_v(cpu_env, twd, tws, twt);
19582 break;
19583 case OPC_BMNZ_V:
19584 gen_helper_msa_bmnz_v(cpu_env, twd, tws, twt);
19585 break;
19586 case OPC_BMZ_V:
19587 gen_helper_msa_bmz_v(cpu_env, twd, tws, twt);
19588 break;
19589 case OPC_BSEL_V:
19590 gen_helper_msa_bsel_v(cpu_env, twd, tws, twt);
19591 break;
19592 default:
19593 MIPS_INVAL("MSA instruction");
9c708c7f 19594 generate_exception_end(ctx, EXCP_RI);
cbe50b9a
YK
19595 break;
19596 }
19597
19598 tcg_temp_free_i32(twd);
19599 tcg_temp_free_i32(tws);
19600 tcg_temp_free_i32(twt);
19601}
19602
19603static void gen_msa_vec(CPUMIPSState *env, DisasContext *ctx)
19604{
19605 switch (MASK_MSA_VEC(ctx->opcode)) {
19606 case OPC_AND_V:
19607 case OPC_OR_V:
19608 case OPC_NOR_V:
19609 case OPC_XOR_V:
19610 case OPC_BMNZ_V:
19611 case OPC_BMZ_V:
19612 case OPC_BSEL_V:
19613 gen_msa_vec_v(env, ctx);
19614 break;
19615 case OPC_MSA_2R:
19616 gen_msa_2r(env, ctx);
19617 break;
3bdeb688
YK
19618 case OPC_MSA_2RF:
19619 gen_msa_2rf(env, ctx);
19620 break;
cbe50b9a
YK
19621 default:
19622 MIPS_INVAL("MSA instruction");
9c708c7f 19623 generate_exception_end(ctx, EXCP_RI);
cbe50b9a
YK
19624 break;
19625 }
19626}
19627
4c789546
YK
19628static void gen_msa(CPUMIPSState *env, DisasContext *ctx)
19629{
19630 uint32_t opcode = ctx->opcode;
19631 check_insn(ctx, ASE_MSA);
19632 check_msa_access(ctx);
19633
19634 switch (MASK_MSA_MINOR(opcode)) {
19635 case OPC_MSA_I8_00:
19636 case OPC_MSA_I8_01:
19637 case OPC_MSA_I8_02:
19638 gen_msa_i8(env, ctx);
19639 break;
80e71591
YK
19640 case OPC_MSA_I5_06:
19641 case OPC_MSA_I5_07:
19642 gen_msa_i5(env, ctx);
19643 break;
d4cf28de
YK
19644 case OPC_MSA_BIT_09:
19645 case OPC_MSA_BIT_0A:
19646 gen_msa_bit(env, ctx);
19647 break;
28f99f08
YK
19648 case OPC_MSA_3R_0D:
19649 case OPC_MSA_3R_0E:
19650 case OPC_MSA_3R_0F:
19651 case OPC_MSA_3R_10:
19652 case OPC_MSA_3R_11:
19653 case OPC_MSA_3R_12:
19654 case OPC_MSA_3R_13:
19655 case OPC_MSA_3R_14:
19656 case OPC_MSA_3R_15:
19657 gen_msa_3r(env, ctx);
19658 break;
1e608ec1
YK
19659 case OPC_MSA_ELM:
19660 gen_msa_elm(env, ctx);
19661 break;
7d05b9c8
YK
19662 case OPC_MSA_3RF_1A:
19663 case OPC_MSA_3RF_1B:
19664 case OPC_MSA_3RF_1C:
19665 gen_msa_3rf(env, ctx);
19666 break;
cbe50b9a
YK
19667 case OPC_MSA_VEC:
19668 gen_msa_vec(env, ctx);
19669 break;
f7685877
YK
19670 case OPC_LD_B:
19671 case OPC_LD_H:
19672 case OPC_LD_W:
19673 case OPC_LD_D:
19674 case OPC_ST_B:
19675 case OPC_ST_H:
19676 case OPC_ST_W:
19677 case OPC_ST_D:
19678 {
19679 int32_t s10 = sextract32(ctx->opcode, 16, 10);
19680 uint8_t rs = (ctx->opcode >> 11) & 0x1f;
19681 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
19682 uint8_t df = (ctx->opcode >> 0) & 0x3;
19683
f7685877 19684 TCGv_i32 twd = tcg_const_i32(wd);
adc370a4
YK
19685 TCGv taddr = tcg_temp_new();
19686 gen_base_offset_addr(ctx, taddr, rs, s10 << df);
f7685877
YK
19687
19688 switch (MASK_MSA_MINOR(opcode)) {
19689 case OPC_LD_B:
adc370a4
YK
19690 gen_helper_msa_ld_b(cpu_env, twd, taddr);
19691 break;
f7685877 19692 case OPC_LD_H:
adc370a4
YK
19693 gen_helper_msa_ld_h(cpu_env, twd, taddr);
19694 break;
f7685877 19695 case OPC_LD_W:
adc370a4
YK
19696 gen_helper_msa_ld_w(cpu_env, twd, taddr);
19697 break;
f7685877 19698 case OPC_LD_D:
adc370a4 19699 gen_helper_msa_ld_d(cpu_env, twd, taddr);
f7685877
YK
19700 break;
19701 case OPC_ST_B:
adc370a4
YK
19702 gen_helper_msa_st_b(cpu_env, twd, taddr);
19703 break;
f7685877 19704 case OPC_ST_H:
adc370a4
YK
19705 gen_helper_msa_st_h(cpu_env, twd, taddr);
19706 break;
f7685877 19707 case OPC_ST_W:
adc370a4
YK
19708 gen_helper_msa_st_w(cpu_env, twd, taddr);
19709 break;
f7685877 19710 case OPC_ST_D:
adc370a4 19711 gen_helper_msa_st_d(cpu_env, twd, taddr);
f7685877
YK
19712 break;
19713 }
19714
19715 tcg_temp_free_i32(twd);
adc370a4 19716 tcg_temp_free(taddr);
f7685877
YK
19717 }
19718 break;
4c789546
YK
19719 default:
19720 MIPS_INVAL("MSA instruction");
9c708c7f 19721 generate_exception_end(ctx, EXCP_RI);
4c789546
YK
19722 break;
19723 }
19724
19725}
19726
d2bfa6e6 19727static void decode_opc(CPUMIPSState *env, DisasContext *ctx)
099e5b4d
LA
19728{
19729 int32_t offset;
19730 int rs, rt, rd, sa;
19731 uint32_t op, op1;
19732 int16_t imm;
19733
19734 /* make sure instructions are on a word boundary */
eeb3bba8
EC
19735 if (ctx->base.pc_next & 0x3) {
19736 env->CP0_BadVAddr = ctx->base.pc_next;
aea14095 19737 generate_exception_err(ctx, EXCP_AdEL, EXCP_INST_NOTAVAIL);
099e5b4d
LA
19738 return;
19739 }
19740
19741 /* Handle blikely not taken case */
19742 if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
42a268c2 19743 TCGLabel *l1 = gen_new_label();
099e5b4d 19744
099e5b4d
LA
19745 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
19746 tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
eeb3bba8 19747 gen_goto_tb(ctx, 1, ctx->base.pc_next + 4);
099e5b4d
LA
19748 gen_set_label(l1);
19749 }
19750
099e5b4d
LA
19751 op = MASK_OP_MAJOR(ctx->opcode);
19752 rs = (ctx->opcode >> 21) & 0x1f;
19753 rt = (ctx->opcode >> 16) & 0x1f;
19754 rd = (ctx->opcode >> 11) & 0x1f;
19755 sa = (ctx->opcode >> 6) & 0x1f;
19756 imm = (int16_t)ctx->opcode;
19757 switch (op) {
19758 case OPC_SPECIAL:
19759 decode_opc_special(env, ctx);
19760 break;
19761 case OPC_SPECIAL2:
4267d3e6 19762 decode_opc_special2_legacy(env, ctx);
099e5b4d
LA
19763 break;
19764 case OPC_SPECIAL3:
19765 decode_opc_special3(env, ctx);
19766 break;
7a387fff
TS
19767 case OPC_REGIMM:
19768 op1 = MASK_REGIMM(ctx->opcode);
19769 switch (op1) {
fecd2646
LA
19770 case OPC_BLTZL: /* REGIMM branches */
19771 case OPC_BGEZL:
19772 case OPC_BLTZALL:
19773 case OPC_BGEZALL:
d9224450 19774 check_insn(ctx, ISA_MIPS2);
fecd2646 19775 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d9224450 19776 /* Fallthrough */
fecd2646
LA
19777 case OPC_BLTZ:
19778 case OPC_BGEZ:
b231c103 19779 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
0aefa333 19780 break;
fecd2646
LA
19781 case OPC_BLTZAL:
19782 case OPC_BGEZAL:
0aefa333
YK
19783 if (ctx->insn_flags & ISA_MIPS32R6) {
19784 if (rs == 0) {
19785 /* OPC_NAL, OPC_BAL */
b231c103 19786 gen_compute_branch(ctx, op1, 4, 0, -1, imm << 2, 4);
0aefa333 19787 } else {
9c708c7f 19788 generate_exception_end(ctx, EXCP_RI);
0aefa333
YK
19789 }
19790 } else {
b231c103 19791 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
0aefa333 19792 }
c9602061 19793 break;
c2e19f3c
AM
19794 case OPC_TGEI: /* REGIMM traps */
19795 case OPC_TGEIU:
19796 case OPC_TLTI:
19797 case OPC_TLTIU:
19798 case OPC_TEQI:
19799
7a387fff 19800 case OPC_TNEI:
d9224450 19801 check_insn(ctx, ISA_MIPS2);
fecd2646 19802 check_insn_opc_removed(ctx, ISA_MIPS32R6);
7a387fff
TS
19803 gen_trap(ctx, op1, rs, -1, imm);
19804 break;
bb238210
YK
19805 case OPC_SIGRIE:
19806 check_insn(ctx, ISA_MIPS32R6);
19807 generate_exception_end(ctx, EXCP_RI);
19808 break;
7a387fff 19809 case OPC_SYNCI:
d75c135e 19810 check_insn(ctx, ISA_MIPS32R2);
a83bddd6
DZ
19811 /* Break the TB to be able to sync copied instructions
19812 immediately */
eeb3bba8 19813 ctx->base.is_jmp = DISAS_STOP;
6af0bf9c 19814 break;
e45a93e2
JL
19815 case OPC_BPOSGE32: /* MIPS DSP branch */
19816#if defined(TARGET_MIPS64)
19817 case OPC_BPOSGE64:
19818#endif
19819 check_dsp(ctx);
b231c103 19820 gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2, 4);
e45a93e2 19821 break;
d4ea6acd
LA
19822#if defined(TARGET_MIPS64)
19823 case OPC_DAHI:
19824 check_insn(ctx, ISA_MIPS32R6);
19825 check_mips_64(ctx);
19826 if (rs != 0) {
19827 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 32);
19828 }
d4ea6acd
LA
19829 break;
19830 case OPC_DATI:
19831 check_insn(ctx, ISA_MIPS32R6);
19832 check_mips_64(ctx);
19833 if (rs != 0) {
19834 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 48);
19835 }
d4ea6acd
LA
19836 break;
19837#endif
6af0bf9c 19838 default: /* Invalid */
923617a3 19839 MIPS_INVAL("regimm");
9c708c7f 19840 generate_exception_end(ctx, EXCP_RI);
6af0bf9c
FB
19841 break;
19842 }
19843 break;
7a387fff 19844 case OPC_CP0:
387a8fe5 19845 check_cp0_enabled(ctx);
7a387fff 19846 op1 = MASK_CP0(ctx->opcode);
6af0bf9c 19847 switch (op1) {
7a387fff
TS
19848 case OPC_MFC0:
19849 case OPC_MTC0:
ead9360e
TS
19850 case OPC_MFTR:
19851 case OPC_MTTR:
5204ea79
LA
19852 case OPC_MFHC0:
19853 case OPC_MTHC0:
d26bc211 19854#if defined(TARGET_MIPS64)
7a387fff
TS
19855 case OPC_DMFC0:
19856 case OPC_DMTC0:
19857#endif
f1aa6320 19858#ifndef CONFIG_USER_ONLY
932e71cd 19859 gen_cp0(env, ctx, op1, rt, rd);
0eaef5aa 19860#endif /* !CONFIG_USER_ONLY */
7a387fff 19861 break;
c38a1d52
AR
19862 case OPC_C0:
19863 case OPC_C0_1:
19864 case OPC_C0_2:
19865 case OPC_C0_3:
19866 case OPC_C0_4:
19867 case OPC_C0_5:
19868 case OPC_C0_6:
19869 case OPC_C0_7:
19870 case OPC_C0_8:
19871 case OPC_C0_9:
19872 case OPC_C0_A:
19873 case OPC_C0_B:
19874 case OPC_C0_C:
19875 case OPC_C0_D:
19876 case OPC_C0_E:
19877 case OPC_C0_F:
f1aa6320 19878#ifndef CONFIG_USER_ONLY
932e71cd 19879 gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
0eaef5aa 19880#endif /* !CONFIG_USER_ONLY */
7a387fff
TS
19881 break;
19882 case OPC_MFMC0:
8706c382 19883#ifndef CONFIG_USER_ONLY
932e71cd 19884 {
099e5b4d 19885 uint32_t op2;
35fbce2c 19886 TCGv t0 = tcg_temp_new();
6c5c1e20 19887
0eaef5aa 19888 op2 = MASK_MFMC0(ctx->opcode);
6c5c1e20
TS
19889 switch (op2) {
19890 case OPC_DMT:
d75c135e 19891 check_insn(ctx, ASE_MT);
9ed5726c 19892 gen_helper_dmt(t0);
35fbce2c 19893 gen_store_gpr(t0, rt);
6c5c1e20
TS
19894 break;
19895 case OPC_EMT:
d75c135e 19896 check_insn(ctx, ASE_MT);
9ed5726c 19897 gen_helper_emt(t0);
35fbce2c 19898 gen_store_gpr(t0, rt);
da80682b 19899 break;
6c5c1e20 19900 case OPC_DVPE:
d75c135e 19901 check_insn(ctx, ASE_MT);
895c2d04 19902 gen_helper_dvpe(t0, cpu_env);
35fbce2c 19903 gen_store_gpr(t0, rt);
6c5c1e20
TS
19904 break;
19905 case OPC_EVPE:
d75c135e 19906 check_insn(ctx, ASE_MT);
895c2d04 19907 gen_helper_evpe(t0, cpu_env);
35fbce2c 19908 gen_store_gpr(t0, rt);
6c5c1e20 19909 break;
01bc435b
YK
19910 case OPC_DVP:
19911 check_insn(ctx, ISA_MIPS32R6);
19912 if (ctx->vp) {
19913 gen_helper_dvp(t0, cpu_env);
19914 gen_store_gpr(t0, rt);
19915 }
19916 break;
19917 case OPC_EVP:
19918 check_insn(ctx, ISA_MIPS32R6);
19919 if (ctx->vp) {
19920 gen_helper_evp(t0, cpu_env);
19921 gen_store_gpr(t0, rt);
19922 }
19923 break;
6c5c1e20 19924 case OPC_DI:
d75c135e 19925 check_insn(ctx, ISA_MIPS32R2);
867abc7e 19926 save_cpu_state(ctx, 1);
895c2d04 19927 gen_helper_di(t0, cpu_env);
35fbce2c 19928 gen_store_gpr(t0, rt);
d2bfa6e6
MR
19929 /* Stop translation as we may have switched
19930 the execution mode. */
eeb3bba8 19931 ctx->base.is_jmp = DISAS_STOP;
6c5c1e20
TS
19932 break;
19933 case OPC_EI:
d75c135e 19934 check_insn(ctx, ISA_MIPS32R2);
867abc7e 19935 save_cpu_state(ctx, 1);
895c2d04 19936 gen_helper_ei(t0, cpu_env);
35fbce2c 19937 gen_store_gpr(t0, rt);
b28425ba
EC
19938 /* DISAS_STOP isn't sufficient, we need to ensure we break
19939 out of translated code to check for pending interrupts */
eeb3bba8
EC
19940 gen_save_pc(ctx->base.pc_next + 4);
19941 ctx->base.is_jmp = DISAS_EXIT;
6c5c1e20
TS
19942 break;
19943 default: /* Invalid */
19944 MIPS_INVAL("mfmc0");
9c708c7f 19945 generate_exception_end(ctx, EXCP_RI);
6c5c1e20
TS
19946 break;
19947 }
6c5c1e20 19948 tcg_temp_free(t0);
7a387fff 19949 }
0eaef5aa 19950#endif /* !CONFIG_USER_ONLY */
6af0bf9c 19951 break;
7a387fff 19952 case OPC_RDPGPR:
d75c135e 19953 check_insn(ctx, ISA_MIPS32R2);
be24bb4f 19954 gen_load_srsgpr(rt, rd);
ead9360e 19955 break;
7a387fff 19956 case OPC_WRPGPR:
d75c135e 19957 check_insn(ctx, ISA_MIPS32R2);
be24bb4f 19958 gen_store_srsgpr(rt, rd);
38121543 19959 break;
6af0bf9c 19960 default:
923617a3 19961 MIPS_INVAL("cp0");
9c708c7f 19962 generate_exception_end(ctx, EXCP_RI);
6af0bf9c
FB
19963 break;
19964 }
19965 break;
31837be3
YK
19966 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC, OPC_ADDI */
19967 if (ctx->insn_flags & ISA_MIPS32R6) {
19968 /* OPC_BOVC, OPC_BEQZALC, OPC_BEQC */
19969 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19970 } else {
19971 /* OPC_ADDI */
19972 /* Arithmetic with immediate opcode */
19973 gen_arith_imm(ctx, op, rt, rs, imm);
19974 }
19975 break;
324d9e32 19976 case OPC_ADDIU:
d75c135e 19977 gen_arith_imm(ctx, op, rt, rs, imm);
7a387fff 19978 break;
324d9e32
AJ
19979 case OPC_SLTI: /* Set on less than with immediate opcode */
19980 case OPC_SLTIU:
d75c135e 19981 gen_slt_imm(ctx, op, rt, rs, imm);
324d9e32
AJ
19982 break;
19983 case OPC_ANDI: /* Arithmetic with immediate opcode */
d4ea6acd 19984 case OPC_LUI: /* OPC_AUI */
324d9e32
AJ
19985 case OPC_ORI:
19986 case OPC_XORI:
d75c135e 19987 gen_logic_imm(ctx, op, rt, rs, imm);
324d9e32 19988 break;
c2e19f3c
AM
19989 case OPC_J: /* Jump */
19990 case OPC_JAL:
7a387fff 19991 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
b231c103 19992 gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
c9602061 19993 break;
31837be3
YK
19994 /* Branch */
19995 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC, OPC_BLEZL */
19996 if (ctx->insn_flags & ISA_MIPS32R6) {
19997 if (rt == 0) {
9c708c7f 19998 generate_exception_end(ctx, EXCP_RI);
31837be3
YK
19999 break;
20000 }
20001 /* OPC_BLEZC, OPC_BGEZC, OPC_BGEC */
20002 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
20003 } else {
20004 /* OPC_BLEZL */
b231c103 20005 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
31837be3
YK
20006 }
20007 break;
20008 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC, OPC_BGTZL */
20009 if (ctx->insn_flags & ISA_MIPS32R6) {
20010 if (rt == 0) {
9c708c7f 20011 generate_exception_end(ctx, EXCP_RI);
31837be3
YK
20012 break;
20013 }
20014 /* OPC_BGTZC, OPC_BLTZC, OPC_BLTC */
20015 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
20016 } else {
20017 /* OPC_BGTZL */
b231c103 20018 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
31837be3
YK
20019 }
20020 break;
20021 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC, OPC_BLEZ */
20022 if (rt == 0) {
20023 /* OPC_BLEZ */
b231c103 20024 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
31837be3
YK
20025 } else {
20026 check_insn(ctx, ISA_MIPS32R6);
20027 /* OPC_BLEZALC, OPC_BGEZALC, OPC_BGEUC */
20028 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
20029 }
20030 break;
20031 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC, OPC_BGTZ */
20032 if (rt == 0) {
20033 /* OPC_BGTZ */
b231c103 20034 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
31837be3
YK
20035 } else {
20036 check_insn(ctx, ISA_MIPS32R6);
20037 /* OPC_BGTZALC, OPC_BLTZALC, OPC_BLTUC */
20038 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
20039 }
20040 break;
20041 case OPC_BEQL:
20042 case OPC_BNEL:
d9224450 20043 check_insn(ctx, ISA_MIPS2);
fecd2646 20044 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d9224450 20045 /* Fallthrough */
31837be3
YK
20046 case OPC_BEQ:
20047 case OPC_BNE:
b231c103 20048 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
c9602061 20049 break;
d9224450
MR
20050 case OPC_LL: /* Load and stores */
20051 check_insn(ctx, ISA_MIPS2);
20052 /* Fallthrough */
20053 case OPC_LWL:
fecd2646
LA
20054 case OPC_LWR:
20055 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d9224450 20056 /* Fallthrough */
c2e19f3c
AM
20057 case OPC_LB:
20058 case OPC_LH:
20059 case OPC_LW:
20060 case OPC_LWPC:
20061 case OPC_LBU:
20062 case OPC_LHU:
d75c135e 20063 gen_ld(ctx, op, rt, rs, imm);
5c13fdfd 20064 break;
fecd2646 20065 case OPC_SWL:
7a387fff 20066 case OPC_SWR:
fecd2646 20067 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b6f3b233 20068 /* fall through */
c2e19f3c
AM
20069 case OPC_SB:
20070 case OPC_SH:
fecd2646 20071 case OPC_SW:
5c13fdfd 20072 gen_st(ctx, op, rt, rs, imm);
7a387fff 20073 break;
d66c7132 20074 case OPC_SC:
d9224450 20075 check_insn(ctx, ISA_MIPS2);
4368b29a 20076 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d66c7132
AJ
20077 gen_st_cond(ctx, op, rt, rs, imm);
20078 break;
7a387fff 20079 case OPC_CACHE:
bf7910c6 20080 check_insn_opc_removed(ctx, ISA_MIPS32R6);
2e15497c 20081 check_cp0_enabled(ctx);
d75c135e 20082 check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
0d74a222
LA
20083 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
20084 gen_cache_operation(ctx, rt, rs, imm);
20085 }
ead9360e 20086 /* Treat as NOP. */
34ae7b51 20087 break;
7a387fff 20088 case OPC_PREF:
bf7910c6 20089 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d75c135e 20090 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
ead9360e 20091 /* Treat as NOP. */
6af0bf9c 20092 break;
4ad40f36 20093
923617a3 20094 /* Floating point (COP1). */
7a387fff
TS
20095 case OPC_LWC1:
20096 case OPC_LDC1:
20097 case OPC_SWC1:
20098 case OPC_SDC1:
5ab5c041 20099 gen_cop1_ldst(ctx, op, rt, rs, imm);
6ea83fed
FB
20100 break;
20101
7a387fff 20102 case OPC_CP1:
5692c6e1
YK
20103 op1 = MASK_CP1(ctx->opcode);
20104
20105 switch (op1) {
20106 case OPC_MFHC1:
20107 case OPC_MTHC1:
5e755519 20108 check_cp1_enabled(ctx);
5692c6e1 20109 check_insn(ctx, ISA_MIPS32R2);
146dd620 20110 /* fall through */
5692c6e1
YK
20111 case OPC_MFC1:
20112 case OPC_CFC1:
20113 case OPC_MTC1:
20114 case OPC_CTC1:
20115 check_cp1_enabled(ctx);
20116 gen_cp1(ctx, op1, rt, rd);
20117 break;
d26bc211 20118#if defined(TARGET_MIPS64)
5692c6e1
YK
20119 case OPC_DMFC1:
20120 case OPC_DMTC1:
20121 check_cp1_enabled(ctx);
20122 check_insn(ctx, ISA_MIPS3);
d9224450 20123 check_mips_64(ctx);
5692c6e1
YK
20124 gen_cp1(ctx, op1, rt, rd);
20125 break;
e189e748 20126#endif
5692c6e1
YK
20127 case OPC_BC1EQZ: /* OPC_BC1ANY2 */
20128 check_cp1_enabled(ctx);
20129 if (ctx->insn_flags & ISA_MIPS32R6) {
20130 /* OPC_BC1EQZ */
31837be3 20131 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
65935f07 20132 rt, imm << 2, 4);
5692c6e1
YK
20133 } else {
20134 /* OPC_BC1ANY2 */
b8aa4598 20135 check_cop1x(ctx);
d75c135e 20136 check_insn(ctx, ASE_MIPS3D);
d75c135e 20137 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
5a5012ec 20138 (rt >> 2) & 0x7, imm << 2);
5692c6e1
YK
20139 }
20140 break;
20141 case OPC_BC1NEZ:
20142 check_cp1_enabled(ctx);
20143 check_insn(ctx, ISA_MIPS32R6);
20144 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
65935f07 20145 rt, imm << 2, 4);
5692c6e1
YK
20146 break;
20147 case OPC_BC1ANY4:
20148 check_cp1_enabled(ctx);
20149 check_insn_opc_removed(ctx, ISA_MIPS32R6);
20150 check_cop1x(ctx);
20151 check_insn(ctx, ASE_MIPS3D);
20152 /* fall through */
20153 case OPC_BC1:
20154 check_cp1_enabled(ctx);
20155 check_insn_opc_removed(ctx, ISA_MIPS32R6);
20156 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
20157 (rt >> 2) & 0x7, imm << 2);
20158 break;
20159 case OPC_PS_FMT:
e29c9628 20160 check_ps(ctx);
b6f3b233 20161 /* fall through */
5692c6e1
YK
20162 case OPC_S_FMT:
20163 case OPC_D_FMT:
20164 check_cp1_enabled(ctx);
20165 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
20166 (imm >> 8) & 0x7);
20167 break;
20168 case OPC_W_FMT:
20169 case OPC_L_FMT:
20170 {
20171 int r6_op = ctx->opcode & FOP(0x3f, 0x1f);
20172 check_cp1_enabled(ctx);
20173 if (ctx->insn_flags & ISA_MIPS32R6) {
20174 switch (r6_op) {
20175 case R6_OPC_CMP_AF_S:
20176 case R6_OPC_CMP_UN_S:
20177 case R6_OPC_CMP_EQ_S:
20178 case R6_OPC_CMP_UEQ_S:
20179 case R6_OPC_CMP_LT_S:
20180 case R6_OPC_CMP_ULT_S:
20181 case R6_OPC_CMP_LE_S:
20182 case R6_OPC_CMP_ULE_S:
20183 case R6_OPC_CMP_SAF_S:
20184 case R6_OPC_CMP_SUN_S:
20185 case R6_OPC_CMP_SEQ_S:
20186 case R6_OPC_CMP_SEUQ_S:
20187 case R6_OPC_CMP_SLT_S:
20188 case R6_OPC_CMP_SULT_S:
20189 case R6_OPC_CMP_SLE_S:
20190 case R6_OPC_CMP_SULE_S:
20191 case R6_OPC_CMP_OR_S:
20192 case R6_OPC_CMP_UNE_S:
20193 case R6_OPC_CMP_NE_S:
20194 case R6_OPC_CMP_SOR_S:
20195 case R6_OPC_CMP_SUNE_S:
20196 case R6_OPC_CMP_SNE_S:
20197 gen_r6_cmp_s(ctx, ctx->opcode & 0x1f, rt, rd, sa);
20198 break;
20199 case R6_OPC_CMP_AF_D:
20200 case R6_OPC_CMP_UN_D:
20201 case R6_OPC_CMP_EQ_D:
20202 case R6_OPC_CMP_UEQ_D:
20203 case R6_OPC_CMP_LT_D:
20204 case R6_OPC_CMP_ULT_D:
20205 case R6_OPC_CMP_LE_D:
20206 case R6_OPC_CMP_ULE_D:
20207 case R6_OPC_CMP_SAF_D:
20208 case R6_OPC_CMP_SUN_D:
20209 case R6_OPC_CMP_SEQ_D:
20210 case R6_OPC_CMP_SEUQ_D:
20211 case R6_OPC_CMP_SLT_D:
20212 case R6_OPC_CMP_SULT_D:
20213 case R6_OPC_CMP_SLE_D:
20214 case R6_OPC_CMP_SULE_D:
20215 case R6_OPC_CMP_OR_D:
20216 case R6_OPC_CMP_UNE_D:
20217 case R6_OPC_CMP_NE_D:
20218 case R6_OPC_CMP_SOR_D:
20219 case R6_OPC_CMP_SUNE_D:
20220 case R6_OPC_CMP_SNE_D:
20221 gen_r6_cmp_d(ctx, ctx->opcode & 0x1f, rt, rd, sa);
20222 break;
20223 default:
d2bfa6e6
MR
20224 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f),
20225 rt, rd, sa, (imm >> 8) & 0x7);
20226
5692c6e1 20227 break;
3f493883 20228 }
5692c6e1
YK
20229 } else {
20230 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
20231 (imm >> 8) & 0x7);
36d23958 20232 }
5692c6e1
YK
20233 break;
20234 }
20235 case OPC_BZ_V:
20236 case OPC_BNZ_V:
20237 case OPC_BZ_B:
20238 case OPC_BZ_H:
20239 case OPC_BZ_W:
20240 case OPC_BZ_D:
20241 case OPC_BNZ_B:
20242 case OPC_BNZ_H:
20243 case OPC_BNZ_W:
20244 case OPC_BNZ_D:
20245 check_insn(ctx, ASE_MSA);
20246 gen_msa_branch(env, ctx, op1);
20247 break;
20248 default:
20249 MIPS_INVAL("cp1");
9c708c7f 20250 generate_exception_end(ctx, EXCP_RI);
5692c6e1 20251 break;
6ea83fed 20252 }
4ad40f36
FB
20253 break;
20254
31837be3
YK
20255 /* Compact branches [R6] and COP2 [non-R6] */
20256 case OPC_BC: /* OPC_LWC2 */
20257 case OPC_BALC: /* OPC_SWC2 */
20258 if (ctx->insn_flags & ISA_MIPS32R6) {
20259 /* OPC_BC, OPC_BALC */
20260 gen_compute_compact_branch(ctx, op, 0, 0,
20261 sextract32(ctx->opcode << 2, 0, 28));
20262 } else {
20263 /* OPC_LWC2, OPC_SWC2 */
20264 /* COP2: Not implemented. */
20265 generate_exception_err(ctx, EXCP_CpU, 2);
20266 }
20267 break;
20268 case OPC_BEQZC: /* OPC_JIC, OPC_LDC2 */
20269 case OPC_BNEZC: /* OPC_JIALC, OPC_SDC2 */
20270 if (ctx->insn_flags & ISA_MIPS32R6) {
20271 if (rs != 0) {
20272 /* OPC_BEQZC, OPC_BNEZC */
20273 gen_compute_compact_branch(ctx, op, rs, 0,
20274 sextract32(ctx->opcode << 2, 0, 23));
20275 } else {
20276 /* OPC_JIC, OPC_JIALC */
20277 gen_compute_compact_branch(ctx, op, 0, rt, imm);
20278 }
20279 } else {
20280 /* OPC_LWC2, OPC_SWC2 */
20281 /* COP2: Not implemented. */
20282 generate_exception_err(ctx, EXCP_CpU, 2);
20283 }
4ad40f36 20284 break;
bd277fa1 20285 case OPC_CP2:
d75c135e 20286 check_insn(ctx, INSN_LOONGSON2F);
bd277fa1
RH
20287 /* Note that these instructions use different fields. */
20288 gen_loongson_multimedia(ctx, sa, rd, rt);
20289 break;
4ad40f36 20290
7a387fff 20291 case OPC_CP3:
fecd2646 20292 check_insn_opc_removed(ctx, ISA_MIPS32R6);
5ab5c041 20293 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
5e755519 20294 check_cp1_enabled(ctx);
36d23958
TS
20295 op1 = MASK_CP3(ctx->opcode);
20296 switch (op1) {
d9224450
MR
20297 case OPC_LUXC1:
20298 case OPC_SUXC1:
20299 check_insn(ctx, ISA_MIPS5 | ISA_MIPS32R2);
20300 /* Fallthrough */
5a5012ec
TS
20301 case OPC_LWXC1:
20302 case OPC_LDXC1:
5a5012ec
TS
20303 case OPC_SWXC1:
20304 case OPC_SDXC1:
d9224450 20305 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
93b12ccc 20306 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
5a5012ec 20307 break;
e0c84da7 20308 case OPC_PREFX:
d9224450 20309 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
ead9360e 20310 /* Treat as NOP. */
e0c84da7 20311 break;
5a5012ec 20312 case OPC_ALNV_PS:
d9224450
MR
20313 check_insn(ctx, ISA_MIPS5 | ISA_MIPS32R2);
20314 /* Fallthrough */
5a5012ec
TS
20315 case OPC_MADD_S:
20316 case OPC_MADD_D:
20317 case OPC_MADD_PS:
20318 case OPC_MSUB_S:
20319 case OPC_MSUB_D:
20320 case OPC_MSUB_PS:
20321 case OPC_NMADD_S:
20322 case OPC_NMADD_D:
20323 case OPC_NMADD_PS:
20324 case OPC_NMSUB_S:
20325 case OPC_NMSUB_D:
20326 case OPC_NMSUB_PS:
d9224450 20327 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
5a5012ec
TS
20328 gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
20329 break;
36d23958 20330 default:
923617a3 20331 MIPS_INVAL("cp3");
9c708c7f 20332 generate_exception_end(ctx, EXCP_RI);
36d23958
TS
20333 break;
20334 }
20335 } else {
e397ee33 20336 generate_exception_err(ctx, EXCP_CpU, 1);
7a387fff 20337 }
4ad40f36
FB
20338 break;
20339
d26bc211 20340#if defined(TARGET_MIPS64)
7a387fff 20341 /* MIPS64 opcodes */
c2e19f3c
AM
20342 case OPC_LDL:
20343 case OPC_LDR:
bf7910c6 20344 case OPC_LLD:
fecd2646 20345 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b6f3b233 20346 /* fall through */
fecd2646 20347 case OPC_LWU:
7a387fff 20348 case OPC_LD:
d75c135e 20349 check_insn(ctx, ISA_MIPS3);
5c13fdfd 20350 check_mips_64(ctx);
d75c135e 20351 gen_ld(ctx, op, rt, rs, imm);
5c13fdfd 20352 break;
c2e19f3c
AM
20353 case OPC_SDL:
20354 case OPC_SDR:
fecd2646 20355 check_insn_opc_removed(ctx, ISA_MIPS32R6);
b6f3b233 20356 /* fall through */
7a387fff 20357 case OPC_SD:
d75c135e 20358 check_insn(ctx, ISA_MIPS3);
e189e748 20359 check_mips_64(ctx);
5c13fdfd 20360 gen_st(ctx, op, rt, rs, imm);
7a387fff 20361 break;
d66c7132 20362 case OPC_SCD:
bf7910c6 20363 check_insn_opc_removed(ctx, ISA_MIPS32R6);
d75c135e 20364 check_insn(ctx, ISA_MIPS3);
d66c7132
AJ
20365 check_mips_64(ctx);
20366 gen_st_cond(ctx, op, rt, rs, imm);
20367 break;
31837be3
YK
20368 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC, OPC_DADDI */
20369 if (ctx->insn_flags & ISA_MIPS32R6) {
20370 /* OPC_BNVC, OPC_BNEZALC, OPC_BNEC */
20371 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
20372 } else {
20373 /* OPC_DADDI */
20374 check_insn(ctx, ISA_MIPS3);
20375 check_mips_64(ctx);
20376 gen_arith_imm(ctx, op, rt, rs, imm);
20377 }
20378 break;
324d9e32 20379 case OPC_DADDIU:
d75c135e 20380 check_insn(ctx, ISA_MIPS3);
e189e748 20381 check_mips_64(ctx);
d75c135e 20382 gen_arith_imm(ctx, op, rt, rs, imm);
7a387fff 20383 break;
31837be3
YK
20384#else
20385 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
20386 if (ctx->insn_flags & ISA_MIPS32R6) {
20387 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
20388 } else {
20389 MIPS_INVAL("major opcode");
9c708c7f 20390 generate_exception_end(ctx, EXCP_RI);
31837be3
YK
20391 }
20392 break;
6af0bf9c 20393#endif
d4ea6acd
LA
20394 case OPC_DAUI: /* OPC_JALX */
20395 if (ctx->insn_flags & ISA_MIPS32R6) {
20396#if defined(TARGET_MIPS64)
20397 /* OPC_DAUI */
20398 check_mips_64(ctx);
db77d852
LA
20399 if (rs == 0) {
20400 generate_exception(ctx, EXCP_RI);
20401 } else if (rt != 0) {
d4ea6acd
LA
20402 TCGv t0 = tcg_temp_new();
20403 gen_load_gpr(t0, rs);
20404 tcg_gen_addi_tl(cpu_gpr[rt], t0, imm << 16);
20405 tcg_temp_free(t0);
20406 }
d4ea6acd 20407#else
9c708c7f 20408 generate_exception_end(ctx, EXCP_RI);
d4ea6acd
LA
20409 MIPS_INVAL("major opcode");
20410#endif
20411 } else {
20412 /* OPC_JALX */
20413 check_insn(ctx, ASE_MIPS16 | ASE_MICROMIPS);
20414 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
b231c103 20415 gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
d4ea6acd 20416 }
364d4831 20417 break;
4c789546 20418 case OPC_MSA: /* OPC_MDMX */
7a387fff 20419 /* MDMX: Not implemented. */
4c789546 20420 gen_msa(env, ctx);
d4ea6acd
LA
20421 break;
20422 case OPC_PCREL:
20423 check_insn(ctx, ISA_MIPS32R6);
eeb3bba8 20424 gen_pcrel(ctx, ctx->opcode, ctx->base.pc_next, rs);
d4ea6acd 20425 break;
6af0bf9c 20426 default: /* Invalid */
923617a3 20427 MIPS_INVAL("major opcode");
9c708c7f 20428 generate_exception_end(ctx, EXCP_RI);
6af0bf9c
FB
20429 break;
20430 }
6af0bf9c
FB
20431}
20432
18f440ed 20433static void mips_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
6af0bf9c 20434{
18f440ed 20435 DisasContext *ctx = container_of(dcbase, DisasContext, base);
9c489ea6 20436 CPUMIPSState *env = cs->env_ptr;
12be9258 20437
18f440ed 20438 ctx->page_start = ctx->base.pc_first & TARGET_PAGE_MASK;
12be9258
EC
20439 ctx->saved_pc = -1;
20440 ctx->insn_flags = env->insn_flags;
20441 ctx->CP0_Config1 = env->CP0_Config1;
20442 ctx->btarget = 0;
20443 ctx->kscrexist = (env->CP0_Config4 >> CP0C4_KScrExist) & 0xff;
20444 ctx->rxi = (env->CP0_Config3 >> CP0C3_RXI) & 1;
20445 ctx->ie = (env->CP0_Config4 >> CP0C4_IE) & 3;
20446 ctx->bi = (env->CP0_Config3 >> CP0C3_BI) & 1;
20447 ctx->bp = (env->CP0_Config3 >> CP0C3_BP) & 1;
20448 ctx->PAMask = env->PAMask;
20449 ctx->mvh = (env->CP0_Config5 >> CP0C5_MVH) & 1;
20450 ctx->eva = (env->CP0_Config5 >> CP0C5_EVA) & 1;
20451 ctx->sc = (env->CP0_Config3 >> CP0C3_SC) & 1;
20452 ctx->CP0_LLAddr_shift = env->CP0_LLAddr_shift;
20453 ctx->cmgcr = (env->CP0_Config3 >> CP0C3_CMGCR) & 1;
4ad40f36 20454 /* Restore delay slot state from the tb context. */
12be9258
EC
20455 ctx->hflags = (uint32_t)ctx->base.tb->flags; /* FIXME: maybe use 64 bits? */
20456 ctx->ulri = (env->CP0_Config3 >> CP0C3_ULRI) & 1;
20457 ctx->ps = ((env->active_fpu.fcr0 >> FCR0_PS) & 1) ||
e29c9628 20458 (env->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F));
12be9258
EC
20459 ctx->vp = (env->CP0_Config5 >> CP0C5_VP) & 1;
20460 ctx->mrp = (env->CP0_Config5 >> CP0C5_MRP) & 1;
20461 ctx->nan2008 = (env->active_fpu.fcr31 >> FCR31_NAN2008) & 1;
20462 ctx->abs2008 = (env->active_fpu.fcr31 >> FCR31_ABS2008) & 1;
20463 restore_cpu_state(env, ctx);
932e71cd 20464#ifdef CONFIG_USER_ONLY
12be9258 20465 ctx->mem_idx = MIPS_HFLAG_UM;
932e71cd 20466#else
12be9258 20467 ctx->mem_idx = hflags_mmu_index(ctx->hflags);
932e71cd 20468#endif
12be9258
EC
20469 ctx->default_tcg_memop_mask = (ctx->insn_flags & ISA_MIPS32R6) ?
20470 MO_UNALN : MO_ALIGN;
190ce7fb 20471
18f440ed
EC
20472 LOG_DISAS("\ntb %p idx %d hflags %04x\n", ctx->base.tb, ctx->mem_idx,
20473 ctx->hflags);
20474}
12be9258 20475
18f440ed
EC
20476static void mips_tr_tb_start(DisasContextBase *dcbase, CPUState *cs)
20477{
20478}
b933066a 20479
18f440ed
EC
20480static void mips_tr_insn_start(DisasContextBase *dcbase, CPUState *cs)
20481{
20482 DisasContext *ctx = container_of(dcbase, DisasContext, base);
c9602061 20483
18f440ed
EC
20484 tcg_gen_insn_start(ctx->base.pc_next, ctx->hflags & MIPS_HFLAG_BMASK,
20485 ctx->btarget);
20486}
31837be3 20487
18f440ed
EC
20488static bool mips_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cs,
20489 const CPUBreakpoint *bp)
20490{
20491 DisasContext *ctx = container_of(dcbase, DisasContext, base);
c9602061 20492
18f440ed
EC
20493 save_cpu_state(ctx, 1);
20494 ctx->base.is_jmp = DISAS_NORETURN;
20495 gen_helper_raise_exception_debug(cpu_env);
20496 /* The address covered by the breakpoint must be included in
20497 [tb->pc, tb->pc + tb->size) in order to for it to be
20498 properly cleared -- thus we increment the PC here so that
20499 the logic setting tb->size below does the right thing. */
20500 ctx->base.pc_next += 4;
20501 return true;
20502}
4ad40f36 20503
18f440ed
EC
20504static void mips_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
20505{
20506 CPUMIPSState *env = cs->env_ptr;
20507 DisasContext *ctx = container_of(dcbase, DisasContext, base);
20508 int insn_bytes;
20509 int is_slot;
4ad40f36 20510
18f440ed
EC
20511 is_slot = ctx->hflags & MIPS_HFLAG_BMASK;
20512 if (!(ctx->hflags & MIPS_HFLAG_M16)) {
20513 ctx->opcode = cpu_ldl_code(env, ctx->base.pc_next);
20514 insn_bytes = 4;
20515 decode_opc(env, ctx);
20516 } else if (ctx->insn_flags & ASE_MICROMIPS) {
20517 ctx->opcode = cpu_lduw_code(env, ctx->base.pc_next);
20518 insn_bytes = decode_micromips_opc(env, ctx);
20519 } else if (ctx->insn_flags & ASE_MIPS16) {
20520 ctx->opcode = cpu_lduw_code(env, ctx->base.pc_next);
20521 insn_bytes = decode_mips16_opc(env, ctx);
20522 } else {
20523 generate_exception_end(ctx, EXCP_RI);
20524 g_assert(ctx->base.is_jmp == DISAS_NORETURN);
20525 return;
20526 }
faf7aaa9 20527
18f440ed
EC
20528 if (ctx->hflags & MIPS_HFLAG_BMASK) {
20529 if (!(ctx->hflags & (MIPS_HFLAG_BDS16 | MIPS_HFLAG_BDS32 |
20530 MIPS_HFLAG_FBNSLOT))) {
20531 /* force to generate branch as there is neither delay nor
20532 forbidden slot */
20533 is_slot = 1;
20534 }
20535 if ((ctx->hflags & MIPS_HFLAG_M16) &&
20536 (ctx->hflags & MIPS_HFLAG_FBNSLOT)) {
20537 /* Force to generate branch as microMIPS R6 doesn't restrict
20538 branches in the forbidden slot. */
20539 is_slot = 1;
eeb3bba8 20540 }
18f440ed
EC
20541 }
20542 if (is_slot) {
20543 gen_branch(ctx, insn_bytes);
20544 }
20545 ctx->base.pc_next += insn_bytes;
1b530a6d 20546
18f440ed
EC
20547 if (ctx->base.is_jmp != DISAS_NEXT) {
20548 return;
6af0bf9c 20549 }
18f440ed
EC
20550 /* Execute a branch and its delay slot as a single instruction.
20551 This is what GDB expects and is consistent with what the
20552 hardware does (e.g. if a delay slot instruction faults, the
20553 reported PC is the PC of the branch). */
20554 if (ctx->base.singlestep_enabled &&
20555 (ctx->hflags & MIPS_HFLAG_BMASK) == 0) {
20556 ctx->base.is_jmp = DISAS_TOO_MANY;
20557 }
20558 if (ctx->base.pc_next - ctx->page_start >= TARGET_PAGE_SIZE) {
20559 ctx->base.is_jmp = DISAS_TOO_MANY;
ed2803da 20560 }
18f440ed
EC
20561}
20562
20563static void mips_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
20564{
20565 DisasContext *ctx = container_of(dcbase, DisasContext, base);
20566
12be9258
EC
20567 if (ctx->base.singlestep_enabled && ctx->base.is_jmp != DISAS_NORETURN) {
20568 save_cpu_state(ctx, ctx->base.is_jmp != DISAS_EXIT);
9c708c7f 20569 gen_helper_raise_exception_debug(cpu_env);
16c00cb2 20570 } else {
12be9258 20571 switch (ctx->base.is_jmp) {
b28425ba 20572 case DISAS_STOP:
12be9258 20573 gen_save_pc(ctx->base.pc_next);
cd314a7d 20574 tcg_gen_lookup_and_goto_ptr();
df1561e2 20575 break;
b28425ba 20576 case DISAS_NEXT:
18f440ed 20577 case DISAS_TOO_MANY:
12be9258
EC
20578 save_cpu_state(ctx, 0);
20579 gen_goto_tb(ctx, 0, ctx->base.pc_next);
16c00cb2 20580 break;
b28425ba 20581 case DISAS_EXIT:
07ea28b4 20582 tcg_gen_exit_tb(NULL, 0);
16c00cb2 20583 break;
b28425ba 20584 case DISAS_NORETURN:
5a5012ec 20585 break;
18f440ed
EC
20586 default:
20587 g_assert_not_reached();
6958549d 20588 }
6af0bf9c 20589 }
18f440ed
EC
20590}
20591
20592static void mips_tr_disas_log(const DisasContextBase *dcbase, CPUState *cs)
20593{
20594 qemu_log("IN: %s\n", lookup_symbol(dcbase->pc_first));
20595 log_target_disas(cs, dcbase->pc_first, dcbase->tb->size);
20596}
20597
20598static const TranslatorOps mips_tr_ops = {
20599 .init_disas_context = mips_tr_init_disas_context,
20600 .tb_start = mips_tr_tb_start,
20601 .insn_start = mips_tr_insn_start,
20602 .breakpoint_check = mips_tr_breakpoint_check,
20603 .translate_insn = mips_tr_translate_insn,
20604 .tb_stop = mips_tr_tb_stop,
20605 .disas_log = mips_tr_disas_log,
20606};
20607
20608void gen_intermediate_code(CPUState *cs, struct TranslationBlock *tb)
20609{
20610 DisasContext ctx;
20611
20612 translator_loop(&mips_tr_ops, &ctx.base, cs, tb);
6af0bf9c
FB
20613}
20614
7db13fae 20615static void fpu_dump_state(CPUMIPSState *env, FILE *f, fprintf_function fpu_fprintf,
8706c382 20616 int flags)
6ea83fed
FB
20617{
20618 int i;
5e755519 20619 int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
5a5012ec 20620
2a5612e6
SW
20621#define printfpr(fp) \
20622 do { \
20623 if (is_fpu64) \
20624 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
20625 " fd:%13g fs:%13g psu: %13g\n", \
20626 (fp)->w[FP_ENDIAN_IDX], (fp)->d, \
20627 (double)(fp)->fd, \
20628 (double)(fp)->fs[FP_ENDIAN_IDX], \
20629 (double)(fp)->fs[!FP_ENDIAN_IDX]); \
20630 else { \
20631 fpr_t tmp; \
20632 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
20633 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
20634 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
20635 " fd:%13g fs:%13g psu:%13g\n", \
20636 tmp.w[FP_ENDIAN_IDX], tmp.d, \
20637 (double)tmp.fd, \
20638 (double)tmp.fs[FP_ENDIAN_IDX], \
20639 (double)tmp.fs[!FP_ENDIAN_IDX]); \
20640 } \
6ea83fed
FB
20641 } while(0)
20642
5a5012ec 20643
9a78eead
SW
20644 fpu_fprintf(f, "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%02x\n",
20645 env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64,
f01be154 20646 get_float_exception_flags(&env->active_fpu.fp_status));
5a5012ec
TS
20647 for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
20648 fpu_fprintf(f, "%3s: ", fregnames[i]);
f01be154 20649 printfpr(&env->active_fpu.fpr[i]);
6ea83fed
FB
20650 }
20651
20652#undef printfpr
20653}
20654
878096ee
AF
20655void mips_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
20656 int flags)
6af0bf9c 20657{
878096ee
AF
20658 MIPSCPU *cpu = MIPS_CPU(cs);
20659 CPUMIPSState *env = &cpu->env;
6af0bf9c 20660 int i;
3b46e624 20661
a7200c9f
SW
20662 cpu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
20663 " LO=0x" TARGET_FMT_lx " ds %04x "
20664 TARGET_FMT_lx " " TARGET_FMT_ld "\n",
3d5be870
TS
20665 env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
20666 env->hflags, env->btarget, env->bcond);
6af0bf9c
FB
20667 for (i = 0; i < 32; i++) {
20668 if ((i & 3) == 0)
20669 cpu_fprintf(f, "GPR%02d:", i);
b5dc7732 20670 cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
6af0bf9c
FB
20671 if ((i & 3) == 3)
20672 cpu_fprintf(f, "\n");
20673 }
568b600d 20674
3594c774 20675 cpu_fprintf(f, "CP0 Status 0x%08x Cause 0x%08x EPC 0x" TARGET_FMT_lx "\n",
5e755519 20676 env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
284b731a
LA
20677 cpu_fprintf(f, " Config0 0x%08x Config1 0x%08x LLAddr 0x%016"
20678 PRIx64 "\n",
5499b6ff 20679 env->CP0_Config0, env->CP0_Config1, env->lladdr);
27e1fb13
MR
20680 cpu_fprintf(f, " Config2 0x%08x Config3 0x%08x\n",
20681 env->CP0_Config2, env->CP0_Config3);
20682 cpu_fprintf(f, " Config4 0x%08x Config5 0x%08x\n",
20683 env->CP0_Config4, env->CP0_Config5);
1cc5af69 20684 if ((flags & CPU_DUMP_FPU) && (env->hflags & MIPS_HFLAG_FPU)) {
7a387fff 20685 fpu_dump_state(env, f, cpu_fprintf, flags);
1cc5af69 20686 }
6af0bf9c
FB
20687}
20688
78ce64f4 20689void mips_tcg_init(void)
39454628 20690{
f01be154 20691 int i;
39454628 20692
f764718d 20693 cpu_gpr[0] = NULL;
bb928dbe 20694 for (i = 1; i < 32; i++)
e1ccc054 20695 cpu_gpr[i] = tcg_global_mem_new(cpu_env,
7db13fae 20696 offsetof(CPUMIPSState, active_tc.gpr[i]),
4b2eb8d2 20697 regnames[i]);
d73ee8a2 20698
863f264d
YK
20699 for (i = 0; i < 32; i++) {
20700 int off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[0]);
20701 msa_wr_d[i * 2] =
e1ccc054 20702 tcg_global_mem_new_i64(cpu_env, off, msaregnames[i * 2]);
cb269f27
YK
20703 /* The scalar floating-point unit (FPU) registers are mapped on
20704 * the MSA vector registers. */
20705 fpu_f64[i] = msa_wr_d[i * 2];
863f264d
YK
20706 off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[1]);
20707 msa_wr_d[i * 2 + 1] =
e1ccc054 20708 tcg_global_mem_new_i64(cpu_env, off, msaregnames[i * 2 + 1]);
863f264d
YK
20709 }
20710
e1ccc054 20711 cpu_PC = tcg_global_mem_new(cpu_env,
7db13fae 20712 offsetof(CPUMIPSState, active_tc.PC), "PC");
4b2eb8d2 20713 for (i = 0; i < MIPS_DSP_ACC; i++) {
e1ccc054 20714 cpu_HI[i] = tcg_global_mem_new(cpu_env,
7db13fae 20715 offsetof(CPUMIPSState, active_tc.HI[i]),
4b2eb8d2 20716 regnames_HI[i]);
e1ccc054 20717 cpu_LO[i] = tcg_global_mem_new(cpu_env,
7db13fae 20718 offsetof(CPUMIPSState, active_tc.LO[i]),
4b2eb8d2 20719 regnames_LO[i]);
4b2eb8d2 20720 }
e1ccc054 20721 cpu_dspctrl = tcg_global_mem_new(cpu_env,
7db13fae 20722 offsetof(CPUMIPSState, active_tc.DSPControl),
4b2eb8d2 20723 "DSPControl");
e1ccc054 20724 bcond = tcg_global_mem_new(cpu_env,
7db13fae 20725 offsetof(CPUMIPSState, bcond), "bcond");
e1ccc054 20726 btarget = tcg_global_mem_new(cpu_env,
7db13fae 20727 offsetof(CPUMIPSState, btarget), "btarget");
e1ccc054 20728 hflags = tcg_global_mem_new_i32(cpu_env,
7db13fae 20729 offsetof(CPUMIPSState, hflags), "hflags");
41db4607 20730
e1ccc054 20731 fpu_fcr0 = tcg_global_mem_new_i32(cpu_env,
7db13fae 20732 offsetof(CPUMIPSState, active_fpu.fcr0),
a7812ae4 20733 "fcr0");
e1ccc054 20734 fpu_fcr31 = tcg_global_mem_new_i32(cpu_env,
7db13fae 20735 offsetof(CPUMIPSState, active_fpu.fcr31),
a7812ae4 20736 "fcr31");
39454628
TS
20737}
20738
5b27a92d 20739#include "translate_init.inc.c"
aaed909a 20740
27e38392
PMD
20741void cpu_mips_realize_env(CPUMIPSState *env)
20742{
20743 env->exception_base = (int32_t)0xBFC00000;
20744
20745#ifndef CONFIG_USER_ONLY
20746 mmu_init(env, env->cpu_model);
20747#endif
20748 fpu_init(env, env->cpu_model);
20749 mvp_init(env, env->cpu_model);
20750}
20751
a7519f2b 20752bool cpu_supports_cps_smp(const char *cpu_type)
bff384a4 20753{
a7519f2b
IM
20754 const MIPSCPUClass *mcc = MIPS_CPU_CLASS(object_class_by_name(cpu_type));
20755 return (mcc->cpu_def->CP0_Config3 & (1 << CP0C3_CMGCR)) != 0;
bff384a4
LA
20756}
20757
a7519f2b 20758bool cpu_supports_isa(const char *cpu_type, unsigned int isa)
bed9e5ce 20759{
a7519f2b
IM
20760 const MIPSCPUClass *mcc = MIPS_CPU_CLASS(object_class_by_name(cpu_type));
20761 return (mcc->cpu_def->insn_flags & isa) != 0;
bed9e5ce
PB
20762}
20763
89777fd1
LA
20764void cpu_set_exception_base(int vp_index, target_ulong address)
20765{
20766 MIPSCPU *vp = MIPS_CPU(qemu_get_cpu(vp_index));
20767 vp->env.exception_base = address;
20768}
20769
1bba0dc9 20770void cpu_state_reset(CPUMIPSState *env)
6ae81775 20771{
55e5c285
AF
20772 MIPSCPU *cpu = mips_env_get_cpu(env);
20773 CPUState *cs = CPU(cpu);
6ae81775 20774
51cc2e78
BS
20775 /* Reset registers to their default values */
20776 env->CP0_PRid = env->cpu_model->CP0_PRid;
20777 env->CP0_Config0 = env->cpu_model->CP0_Config0;
20778#ifdef TARGET_WORDS_BIGENDIAN
20779 env->CP0_Config0 |= (1 << CP0C0_BE);
20780#endif
20781 env->CP0_Config1 = env->cpu_model->CP0_Config1;
20782 env->CP0_Config2 = env->cpu_model->CP0_Config2;
20783 env->CP0_Config3 = env->cpu_model->CP0_Config3;
b4160af1
PJ
20784 env->CP0_Config4 = env->cpu_model->CP0_Config4;
20785 env->CP0_Config4_rw_bitmask = env->cpu_model->CP0_Config4_rw_bitmask;
b4dd99a3
PJ
20786 env->CP0_Config5 = env->cpu_model->CP0_Config5;
20787 env->CP0_Config5_rw_bitmask = env->cpu_model->CP0_Config5_rw_bitmask;
51cc2e78
BS
20788 env->CP0_Config6 = env->cpu_model->CP0_Config6;
20789 env->CP0_Config7 = env->cpu_model->CP0_Config7;
2a6e32dd
AJ
20790 env->CP0_LLAddr_rw_bitmask = env->cpu_model->CP0_LLAddr_rw_bitmask
20791 << env->cpu_model->CP0_LLAddr_shift;
20792 env->CP0_LLAddr_shift = env->cpu_model->CP0_LLAddr_shift;
51cc2e78
BS
20793 env->SYNCI_Step = env->cpu_model->SYNCI_Step;
20794 env->CCRes = env->cpu_model->CCRes;
20795 env->CP0_Status_rw_bitmask = env->cpu_model->CP0_Status_rw_bitmask;
20796 env->CP0_TCStatus_rw_bitmask = env->cpu_model->CP0_TCStatus_rw_bitmask;
20797 env->CP0_SRSCtl = env->cpu_model->CP0_SRSCtl;
20798 env->current_tc = 0;
20799 env->SEGBITS = env->cpu_model->SEGBITS;
20800 env->SEGMask = (target_ulong)((1ULL << env->cpu_model->SEGBITS) - 1);
20801#if defined(TARGET_MIPS64)
20802 if (env->cpu_model->insn_flags & ISA_MIPS3) {
20803 env->SEGMask |= 3ULL << 62;
20804 }
20805#endif
20806 env->PABITS = env->cpu_model->PABITS;
51cc2e78
BS
20807 env->CP0_SRSConf0_rw_bitmask = env->cpu_model->CP0_SRSConf0_rw_bitmask;
20808 env->CP0_SRSConf0 = env->cpu_model->CP0_SRSConf0;
20809 env->CP0_SRSConf1_rw_bitmask = env->cpu_model->CP0_SRSConf1_rw_bitmask;
20810 env->CP0_SRSConf1 = env->cpu_model->CP0_SRSConf1;
20811 env->CP0_SRSConf2_rw_bitmask = env->cpu_model->CP0_SRSConf2_rw_bitmask;
20812 env->CP0_SRSConf2 = env->cpu_model->CP0_SRSConf2;
20813 env->CP0_SRSConf3_rw_bitmask = env->cpu_model->CP0_SRSConf3_rw_bitmask;
20814 env->CP0_SRSConf3 = env->cpu_model->CP0_SRSConf3;
20815 env->CP0_SRSConf4_rw_bitmask = env->cpu_model->CP0_SRSConf4_rw_bitmask;
20816 env->CP0_SRSConf4 = env->cpu_model->CP0_SRSConf4;
7207c7f9
LA
20817 env->CP0_PageGrain_rw_bitmask = env->cpu_model->CP0_PageGrain_rw_bitmask;
20818 env->CP0_PageGrain = env->cpu_model->CP0_PageGrain;
74dbf824 20819 env->CP0_EBaseWG_rw_bitmask = env->cpu_model->CP0_EBaseWG_rw_bitmask;
f1cb0951 20820 env->active_fpu.fcr0 = env->cpu_model->CP1_fcr0;
599bc5e8 20821 env->active_fpu.fcr31_rw_bitmask = env->cpu_model->CP1_fcr31_rw_bitmask;
ba5c79f2 20822 env->active_fpu.fcr31 = env->cpu_model->CP1_fcr31;
863f264d 20823 env->msair = env->cpu_model->MSAIR;
51cc2e78
BS
20824 env->insn_flags = env->cpu_model->insn_flags;
20825
0eaef5aa 20826#if defined(CONFIG_USER_ONLY)
03e6e501 20827 env->CP0_Status = (MIPS_HFLAG_UM << CP0St_KSU);
68473f15
RH
20828# ifdef TARGET_MIPS64
20829 /* Enable 64-bit register mode. */
20830 env->CP0_Status |= (1 << CP0St_PX);
20831# endif
20832# ifdef TARGET_ABI_MIPSN64
20833 /* Enable 64-bit address mode. */
20834 env->CP0_Status |= (1 << CP0St_UX);
20835# endif
94159135
MI
20836 /* Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
20837 hardware registers. */
20838 env->CP0_HWREna |= 0x0000000F;
91a75935 20839 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
03e6e501 20840 env->CP0_Status |= (1 << CP0St_CU1);
91a75935 20841 }
6f0af304
PJ
20842 if (env->CP0_Config3 & (1 << CP0C3_DSPP)) {
20843 env->CP0_Status |= (1 << CP0St_MX);
853c3240 20844 }
4d66261f
PJ
20845# if defined(TARGET_MIPS64)
20846 /* For MIPS64, init FR bit to 1 if FPU unit is there and bit is writable. */
20847 if ((env->CP0_Config1 & (1 << CP0C1_FP)) &&
20848 (env->CP0_Status_rw_bitmask & (1 << CP0St_FR))) {
68473f15
RH
20849 env->CP0_Status |= (1 << CP0St_FR);
20850 }
4d66261f 20851# endif
932e71cd
AJ
20852#else
20853 if (env->hflags & MIPS_HFLAG_BMASK) {
20854 /* If the exception was raised from a delay slot,
20855 come back to the jump. */
c3577479
MR
20856 env->CP0_ErrorEPC = (env->active_tc.PC
20857 - (env->hflags & MIPS_HFLAG_B16 ? 2 : 4));
aa328add 20858 } else {
932e71cd
AJ
20859 env->CP0_ErrorEPC = env->active_tc.PC;
20860 }
89777fd1 20861 env->active_tc.PC = env->exception_base;
51cc2e78
BS
20862 env->CP0_Random = env->tlb->nb_tlb - 1;
20863 env->tlb->tlb_in_use = env->tlb->nb_tlb;
932e71cd 20864 env->CP0_Wired = 0;
01bc435b 20865 env->CP0_GlobalNumber = (cs->cpu_index & 0xFF) << CP0GN_VPId;
0a2672b7 20866 env->CP0_EBase = (cs->cpu_index & 0x3FF);
d3d93c6c 20867 if (mips_um_ksegs_enabled()) {
0a2672b7
JH
20868 env->CP0_EBase |= 0x40000000;
20869 } else {
74dbf824 20870 env->CP0_EBase |= (int32_t)0x80000000;
0a2672b7 20871 }
c870e3f5
YK
20872 if (env->CP0_Config3 & (1 << CP0C3_CMGCR)) {
20873 env->CP0_CMGCRBase = 0x1fbf8000 >> 4;
20874 }
a0c80608
PB
20875 env->CP0_EntryHi_ASID_mask = (env->CP0_Config4 & (1 << CP0C4_AE)) ?
20876 0x3ff : 0xff;
932e71cd
AJ
20877 env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
20878 /* vectored interrupts not implemented, timer on int 7,
20879 no performance counters. */
20880 env->CP0_IntCtl = 0xe0000000;
20881 {
20882 int i;
20883
20884 for (i = 0; i < 7; i++) {
20885 env->CP0_WatchLo[i] = 0;
20886 env->CP0_WatchHi[i] = 0x80000000;
fd88b6ab 20887 }
932e71cd
AJ
20888 env->CP0_WatchLo[7] = 0;
20889 env->CP0_WatchHi[7] = 0;
fd88b6ab 20890 }
932e71cd
AJ
20891 /* Count register increments in debug mode, EJTAG version 1 */
20892 env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
9e56e756 20893
4b69c7e2
JH
20894 cpu_mips_store_count(env, 1);
20895
9e56e756
EI
20896 if (env->CP0_Config3 & (1 << CP0C3_MT)) {
20897 int i;
20898
20899 /* Only TC0 on VPE 0 starts as active. */
20900 for (i = 0; i < ARRAY_SIZE(env->tcs); i++) {
55e5c285 20901 env->tcs[i].CP0_TCBind = cs->cpu_index << CP0TCBd_CurVPE;
9e56e756
EI
20902 env->tcs[i].CP0_TCHalt = 1;
20903 }
20904 env->active_tc.CP0_TCHalt = 1;
259186a7 20905 cs->halted = 1;
9e56e756 20906
55e5c285 20907 if (cs->cpu_index == 0) {
9e56e756
EI
20908 /* VPE0 starts up enabled. */
20909 env->mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
20910 env->CP0_VPEConf0 |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
20911
20912 /* TC0 starts up unhalted. */
259186a7 20913 cs->halted = 0;
9e56e756
EI
20914 env->active_tc.CP0_TCHalt = 0;
20915 env->tcs[0].CP0_TCHalt = 0;
20916 /* With thread 0 active. */
20917 env->active_tc.CP0_TCStatus = (1 << CP0TCSt_A);
20918 env->tcs[0].CP0_TCStatus = (1 << CP0TCSt_A);
20919 }
20920 }
cec56a73
JH
20921
20922 /*
20923 * Configure default legacy segmentation control. We use this regardless of
20924 * whether segmentation control is presented to the guest.
20925 */
20926 /* KSeg3 (seg0 0xE0000000..0xFFFFFFFF) */
20927 env->CP0_SegCtl0 = (CP0SC_AM_MK << CP0SC_AM);
20928 /* KSeg2 (seg1 0xC0000000..0xDFFFFFFF) */
20929 env->CP0_SegCtl0 |= ((CP0SC_AM_MSK << CP0SC_AM)) << 16;
20930 /* KSeg1 (seg2 0xA0000000..0x9FFFFFFF) */
20931 env->CP0_SegCtl1 = (0 << CP0SC_PA) | (CP0SC_AM_UK << CP0SC_AM) |
20932 (2 << CP0SC_C);
20933 /* KSeg0 (seg3 0x80000000..0x9FFFFFFF) */
20934 env->CP0_SegCtl1 |= ((0 << CP0SC_PA) | (CP0SC_AM_UK << CP0SC_AM) |
20935 (3 << CP0SC_C)) << 16;
20936 /* USeg (seg4 0x40000000..0x7FFFFFFF) */
20937 env->CP0_SegCtl2 = (2 << CP0SC_PA) | (CP0SC_AM_MUSK << CP0SC_AM) |
20938 (1 << CP0SC_EU) | (2 << CP0SC_C);
20939 /* USeg (seg5 0x00000000..0x3FFFFFFF) */
20940 env->CP0_SegCtl2 |= ((0 << CP0SC_PA) | (CP0SC_AM_MUSK << CP0SC_AM) |
20941 (1 << CP0SC_EU) | (2 << CP0SC_C)) << 16;
20942 /* XKPhys (note, SegCtl2.XR = 0, so XAM won't be used) */
20943 env->CP0_SegCtl1 |= (CP0SC_AM_UK << CP0SC1_XAM);
51cc2e78 20944#endif
ddc584bd
LA
20945 if ((env->insn_flags & ISA_MIPS32R6) &&
20946 (env->active_fpu.fcr0 & (1 << FCR0_F64))) {
20947 /* Status.FR = 0 mode in 64-bit FPU not allowed in R6 */
20948 env->CP0_Status |= (1 << CP0St_FR);
20949 }
20950
0305d194
YK
20951 if (env->CP0_Config3 & (1 << CP0C3_ISA)) {
20952 /* microMIPS on reset when Config3.ISA == {1, 3} */
20953 env->hflags |= MIPS_HFLAG_M16;
20954 }
20955
863f264d
YK
20956 /* MSA */
20957 if (env->CP0_Config3 & (1 << CP0C3_MSAP)) {
20958 msa_reset(env);
20959 }
20960
03e6e501 20961 compute_hflags(env);
599bc5e8 20962 restore_fp_status(env);
e117f526 20963 restore_pamask(env);
27103424 20964 cs->exception_index = EXCP_NONE;
3b3c1694
LA
20965
20966 if (semihosting_get_argc()) {
20967 /* UHI interface can be used to obtain argc and argv */
20968 env->active_tc.gpr[4] = -1;
20969 }
6af0bf9c 20970}
d2856f1a 20971
bad729e2
RH
20972void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb,
20973 target_ulong *data)
d2856f1a 20974{
bad729e2 20975 env->active_tc.PC = data[0];
d2856f1a 20976 env->hflags &= ~MIPS_HFLAG_BMASK;
bad729e2 20977 env->hflags |= data[1];
4636401d
AJ
20978 switch (env->hflags & MIPS_HFLAG_BMASK_BASE) {
20979 case MIPS_HFLAG_BR:
20980 break;
20981 case MIPS_HFLAG_BC:
20982 case MIPS_HFLAG_BL:
20983 case MIPS_HFLAG_B:
bad729e2 20984 env->btarget = data[2];
4636401d
AJ
20985 break;
20986 }
d2856f1a 20987}